Chatwoot integration plugin for open-wa
Part of the @open-wa v5 monorepo.
@open-wa/integration-chatwoot bridges WhatsApp messages with Chatwoot CRM. The plugin creates a Chatwoot client, initializes the Chatwoot inbox when the open-wa core emits core.started, processes WhatsApp message.received events, and exposes a Hono router through createChatwootRouter for Chatwoot webhooks.
Use this integration when WhatsApp conversations should appear in Chatwoot and Chatwoot agent replies should be sent back through the open-wa client.
The plugin config is validated by the plugin SDK schema in src/plugin.ts.
| Field | Required | Source-visible behavior |
|---|---|---|
chatwootUrl |
Yes | URL for the Chatwoot instance. The client parses the Chatwoot origin, account ID, and optional inbox ID from this value. |
chatwootApiAccessToken |
Yes | Sent as api_access_token on Chatwoot API requests. |
apiHost |
No | Public API host used to build the expected Chatwoot webhook URL. |
host |
No | Used with https and port to build the webhook URL when apiHost is not provided. |
https |
No | Selects https or http when constructing the webhook URL from host and port. |
port |
No | Used in the constructed webhook URL when apiHost is not provided. |
apiKey |
No | Appended to the Chatwoot webhook URL as api_key when present. |
forceUpdateCwWebhook |
No | Defaults to false in the schema. When true, initialization patches the Chatwoot inbox webhook URL. |
The generated webhook URL is /plugins/chatwoot/webhook under the selected API host.
- On
core.started, the plugin callsclient.getHostNumber(), initializes the Chatwoot client with the currentsessionId, and finds or creates a Chatwoot inbox. - If the Chatwoot URL does not include an account ID, the client requests
/api/v1/profileto discover it. - If no inbox ID is present, the client searches existing inboxes for
additional_attributes.hostAccountNumber; otherwise it creates an API inbox namedopen-wa-{hostAccountNumber || sessionId}. - On
message.received, group and broadcast chats are skipped, ignored echo messages are skipped, contacts and conversations are found or created, and messages are sent to Chatwoot. - Media messages with
cloudUrlare sent to Chatwoot as a file URL in text. Media messages withoutcloudUrlcan be decrypted throughclient.decryptMediaand uploaded to Chatwoot as attachments whendeprecatedMms3Urlandmimetypeare present. - The router handles
POST /webhookfor Chatwoot outbound messages. It ignores source echo payloads, incoming/private/non-message_createdevents, sends attachments withsendImage, sends detected locations withsendLocation, sends detected URLs withsendLinkWithAutoPreview, and otherwise sends text withsendText. - On
dispose, the plugin logs that the integration was disposed.
- Default export and
chatwootPluginfromsrc/plugin.ts. ChatwootClientfromsrc/client.ts.createChatwootRouterfromsrc/middleware.ts.ChatwootPluginConfigandChatwootConfigtypes.
pnpm --filter @open-wa/integration-chatwoot buildpnpm --filter @open-wa/integration-chatwoot devpnpm --filter @open-wa/integration-chatwoot lintpnpm --filter @open-wa/integration-chatwoot clean
See the docs site.
H-DNH V1.0 - Hippocratic + Do Not Harm