Integrate third-party chatbots with actions and triggers

Zoom Contact Center supports integrating third-party chatbot platforms and homegrown AI agents or bots into chat flows through Zoom Marketplace apps. If you are working with a third-party bot provider, you can share this documentation with them and review whether they are able to connect their bot to the ZCC chatbot framework.

By integrating your chatbot with Zoom Contact Center, you gain access to a full suite of engagement capabilities including chat and messaging capabilities, video escalation, cobrowsing, and screen sharing. Your bot can leverage Contact Center's intelligent routing and queue management to seamlessly transition conversations to live agents, while providing unified analytics and reporting across all engagement channels.

Zoom provides the consumer user interface through the Zoom Contact Center web SDK and handles orchestration. Any bot that can interface with the chatbot framework can plug in through the bot widget and route through the bot flow.

Using action and trigger mode, your app will be visible in the bot widget and you can route chat engagements to external bots that provide automated responses and hand off conversations to live agents when needed through the bot flow.

Action and trigger mode provides two integration capabilities:

  • Action (synchronous) - Contact Center sends a consumer message to your bot and waits for a response
  • Trigger (asynchronous) - Your bot pushes replies back to Contact Center asynchronously for long-running operations

Actions can standalone for immediate bot responses. Triggers must be paired with actions and are used when your bot needs additional processing time.

Prerequisites

Before you begin, ensure you have the following:

  • Admin role with "Zoom for developers" permission enabled. For more information, see Check role permissions in the Build your app guide.
  • Chatbot action mode enabled. For more information, contact Zoom technical support.
  • Contact Center Admin role for Flow, Queue, and Entry Point configuration
  • Access to Contact Center Management > Roles

Create and configure the Marketplace app

Create a General App on Zoom Marketplace and configure it for Contact Center chatbot integration.

Create the app

Create a new General App on Zoom Marketplace.

  1. Sign in to Zoom Marketplace.
  2. Choose Develop and then Build app.
  3. Choose General App and then Create.
  4. (Optional) Rename your app.

Configure app type

Change the app to admin-managed mode, which is required for Contact Center chatbot integration.

  1. In the navigation pane, choose Basic Information.
  2. In the Select how the app is managed section, select Admin-managed.
  3. Choose Save.

Add a custom form (optional)

If your bot requires connection-level configuration (such as botId or projectId), add a custom form.

  1. In the navigation pane, choose Custom Form.
  2. Add your configuration fields.
  3. In the Field setting levels, select Connection-level.
  4. Choose Save Changes.

Configure base URL and authentication

Set up the base URL and authentication method for your bot API.

  1. In the navigation pane, choose Connect.
  2. Choose Base URL & authentication.
  3. Enter your Base URL (for example, https://your-bot-platform.com/api).
  4. Select your authentication method (API Key, OAuth 2.0, Basic Auth, Bearer Token, or JWT Bearer).
  5. Configure the authentication credentials.
  6. Choose Save changes.

Configure the action

Actions define how Contact Center sends messages to your bot and transforms the responses.

Add an endpoint

Create an endpoint that Contact Center will call to send messages to your bot.

  1. In the navigation pane, choose Connect.
  2. Choose Endpoints.
  3. Choose + New endpoint.
  4. Configure the endpoint:
    • Method: POST
    • Display name: send_message_to_bot
    • Endpoint path: /send_message_to_bot
    • Parameters: Leave empty
  5. Choose Save.

The complete endpoint URL will be your Base URL combined with the endpoint path (for example, https://your-bot-platform.com/api/send_message_to_bot).

Create the action

Use the actions wizard to configure how Contact Center interacts with your bot.

  1. In the navigation pane, choose Actions and Triggers.
  2. Choose + New action.
  3. Select Built-in actions.

Note

If you don't see Built-in actions as an option, verify that Chatbot action mode has been enabled for your account. Contact Zoom technical support to enable this feature.

  1. In the action dropdown, select zcc.chatbot_send_message_to_bot.
  2. Choose Next.
  3. On the access page, verify Contact Center Chatbot is checked and choose Next.
  4. On the Form Builder page, use the predefined fields and choose Next.
  5. On the Transformations page:
    • In UI mode, select your endpoint from the dropdown
    • Switch to Script mode
    • Write your transformation script (see examples below)
  6. Optionally test your action, then choose Finish.

Write the transformation script

The transformation script converts between Contact Center's message format and your bot's API format.

Available APIs

Use these APIs in your transformation script.

  • ctx.inputData - Access Contact Center input fields
  • zm.fetch({ url, method, data }) - Make HTTP requests to your endpoint
  • zm.handleResponse(result, successFn, errorFn) - Handle responses (2xx/3xx codes trigger success function)
  • zm.log.info('message {}', value) - Log messages using {} placeholders

Input format (Contact Center to bot)

Contact Center sends messages to your bot in this format.

{
    "id": "msg-001",
    "sessionId": "sess-abc-123",
    "conversationMode": "START_CONVERSATION",
    "message": { "type": "text", "value": "hi" },
    "conversationVariables": {
        "global_system.Engagement.timezone": "America/New_York"
    },
    "additionalPayload": null,
    "languageCode": "en-US",
    "timestamp": 1700000000000,
    "userId": "user-xyz-789",
    "customData": {
        "botId": "bot-001",
        "flowId": "flow-001",
        "signature": "<zcc-injected-signature>",
        "connectionId": "conn-001"
    }
}

Key fields:

  • conversationVariables - Only populated on START_CONVERSATION, empty {} on subsequent messages
  • additionalPayload - null for text messages, contains interaction data for forms/cards/quick replies
  • message.type - Can be text, html, markdown, quickReplies, picker, image, card, form, and more
  • customData - Opaque blob that must be preserved and returned unchanged

Output format (bot to Contact Center)

Your bot must return responses in this format.

{
    "id": "resp-001",
    "sessionId": "sess-abc-123",
    "body": [{ "type": "text", "value": "Hi, I'm your virtual agent!" }],
    "timestamp": 1700000001000,
    "userId": "user-xyz-789",
    "completed": false,
    "customData": { "...": "write back as-is" }
}

Required fields:

  • userId - Must match the request value exactly
  • customData - Must match the request value exactly (treat as opaque, never parse or modify)
  • completed - Set to false to continue conversation, true to end and proceed to next flow step

Don't parse customData

Always pass customData through unchanged. It contains anti-forgery tokens and internal state that may change across versions. Never parse, validate, or construct customData fields.

Script examples

The following examples show common transformation script patterns for different integration scenarios.

Pass-through for trigger support

Use this script when your bot supports asynchronous responses via triggers.

zm.log.info("Action script start - pass-through");
const {
    id,
    sessionId,
    conversationMode,
    message,
    conversationVariables,
    additionalPayload,
    languageCode,
    timestamp,
    userId,
    customData,
} = ctx.inputData;
const myCustomData = customData; // Save to pass back unchanged in response
const result = await zm.fetch({
    url: "/send_message_to_bot",
    method: "POST",
    data: {
        id,
        sessionId,
        conversationMode,
        message,
        conversationVariables,
        additionalPayload,
        languageCode,
        timestamp,
        userId,
        customData,
    },
});
return zm.handleResponse(
    result,
    (body) => {
        zm.log.info("Bot response received");
        body.customData = myCustomData;
        return body;
    },
    (code, msg, body) => {
        zm.log.error("Request failed. Code: {}, message: {}", code, msg);
        return zm.errorResponse(code, msg, body);
    },
);

Custom format transformation

Use this script when your bot uses a different API format and returns responses synchronously.

If your bot expects this format:

{
    "botMessage": { "type": "text", "value": "hi" },
    "session": "sess-abc-123",
    "user": "user-xyz-789",
    "time": 1700000000000,
    "mode": "START_CONVERSATION",
    "lang": "en-US",
    "variables": {},
    "payload": null
}

And returns this format:

{
    "messageId": "bot-resp-001",
    "replyText": "Response text",
    "isComplete": false
}

Use this transformation script:

zm.log.info("Action script start - custom transformation");
const {
    id,
    sessionId,
    conversationMode,
    message,
    conversationVariables,
    additionalPayload,
    languageCode,
    timestamp,
    userId,
    customData,
} = ctx.inputData;
const myCustomData = customData; // Save to pass back unchanged in response
const result = await zm.fetch({
    url: "/send_message_to_bot",
    method: "POST",
    data: {
        botMessage: message,
        session: sessionId,
        user: userId,
        time: timestamp,
        mode: conversationMode,
        lang: languageCode,
        variables: conversationVariables,
        payload: additionalPayload,
    },
});
return zm.handleResponse(
    result,
    (body) => {
        zm.log.info(
            "Bot response received, transforming to Contact Center format",
        );
        return {
            id: body.messageId || id,
            sessionId: sessionId,
            body: [{ type: "text", value: body.replyText }],
            timestamp: Date.now(),
            userId: userId,
            completed: body.isComplete || false,
            customData: myCustomData,
        };
    },
    (code, msg, body) => {
        zm.log.error("Request failed. Code: {}, message: {}", code, msg);
        return zm.errorResponse(code, msg, body);
    },
);

Configure the trigger (for asynchronous responses)

Triggers allow your bot to push responses back to Contact Center asynchronously when processing takes longer than the action timeout allows. Triggers must always be paired with an action. The action initiates the request to your bot, and the trigger provides an asynchronous response channel for your bot to send replies back when processing is complete.

Create a static webhook

Create an incoming webhook that your bot will call to send asynchronous responses.

  1. In the navigation pane, choose Connect.
  2. Choose Incoming webhooks.
  3. Choose + New incoming webhook.
  4. Configure your webhook settings.
  5. Choose Save changes.

When using triggers, your bot must include the customData object from the original action request in the webhook callback. Contact Center uses this data to route the response to the correct conversation.

Note

One app can have at most one zcc.chatbot_send_message_to_bot action and one zcc.bot_message trigger.

Test the integration

Test your integration in two stages: first validate the app configuration in Zoom Marketplace, then test the complete conversation flow in the Contact Center admin portal.

Test in Zoom Marketplace

Validate your endpoint configuration and transformation script in Zoom Marketplace where you created your app.

  1. In the navigation pane, choose Connect.
  2. Choose Base URL & authentication.
  3. In the Test connection section, choose + Add connection to create a test connection.
  4. Use the test connection to validate endpoint connectivity.
  5. In the navigation pane, choose Actions and Triggers.
  6. Open your action and use the Test step with sample input to verify your transformation logic.

Create a production connection

Create a production connection in Zoom Marketplace that you'll use in your Contact Center flow.

  1. In the navigation pane, choose Connect.
  2. Choose Base URL & authentication.
  3. Choose + Add connection to create a new connection with your bot's production credentials.

Test in the admin portal

Test the complete conversation flow from consumer interaction through bot response and agent handoff in the Contact Center admin portal.

  1. Sign in to the Zoom admin portal.
  2. In the navigation pane, choose Contact Center Management.
  3. Choose Flows.
  4. Create a flow with a Bot node that uses your production connection.
  5. Configure a Queue and Entry Point for the flow.
  6. Initiate a test conversation as a consumer.
  7. Verify bot responses and conversation flow.
  8. If your bot supports handoff, test the transition to a live agent.

After successful testing, publish your app on Zoom Marketplace to make it available for installation by Contact Center admins.