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

# Make

> Wire a bot to a Make scenario — verification, replies, files, and the response_url pattern.

Make (formerly Integromat) drives a bot well once you get past two quirks: its default `Accepted` reply, and the fact that it must *learn* your payload shape before you can map fields.

## Set up the trigger

<Steps>
  <Step title="Add a Custom webhook">
    Create one, copy the URL, and paste it into your bot's webhook settings.
  </Step>

  <Step title="Teach Make the payload shape">
    Click **Re-determine data structure**, then press **Verify** in your bot settings. Make catches the `webhook.verify` event and learns the fields.

    <Note>
      Until Make has seen a real payload, the mapping panel is empty — you cannot pick `response_url` or `message.text`. This step is not optional.
    </Note>
  </Step>

  <Step title="Add a Router">
    Route on `event`, with routes for `webhook.verify` and `message.created`.
  </Step>
</Steps>

## Pass verification

On the `webhook.verify` route, add a **Webhook response** module:

* **Status**: `200`
* **Body**: `{{1.challenge}}`
* **Custom headers**: none needed

<Tip>
  Make often wraps a mapped value in quotes, sending `"3f9a8c2e"` instead of `3f9a8c2e`. We allow exactly one pair of wrapping quotes, so both work. You can also send proper JSON if you like:

  ```json theme={null}
  { "challenge": "{{1.challenge}}" }
  ```

  with a `Content-Type: application/json` header — though the content type is ignored either way.
</Tip>

## Reply in the same request

For work under 10 seconds, end the route with a **Webhook response** module:

* **Status**: `200`
* **Body**:

```json theme={null}
{
  "text": "Your order **#4821** has shipped! 🎉",
  "buttons": [
    { "label": "Track package", "value": "4821" },
    { "label": "Contact support" }
  ]
}
```

* **Custom headers**: `Content-Type` → `application/json`

<Warning>
  Without a **Webhook response** module, Make replies `Accepted` the moment the scenario starts. We know that body and block it, so your customer sees nothing at all — no message, no error. If your Make bot is silent, this is why.
</Warning>

## Reply later

Anything slower than 10 seconds must confirm first.

<Steps>
  <Step title="Confirm">
    A **Webhook response** module with **Status** `200` and an empty **Body**, placed right after the trigger. The typing dots stay on.
  </Step>

  <Step title="Do the work">
    Anything you like, for up to 45 minutes.
  </Step>

  <Step title="POST the answer">
    Add an **HTTP → Make a request** module:

    * **URL**: `{{1.response_url}}`
    * **Method**: `POST`
    * **Body type**: `Raw`
    * **Content type**: `JSON (application/json)`
    * **Request content**:

    ```json theme={null}
    {
      "mid": "reply-{{1.event_id}}",
      "blocks": [
        { "type": "text", "text": "{{5.result}}" }
      ]
    }
    ```

    No authorization header — the key lives in the URL.
  </Step>
</Steps>

<Tip>
  **Always set a `mid`.** Make retries failed modules by default. Without a `mid`, each retry posts another copy. With one, retries become updates. Building it from `{{1.event_id}}` keeps it the same across tries.
</Tip>

## Send a file

Two modules.

<Steps>
  <Step title="Upload">
    **HTTP → Make a request**:

    * **URL**: `{{1.response_url}}/files`
    * **Method**: `POST`
    * **Body type**: `Multipart/form-data`
    * Add a field named `file`, type **File**, mapped from the earlier module's file data
    * You can also add a `filename` text field

    Turn on **Parse response**, and you get `file.file_id` back.
  </Step>

  <Step title="Post the message">
    **HTTP → Make a request**:

    * **URL**: `{{1.response_url}}`
    * **Body type**: `Raw` → `JSON`
    * **Request content**:

    ```json theme={null}
    {
      "mid": "june-report",
      "blocks": [
        { "type": "text", "text": "Here's your report 📊" },
        { "type": "file", "file_id": "{{2.file.file_id}}", "name": "june-report.pdf" }
      ]
    }
    ```
  </Step>
</Steps>

## Show progress

Several **HTTP** modules pointing at the same `response_url`, all sharing one `mid`:

```json theme={null}
{
  "mid": "job-42",
  "blocks": [
    { "type": "status", "state": "in_progress", "label": "Generating", "progress": 40 }
  ]
}
```

Then the same `mid` with `"state": "success"`. One bubble, changing.

## Handle button clicks

Clicks hit the same webhook with `event` set to `interaction.button_clicked`. Add a Router branch and map:

* `{{1.action_id}}` — which action
* `{{1.value}}` — your data
* `{{1.message_metadata}}` — state you attached when sending

<Note>
  Run **Re-determine data structure** and click a real button once, or Make will not know these fields exist.
</Note>

## Fixing problems

<AccordionGroup>
  <Accordion title="The bot says nothing">
    No **Webhook response** module, so Make replied `Accepted` and we blocked it. Add one.
  </Accordion>

  <Accordion title="I cannot map response_url">
    Make has not learned the structure. Click **Re-determine data structure**, then trigger a real event.
  </Accordion>

  <Accordion title="Verification fails with bad_challenge">
    Make sure the scenario is **ON**, not just open in the editor, and that the reply body maps `{{1.challenge}}`. The wizard shows what we received.
  </Accordion>

  <Accordion title="Every message arrives twice">
    Make retried, and you have no `mid`. Add `"mid": "reply-{{1.event_id}}"`.
  </Accordion>

  <Accordion title="422 BLOCK_VALIDATION_FAILED">
    Usually **Body type** is not `Raw` + `JSON`, so Make sent form data instead. Check the `issues` list in the reply, or your bot's delivery log.
  </Accordion>
</AccordionGroup>
