Compare commits

...

5 Commits

Author SHA1 Message Date
Wim
b4a4eb0057 Update changelog 2017-04-08 00:50:17 +02:00
Wim
b469c8ddbd Rejoin channel when kicked (irc). Closes #146 2017-04-08 00:42:37 +02:00
Wim
eee0036c7f Modify iconurl correctly (mattermost). Closes #145 2017-04-08 00:16:46 +02:00
Wim
89c66b9430 Reconnect on session removal (mattermost) 2017-04-07 23:27:41 +02:00
Wim
bd38319d83 Add support for showing/hiding join/leave messages from mattermost. Closes #147 2017-04-07 22:27:36 +02:00
7 changed files with 75 additions and 14 deletions

View File

@@ -10,8 +10,9 @@ import (
) )
const ( const (
EVENT_JOIN_LEAVE = "join_leave" EVENT_JOIN_LEAVE = "join_leave"
EVENT_FAILURE = "failure" EVENT_FAILURE = "failure"
EVENT_REJOIN_CHANNELS = "rejoin_channels"
) )
type Message struct { type Message struct {

View File

@@ -167,14 +167,19 @@ func (b *Birc) handleNewConnection(event *irc.Event) {
i.AddCallback("JOIN", b.handleJoinPart) i.AddCallback("JOIN", b.handleJoinPart)
i.AddCallback("PART", b.handleJoinPart) i.AddCallback("PART", b.handleJoinPart)
i.AddCallback("QUIT", b.handleJoinPart) i.AddCallback("QUIT", b.handleJoinPart)
i.AddCallback("KICK", b.handleJoinPart)
i.AddCallback("*", b.handleOther) i.AddCallback("*", b.handleOther)
// we are now fully connected // we are now fully connected
b.connected <- struct{}{} b.connected <- struct{}{}
} }
func (b *Birc) handleJoinPart(event *irc.Event) { func (b *Birc) handleJoinPart(event *irc.Event) {
flog.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account)
channel := event.Arguments[0] channel := event.Arguments[0]
if event.Code == "KICK" {
flog.Infof("Got kicked from %s by %s", channel, event.Nick)
b.Remote <- config.Message{Username: "system", Text: "rejoin", Channel: channel, Account: b.Account, Event: config.EVENT_REJOIN_CHANNELS}
return
}
if event.Code == "QUIT" { if event.Code == "QUIT" {
if event.Nick == b.Nick && strings.Contains(event.Raw, "Ping timeout") { if event.Nick == b.Nick && strings.Contains(event.Raw, "Ping timeout") {
flog.Infof("%s reconnecting ..", b.Account) flog.Infof("%s reconnecting ..", b.Account)
@@ -182,6 +187,7 @@ func (b *Birc) handleJoinPart(event *irc.Event) {
return return
} }
} }
flog.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account)
b.Remote <- config.Message{Username: "system", Text: event.Nick + " " + strings.ToLower(event.Code) + "s", Channel: channel, Account: b.Account, Event: config.EVENT_JOIN_LEAVE} b.Remote <- config.Message{Username: "system", Text: event.Nick + " " + strings.ToLower(event.Code) + "s", Channel: channel, Account: b.Account, Event: config.EVENT_JOIN_LEAVE}
flog.Debugf("handle %#v", event) flog.Debugf("handle %#v", event)
} }

View File

@@ -72,6 +72,7 @@ func (b *Bmattermost) Connect() error {
flog.Info("Connection succeeded") flog.Info("Connection succeeded")
b.TeamId = b.mc.GetTeamId() b.TeamId = b.mc.GetTeamId()
go b.mc.WsReceiver() go b.mc.WsReceiver()
go b.mc.StatusLoop()
} }
go b.handleMatter() go b.handleMatter()
return nil return nil
@@ -100,6 +101,7 @@ func (b *Bmattermost) Send(msg config.Message) error {
} }
if !b.Config.UseAPI { if !b.Config.UseAPI {
matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL} matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL}
matterMessage.IconURL = msg.Avatar
matterMessage.Channel = channel matterMessage.Channel = channel
matterMessage.UserName = nick matterMessage.UserName = nick
matterMessage.Type = "" matterMessage.Type = ""
@@ -131,6 +133,14 @@ func (b *Bmattermost) handleMatter() {
func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) { func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) {
for message := range b.mc.MessageChan { for message := range b.mc.MessageChan {
flog.Debugf("%#v", message.Raw.Data)
if message.Type == "system_join_leave" ||
message.Type == "system_join_channel" ||
message.Type == "system_leave_channel" {
flog.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account)
b.Remote <- config.Message{Username: "system", Text: message.Text, Channel: message.Channel, Account: b.Account, Event: config.EVENT_JOIN_LEAVE}
continue
}
// do not post our own messages back to irc // do not post our own messages back to irc
// only listen to message from our team // only listen to message from our team
if message.Raw.Event == "posted" && b.mc.User.Username != message.Username && message.Raw.Data["team_id"].(string) == b.TeamId { if message.Raw.Event == "posted" && b.mc.User.Username != message.Username && message.Raw.Data["team_id"].(string) == b.TeamId {

View File

@@ -1,8 +1,17 @@
# v0.11.0-dev # v0.11.0-dev
## New features ## New features
* general: reusing the same account on multiple gateways now also reuses the connection. * general: reusing the same account on multiple gateways now also reuses the connection.
This is particuarly useful for irc. See #87 This is particuarly useful for irc. See #87
* general: the Name is now REQUIRED and needs to be UNIQUE for each gateway configuration * general: the Name is now REQUIRED and needs to be UNIQUE for each gateway configuration
* telegram: Support edited messages (telegram). See #141
* mattermost: Add support for showing/hiding join/leave messages from mattermost. Closes #147
* mattermost: Reconnect on session removal/timeout (mattermost)
* irc: Rejoin channel when kicked (irc).
## Bugfix
* mattermost: Remove space after nick (mattermost). Closes #142
* mattermost: Modify iconurl correctly (mattermost).
* irc: Fix join/leave regression (irc)
# v0.10.3 # v0.10.3
## Bugfix ## Bugfix

View File

@@ -103,6 +103,15 @@ func (gw *Gateway) handleReceive() {
} }
} }
} }
if msg.Event == config.EVENT_REJOIN_CHANNELS {
for _, br := range gw.Bridges {
if msg.Account == br.Account {
br.Joined = make(map[string]bool)
br.JoinChannels()
}
}
continue
}
if !gw.ignoreMessage(&msg) { if !gw.ignoreMessage(&msg) {
msg.Timestamp = time.Now() msg.Timestamp = time.Now()
for _, br := range gw.Bridges { for _, br := range gw.Bridges {
@@ -190,6 +199,7 @@ func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) {
} }
log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel.Name) log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel.Name)
msg.Channel = channel.Name msg.Channel = channel.Name
gw.modifyAvatar(&msg, dest)
gw.modifyUsername(&msg, dest) gw.modifyUsername(&msg, dest)
// for api we need originchannel as channel // for api we need originchannel as channel
if dest.Protocol == "api" { if dest.Protocol == "api" {
@@ -229,6 +239,17 @@ func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) {
msg.Username = nick msg.Username = nick
} }
func (gw *Gateway) modifyAvatar(msg *config.Message, dest *bridge.Bridge) {
iconurl := gw.Config.General.IconURL
if iconurl == "" {
iconurl = dest.Config.IconURL
}
iconurl = strings.Replace(iconurl, "{NICK}", msg.Username, -1)
if msg.Avatar == "" {
msg.Avatar = iconurl
}
}
func getChannelID(msg config.Message) string { func getChannelID(msg config.Message) string {
return msg.Channel + msg.Account return msg.Channel + msg.Account
} }

View File

@@ -64,7 +64,8 @@ IgnoreNicks="ircspammer1 ircspammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -114,7 +115,8 @@ IgnoreNicks="ircspammer1 ircspammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -157,7 +159,8 @@ IgnoreNicks="spammer1 spammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}/{BRIDGE}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}/{BRIDGE}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -250,7 +253,8 @@ IgnoreNicks="ircspammer1 ircspammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -282,7 +286,8 @@ IgnoreNicks="ircspammer1 ircspammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -362,7 +367,8 @@ IgnoreNicks="ircspammer1 ircspammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -397,7 +403,8 @@ IgnoreNicks="ircspammer1 ircspammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -432,7 +439,8 @@ IgnoreNicks="spammer1 spammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -489,7 +497,8 @@ IgnoreNicks="ircspammer1 ircspammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false
@@ -532,7 +541,8 @@ IgnoreNicks="spammer1 spammer2"
#OPTIONAL (default empty) #OPTIONAL (default empty)
RemoteNickFormat="[{PROTOCOL}] <{NICK}> " RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
#Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) #Enable to show users joins/parts from other bridges
#Only works hiding/show messages from irc and mattermost bridge for now
#OPTIONAL (default false) #OPTIONAL (default false)
ShowJoinPart=false ShowJoinPart=false

View File

@@ -34,6 +34,7 @@ type Message struct {
Channel string Channel string
Username string Username string
Text string Text string
Type string
} }
type Team struct { type Team struct {
@@ -177,6 +178,7 @@ func (m *MMClient) Login() error {
} }
b.Reset() b.Reset()
m.log.Debug("WsClient: connected")
m.WsSequence = 1 m.WsSequence = 1
m.WsPingChan = make(chan *model.WebSocketResponse) m.WsPingChan = make(chan *model.WebSocketResponse)
// only start to parse WS messages when login is completely done // only start to parse WS messages when login is completely done
@@ -266,6 +268,7 @@ func (m *MMClient) parseActionPost(rmsg *Message) {
} }
rmsg.Username = m.GetUser(data.UserId).Username rmsg.Username = m.GetUser(data.UserId).Username
rmsg.Channel = m.GetChannelName(data.ChannelId) rmsg.Channel = m.GetChannelName(data.ChannelId)
rmsg.Type = data.Type
rmsg.Team = m.GetTeamName(rmsg.Raw.Data["team_id"].(string)) rmsg.Team = m.GetTeamName(rmsg.Raw.Data["team_id"].(string))
// direct message // direct message
if rmsg.Raw.Data["channel_type"] == "D" { if rmsg.Raw.Data["channel_type"] == "D" {
@@ -628,6 +631,7 @@ func (m *MMClient) StatusLoop() {
m.Logout() m.Logout()
m.WsQuit = false m.WsQuit = false
m.Login() m.Login()
go m.WsReceiver()
} }
} }
time.Sleep(time.Second * 60) time.Sleep(time.Second * 60)