Skip to content

Commit

Permalink
chore: Cleanup Slack/Mattermost/MSTeams notifiers (#9240)
Browse files Browse the repository at this point in the history
* chore: Cleanup Slack/Mattermost/MSTeams notifiers

These will need some refactoring for #8840 and this will hopefully
simplify this.

* Cleanup
  • Loading branch information
Dschoordsch committed Dec 4, 2023
1 parent 662ec2b commit 3bf4b81
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 261 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import sendToSentry from '../../../../utils/sendToSentry'
import {DataLoaderWorker} from '../../../graphql'
import getSummaryText from './getSummaryText'
import {NotificationIntegrationHelper} from './NotificationIntegrationHelper'
import {Notifier} from './Notifier'
import {getTeamPromptResponsesByMeetingId} from '../../../../postgres/queries/getTeamPromptResponsesByMeetingIds'
import {createNotifier} from './Notifier'
import {analytics} from '../../../../utils/analytics/analytics'

const notifyMSTeams = async (
Expand Down Expand Up @@ -346,87 +345,16 @@ async function getMSTeams(dataLoader: DataLoaderWorker, teamId: string, userId:
.get('bestTeamIntegrationProviders')
.load({service: 'msTeams', teamId, userId})
return provider
? MSTeamsNotificationHelper({
...(provider as IntegrationProviderMSTeams),
userId
})
: null
? [
MSTeamsNotificationHelper({
...(provider as IntegrationProviderMSTeams),
userId
})
]
: []
}

async function loadMeetingTeam(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const [team, meeting] = await Promise.all([
dataLoader.get('teams').load(teamId),
dataLoader.get('newMeetings').load(meetingId)
])
return {
meeting,
team
}
}

export const MSTeamsNotifier: Notifier = {
async startMeeting(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
;(await getMSTeams(dataLoader, team.id, meeting.facilitatorUserId))?.startMeeting(meeting, team)
},

async endMeeting(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
;(await getMSTeams(dataLoader, team.id, meeting.facilitatorUserId))?.endMeeting(
meeting,
team,
null
)
},

async startTimeLimit(
dataLoader: DataLoaderWorker,
scheduledEndTime: Date,
meetingId: string,
teamId: string
) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
;(await getMSTeams(dataLoader, team.id, meeting.facilitatorUserId))?.startTimeLimit(
scheduledEndTime,
meeting,
team
)
},

async endTimeLimit(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
;(await getMSTeams(dataLoader, team.id, meeting.facilitatorUserId))?.endTimeLimit(meeting, team)
},

async integrationUpdated(dataLoader: DataLoaderWorker, teamId: string, userId: string) {
;(await getMSTeams(dataLoader, teamId, userId))?.integrationUpdated()
},

async standupResponseSubmitted(
dataLoader: DataLoaderWorker,
meetingId: string,
teamId: string,
userId: string
) {
const [{meeting, team}, user, responses] = await Promise.all([
loadMeetingTeam(dataLoader, meetingId, teamId),
dataLoader.get('users').load(userId),
getTeamPromptResponsesByMeetingId(meetingId)
])
const response = responses.find(({userId: responseUserId}) => responseUserId === userId)
if (!meeting || !team || !response || !user) return
;(await getMSTeams(dataLoader, teamId, userId))?.standupResponseSubmitted(
meeting,
team,
user,
response
)
}
}
export const MSTeamsNotifier = createNotifier(getMSTeams)

function GenerateACMeetingTitle(meetingTitle: string) {
const titleTextBlock = new AdaptiveCards.TextBlock(meetingTitle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import {
makeHackedFieldButtonValue
} from './makeMattermostAttachments'
import {NotificationIntegrationHelper} from './NotificationIntegrationHelper'
import {Notifier} from './Notifier'
import {getTeamPromptResponsesByMeetingId} from '../../../../postgres/queries/getTeamPromptResponsesByMeetingIds'
import {createNotifier} from './Notifier'
import {analytics} from '../../../../utils/analytics/analytics'

const notifyMattermost = async (
Expand Down Expand Up @@ -322,90 +321,13 @@ async function getMattermost(dataLoader: DataLoaderWorker, teamId: string, userI
.get('bestTeamIntegrationProviders')
.load({service: 'mattermost', teamId, userId})
return provider
? MattermostNotificationHelper({
...(provider as IntegrationProviderMattermost),
userId
})
: null
}

async function loadMeetingTeam(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const [team, meeting] = await Promise.all([
dataLoader.get('teams').load(teamId),
dataLoader.get('newMeetings').load(meetingId)
])
return {
meeting,
team
}
? [
MattermostNotificationHelper({
...(provider as IntegrationProviderMattermost),
userId
})
]
: []
}

export const MattermostNotifier: Notifier = {
async startMeeting(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
;(await getMattermost(dataLoader, team.id, meeting.facilitatorUserId))?.startMeeting(
meeting,
team
)
},

async endMeeting(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
;(await getMattermost(dataLoader, team.id, meeting.facilitatorUserId))?.endMeeting(
meeting,
team,
null
)
},

async startTimeLimit(
dataLoader: DataLoaderWorker,
scheduledEndTime: Date,
meetingId: string,
teamId: string
) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
;(await getMattermost(dataLoader, team.id, meeting.facilitatorUserId))?.startTimeLimit(
scheduledEndTime,
meeting,
team
)
},

async endTimeLimit(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
;(await getMattermost(dataLoader, team.id, meeting.facilitatorUserId))?.endTimeLimit(
meeting,
team
)
},

async integrationUpdated(dataLoader: DataLoaderWorker, teamId: string, userId: string) {
;(await getMattermost(dataLoader, teamId, userId))?.integrationUpdated()
},

async standupResponseSubmitted(
dataLoader: DataLoaderWorker,
meetingId: string,
teamId: string,
userId: string
) {
const [{meeting, team}, user, responses] = await Promise.all([
loadMeetingTeam(dataLoader, meetingId, teamId),
dataLoader.get('users').load(userId),
getTeamPromptResponsesByMeetingId(meetingId)
])
const response = responses.find(({userId: responseUserId}) => responseUserId === userId)
if (!meeting || !team || !response || !user) return
;(await getMattermost(dataLoader, teamId, userId))?.standupResponseSubmitted(
meeting,
team,
user,
response
)
}
}
export const MattermostNotifier = createNotifier(getMattermost)
113 changes: 112 additions & 1 deletion packages/server/graphql/mutations/helpers/notifications/Notifier.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {SlackNotificationEvent} from '../../../../database/types/SlackNotification'
import {getTeamPromptResponsesByMeetingId} from '../../../../postgres/queries/getTeamPromptResponsesByMeetingIds'
import {DataLoaderWorker} from '../../../graphql'
import {NotifyResponse} from './NotificationIntegrationHelper'
import {NotificationIntegration, NotifyResponse} from './NotificationIntegrationHelper'

export type Notifier = {
startMeeting(dataLoader: DataLoaderWorker, meetingId: string, teamId: string): Promise<void>
Expand Down Expand Up @@ -34,3 +36,112 @@ export type Notifier = {
userId: string
): Promise<void>
}

export type NotificationIntegrationLoader = (
dataLoader: DataLoaderWorker,
teamId: string,
userId: string,
event: SlackNotificationEvent
) => Promise<NotificationIntegration[]>

async function loadMeetingTeam(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const [team, meeting] = await Promise.all([
dataLoader.get('teams').load(teamId),
dataLoader.get('newMeetings').load(meetingId)
])
return {
meeting,
team
}
}

export const createNotifier = (loader: NotificationIntegrationLoader): Notifier => ({
async startMeeting(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
const notifiers = await loader(dataLoader, team.id, meeting.facilitatorUserId, 'meetingStart')
notifiers.forEach((notifier) => notifier.startMeeting(meeting, team))
},

async updateMeeting(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
const notifiers = await loader(dataLoader, team.id, meeting.facilitatorUserId, 'meetingStart')
notifiers.forEach((notifier) => notifier.updateMeeting?.(meeting, team))
},

async endMeeting(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
const meetingResponses = await getTeamPromptResponsesByMeetingId(meetingId)
const standupResponses = await Promise.all(
meetingResponses.map(async (response) => {
const user = await dataLoader.get('users').loadNonNull(response.userId)
return {
user,
response
}
})
)
const notifiers = await loader(dataLoader, team.id, meeting.facilitatorUserId, 'meetingEnd')
notifiers.forEach((notifier) => notifier.endMeeting(meeting, team, standupResponses))
},

async startTimeLimit(
dataLoader: DataLoaderWorker,
scheduledEndTime: Date,
meetingId: string,
teamId: string
) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
const notifiers = await loader(
dataLoader,
team.id,
meeting.facilitatorUserId,
'MEETING_STAGE_TIME_LIMIT_START'
)
notifiers.forEach((notifier) => notifier.startTimeLimit(scheduledEndTime, meeting, team))
},

async endTimeLimit(dataLoader: DataLoaderWorker, meetingId: string, teamId: string) {
const {meeting, team} = await loadMeetingTeam(dataLoader, meetingId, teamId)
if (!meeting || !team) return
const notifiers = await loader(
dataLoader,
team.id,
meeting.facilitatorUserId,
'MEETING_STAGE_TIME_LIMIT_END'
)
notifiers.forEach((notifier) => notifier.endTimeLimit(meeting, team))
},

async integrationUpdated(dataLoader: DataLoaderWorker, teamId: string, userId: string) {
const notifiers = await loader(dataLoader, teamId, userId, 'meetingEnd')
notifiers.forEach((notifier) => notifier.integrationUpdated())
},

async standupResponseSubmitted(
dataLoader: DataLoaderWorker,
meetingId: string,
teamId: string,
userId: string
) {
const [{meeting, team}, user, responses] = await Promise.all([
loadMeetingTeam(dataLoader, meetingId, teamId),
dataLoader.get('users').load(userId),
getTeamPromptResponsesByMeetingId(meetingId)
])
const response = responses.find(({userId: responseUserId}) => responseUserId === userId)
if (!meeting || !team || !response || !user) return
const notifiers = await loader(
dataLoader,
team.id,
meeting.facilitatorUserId,
'STANDUP_RESPONSE_SUBMITTED'
)
notifiers.forEach((notifier) =>
notifier.standupResponseSubmitted(meeting, team, user, response)
)
}
})

0 comments on commit 3bf4b81

Please sign in to comment.