A technical walkthrough details the construction of a bidirectional bridge that integrates the MAX messenger and VK communities into Chatwoot as separate API inboxes. The solution avoids web scraping and personal account automation by relying exclusively on official bot endpoints and community callback mechanisms.
The architecture consists of a minimal Node.js service exposing four webhook routes: incoming events from MAX, VK Callback API confirmations and messages, plus protected outgoing routes triggered by Chatwoot message_created events. All traffic terminates at a reverse proxy while the container itself remains isolated on an internal Docker network.
Contacts are created with stable identifiers prefixed by channel (max: or vk:) to prevent cross-platform collisions. Conversations are then linked via source_id returned by the Chatwoot Application API, and mappings are persisted in a JSON file inside a named Docker volume to survive container restarts.
Incoming MAX messages are authenticated using the X-Max-Bot-Api-Secret header and filtered to exclude bot-generated updates. VK events undergo group_id and secret validation, with only message_new events processed. Photographs from VK are downloaded at maximum resolution and forwarded as multipart attachments.
Outbound messages from Chatwoot are filtered to ensure only genuine operator replies are relayed. MAX messages use the platform-api2 endpoint with Authorization tokens supplied via mounted secrets. VK image uploads follow the three-step photos.getMessagesUploadServer, upload, and photos.saveMessagesPhoto flow.
Deduplication relies on message IDs stored in limited ring buffers of the last 2000 events. The author notes that this provides protection against duplicate webhooks but does not guarantee exactly-once semantics. SSRF risks are mitigated by enforcing HTTPS, exact origin matching for Chatwoot URLs, MIME-type restrictions, size limits, and redirect validation.
The implementation is packaged as a minimal Alpine-based Docker image running as an unprivileged user. Production recommendations include replacing the JSON state file with a transactional database, adding a durable queue with dead-letter handling, and implementing structured logging plus rate-limit awareness.


