Discord#
Discord is registered for read-only API sync with sync-coupled user import. An organization supplies its own Discord bot, one guild id, and an allow-list of Forum channel ids. The adapter imports public Forum posts and their starter messages into a reviewable TeamBoost import session; it does not import ordinary chat channels, private threads, or age-restricted Forums.
| Capability | Method | Status |
|---|---|---|
SYNC |
Pull selected public Forum posts through Discord REST API v10 | Built |
USER_IMPORT |
Bring the selected guild's human member directory into task-import mapping | Built as part of API sync |
CSV_IMPORT |
Upload a Discord export | Not built |
WEBHOOK |
Receive Forum/thread/message changes | Not built |
The endpoints below live under /api/v1/providers/discord/.... They are generic:
the same routes serve any registered provider by substituting the {provider}
path segment. All routes require an organization-scoped user token (see
Authentication).
Discovery#
GET /api/v1/providers/discord
{
"status": "success",
"data": { "provider": "discord", "capabilities": ["SYNC", "USER_IMPORT"] }
}
Bot Setup And Credential Verification#
Create a customer-managed Discord application and install its bot into the
selected guild with the bot scope. The read-only sync needs:
- View Channels and Read Message History permissions on each selected Forum;
- Server Members Intent for the guild member directory; and
- Message Content Intent for Forum starter content.
Do not grant administrator, channel-management, moderation, message-send, or thread-management permissions for this read-only integration.
Store one strict versioned credential envelope per TeamBoost organization:
PUT /api/v1/providers/discord/credentials?organization_id=<id>
POST /api/v1/providers/discord/credentials/verify?organization_id=<id>
The write-only outer request contains a JSON-serialized secret:
{
"secret": "{\"version\":1,\"botToken\":\"...\",\"guildId\":\"100000000000000001\",\"forumChannelIds\":[\"100000000000000002\"]}"
}
The inner envelope accepts exactly these camel-case fields. version must be
1; ids must be canonical positive decimal Discord snowflakes; and
forumChannelIds must contain 1–25 unique ids. Raw-token and extra-field
fallbacks are rejected.
Verification checks the bot identity, guild, Forum allow-list, representative
starter-message visibility when a post exists, and guild-member access. A
selected channel must be a public, non-NSFW Forum in the configured guild.
Rejected tokens, missing permissions/intents, mismatched scope, malformed JSON,
and inaccessible configured guild/Forum resources return invalid_api_key. If
a listed Forum post's starter message disappears before it can be fetched, the
sync fails closed with service_unavailable instead of mislabeling the valid
bot credential or persisting a partial session. Stored secrets are encrypted at
rest, organization-scoped, replaceable through the same PUT, and never
returned by the credential endpoints.
Importing Forum Posts#
POST /api/v1/providers/discord/imports/sync?organization_id=<id>
The adapter uses Discord REST API v10 with Authorization: Bot <token>. It
fetches the configured guild and channels, active guild threads, public archived
threads under each selected Forum, each selected thread's starter message, and
the full guild member directory. Threads are filtered back to the configured
Forum allow-list before mapping.
The first shipped pull is deliberately bounded:
- active public posts plus public archived posts from the preceding 90 days;
- at most 25 selected Forums and 500 combined posts;
- at most 100 archived pages per Forum and 100 member pages;
- at most 5 concurrent starter-message requests;
- at most 3 request attempts and 60 seconds of cumulative provider-directed rate-limit waiting per client run.
The adapter fails loudly when a bound is exhausted instead of returning a
silently truncated import. It follows Discord's live rate-limit headers and
retry_after values, retries bounded network/5xx failures, and does not retry
deterministic 4xx failures.
User Mapping#
USER_IMPORT rides the sync flow. Human guild members become mapping candidates
using the stable Discord user snowflake as sourceAccountId. Display-name
precedence is guild nickname, then global display name, then username. Discord's
guild directory does not supply e-mail addresses, so matching is name-based or
manual. Bots and system users are excluded. Members still pending membership
screening remain visible with an explicit review suffix in their proposed name.
When the starter's human author is mapped, the adapter proposes that TeamBoost
member as both creatorId and requestedById. ownerId remains unset because a
Discord Forum post has no assignee. Bot, system, webhook, and unmapped authors do
not receive an invented TeamBoost identity.
Projection Field Coverage#
| Discord source | TeamBoost draft field | Notes |
|---|---|---|
Thread name |
title |
Fewer than two usable characters is a projection error |
Starter content |
description |
Requires Message Content Intent for normal text posts |
| Forum post | type |
Defaults to OTHER with a mapping note |
| Archive/lock state | status |
Left unset; Discord archive is not task completion |
| No native task priority | priority |
Defaults to UNKNOWN with a mapping note |
| Applied Forum tags | labels |
Uses configured tag display names; stable tag ids stay in context |
| Mapped human starter author | creatorId, requestedById |
Both map to the author; ownerId stays unset |
| Guild name | projectTitle |
Discord - <guild name> |
| Guild and Forum names | taskGroupTitle |
<guild name> - #<forum name> |
| Discord task lifecycle | scheduleStage |
Defaults to PENDING |
| Guild, Forum, thread, author, jump URL, tags, archive/lock state, counts, safe attachment/embed/poll/reaction summaries | descriptionJson.discord |
Attachment URLs are excluded from the projected draft |
The import session's authorized lossless source record retains the selected
guild, Forum, thread, and starter-message response for review. The projected
draft deliberately omits signed attachment URLs so expiring credential-bearing
CDN links are not copied into a TeamBoost task.
Not Built Yet#
- Ordinary text-channel messages, replies, private threads, private Forums, or NSFW/age-restricted sources.
- Discord Gateway ingestion for real-time Forum/thread/message events.
- Discord interactions or slash commands such as a create-task command.
- A shared TeamBoost-managed Discord bot installation flow.
- CSV or personal Discord data-package import.
- Standalone member-directory import before task sync.
- Live Discord validation in automated tests; release smoke requires an isolated non-production guild, application, bot token, and synthetic Forum content.