webhook-impersonation

Discord bots post as themselves — one identity, the bot's name and avatar. YouTeacher's Discord bridge needs the opposite: every message that leaves the bridge should look like it came from the individual YouTeacher user who wrote it, with their display name and their avatar. The bridge gets there by riding on Discord webhooks, which let a single sender override the name and avatar on a per-message basis.

One managed webhook per channel. The first time the bridge posts into a channel, it looks for a webhook it already owns there — recognised by a fixed name, YouTeacher Bridge — and creates one only if none exists. That webhook is cached per channel so the lookup happens once. Every user's message in that channel then goes out through the same shared webhook, but each send overrides the display name and avatar with that user's own, so Discord shows a distinct author per message even though the underlying sender is one webhook. A user with no profile picture falls back to a default avatar, so they look the same here as on the web surface. Outgoing messages are sent with mention-parsing disabled, so text can't be turned into a live @-ping by the act of relaying it.

An attribution store remembers who each message belongs to. Sending through a webhook loses the link back to the YouTeacher user — Discord only knows "some webhook posted this." So on every successful send the bridge records, keyed by the new message id, which YouTeacher user it belongs to (plus the name and avatar used). This store is in-memory with a 30-day expiry and periodic cleanup. It is deliberately not replicated: the bot serves a single guild from a single instance, so there is no second copy to keep in sync.

Ownership is enforced on edit and delete — not just posting. Because everyone shares one channel webhook, the webhook token alone can't say whose message is whose. Before editing or deleting, the bridge runs two checks. First: the target message must actually have been posted by this bridge's webhook — a message from anything else is refused. Second: the attribution record for that message must name the same YouTeacher user who is asking. Only when both hold does the edit or delete proceed. This is the load-bearing safety property — it stops one user from editing or deleting another user's message, even though at the Discord layer they all sit behind the same sender.

Replies are encoded into the message text, not the reply field. Discord's normal reply link (message_reference) is silently dropped when you post through a webhook, so the bridge can't use it. Instead it prepends a small, Discord-native markdown line to the content: a subtle quoted line naming who's being replied to plus a clickable jump link to the original. Discord's own client renders this as reply-like UI, and the bridge parses that same prefix line back out when reading, turning it into a structured reference for the YouTeacher view — so both surfaces agree, with the message content itself as the single source of truth. Editing a reply re-attaches the prefix, so an edit can't silently demote a reply into a plain message. A forwarded message uses the same prefix trick, and an older marker format is still recognised on read so messages posted by earlier builds keep rendering.

Related

about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →