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

# Lua

> Request context for the current turn, the inbound channel and the provider's raw webhook payload

`Lua.request` tells your code which [channel](/concepts/channels) the current turn came from and, on channels that deliver messages by webhook, the raw payload the provider sent. It is defined in every execution context. Outside a conversation turn, in a job, a webhook, or a trigger, there is no inbound channel: `channel` is `unknown` and `webhook` is `undefined`. A [model resolver](/concepts/models) on `LuaAgent` receives the same `LuaRequest` as its argument.

*Verified against lua-cli 3.33.0.*

```ts theme={null}
import { Lua } from 'lua-cli';
```

## Quick example

A tool condition can hide the tool on channels where it makes no sense.

```ts theme={null}
import { LuaTool, Lua, Data } from 'lua-cli';
import { z } from 'zod';

export default class ShareStoreLocationTool implements LuaTool {
  name = 'share_store_location';
  description = 'Send the store location as a WhatsApp location card';
  inputSchema = z.object({ storeId: z.string() });

  condition = async () => Lua.request.channel === 'whatsapp';

  async execute(input: z.infer<typeof this.inputSchema>) {
    const store = await Data.getEntry('stores', input.storeId);
    return { name: store.name, address: store.address, channel: Lua.request.channel };
  }
}
```

## Properties

### request.channel

The channel the current turn arrived on.

```ts theme={null}
Lua.request.channel: Channel
```

| Value                                                                                                                   | When                                                                                |
| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `pop`                                                                                                                   | The web widget. The `Channel` type spells this value `web`, so compare against both |
| `whatsapp`, `facebook`, `instagram`, `slack`, `teams`, `front`, `messagebird`, `email`, `rcs`, `sms`, `mms`, `imessage` | A message on that channel; `facebook` is Messenger                                  |
| `phone`                                                                                                                 | A voice call. Not in the `Channel` union, so compare it as a string                 |
| `meeting`                                                                                                               | A meeting the agent joined                                                          |
| `device`                                                                                                                | A turn from a device                                                                |
| `api`                                                                                                                   | The REST chat API                                                                   |
| `agent-invocation`                                                                                                      | A turn started by `Agents.invoke`, unless the caller set `channel`                  |
| `dev`                                                                                                                   | `lua test`                                                                          |
| `unknown`                                                                                                               | A job, webhook, or trigger, or a channel the runtime didn't label                   |

`Channel` is a union of the common names plus `string`, so comparing against any value type-checks. Keep a default branch. The outbound names on [`Channels.send`](/reference/sdk/channels) differ for two channels: `webchat` sends to the web widget, and `messenger` sends to `facebook`.

### request.webhook

The provider's raw event for the inbound message, when the channel delivers by webhook.

```ts theme={null}
Lua.request.webhook: { payload: any } | undefined
```

`webhook` is set when the provider delivered the message by webhook, which is the case for WhatsApp, Messenger, Instagram, Slack, and email, and `undefined` for the web widget, the REST API, `lua test`, and every context outside a turn. `payload` is the provider's own object: the WhatsApp Cloud API webhook entry, the Slack Events API event, and so on. For email it is a parsed message rather than raw MIME: `messageId`, `inReplyTo`, `references`, `subject`, `from`, `to`, `cc`, `bcc`, `replyTo`, `date`, and `headerLines`, where the ids are bare (no angle brackets) and each address is `{ address, name }`.

**Example**

```ts theme={null}
import { Lua } from 'lua-cli';

export function inboundWhatsAppIds() {
  const webhook = Lua.request.webhook;
  if (Lua.request.channel !== 'whatsapp' || !webhook) return undefined;
  const value = webhook.payload.entry?.[0]?.changes?.[0]?.value;
  return { messageId: value?.messages?.[0]?.id, phoneNumberId: value?.metadata?.phone_number_id };
}
```

## Types

<ResponseField name="LuaRuntime" type="interface">
  `{ request: LuaRequest }`, the type of `Lua`.
</ResponseField>

<ResponseField name="LuaRequest" type="interface">
  `{ channel: Channel; webhook?: WebhookRequest }`. Also the argument type of a model resolver, `LuaAgentModel = string | ((request: LuaRequest) => string | Promise<string>)`.
</ResponseField>

<ResponseField name="WebhookRequest" type="interface">
  `{ payload: any }`.
</ResponseField>

<ResponseField name="Channel" type="union">
  `'web' | 'whatsapp' | 'facebook' | 'instagram' | 'slack' | 'teams' | 'front' | 'messagebird' | 'api' | 'dev' | 'email' | string`. The runtime also produces the values listed under `request.channel` that the union doesn't spell out.
</ResponseField>

## See also

* [About execution contexts](/concepts/execution-contexts) — what `User`, `Lua.request`, and `env` resolve to in each context
* [`LuaAgent`](/reference/sdk/luaagent) — the model resolver that receives `LuaRequest`
* [`Channels`](/reference/sdk/channels) — the outbound channel names
* [About channels](/concepts/channels) — every channel and how it delivers
