- the "type" of the matrix id, used to update things properly next time. for example, whether it is the message text or an attachment. alternatively, whether it is a primary or supporting event for the discord message, primary being message content and supporting being embeds or attachments or etc.
There needs to be a way to easily manually trigger something later. For example, it should be easy to manually retry sending a message, or check all members for changes, etc.
2. Create channel rooms for the channels. Store the channel-room ID relationship in the database. (Probably no need to store parent-child relationships in the database?)
3. Send state events to put the channel rooms in the space.
Need to backfill any messages that were missed while offline.
After logging in, check last_message_id on each channel and compare against database to see if anything has been missed. However, mustn't interpret old channels from before the bridge was created as being "new". So, something has been missed if:
- The last_message_id is not in the table of bridged messages
- The channel is already set up with a bridged room
- A message has been bridged in that channel before
(If either of the last two conditions is false, that means the channel predates the bridge and we haven't actually missed anything there.)
For channels that have missed messages, use the getChannelMessages function, and bridge each in turn.
Can use custom transaction ID (?) to send the original timestamps to Matrix. See appservice docs for details.
- Otherwise, could use an account per webhook ID, but if webhook IDs are often deleted and re-created, this could still end up leaving too many accounts in the room.
- The original bridge uses an account per webhook display name, which makes the most sense in terms of canonical accounts, but leaves too many accounts in the room.
m->d reactions will have to be sent as the bridge bot since webhooks cannot add reactions. This also means Discord users can't tell who reacted. We will have to tolerate this.
Need to know the event ID of the reaction event so we can redact it. We can look it up with `/v1/rooms/!x/relations/$x/m.annotation`. (If the message was edited, use its original event ID in the query.) This gets all event details for all reactions from the homeserver.
If it is a custom emoji, we will need to use the existing `emoji` table to resolve the emoji ID to the key.
Then we can pick the one to redact based on the `key` and `sender` and redact it.
This also works for _remove emoji_ and _remove all_.
**Removed m->d**
Need to know the discord ID of the message that was reacted to. If we know the event ID of what was reacted to, we can look up the Discord ID in the usual database. Unfortunately, after a reaction has been redacted, it's already too late to look up which event it was redacted from.
So we do need a database table. It will only hold reactions that were sent by Matrix users and were successfully bridged. It will associate the reaction event ID with the Discord message ID it was reacted on (skipping the middleman).
insert into emoji select replace(substr(discord_url, 35), ".gif", "") as id, 1 as animated, mxc_url from file where discord_url like 'https://cdn.discordapp.com/emojis/%.gif';
insert into emoji select replace(substr(discord_url, 35), ".png", "") as id, 0 as animated, mxc_url from file where discord_url like 'https://cdn.discordapp.com/emojis/%.png';
Discord's gateway events when a thread is created off a message:
1. Regular MESSAGE_CREATE of the message that it's going to branch off in the future. Example ID -6423
2. It MESSAGE_UPDATEd the ID -6423 with this whole data: {id:-6423,flags: 32,channel_id:-2084,guild_id:-1727} (ID is the message ID it's branching off, channel ID is the parent channel containing the message ID it's branching off)
3. It THREAD_CREATEd and gave us a channel object with type 11 (public thread) and parent ID -2084 and ID -6423.
4. It MESSAGE_CREATEd type 21 with blank content and a message reference pointing towards channel -2084 message -6423. (That's the message it branched from in the parent channel.) This MESSAGE_CREATE got ID -4631 (a new ID). Apart from that it's a regular message object.
5. Finally, as the first "real" message in that thread (which a user must send to create that thread!) it sent a regular message object with a new message ID and a channel ID of -6423.
When viewing this thread, it shows the message branched from at the top, and then the first "real" message right underneath, as separate groups.
### Problem 1
If THREAD_CREATE creates the matrix room, this will still be in-flight when MESSAGE_CREATE ensures the room exists and creates a room too. There will be two rooms created and the bridge falls over.
#### Possible solution: Ignore THREAD_CREATE
Then the room will be implicitly created by the two MESSAGE_CREATEs, which are in series.
#### Possible solution: Store in-flight room creations - ✔️ this solution is implemented
Then the room will definitely only be created once, and we can still handle both events if we want to do special things for THREAD_CREATE.
#### Possible solution: Don't implicitly create rooms
But then old and current threads would never have their messages bridged unless I manually intervene. Don't like that.
### Problem 2
MESSAGE_UPDATE with flags=32 is telling that message to become an announcement of the new thread's creation, but this happens before THREAD_CREATE. The matrix room won't actually exist when we see MESSAGE_UPDATE, therefore we cannot make the MESSAGE_UPDATE link to the new thread.
#### Possible solution: Ignore MESSAGE_UPDATE and bridge THREAD_CREATE as the announcement - ✔️ this solution is implemented
When seeing THREAD_CREATE (if we use solution B above) we could react to it by creating the thread announcement message in the parent channel. This is possible because THREAD_CREATE gives a thread object and that includes the parent channelID to send the announcement message to.
While the thread announcement message could look more like Discord-side by being an edit of the message it branched off:
> look at my cat
>
> Thread started: [#cat thread]
if the thread branched off a matrix user's message then the bridge wouldn't be able to edit it, so this wouldn't work.
Regardless, it would make the most sense to post a new message like this to the parent room: