Skip to content

feat(threads): add comment auto-reply automation - #1020

Draft
AlanSyue wants to merge 2 commits into
ChatbotXIO:mainfrom
AlanSyue:feat/threads-comment-automation
Draft

feat(threads): add comment auto-reply automation#1020
AlanSyue wants to merge 2 commits into
ChatbotXIO:mainfrom
AlanSyue:feat/threads-comment-automation

Conversation

@AlanSyue

Copy link
Copy Markdown
Contributor

Adds Threads as a comment-automation channel: connect a Threads account, define keyword-matched automations against your posts, and auto-reply publicly to matching comments — the same flow Facebook and Instagram comment automations already offer.

What's included

New integration package — integrations/threads/

  • Threads OAuth (authorize → short-lived → long-lived exchange) plus refreshAuth for the 60-day token
  • Webhook handler for comment events, with error sanitizing/mapping consistent with the sibling Meta integrations
  • Registers the comment channel only. Threads has no Messaging API, so no message channel is declared rather than declaring one that always fails.

Database

  • New IntegrationThreads table (one row per connected account; unique on threadsUserId and on inboxId)
  • fbCommentAutomationType gains a threads value

Worker — comment automation extended to Threads

The existing pipeline now runs on Threads behind explicit capability predicates rather than silent no-ops:

capability messenger / instagram threads
public comment reply yes yes
private reply (DM) yes no — Threads has no private-reply API
like the user's comment yes no — no POST /{comment-id}/likes equivalent
hide comment yes no

An automation configured with an action the channel cannot perform logs an unsupported-capability line instead of enqueuing a job that could only fail, and the dedup/counter accounting only records a reply that actually went out.

Token refresh registers into the existing refreshChannelTokens adapter on the daily 02:00 run. Threads tokens are 60-day, so it deliberately does not join the midday short-lived pass.

Builder

  • Threads entry in CHANNEL_CAPABILITIES, so it appears in the channel create picker and settings without any new hardcoded channel list
  • Platform-credential screen for the Threads app (app id/secret + webhook URL) and the connect / disconnect / reconnect flows
  • threads-comments CRUD pages mirroring the existing Facebook and Instagram comment-automation screens
  • All strings go through useTranslations(); 20 locale files updated

Testing

workspace result
apps/worker 168 files / 1620 tests
apps/builder 266 files / 1668 tests
@chatbotx.io/integration-threads 5 files / 56 tests
@chatbotx.io/integration-messenger 29 files / 209 tests
@chatbotx.io/integration-instagram 13 files / 58 tests
@chatbotx.io/integration-instagram-facebook 10 files / 32 tests
@chatbotx.io/database 23 files / 417 tests

pnpm lint is clean, as are check-types for worker, builder and database.

Notes for review

  • Existing channels are untouched. Every new supports* predicate returns true for messenger / instagram / instagramFacebook, so all the new guards are no-ops on those channels.
  • Migrations are generated on top of 20260820152925_create_channel_api. The enum value is a separate migration because Postgres cannot use a newly added enum value inside the transaction that adds it.
  • Opened as a draft — happy to split the builder surface out of the integration + worker core if you would prefer to review this in smaller pieces.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Jr3BRqH3woCzbcePEBPira

AlanSyue and others added 2 commits August 22, 2026 19:03
The threads workspace re-exported the node vitest preset verbatim, and MSW
is opt-in there (see packages/vitest-config/src/node.ts): without
`mswSetupFiles` the shared `setupServer()` is never started, so every
`server.use(...)` handler in `__tests__/auth.test.ts` and
`__tests__/comment.test.ts` was registered against a server that was not
listening. Those 11 tests reached the real graph.threads.com and failed on
live OAuth errors.

Opt into the MSW lifecycle the same way instagram, instagram-facebook and
messenger do. No test assertion is changed; the handlers already existed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jr3BRqH3woCzbcePEBPira
@github-actions github-actions Bot added the feature New feature or request label Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant