matterbridge
matterbridge copied to clipboard
[Matrix] switch to mautrix-go + initial support for application services
Hello,
This is a revival of #1541, #1543 and #1544.
Fixes #137.
Before considering reviewing this, I would really like for other people to confirm that it works for them, to detect some of the numerous issues that must be lurking inside this changeset.
If you want to test the appservice support, you can use the same example configuration than in #1544.
The work that remains to be done mainly revolves around application services:
- [ ] supporting more complex regexps for the usernames
- [ ] accepting rooms not explictly hardcoded in the config (that is the whole point of app services after all, yet currently it only relays messages for rooms that are already defined in the config)
- [ ] testing this enough to be confident it works as expected
accepting rooms not explictly hardcoded in the config (that is the whole point of app services after all, yet currently it only relays messages for rooms that are already defined in the config)
That seem unlikely to happen given Matterbridge config heavy approach, but it would be really nice if this appservice improvement could properly create ghost users Matrix side through the bridge.
Agreed on both counts!
As for the "proper ghost accounts", that's actually what it does:
I am not a Go developer and thus don't have an dev environment to compile this easily. But if you can share a x86_64 binary I am willing to test it in a IRC-Matrix-Discord setting.
@nightmared thanks for your work! :) Could you rebase on master? I've updated dependencies.
I'll try to test later
Does this also bring support for IRC NOTICE
-> Matrix m.notice
(https://github.com/42wim/matterbridge/issues/1393) or should that be done in a separate PR?
I don't know if the previous library supported m.notice
.
I am not a Go developer and thus don't have an dev environment to compile this easily. But if you can share a x86_64 binary I am willing to test it in a IRC-Matrix-Discord setting.
Sure thing, here is one: https://nightmared.fr/files/matterbridge-2022-08-14.
You can verify its integrity with sha256sum:
5d9511d784b6d4716af917026b79ab9921f65397ca8660baa40bce73b22c8f39 dev/matterbridge/matterbridge
Sorry about the time this took me, I have discovered the joys of COVID19 these past few days, and unsurprisingly that doesn't really help focusing on code (or anything really) ^_^ Anyway, I have rebased this on master, and I will take a look to see if I can tackle the CodeClimate issues.
Does this also bring support for IRC
NOTICE
-> Matrixm.notice
(#1393) or should that be done in a separate PR?I don't know if the previous library supported
m.notice
.
No, I haven't added support for m.notice
in this PR, because if I'm being honest, I didn't even knew this feature existed!
That being said, I don't think there should be any blocker for implementing this.
For golangci-lint, while I could reproduce locally the golangci-lint messages about the extraneous spaces in // nolint
, I do not have these error messages even though I also have golangci-lint v1.48.0:
Error: File is not `gofmt`-ed with `-s` (gofmt)
Error: File is not `gofmt`-ed with `-s` (gofmt)
Error: File is not `gofmt`-ed with `-s` (gofmt)
Error: File is not `gofmt`-ed with `-s` (gofmt)
Error: File is not `gofmt`-ed with `-s` (gofmt)
Does anyone happen to know why that is ?
Hi, is this still being worked on? I have had so much problems with other bridges yet matterbridge works really well. Would love to have this feature.
@Akselmo Yes, this is definitely still ongoing :)
I'm currently waiting for user feeback to know if it works for other people, and if the current design seems acceptable or if I have to go back to the drawing board.
So if you happen to have some feedback, or to know people who might, I woul be happy to hear some or discuss this further!
@Akselmo Yes, this is definitely still ongoing :)
I'm currently waiting for user feeback to know if it works for other people, and if the current design seems acceptable or if I have to go back to the drawing board.
Ah, I could try building this with your PR and see if it works for me.
Alright I got it to work, here's some feedback!
- I can't use the internal id's for channel names (probably has something to do with the appservice regex, changed it to
#.*
and all my channels work with it) - Avatars do not get over the bridge in either direction. The stable build has the webhook support and the avatars get over bridge to Discord at least. I tried with
localhost
and my matrix domain in the appservice settings. No dice.- To add, the bridgebot is sending its own avatar from matrix to discord, instead of the user.
- The
RemoteNickFormat="<{NICK}> "
can't be anything else but that. I tried to remove the<>
but it stopped working. I tried to remove them because the nick looks like this:<Aks>
Anyhow so far so good and I prefer this way much more over the other bridge bots I've tried.
Thanks for the feedback!
- For the internal ID, that's concerning. Could you tell more about what it meant for the rooms IDs to not work? To you not receiving messages?
- For the avatar, this is a known problem: https://github.com/mautrix/go/pull/83. This should be fixed once mautrix-go will have published a new version of the library, that we would apply by updating the vendored dependency.
- Not being able to change the Nickname format is surprising. I will perform some tests locally to see if I can reproduce (and fix the
<
-><
conversion) - probably not today though.
* For the internal ID, that's concerning. Could you tell more about what it meant for the rooms IDs to not work? To you not receiving messages?
If the room ID started with !randomlettershere:address.org
it wouldn't work: It couldn't find the address. But I think this was because the appservice regexp has #
in the beginning, so it was trying to look for #!randomlettershere
and failed because of that.
It's not that big of a deal since using the public address of the channels worked. I tend to use the internal addresses/ID's in case I change the public address, so it still keeps pointing to right place.
* Not being able to change the Nickname format is surprising. I will perform some tests locally to see if I can reproduce (and fix the `<` -> `<` conversion) - probably not today though.
I could try changing it again, it was a bit odd. Sometimes when closing the bot and then starting it up again it wouldn't launch the appservice and worked in the non-appservice way: Instead of ghost accounts it would just relay messages with <name> bla
way.
Edit: Okay I changed it and now it works. It seems that if the appservice is not up, it relays the messages normal way, but when appservice is up it uses the ghost bots.
Could perhaps make it so that I could change different nick style for the appservice bots itself?
I also noticed custom emojis wont go over the bridge either. I guess this is also something to do with Mautrix?
What do you mean by "custom emojis"? Reactions to messages? If you mean reactions, AFAIK they weren't shared across bridges prior to this MR either (but I could be wrong of course).
What do you mean by "custom emojis"? Reactions to messages? If you mean reactions, AFAIK they weren't shared across bridges prior to this MR either (but I could be wrong of course).
I mean actual emojis and stickers.
Here's an example of Discord custom emoji to Matrix
Discord:
Matrix:
And from Matrix to Discord
Matrix
Discord
This bridge has managed to solve this issue, so maybe theres something we could use? https://github.com/matrix-org/matrix-appservice-discord
Also, something new I noticed!
After enabling appservice, someone on the Matrix channel has to talk first for the appservice to be active.
After enabling bot, the first message there came from Discord, without the appservice. But after I said something in the Matrix channel, then tried again from Discord, the appservice was enabled.
Also it seems I can't delete messages on discord from matrix side.
Thanks for all these reports, I will take a look at them (mostly this week-end I think)!
No problem, I don't know Go but I can also look into some issues if I got time.
After enabling appservice, someone on the Matrix channel has to talk first for the appservice to be active.
After enabling bot, the first message there came from Discord, without the appservice. But after I said something in the Matrix channel, then tried again from Discord, the appservice was enabled.
Yes, that is a bit sad but I have seen that issue too. This is a consequence of the appservice design: the server only pushes events to the application service when there is new messages. Which means at least one message must be received before the application service kicks in and replace the classic syncer for handling messages from the room.
The same logic means we can receive twice the first message send on a matrix room after a bridge restart: one from the classical syncer and a second one from the appservice. This lead to that first message being sent (e.g. to a Discord gateway) and then being resent instantly (the message have the same ID, so Discord actually show the message as "(edited)" instead of showing it twice).
Work remaining on this subject:
- [ ] look into handling graciously appservice failures (if the server is reconfigured to disable the application service, right now you need to restart the bridge for it to start treating messages from the "classical syncer" again - we mute the classical syncer for rooms where we already receive events. This ensures we don't treat events twice)
- [ ] test if we could force the server to ping the appservice listener on every room, hence solving the "first message" boostraping problem described earlier (by sending some fake event like a typing notification maybe?)
- [ ] try to detect and fix the first matrix message being sent twice
Alright, to sum up the work done or remaining to do:
- [x] Adding bidirectionnal avatar support
- [x] Convert transparently between IRC NOTICE and matrix] m.notice messages
- [x] Fix the deletion of messages from [matrix] when received over application services
- [x] Fix various issues with the displayname/avatar caching
- [ ] Add the option to have a different "Nickname template" for appservice messages and for messages sent over the "classical syncer"
- [ ] emojis and stickers support (cf. https://github.com/42wim/matterbridge/pull/1864#issuecomment-1234552002)
- [x] look into handling graciously appservice failures (if the server is reconfigured to disable the application service, right now you need to restart the bridge for it to start treating messages from the "classical syncer" again - we mute the classical syncer for rooms where we already receive events. This ensures we don't treat events twice)
- [ ] test if we could force the server to ping the appservice listener on every room, hence solving the "first message" boostraping problem described earlier (by sending some fake event like a typing notification maybe?)
- [ ] detect and fix the first matrix message being sent twice -> could be done by merging gracefully messages from the application service and the "classical syncer", which would also be useful for the first caveat described below. This will probably require even more caching ;)
- [ ] support more complex regexps for the usernames in the application service configuration file
- [ ] testing this patcch series enough to be confident it works as expected
- [ ] document better the options/how to configure the application services
- [ ] support matrix/Discord spoilers
Planned, then rejected:
- Accepting rooms not explictly hardcoded in the config (that is the whole point of app services after all, yet currently it only relays messages for rooms that are already defined in the config). Rationale: not in the spirit of matterbridge explicit configuration
Known caveats:
- If the bridge is down while the homeserver receives messages on bridged room, the homeserver will apply some exponential backoff trying to reach the application service endpoint (https://github.com/matrix-org/synapse/blob/d736d5cfadcc9a56523fcb1cfe8cb1d2be47a4ec/synapse/appservice/scheduler.py#L489-L493), which means that the bridge will only use the classical syncer for up to 9 minutes. Worse, as we disable message receiving over the classical syncer if the application service worked at some point since the bridge started, this means that the bridge would be non-functional for that duration!
Thanks to @Akselmo for the feedback!
Thanks to @Akselmo for the feedback!
No problem. :)
Accepting rooms not explictly hardcoded in the config (that is the whole point of app services after all, yet currently it only relays messages for rooms that are already defined in the config). Rationale: not in the spirit of matterbridge explicit configuration
Personally I don't mind this at all. I prefer having explicit control over what is bridged and what is not. Helps with channels that shouldn't be shared from one system to another.
test if we could force the server to ping the appservice listener on every room, hence solving the "first message" boostraping problem described earlier (by sending some fake event like a typing notification maybe?)
This could work. Alternatively, sending a message "Brige is now enabled" could work. Could also make the bot delete the message after some time. This is not a good solution however since it'll then show notifications for channels even after deleting the message, at least on Discord side. The Matrix side of the bot could just say "Re-enabling bridge" as deletion reason as well.
Anyhow, will gladly do more testing, just ping me here and I'll help. :)
For golangci-lint, while I could reproduce locally the golangci-lint messages about the extraneous spaces in
// nolint
, I do not have these error messages even though I also have golangci-lint v1.48.0:Error: File is not `gofmt`-ed with `-s` (gofmt) Error: File is not `gofmt`-ed with `-s` (gofmt) Error: File is not `gofmt`-ed with `-s` (gofmt) Error: File is not `gofmt`-ed with `-s` (gofmt) Error: File is not `gofmt`-ed with `-s` (gofmt)
Does anyone happen to know why that is ?
It seems that the last linter issues is because you have a space between //nolint: somelinter
instead of //nolint:somelinter
I've also removed a lot of useless (for this project) linters, so you can probably remove a few of those //nolint
ones (https://github.com/42wim/matterbridge/blob/master/.golangci.yaml#L172-L214)
Note: I rebased on top of master, which includes #1875, but I just threw away these modifications (read: I haven't bothered to re-implement them yet). Please let me know (once the discussion over there about whether this generates too much state events or not is settled) what would be preferred.
Just to mention, tell me whenever there's good point for another test!
Code Climate has analyzed commit 9827a9b7 and detected 7 issues on this pull request.
Here's the issue category breakdown:
Category | Count |
---|---|
Complexity | 7 |
View more on Code Climate.
The last commit adds sticker support, but only in one direction, as I don't have a Discord Nitro account to test/implement the other side.
@Akselmo you can test the new version if you want, but the issues outlined in https://github.com/42wim/matterbridge/pull/1864#issuecomment-1236121443 have not been fixed so far, so not much have changed!
Hi, just curious if you have time to work on this more?
Sorry, I haven't had time to work on this the last few weeks, and probably won't for another week or two :/
(But I'm still commited to making this merged someday !)
Couple things i feel like are good to report in:
Mentions in both directions do not work
Replies do not work, but these could also just use mentions at first, maybe >quote the message being replied to in the sent message.