42wim / matterircd

Connect to your mattermost or slack using your IRC-client of choice.
MIT License
294 stars 60 forks source link

Unable to /join a public channel or /part any channel from IRC #479

Closed kot0dama closed 1 year ago

kot0dama commented 2 years ago

Hi,

When I try to join a specific public channel from my IRC client, I get this:

:matterircd 473 kotodama #whatever :Cannot join channel (+i)

Same if I try using ~ instead of #. When I join the same channel from WebUI, channel being public and not invite only, I properly get a:

:kotodama!xxxx@localhost JOIN #whatever

Also, when I /part a channel from my IRC client, it behaves as if I left the channel, but then I'm still on said channel when I connect to mattermost WebUI. This is the raw log from hexchat:

<<PART #whatever :Leaving
>> :kotodama!xxxx@localhost PART #whatever :Leaving
>> :matterircd 442 #whatever :You're not on that channel

Let me know if there's anything I missed or if you need more details. Thank you!

kot0dama commented 2 years ago

Might be related to #237

42wim commented 2 years ago

wrt to /part => partfake see https://github.com/42wim/matterircd/blob/master/matterircd.toml.example#L83-L90

/join should work.. run with --debug and rebuild from master if you're using mattermost 7.x also put your defaultTeam https://github.com/42wim/matterircd/blob/master/matterircd.toml.example#L51 otherwise you need to do /join #yourteam/whatever

kot0dama commented 2 years ago

Ah sorry I overlooked the partfake setting.

About joining channels, we're using MM 6.x but then I already set defaultTeam to our current sole team.

time="2022-10-17T04:19:33+02:00" level=debug msg="<- JOIN #some-existing-public-channel" module=matterircd
time="2022-10-17T04:19:33+02:00" level=debug msg="Joining " prefix=matterclient
time="2022-10-17T04:19:33+02:00" level=debug msg="join channel some-existing-public-channel, id , err: : Invalid or missing channel_id parameter in request URL., "
time="2022-10-17T04:19:33+02:00" level=error msg="Cannot join channel some-existing-public-channel, id , err: cannot join channel (+i)" module=matterircd
time="2022-10-17T04:19:33+02:00" level=debug msg="-> :matterircd 473 loic #some-existing-public-channel :Cannot join channel (+i)" module=matterircd
time="2022-10-17T04:19:33+02:00" level=debug msg="Executed &irc.Message{Prefix:(*irc.Prefix)(nil), Command:\"JOIN\", Params:[]string{\"#some-existing-public-channel\"}, Trailing:\"\", EmptyTrailing:false} <nil>" module=matterircd

Same when using #myteam/some-existing-public-channel. Let me know if there's anything I can test, or add to logging.

Cheers

42wim commented 2 years ago

Well, this shows that it cannot find the channel. This can be because the teamID/name is incorrect, or it doesn't have access to the channel. Does your team name is something special, utf-8, spaces, special characters ? or is the channel something special as a name ?

Redacting too much information makes it harder to debug.

As a workaround just join the channel using the webbrowser, this should be a one-time action.

kot0dama commented 1 year ago

The team name is nothing special, just "canonical". The channel itself is public and consists of letters and dashes only (and public information but then I did not see the point in keeping the name on this bug report).

Afaik, it has never worked for at least 2 people (including myself), on any channel we wanted to join. We're indeed using the web version of MM when we need to join a channel, but I felt this issue should be reported.

42wim commented 1 year ago

What mattermost version?

kot0dama commented 1 year ago

Mattermost Version: 6.6.0 Database Schema Version: 78

hloeung commented 1 year ago

I can confirm this is the case and seems to do with the m.mc.GetChannelID() call. I added some debugging earlier this morning:

[hloeung@dharkan matterircd]$ git diff
diff --git a/bridge/mattermost6/mattermost.go b/bridge/mattermost6/mattermost.go
index 0d9e4d3..fbcb8c2 100644
--- a/bridge/mattermost6/mattermost.go
+++ b/bridge/mattermost6/mattermost.go
@@ -182,20 +182,27 @@ func (m *Mattermost) Join(channelName string) (string, string, error) {

        sp := strings.Split(channelName, "/")
        if len(sp) > 1 {
+               logger.Infof("Haw sp0: %s", sp[0])
                team, _, _ := m.mc.Client.GetTeamByName(sp[0], "")
                if team == nil {
                        return "", "", fmt.Errorf("cannot join channel (+i)")
                }

+               logger.Infof("Haw team: %s", team.Id)
                teamID = team.Id
                channelName = sp[1]
+               logger.Infof("Haw sp1: %s", sp[1])
        }

        if teamID == "" {
                teamID = m.mc.Team.ID
+               logger.Infof("Haw teamid here somehow: %s", teamID)
        }

+       logger.Infof("Haw channelName: %s", channelName)
+       logger.Infof("Haw teamID: %s", teamID)
        channelID := m.mc.GetChannelID(channelName, teamID)
+       logger.Infof("Haw channelID: %s", channelID)

        err := m.mc.JoinChannel(channelID)
        logger.Debugf("join channel %s, id %s, err: %v", channelName, channelID, err)

Now on trying to join, I get this:

INFO[2022-11-02T08:16:02+11:00] login succeeded
INFO[2022-11-02T08:16:34+11:00] Haw teamid here somehow: sqmc4sz45prypmkfctwynm5yjr
INFO[2022-11-02T08:16:34+11:00] Haw channelName: matterircd
INFO[2022-11-02T08:16:34+11:00] Haw teamID: sqmc4sz45prypmkfctwynm5yjr
INFO[2022-11-02T08:16:34+11:00] Haw channelID:
ERRO[2022-11-02T08:16:34+11:00] Cannot join channel matterircd, id , err: cannot join channel (+i)  module=matterircd

Even with team name it's failing:

INFO[2022-11-02T08:21:18+11:00] Haw sp0: canonical
INFO[2022-11-02T08:21:18+11:00] Haw team: sqmc4sz45prypmkfctwynm5yjr
INFO[2022-11-02T08:21:18+11:00] Haw sp1: matterircd
INFO[2022-11-02T08:21:18+11:00] Haw channelName: matterircd
INFO[2022-11-02T08:21:18+11:00] Haw teamID: sqmc4sz45prypmkfctwynm5yjr
INFO[2022-11-02T08:21:18+11:00] Haw channelID:
ERRO[2022-11-02T08:21:19+11:00] Cannot join channel canonical/matterircd, id , err: cannot join channel (+i)  module=matterircd
hloeung commented 1 year ago

Cowboying out channelID as follows:

        channelID = "uw577mmmgfbtjg9i6bz9wk97or"
        logger.Infof("Haw channelID: %s", channelID)

        err := m.mc.JoinChannel(channelID)

Works.

hloeung commented 1 year ago

The issue is with m.mc.JoinChannel(channelID) where adding logging output (vendor/github.com/matterbridge/matterclient/channels.go) shows only the first 357 channels returned and used for comparison.

hloeung commented 1 year ago

Maybe rather than loop through list of all channels, use the Mattermost API GetChannelByNameForTeamNameRoute / https://api.mattermost.com/#tag/channels/operation/GetChannelByName ?

hloeung commented 1 year ago

@kot0dama , try this patch in https://github.com/42wim/matterircd/pull/487

42wim commented 1 year ago

Maybe rather than loop through list of all channels, use the Mattermost API GetChannelByNameForTeamNameRoute / https://api.mattermost.com/#tag/channels/operation/GetChannelByName ?

It's probably done this way so we have a cache instead of sending too many requests to mattermost. We do ask for 5000 channels though

mmchannels, resp, err = m.Client.GetPublicChannelsForTeam(teamID, 0, 5000, "")
hloeung commented 1 year ago

I think this is a server side issue then:

$ curl -s -q -H 'Authorization: Bearer ...' "https://chat.myserver.local/api/v4/teams/sqmc.../channels?page=0&per_page=5000&include_total_count=true"  | jq '.[]' | grep '"id":' | wc -l
200
$ curl -s -q -H 'Authorization: Bearer ...' "https://chat.myserver.local/api/v4/teams/sqmc.../channels?page=0&per_page=10&include_total_count=true"  | jq '.[]' | grep '"id":' | wc -l
10

With that query directly via the API, I only get 200 results returned.

This is with MM 6.6.0.

I think the workaround of using GetChannelByName is needed here rather than get all available channels and try walk through? With GetChannelbyName, we're also able to join private channels.

hloeung commented 1 year ago

Or perhaps use the cache and fall back? So:

        for _, t := range m.OtherTeams {
                if t.ID == teamID {
                        for _, channel := range append(t.Channels, t.MoreChannels...) {
                                if getNormalisedName(channel) == name {
                                        return channel.Id
                                }
                        }
                }
        }

        // Fallback if it's not found in the t.Channels or t.MoreChannels cache.
        channel, resp, err := m.Client.GetChannelByName(name, teamID, "")
        if err != nil || resp == nil {
                return ""
        }
        return channel.Id
hloeung commented 1 year ago

Upstream change - https://github.com/42wim/matterbridge/pull/1909

We can re-vendor these changes if/when it's accepted in matterbridge upstream.

hloeung commented 1 year ago

Maybe similar upstream bug https://github.com/mattermost/mattermost-server/issues/20810. But its old, I'll file a new one tomorrow.

hloeung commented 1 year ago

Here too https://forum.mattermost.com/t/solved-how-to-increase-the-maximum-page-size-of-request/4476/3

hloeung commented 1 year ago

https://github.com/mattermost/mattermost-server/blob/master/web/params.go#L17

const (
    PageDefault        = 0
    PerPageDefault     = 60
    PerPageMaximum     = 200
    LogsPerPageDefault = 10000
    LogsPerPageMaximum = 10000
    LimitDefault       = 60
    LimitMaximum       = 200
)

I think I got 357 channels earlier was because it combines both:

    for _, t := range m.OtherTeams {
        for _, channel := range append(t.Channels, t.MoreChannels...) {

That's Channels and MoreChannels.

42wim commented 1 year ago

Thanks for digging in this @hloeung

42wim commented 1 year ago

Thanks to @hloeung this is now fixed in master