> ## Documentation Index
> Fetch the complete documentation index at: https://docs.os.meetluno.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# App events

> Run workflows when connected apps emit events.

A common goal is "run this when something happens in another app," such as a new GitHub issue, a paid Stripe invoice, or a Linear status change. Luno OS doesn't have a separate app-event trigger type; instead you react to app events with the [trigger sources](https://docs.os.meetluno.ai/learn/triggers/overview.md) you already have, pointed at the app. This page covers the patterns.

> [!NOTE]
>
> There's no `defineAppEventSource`. The three sources ([webhook](https://docs.os.meetluno.ai/learn/triggers/webhooks.md), [schedule](https://docs.os.meetluno.ai/learn/triggers/schedules.md), and [poll](https://docs.os.meetluno.ai/learn/triggers/polling.md)) cover app events. Pick the one that matches how the app delivers events.

## When the app sends webhooks

Most modern apps can push events to a URL. This is the best option when it's available: point the app's webhook at a [webhook trigger](https://docs.os.meetluno.ai/learn/triggers/webhooks.md).

1. Define a `defineWebhookSource` with a `payload` schema for the app's event.
2. Get the URL with `luno triggers url <endpoint>` and register it in the app's settings.
3. Put event-type constraints (literals, enums) in the `payload` schema so only the events you care about fire.

```ts src/triggers/stripe-invoice-paid.ts theme={null}
import { defineWebhookSource } from "@meetluno/luno/trigger";
import { z } from "zod";
import workflow from "../workflows/invoice-paid";

export default defineWebhookSource({
  slug: "stripe-invoice-paid",
  name: "Stripe invoice paid",
  description: "Fires when Stripe sends an invoice.paid event.",
  endpoint: "stripe",
  payload: z.object({
    type: z.literal("invoice.paid"),
    data: z.object({ id: z.string() }),
  }),
}).attach({
  workflow,
  transform: (payload) => ({ invoiceId: payload.data.id }),
});
```

Providers that send every event type to one URL fit the [shared endpoint](https://docs.os.meetluno.ai/learn/triggers/webhooks.md#shared-endpoints) pattern: many triggers on a single `endpoint`, each with its own `payload` for its event.

## When the app doesn't push events

If an app has no webhooks (or you'd rather pull), use a [poll trigger](https://docs.os.meetluno.ai/learn/triggers/polling.md). Its `run()` checks the app's API on a schedule and starts a run only when there's something new:

```ts src/triggers/new-issues.ts theme={null}
import { definePollSource } from "@meetluno/luno/trigger";
import workflow from "../workflows/handle-issue";

export default definePollSource({
  slug: "new-issues",
  name: "New issues",
  description: "Polls for open issues every ten minutes.",
  schedule: "*/10 * * * *",
  run: async () => fetchOpenIssues(),
  filter: (result) => result.issues.length > 0,
}).attach({ workflow });
```

When the source you're polling needs credentials, resolve them through an [action](https://docs.os.meetluno.ai/learn/actions/overview.md) that you call from `run()`, or read them from your project's [credentials](https://docs.os.meetluno.ai/learn/credentials/overview.md).

## Chat apps: the Slack gateway

Conversations are different from events. To let people talk to an [agent](https://docs.os.meetluno.ai/learn/agents/overview.md) from Slack (mention it in a channel or DM it), connect the **Luno OS Slack App** (`luno connect slack --kind luno`; catalog slug `slackbot`) and use the Slack **gateway** rather than a trigger. The gateway delivers inbound messages to an agent and posts replies back as the bot. See [external channels](https://docs.os.meetluno.ai/learn/agents/external-channels.md).

## Finding integrations

To react to an app, call its API from an action inside a poll's `run()`, or point its webhooks at Luno OS as above. See [integrations](https://docs.os.meetluno.ai/integrations.md) for connecting apps.

## Next steps

> **[Webhooks](https://docs.os.meetluno.ai/learn/triggers/webhooks.md)**
>
> Receive events the app pushes to a URL.

> **[Polling](https://docs.os.meetluno.ai/learn/triggers/polling.md)**
>
> Pull events from an app on a schedule.

> **[External channels](https://docs.os.meetluno.ai/learn/agents/external-channels.md)**
>
> Connect agents to Slack and other chat surfaces.

> **[Integrations](https://docs.os.meetluno.ai/integrations.md)**
>
> Connect the apps you use.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.