42wim/matterircd

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

kot0dama opened this issue · 21 comments

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!

Might be related to #237

42wim commented

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

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

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.

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

What mattermost version?

Mattermost Version: 6.6.0
Database Schema Version: 78

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

Cowboying out channelID as follows:

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

        err := m.mc.JoinChannel(channelID)

Works.

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.

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

@kot0dama , try this patch in #487

42wim commented

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, "")

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.

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

Upstream change - 42wim/matterbridge#1909

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

Maybe similar upstream bug mattermost/mattermost-server#20810. But its old, I'll file a new one tomorrow.

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

Thanks for digging in this @hloeung

42wim commented

Thanks to @hloeung this is now fixed in master