@@ -4,7 +4,8 @@ import makeAppURL from 'parabol-client/utils/makeAppURL'
4
4
import findStageById from 'parabol-client/utils/meetings/findStageById'
5
5
import { phaseLabelLookup } from 'parabol-client/utils/meetings/lookups'
6
6
import appOrigin from '../../../../appOrigin'
7
- import { IntegrationProviderMattermost as IIntegrationProviderMattermost } from '../../../../postgres/queries/getIntegrationProvidersByIds'
7
+ import { TeamMemberIntegrationAuth } from '../../../../postgres/pg'
8
+ import { IntegrationProviderMattermost } from '../../../../postgres/queries/getIntegrationProvidersByIds'
8
9
import { SlackNotification , Team } from '../../../../postgres/types'
9
10
import IUser from '../../../../postgres/types/IUser'
10
11
import { AnyMeeting , MeetingTypeEnum } from '../../../../postgres/types/Meeting'
@@ -23,16 +24,18 @@ import {
23
24
makeHackedFieldButtonValue
24
25
} from './makeMattermostAttachments'
25
26
26
- type IntegrationProviderMattermost = IIntegrationProviderMattermost & { teamId : string }
27
-
28
27
const notifyMattermost = async (
29
28
event : SlackNotification [ 'event' ] ,
30
- webhookUrl : string ,
29
+ channel : { webhookUrl : string | null ; serverBaseUrl : string | null ; sharedSecret : string | null } ,
31
30
user : IUser ,
32
31
teamId : string ,
33
32
textOrAttachmentsArray : string | unknown [ ] ,
34
33
notificationText ?: string
35
34
) => {
35
+ const { webhookUrl} = channel
36
+ if ( ! webhookUrl ) {
37
+ return 'success'
38
+ }
36
39
const manager = new MattermostServerManager ( webhookUrl )
37
40
const result = await manager . postMessage ( textOrAttachmentsArray , notificationText )
38
41
if ( result instanceof Error ) {
@@ -89,7 +92,11 @@ const makeEndMeetingButtons = (meeting: AnyMeeting) => {
89
92
}
90
93
}
91
94
92
- type MattermostNotificationAuth = IntegrationProviderMattermost & { userId : string }
95
+ type MattermostNotificationAuth = IntegrationProviderMattermost & {
96
+ userId : string
97
+ teamId : string
98
+ channel : string | null
99
+ }
93
100
94
101
const makeTeamPromptStartMeetingNotification = (
95
102
team : Team ,
@@ -164,8 +171,6 @@ const MattermostNotificationHelper: NotificationIntegrationHelper<MattermostNoti
164
171
notificationChannel
165
172
) => ( {
166
173
async startMeeting ( meeting , team , user ) {
167
- const { webhookUrl} = notificationChannel
168
-
169
174
const searchParams = {
170
175
utm_source : 'mattermost meeting start' ,
171
176
utm_medium : 'product' ,
@@ -179,12 +184,11 @@ const MattermostNotificationHelper: NotificationIntegrationHelper<MattermostNoti
179
184
meetingUrl
180
185
)
181
186
182
- return notifyMattermost ( 'meetingStart' , webhookUrl , user , team . id , notification )
187
+ return notifyMattermost ( 'meetingStart' , notificationChannel , user , team . id , notification )
183
188
} ,
184
189
185
190
async endMeeting ( meeting , team , user ) {
186
191
const { summary} = meeting
187
- const { webhookUrl} = notificationChannel
188
192
189
193
const summaryText = await getSummaryText ( meeting )
190
194
const meetingUrl = makeAppURL ( appOrigin , `meet/${ meeting . id } ` )
@@ -220,12 +224,11 @@ const MattermostNotificationHelper: NotificationIntegrationHelper<MattermostNoti
220
224
title_link : meetingUrl
221
225
} )
222
226
]
223
- return notifyMattermost ( 'meetingEnd' , webhookUrl , user , team . id , attachments )
227
+ return notifyMattermost ( 'meetingEnd' , notificationChannel , user , team . id , attachments )
224
228
} ,
225
229
226
230
async startTimeLimit ( scheduledEndTime , meeting , team , user ) {
227
231
const { name : meetingName , phases, facilitatorStageId} = meeting
228
- const { webhookUrl} = notificationChannel
229
232
230
233
const { name : teamName } = team
231
234
const stageRes = findStageById ( phases , facilitatorStageId )
@@ -274,15 +277,14 @@ const MattermostNotificationHelper: NotificationIntegrationHelper<MattermostNoti
274
277
275
278
return notifyMattermost (
276
279
'MEETING_STAGE_TIME_LIMIT_START' ,
277
- webhookUrl ,
280
+ notificationChannel ,
278
281
user ,
279
282
team . id ,
280
283
attachments
281
284
)
282
285
} ,
283
286
async endTimeLimit ( meeting , team , user ) {
284
287
const { name : meetingName } = meeting
285
- const { webhookUrl} = notificationChannel
286
288
const { name : teamName } = team
287
289
const meetingUrl = makeAppURL ( appOrigin , `meet/${ meeting . id } ` )
288
290
@@ -312,11 +314,17 @@ const MattermostNotificationHelper: NotificationIntegrationHelper<MattermostNoti
312
314
)
313
315
]
314
316
315
- return notifyMattermost ( 'MEETING_STAGE_TIME_LIMIT_END' , webhookUrl , user , team . id , attachments )
317
+ return notifyMattermost (
318
+ 'MEETING_STAGE_TIME_LIMIT_END' ,
319
+ notificationChannel ,
320
+ user ,
321
+ team . id ,
322
+ attachments
323
+ )
316
324
} ,
317
325
async integrationUpdated ( user ) {
318
326
const message = `Integration webhook configuration updated`
319
- const { webhookUrl , teamId} = notificationChannel
327
+ const { teamId} = notificationChannel
320
328
321
329
const attachments = [
322
330
makeFieldsAttachment (
@@ -331,7 +339,7 @@ const MattermostNotificationHelper: NotificationIntegrationHelper<MattermostNoti
331
339
}
332
340
)
333
341
]
334
- return notifyMattermost ( 'meetingEnd' , webhookUrl , user , teamId , attachments )
342
+ return notifyMattermost ( 'meetingEnd' , notificationChannel , user , teamId , attachments )
335
343
} ,
336
344
async standupResponseSubmitted ( ) {
337
345
// Not implemented
@@ -340,17 +348,37 @@ const MattermostNotificationHelper: NotificationIntegrationHelper<MattermostNoti
340
348
} )
341
349
342
350
async function getMattermost ( dataLoader : DataLoaderWorker , teamId : string , userId : string ) {
343
- const provider = await dataLoader
344
- . get ( 'bestTeamIntegrationProviders' )
345
- . load ( { service : 'mattermost' , teamId, userId} )
346
- return provider && provider . teamId
347
- ? [
348
- MattermostNotificationHelper ( {
349
- ...( provider as IntegrationProviderMattermost ) ,
350
- userId
351
- } )
352
- ]
353
- : [ ]
351
+ const auths = await dataLoader
352
+ . get ( 'teamMemberIntegrationAuthsByTeamId' )
353
+ . load ( { service : 'mattermost' , teamId} )
354
+
355
+ // filter the auths
356
+ // for webhook, keep only 1 as we don't know the channel
357
+ // if there are sharedSecret integrations, prefer these, but keep channels unique
358
+ const filteredAuths = auths . reduce ( ( acc , auth ) => {
359
+ if ( auth . channel ) {
360
+ if ( ! acc . some ( ( a ) => a . channel === auth . channel ) ) {
361
+ acc . push ( auth )
362
+ }
363
+ }
364
+ return acc
365
+ } , [ ] as TeamMemberIntegrationAuth [ ] )
366
+ if ( filteredAuths . length === 0 ) {
367
+ const webhookAuth =
368
+ auths . find ( ( auth ) => auth . userId === userId ) ?? auths . filter ( ( auth ) => ! auth . channel ) [ 0 ]
369
+ if ( webhookAuth ) {
370
+ filteredAuths . push ( webhookAuth )
371
+ }
372
+ }
373
+
374
+ return Promise . all (
375
+ filteredAuths . map ( async ( auth ) => {
376
+ const provider = ( await dataLoader
377
+ . get ( 'integrationProviders' )
378
+ . loadNonNull ( auth . providerId ) ) as IntegrationProviderMattermost
379
+ return MattermostNotificationHelper ( { ...provider , teamId, userId, channel : auth . channel } )
380
+ } )
381
+ )
354
382
}
355
383
356
384
export const MattermostNotifier = createNotifier ( getMattermost )
0 commit comments