# Multiple triggers & wildcards
Source: https://www.inngest.com/docs/guides/multiple-triggers

Inngest functions can be configured to trigger on multiple events or schedules.

Using multiple triggers is useful for running the same logic for a wide array of events, or
ensuring something also runs on a schedule, for example running an integrity
check every morning, or when requested using an event.

Multiple triggers can be configured using an [list of triggers](#multiple-triggers), or [wildcard event triggers](#wildcard-event-triggers).

## Multiple triggers

Functions support up to 10 unique triggers. This allows you to explicitly match multiple events, or schedules. Multiple schedules that overlap will be de-duplicated - Learn more about [overlapping crons](#overlapping-crons).

<CodeGroup>
```ts {{ title: "TypeScript" }}
inngest.createFunction(
  { id: "resync-user-data" },
  [
    { event: "user.created" },
    { event: "user.updated" },
    { cron: "0 5 * * *" }, // Every morning at 5am
  ],
  async ({ event, step }) => {
    // ...
  },
);
```
```go {{ title: "Go" }}
inngestgo.CreateFunction(
	client,
	inngestgo.FunctionOpts{Name: "resync-user-data"},
	inngestgo.MultipleTriggers{
		inngestgo.EventTrigger("user.created", nil),
		inngestgo.EventTrigger("user.updated", nil),
		inngestgo.CronTrigger("0 5 * * *"),
	},
	func(ctx context.Context, input inngestgo.Input[map[string]any]) (any, error) {
		// ...
		return nil, nil
	},
)
```
```py {{ title: "Python" }}
@inngest_client.create_function(
    fn_id="resync-user-data",
    trigger=[
        inngest.TriggerEvent(event="user.created"),
        inngest.TriggerEvent(event="user.updated"),
        inngest.TriggerCron(cron="0 5 * * *")
    ],
)
def my_handler(ctx: inngest.Context) -> None:
     # ...
```
</CodeGroup>

## Wildcard event triggers

Event triggers can be configured using wildcards to match multiple events. This is useful for matching entire groups of events for cases like forwarding events to another system, like an real-time ETL.

Wildcards can be used after any `/` or `.` character to match entire groups of events. Here are some examples:

* `app/*` matches any event with the `app` prefix, like `app/user.created` and `app/blog.post.published`.
* `app/user.*` matches any event with the `app/user.` prefix, like `app/user.created` and `app/user.updated`.
* `app/blog.post.*` matches any event with the `app/blog.post.` prefix, like `app/blog.post.published`.

<Info>
Wildcards cannot be used following any characters other than `/` and `.` or in the middle of a pattern, so mid-word wildcards like `app/user.update*` and `app/blog.*.published` are not supported.
</Info>

### Defining types for wildcard triggers

To define types for wildcard triggers, you need to explicitly define

```ts
type WildcardEvents = {
  "app/blog.post.*": {
    name: "app/blog.post.created" | "app/blog.post.published";
    data: {
      postId: string;
      authorId: string;
      createdAt: string;
    } | {
      postId: string;
      authorId: string;
      publishedAt: string;
    }
  }
}
new Inngest({
  id: "my-app",
  schemas: new EventSchemas().fromRecord<WildcardEvents>()
});

inngest.createFunction(
  { id: "blog-updates-to-slack" },
  { event: "app/blog.post.*" },
  async ({ event, step }) => {
    // ...
  },
);
```

## Determining event types

In the handler for a function with multiple triggers, the event that triggered
the function can be determined using the `event.name` property.

<CodeGroup>
```ts {{ title: "TypeScript" }}
async ({ event }) => {
  //      ^? type event: EventA | EventB | InngestScheduledEvent | InngestFnInvoked
  if (event.name === "a") {
    // `event` is type narrowed to only the `a` event
  } else if (event.name === "b") {
    // `event` is type narrowed to only the `b` event
  } else {
    // `event` is type narrowed to only the `inngest/function.invoked` event
  }
}
```
```go {{ title: "Go" }}
func(ctx context.Context, input inngestgo.Input[map[string]any]) (any, error) {
	switch input.Event.Name {
	case "a":
		// Handle event A
	case "b":
		// Handle event B
	case "inngest/function.invoked":
		// Handle function invoked event
	}
	return nil, nil
},
```
</CodeGroup>

Note that batches of `events` can contain many different events; you will need
to assert the shape of each event in a batch individually.

## Overlapping crons

If your function defines multiple cron triggers, the schedules may sometimes overlap. For example, a cron `0 * * * *` that runs every hour and a cron `*/30 * * * *` that runs every half hour would overlap at the start of each hour.

Only one cron job will be run for each given second, so in this case above, one cron would run every half hour.

{/* There's a place for wildcards here if we want to talk about them. They're
pretty undocumented... */}