Sync Bot — Server Mirroring

Synchronisation

How structure, messages, reactions and names are synced in detail.

Synchronisation

Structure (A → B)

Changes to the category on Server A are carried over to Server B:

  • Creating, deleting, renaming channels
  • Order (position) of the channels
  • Properties: type (text, voice, forum, announcement), topic, slowmode, NSFW

Channel and category names

Names follow Server A by default:

  • Without a custom name, a channel on B always follows A's name — including later renames on A.
  • If a channel on B is renamed via the Discord UI, the bot reverts the name (to A's name, or to the custom name if one is set).
  • A custom name is only created through /sync rename-channel — the channel is then locked and no longer overwritten by renames on A.
  • The category on B can only be permanently renamed through /sync rename-category.

Messages (A ↔ B)

Messages are mirrored both ways through webhooks — with the original author's display name and avatar. Text, attachments and embeds are carried over.

  • Edits and deletes are mirrored, as are bulk deletes (purge).
  • Messages from bots and third-party webhooks are mirrored too.
  • Mentions trigger real pings — @user, roles and @everyone/@here.
Loop prevention: messages that originate from the bot's own webhooks are detected and never re-mirrored. This is exactly why a persistent database is needed (see below).

Reactions

Reactions are mirrored 1:1 (add and remove).

Discord does not allow reacting "on behalf of" another user — the mirrored reaction is added by the bot. The emoji appears correctly on the partner post, but as a bot reaction. Custom emojis from servers the bot is not a member of can't be added and are skipped.

Limits

  • Message mirroring runs for text and announcement channels. Voice and forum channels are mirrored structurally, but not as a message stream.

Database

The bot stores its state in a SQLite database with four tables:

TableContents
sync_pairsThe A ↔ B connection incl. category info and status
channel_mappingsSource channel ↔ target channel plus both webhooks
message_mappingsOriginal message ↔ mirrored message (for edits/deletes)
custom_namesLocked channel names on Server B
The database is state-critical. If it does not live on a persistent path (DATABASE_PATH), the webhook IDs are lost after a restart and loop prevention no longer works.
Copyright © 2026