99 "github.com/42wim/matterbridge/bridge/config"
1010 "github.com/42wim/matterbridge/bridge/helper"
1111 "github.com/slack-go/slack"
12+ "github.com/slack-go/slack/slackevents"
13+ "github.com/slack-go/slack/socketmode"
1214)
1315
1416// ErrEventIgnored is for events that should be ignored
@@ -47,58 +49,74 @@ func (b *Bslack) handleSlack() {
4749}
4850
4951func (b * Bslack ) handleSlackClient (messages chan * config.Message ) {
50- for msg := range b .rtm .IncomingEvents {
51- if msg .Type != sUserTyping && msg .Type != sHello && msg .Type != sLatencyReport {
52- b .Log .Debugf ("== Receiving event %#v" , msg .Data )
53- }
54- switch ev := msg .Data .(type ) {
55- case * slack.UserTypingEvent :
56- if ! b .GetBool ("ShowUserTyping" ) {
57- continue
58- }
59- rmsg , err := b .handleTypingEvent (ev )
60- if err == ErrEventIgnored {
61- continue
62- } else if err != nil {
63- b .Log .Errorf ("%#v" , err )
64- continue
52+ for msg := range b .smc .Events {
53+ switch msg .Type {
54+ case socketmode .EventTypeConnected :
55+ if authTest , authErr := b .smc .AuthTest (); authErr == nil {
56+ if botInfo , infoErr := b .smc .GetBotInfo (authTest .BotID ); infoErr == nil {
57+ b .si = botInfo
58+
59+ b .channels .populateChannels (true )
60+ b .users .populateUsers (true )
61+ } else {
62+ b .Log .Fatalf ("Unable to identify bot user" )
63+ }
64+ } else {
65+ b .Log .Fatalf ("Unable to identify bot user" )
6566 }
67+ case socketmode .EventTypeConnectionError :
68+ ev , _ := msg .Data .(slack.ConnectionErrorEvent )
69+
70+ b .Log .Errorf ("Connection failed %#v %#v" , ev .Error (), ev .ErrorObj )
71+ case socketmode .EventTypeErrorWriteFailed :
72+ ev , _ := msg .Data .(socketmode.ErrorWriteFailed )
73+
74+ b .Log .Debugf ("%#v" , ev .Cause .Error ())
75+ case socketmode .EventTypeInvalidAuth :
76+ ev , _ := msg .Data .(slack.InvalidAuthEvent )
77+
78+ b .Log .Fatalf ("Invalid Token %#v" , ev )
79+ case socketmode .EventTypeHello , socketmode .EventTypeConnecting :
80+ continue
81+
82+ case socketmode .EventTypeEventsAPI :
83+ b .smc .Ack (* msg .Request )
84+
85+ eventsAPIEvent , ok := msg .Data .(slackevents.EventsAPIEvent )
86+
87+ if ! ok {
88+ b .Log .Debugf ("Ignored %+v" , eventsAPIEvent )
6689
67- messages <- rmsg
68- case * slack.MessageEvent :
69- if b .skipMessageEvent (ev ) {
70- b .Log .Debugf ("Skipped message: %#v" , ev )
7190 continue
7291 }
73- rmsg , err := b .handleMessageEvent (ev )
74- if err != nil {
75- b .Log .Errorf ("%#v" , err )
76- continue
92+
93+ switch innerEventData := eventsAPIEvent .InnerEvent .Data .(type ) {
94+ case * slackevents.MessageEvent :
95+ if b .skipMessageEvent (innerEventData ) {
96+ b .Log .Debugf ("Skipped message: %#v" , innerEventData )
97+ continue
98+ }
99+ rmsg , err := b .handleMessageEvent (innerEventData )
100+ if err != nil {
101+ b .Log .Errorf ("%#v" , err )
102+ continue
103+ }
104+ messages <- rmsg
105+ case * slackevents.MemberJoinedChannelEvent :
106+ if innerEventData .User == b .si .UserID {
107+ channel , err := b .smc .GetConversationInfo (innerEventData .Channel , false )
108+
109+ if err != nil {
110+ b .Log .Errorf ("Unable to get conversation info for channel %s" , innerEventData .Channel )
111+ }
112+
113+ b .channels .registerChannel (* channel )
114+ } else {
115+ b .users .populateUser (innerEventData .User )
116+ }
77117 }
78- messages <- rmsg
79- case * slack.OutgoingErrorEvent :
80- b .Log .Debugf ("%#v" , ev .Error ())
81- case * slack.ChannelJoinedEvent :
82- // When we join a channel we update the full list of users as
83- // well as the information for the channel that we joined as this
84- // should now tell that we are a member of it.
85- b .channels .registerChannel (ev .Channel )
86- case * slack.ConnectedEvent :
87- b .si = ev .Info
88- b .channels .populateChannels (true )
89- b .users .populateUsers (true )
90- case * slack.InvalidAuthEvent :
91- b .Log .Fatalf ("Invalid Token %#v" , ev )
92- case * slack.ConnectionErrorEvent :
93- b .Log .Errorf ("Connection failed %#v %#v" , ev .Error (), ev .ErrorObj )
94- case * slack.MemberJoinedChannelEvent :
95- b .users .populateUser (ev .User )
96- case * slack.HelloEvent , * slack.LatencyReport , * slack.ConnectingEvent :
97- continue
98- case * slack.UserChangeEvent :
99- b .users .invalidateUser (ev .User .ID )
100118 default :
101- b .Log .Debugf ("Unhandled incoming event: %T " , ev )
119+ b .Log .Debugf ("== Receiving event %#v " , msg . Data )
102120 }
103121 }
104122}
@@ -119,47 +137,44 @@ func (b *Bslack) handleMatterHook(messages chan *config.Message) {
119137}
120138
121139// skipMessageEvent skips event that need to be skipped :-)
122- func (b * Bslack ) skipMessageEvent (ev * slack .MessageEvent ) bool {
140+ func (b * Bslack ) skipMessageEvent (ev * slackevents .MessageEvent ) bool {
123141 switch ev .SubType {
124142 case sChannelLeave , sChannelJoin :
125143 return b .GetBool (noSendJoinConfig )
126144 case sPinnedItem , sUnpinnedItem :
127145 return true
128146 case sChannelTopic , sChannelPurpose :
129147 // Skip the event if our bot/user account changed the topic/purpose
130- if ev .User == b .si . User .ID {
148+ if ev .BotID == b .si .ID {
131149 return true
132150 }
133151 }
134152
135153 // Check for our callback ID
136154 hasOurCallbackID := false
137- if len (ev .Blocks .BlockSet ) == 1 {
138- block , ok := ev .Blocks .BlockSet [0 ].(* slack.SectionBlock )
155+
156+ if len (ev .Attachments ) == 1 {
157+ block , ok := ev .Attachments [0 ].Blocks .BlockSet [0 ].(* slack.SectionBlock )
139158 hasOurCallbackID = ok && block .BlockID == "matterbridge_" + b .uuid
140159 }
141160
142- if ev .SubMessage != nil {
161+ if ev .Message != nil {
143162 // It seems ev.SubMessage.Edited == nil when slack unfurls.
144163 // Do not forward these messages. See Github issue #266.
145- if ev .SubMessage .ThreadTimestamp != ev .SubMessage .Timestamp &&
146- ev .SubMessage .Edited == nil {
147- return true
148- }
149- // see hidden subtypes at https://api.slack.com/events/message
150- // these messages are sent when we add a message to a thread #709
151- if ev .SubType == "message_replied" && ev .Hidden {
164+ if ev .Message .ThreadTimeStamp != ev .Message .TimeStamp &&
165+ ev .Message .Edited == nil {
152166 return true
153167 }
154- if len (ev .SubMessage .Blocks .BlockSet ) == 1 {
155- block , ok := ev .SubMessage .Blocks .BlockSet [0 ].(* slack.SectionBlock )
168+
169+ if len (ev .Message .Attachments ) == 1 {
170+ block , ok := ev .Message .Attachments [0 ].Blocks .BlockSet [0 ].(* slack.SectionBlock )
156171 hasOurCallbackID = ok && block .BlockID == "matterbridge_" + b .uuid
157172 }
158173 }
159174
160175 // Skip any messages that we made ourselves or from 'slackbot' (see #527).
161176 if ev .Username == sSlackBotUser ||
162- (b .rtm != nil && ev .Username == b .si .User . Name ) || hasOurCallbackID {
177+ (b .smc != nil && ev .BotID == b .si .ID ) || hasOurCallbackID {
163178 return true
164179 }
165180
@@ -169,7 +184,7 @@ func (b *Bslack) skipMessageEvent(ev *slack.MessageEvent) bool {
169184 return false
170185}
171186
172- func (b * Bslack ) filesCached (files []slack .File ) bool {
187+ func (b * Bslack ) filesCached (files []slackevents .File ) bool {
173188 for i := range files {
174189 if ! b .fileCached (& files [i ]) {
175190 return false
@@ -194,7 +209,7 @@ func (b *Bslack) filesCached(files []slack.File) bool {
194209// 5. Handle any attachments of the received event.
195210// 6. Check that the Matterbridge message that we end up with after at the end of the
196211// pipeline is valid before sending it to the Matterbridge router.
197- func (b * Bslack ) handleMessageEvent (ev * slack .MessageEvent ) (* config.Message , error ) {
212+ func (b * Bslack ) handleMessageEvent (ev * slackevents .MessageEvent ) (* config.Message , error ) {
198213 rmsg , err := b .populateReceivedMessage (ev )
199214 if err != nil {
200215 return nil , err
@@ -214,15 +229,15 @@ func (b *Bslack) handleMessageEvent(ev *slack.MessageEvent) (*config.Message, er
214229 // This is probably a webhook we couldn't resolve.
215230 return nil , fmt .Errorf ("message handling resulted in an empty bot message (probably an incoming webhook we couldn't resolve): %#v" , ev )
216231 }
217- if ev .SubMessage != nil {
218- return nil , fmt .Errorf ("message handling resulted in an empty message: %#v with submessage %#v" , ev , ev .SubMessage )
232+ if ev .Message != nil {
233+ return nil , fmt .Errorf ("message handling resulted in an empty message: %#v with submessage %#v" , ev , ev .Message )
219234 }
220235 return nil , fmt .Errorf ("message handling resulted in an empty message: %#v" , ev )
221236 }
222237 return rmsg , nil
223238}
224239
225- func (b * Bslack ) handleStatusEvent (ev * slack .MessageEvent , rmsg * config.Message ) bool {
240+ func (b * Bslack ) handleStatusEvent (ev * slackevents .MessageEvent , rmsg * config.Message ) bool {
226241 switch ev .SubType {
227242 case sChannelJoined , sMemberJoined :
228243 // There's no further processing needed on channel events
@@ -235,16 +250,16 @@ func (b *Bslack) handleStatusEvent(ev *slack.MessageEvent, rmsg *config.Message)
235250 b .channels .populateChannels (false )
236251 rmsg .Event = config .EventTopicChange
237252 case sMessageChanged :
238- rmsg .Text = ev .SubMessage .Text
253+ rmsg .Text = ev .Message .Text
239254 // handle deleted thread starting messages
240- if ev .SubMessage .Text == "This message was deleted." {
255+ if ev .Message .Text == "This message was deleted." {
241256 rmsg .Event = config .EventMsgDelete
242257 return true
243258 }
244259 case sMessageDeleted :
245260 rmsg .Text = config .EventMsgDelete
246261 rmsg .Event = config .EventMsgDelete
247- rmsg .ID = ev .DeletedTimestamp
262+ rmsg .ID = ev .PreviousMessage . TimeStamp
248263 // If a message is being deleted we do not need to process
249264 // the event any further so we return 'true'.
250265 return true
@@ -254,7 +269,7 @@ func (b *Bslack) handleStatusEvent(ev *slack.MessageEvent, rmsg *config.Message)
254269 return false
255270}
256271
257- func (b * Bslack ) handleAttachments (ev * slack .MessageEvent , rmsg * config.Message ) {
272+ func (b * Bslack ) handleAttachments (ev * slackevents .MessageEvent , rmsg * config.Message ) {
258273 // File comments are set by the system (because there is no username given).
259274 if ev .SubType == sFileComment {
260275 rmsg .Username = sSystemUser
@@ -287,23 +302,8 @@ func (b *Bslack) handleAttachments(ev *slack.MessageEvent, rmsg *config.Message)
287302 }
288303}
289304
290- func (b * Bslack ) handleTypingEvent (ev * slack.UserTypingEvent ) (* config.Message , error ) {
291- if ev .User == b .si .User .ID {
292- return nil , ErrEventIgnored
293- }
294- channelInfo , err := b .channels .getChannelByID (ev .Channel )
295- if err != nil {
296- return nil , err
297- }
298- return & config.Message {
299- Channel : channelInfo .Name ,
300- Account : b .Account ,
301- Event : config .EventUserTyping ,
302- }, nil
303- }
304-
305305// handleDownloadFile handles file download
306- func (b * Bslack ) handleDownloadFile (rmsg * config.Message , file * slack .File , retry bool ) error {
306+ func (b * Bslack ) handleDownloadFile (rmsg * config.Message , file * slackevents .File , retry bool ) error {
307307 if b .fileCached (file ) {
308308 return nil
309309 }
@@ -365,7 +365,7 @@ func (b *Bslack) handleGetChannelMembers(rmsg *config.Message) bool {
365365// identically named file but with different content will be uploaded correctly
366366// (the assumption is that such name collisions will not occur within the given
367367// timeframes).
368- func (b * Bslack ) fileCached (file * slack .File ) bool {
368+ func (b * Bslack ) fileCached (file * slackevents .File ) bool {
369369 if ts , ok := b .cache .Get ("file" + file .ID ); ok && time .Since (ts .(time.Time )) < time .Minute {
370370 return true
371371 } else if ts , ok = b .cache .Get ("filename" + file .Name ); ok && time .Since (ts .(time.Time )) < 10 * time .Second {
0 commit comments