# Official provider adapters Standard-library-only Go package for text sending and verified inbound message normalization. No outgoing requests are made by tests. Import the `.go` files into GoChat's provider package; the temporary `go.mod` is only for standalone validation. ## Public API ```go client := provider.NewClient() externalID, err := client.Verify(ctx, account) // read-only identity validation messageID, err := client.Send(ctx, account, recipientID, text, clientUUID) challenge, handled, err := provider.Challenge(account, request, rawBody) events, err := provider.ParseWebhook(account, request, rawBody) ``` `Verify` returns the canonical external ID and rejects a different configured ID. It does not send messages, subscribe an app, or register a webhook. `Send` requires the operator to have authorized the actual outgoing message. The parent server enforces message windows and operator authorization. | Provider key | Account ExternalID | AccessToken | Secret | VerifyToken | Recipient / conversation ID | | --- | --- | --- | --- | --- | --- | | `line` | Bot's `userId` from `/v2/bot/info` | Channel access token | Channel secret | Unused | User, group, or room ID from source | | `telegram` | Bot ID from `getMe` | Bot token | Unused | Unique `setWebhook.secret_token` for this bot | Chat ID, including negative group/channel IDs | | `messenger` | Facebook Page ID | Page access token | Meta app secret | App webhook verify token | Page-scoped sender ID | | `instagram` | Professional IG user ID | Instagram Login access token | Meta app secret | App webhook verify token | Instagram-scoped sender ID | | `whatsapp` | Phone-number ID, **not WABA ID** | Cloud API token | Meta app secret | App webhook verify token | Sender phone / `wa_id` | | `slack` | Workspace `team_id` from `auth.test` | Bot OAuth access token | App signing secret | Unused | Slack channel ID | Instagram uses **Instagram Login** and `graph.instagram.com`, requiring `instagram_business_manage_messages`. Tokens obtained with Facebook Login are a different integration and are not interchangeable. Graph version defaults to the explicitly pinned `v25.0`; set `Client.GraphVersion` to a supported version enabled on the Meta app. The default is not a claim that v25 is the latest version. Messenger needs `pages_messaging` to send/reply and `pages_manage_metadata` for page webhook subscriptions. GoChat's identity check (`GET /me?fields=id,name`) also requires `pages_read_engagement` on the Page token. In a live test on 2026-09-07, Meta returned HTTP 400 / code 100 without that permission, including when requesting `fields=id` alone. A signed inbound message can therefore arrive while the identity check still fails; GoChat intentionally keeps outbound sending blocked until verification succeeds. After the Page owner grants the additional scope, generate/update the Page token and run verification again. The scope also permits reading Page content and engagement data; explain this scope when asking the owner to grant it. See [Meta's Page permission guidance](https://developers.facebook.com/docs/apps/review/login-permissions#manage-pages). Meta failures expose only HTTP status and numeric error code/subcode in GoChat. Remote error text and trace data are never displayed or logged by the adapter because they can contain credentials or customer data. All other providers use fixed official hosts. Graph path fields and Telegram token syntax are restricted, redirects are disabled, requests have a 15-second deadline, responses are limited, and errors never include raw HTTP bodies or transport URLs containing tokens. ## Webhook integration 1. Resolve the account from the server-owned callback path and load credentials on the server. 2. Read at most 1 MiB with `http.MaxBytesReader` before calling the package. The package also rejects larger byte slices. 3. Call `Challenge`; handle its error before responding with any challenge. 4. Call `ParseWebhook` for POST events. It authenticates the unmodified raw bytes **before** JSON decoding. Telegram authenticates the secret header, since Telegram does not offer a payload HMAC here. 5. Commit messages using a durable unique index on `(account_id, event.ID)` before acknowledging delivery. The parser deduplicates only within a single request; delivery retries can occur later. 6. Preserve the provider timestamp. A missing timestamp stays zero, so the server must not treat it as reopening a Meta customer-service window. LINE validates destination; Meta filters Page/Instagram entry and recipient IDs; WhatsApp routes on `value.metadata.phone_number_id`; Slack matches the workspace. Require ExternalID for every webhook account other than Telegram, whose secret token must be unique per bot account. Slack signatures include a timestamp with a five-minute replay window. Meta GET challenges use a constant-time verify-token comparison; Slack challenges require a valid signature. Inbound attachment metadata becomes a readable placeholder, with caption where available. No remote attachment URL is fetched or returned. Meta echoes, Slack bot events, message edits/deletions and non-message delivery/status events are ignored. Telegram normal bot messages and channel posts are supported; Telegram Business connections are a separate adapter requirement. `clientUUID` adds LINE's retry key when it is a UUID. An accepted duplicate LINE request is recognized from HTTP 409 plus `X-Line-Accepted-Request-Id`. The other adapters do not promise network-level exactly-once delivery: do not automatically resend after an uncertain timeout. A returned ID confirms API acceptance, not final device delivery. LINE may return a request ID when its response contains no message ID. ## Validation ```sh GOCACHE=/tmp/gochat-provider-cache go test -race -cover ./... ``` Tests exercise raw-body tampering, invalid signatures before parsing, Slack replay and challenge authentication, Meta multi-account routing, WhatsApp phone-number routing, LINE group/room IDs, Telegram large integer IDs, duplicate and echo suppression, attachment URL exclusion, missing timestamps, API `ok:false` responses, HTTP failures without credential leakage, fixed hosts, redirect blocking and identity verification. Live credential/account tests are still required before claiming a connected account. ## Primary references - [LINE signature verification](https://developers.line.biz/en/docs/messaging-api/verify-webhook-signature/) - [LINE Messaging API reference](https://developers.line.biz/en/reference/messaging-api/) - [Telegram Bot API](https://core.telegram.org/bots/api) - [Meta Messenger Send API collection](https://www.postman.com/meta/messenger-platform-api/folder/7cc3gd2/send-api) - [Meta Instagram API collection](https://www.postman.com/meta/instagram/documentation/6yqw8pt/instagram-api) - [Meta WhatsApp Cloud API collection](https://www.postman.com/meta/whatsapp-business-platform/documentation/wlk6lh4/whatsapp-cloud-api) - [Slack request signature verification](https://docs.slack.dev/authentication/verifying-requests-from-slack/) - [Slack chat.postMessage](https://docs.slack.dev/reference/methods/chat.postMessage/) - [Slack auth.test](https://docs.slack.dev/reference/methods/auth.test/) ## Website Chat (local connector) Website Chat is created and managed through `/api/widgets`, not the generic social-account credentials endpoint. It feeds the same inbox and canonical ingest. Replies become available to the visitor through the local database; no provider HTTP is sent. The visitor projection excludes internal notes, delivery errors, agent identities and other visitors' conversations. Read setup, origin policy, rate limits and session expiry in [Zaapi feature documentation](zaapi-features.md). ## TikTok Business Messaging Use the approved developer App ID and App Secret, the authorized Business Account open_id, and short-term access token. Add a refresh token for renewal. GoChat verifies token identity and Messaging permissions, supports signed app-level callbacks at `/webhooks/tiktok`, and sends text to the actual conversation ID. Token renewal and webhook configuration are administrator actions; callback replacement applies across the app. Read [TikTok setup and limits](/docs/tiktok). This adapter does not cover TikTok Shop, personal inbox ownership or historical imports.