-
Notifications
You must be signed in to change notification settings - Fork 35
/
issueHandler.ts
120 lines (112 loc) · 4.11 KB
/
issueHandler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import {Response} from 'express';
import Item, {ItemColumn} from '../../../models/Item.model';
import SentryInstallation from '../../../models/SentryInstallation.model';
import User from '../../../models/User.model';
async function handleAssigned(
sentryInstallation: SentryInstallation,
issueData: Record<string, any>
) {
// Find or create an item to associate with the Sentry issue
const [item, isItemNew] = await Item.findOrCreate({
where: {sentryId: issueData.id, organization_id: sentryInstallation.organizationId},
defaults: {
...getItemDefaultsFromSentryIssue(sentryInstallation, issueData),
column: ItemColumn.Doing,
},
});
console.info(`${isItemNew ? 'Created' : 'Found'} linked item from Sentry issue`);
// Find or create a user to associate with the item
// Note: The assignee in Sentry might be a team, which you could handle here as well
const {type, email, name} = issueData.assignedTo;
if (type === 'user') {
const [user, isUserNew] = await User.findOrCreate({
where: {username: email},
defaults: {
name,
username: email,
avatar: `https://ui-avatars.com/api/?name=${name}&background=random`,
organizationId: sentryInstallation.organizationId,
},
});
await user.$add('items', item);
console.info(`Assigned to ${isUserNew ? 'new' : 'existing'} user:`, user.username);
}
}
async function handleCreated(
sentryInstallation: SentryInstallation,
issueData: Record<string, any>
) {
// Create an item to associate with the Sentry Issue
await Item.create(getItemDefaultsFromSentryIssue(sentryInstallation, issueData));
console.info('Created linked item from Sentry issue');
}
async function handleIgnored(
sentryInstallation: SentryInstallation,
issueData: Record<string, any>
) {
// Find or create an item to associate with the Sentry Issue
const [item, isItemNew] = await Item.findOrCreate({
where: {sentryId: issueData.id, organization_id: sentryInstallation.organizationId},
defaults: getItemDefaultsFromSentryIssue(sentryInstallation, issueData),
});
console.info(`${isItemNew ? 'Created' : 'Found'} linked item from Sentry issue`);
// Mark the item as ignored
item.isIgnored = true;
await item.save();
console.info('Marked item as ignored');
}
async function handleResolved(
sentryInstallation: SentryInstallation,
issueData: Record<string, any>
) {
// Find or create an item to associate with the Sentry Issue
const [item, isItemNew] = await Item.findOrCreate({
where: {sentryId: issueData.id, organization_id: sentryInstallation.organizationId},
defaults: getItemDefaultsFromSentryIssue(sentryInstallation, issueData),
});
console.info(`${isItemNew ? 'Created' : 'Found'} linked item from Sentry Issue`);
// Update the item's column to DONE
item.column = ItemColumn.Done;
await item.save();
console.info(`Updated item's column to '${ItemColumn.Done}'`);
}
export default async function issueHandler(
response: Response,
action: string,
sentryInstallation: SentryInstallation,
data: Record<string, any>
): Promise<void> {
const {issue: issueData} = data;
switch (action) {
case 'assigned':
await handleAssigned(sentryInstallation, issueData);
response.status(202);
break;
case 'created':
await handleCreated(sentryInstallation, issueData);
response.status(201);
break;
case 'ignored':
await handleIgnored(sentryInstallation, issueData);
response.status(202);
break;
case 'resolved':
await handleResolved(sentryInstallation, issueData);
response.status(202);
break;
default:
console.info(`Unhandled Sentry issue action: ${action}`);
response.status(400);
}
}
export const getItemDefaultsFromSentryIssue = (
sentryInstallation: SentryInstallation,
issueData: Record<string, any>
) => ({
organizationId: sentryInstallation.organizationId,
title: issueData.title as string,
description: `${issueData.shortId} - ${issueData.culprit}`,
column: issueData.status === 'resolved' ? ItemColumn.Done : ItemColumn.Todo,
isIgnored: issueData.status === 'ignored',
sentryId: issueData.id,
});