correspond.channels.discord#

Discord: a bot reading and posting in channels over REST, through discorddol.

Reference: discord:<channel id>, a channel or a thread (Discord numbers both with snowflakes). A bot reads only the channels its server roles let it see, and since Discord made message content a privileged intent, it reads the text of a message only when the Message Content intent is enabled for it (Developer Portal, Bot, Privileged Gateway Intents; a bot in more than 100 servers needs Discord’s approval) or when the message mentions it.

  • read fetches the channel’s history (the latest 50 messages unless limit says).

  • listen polls the channel for messages newer than the last one seen (the cursor is that message’s id; a first poll looks back a day): new messages, not edits or deletions. With listen_via = "gateway" it opens the gateway for a short window instead and reports new, edited and deleted messages; the cursor is the gateway session, which the next listen resumes (Discord replays what was missed) rather than identifying again, since 1,000 identifies in a day reset the bot token.

  • send posts a message (2,000 characters at most); a title is prepended in bold. With reply_to it is a Discord reply to that message (its author is not pinged). Only the users it mentions as <@id> are pinged: @everyone, @here and role mentions stay text, through Discord’s allowed mentions.

  • verify grades an HTTP interaction Discord posted to your endpoint: crypto when its Ed25519 signature (X-Signature-Ed25519 over X-Signature-Timestamp + body) checks against the application’s public key, forged otherwise. Discord sends deliberately invalid signatures to test the endpoint; those must come back forged (answer them 401).

Senders are platform: Discord authenticated the account, and correspond fetched the message from the API itself. A server member’s role ids are its authority. The bot token never appears in an error or a plan.

Needs the discord extra (discorddol, over discord.py in REST-only mode), imported on first use, not when the channel is listed.

>>> Discord().parse_ref("123456789012345678").encoded
'discord:123456789012345678'

Classes

Discord(*[, backend, http, run, clock, gateway])

A Discord bot over REST: read a channel, poll it for new messages, post to it.

class correspond.channels.discord.Discord(*, backend=None, http=<function urllib_http>, run=<function run>, clock=<built-in function time>, gateway=<function gateway_window>)[source]#

Bases: object

A Discord bot over REST: read a channel, poll it for new messages, post to it.

audience(ref, *, draft=None)[source]#

A DM’s two participants (or a group DM’s members), listed; otherwise the server’s members who can view the channel, never listed.

The channel is looked up once per reference. When it cannot be (no lookup in this backend, or Discord refused), the answer is the wider server group.

Return type:

Audience

property backend: Any#

discorddol’s REST backend with the configured bot token, or the one passed in.

property capabilities: Capabilities#

A bot’s view of Discord, over REST.

parse_ref(id)[source]#

A channel or thread id.

Return type:

ConversationRef

poll(ref, *, cursor=None, limit=None)[source]#

Messages newer than cursor (a message id), oldest first; a first poll looks back a day.

With listen_via = "gateway", one gateway window instead (see the module docstring).

read(ref, *, since=None, limit=None)[source]#

The channel’s latest messages (limit, else 50), oldest first; with since, only those after it.

Return type:

list[Message]

send(ref, draft, *, dry_run=False)[source]#

Post draft.text (the title, if any, prepended in bold) to the channel.

Return type:

SendResult

verify(headers, body)[source]#

crypto when X-Signature-Ed25519 checks over a fresh X-Signature-Timestamp + body, forged otherwise.

Raises MissingRequirement when the public key is unset or unusable (a configuration error, never a verdict on the request). Replay protection is the five-minute window only: a captured request can be replayed within it, so act idempotently on an interaction’s id.

Return type:

Authenticity