Skip to content

Commit 399082e

Browse files
Merge pull request #228 from johnseekins-pathccm/regex-fixes
A few incident trigger tweaks
2 parents 46ca664 + 028978e commit 399082e

File tree

5 files changed

+137
-104
lines changed

5 files changed

+137
-104
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ Then add **hubot-pager-me** to your `external-scripts.json`:
2727
| `HUBOT_PAGERDUTY_FROM_EMAIL` | Yes | The email of the default "actor" user for incident creation and modification. |
2828
| `HUBOT_PAGERDUTY_USER_ID` | No`*` | The user ID of a PagerDuty user for your bot. This is only required if you want chat users to be able to trigger incidents without their own PagerDuty user.
2929
| `HUBOT_PAGERDUTY_SERVICE_API_KEY` | No`*` | The [Incident Service Key](https://v2.developer.pagerduty.com/docs/incident-creation-api) to use when creating a new incident. This should be assigned to a dummy escalation policy that doesn't actually notify, as Hubot will trigger on this before reassigning it.
30-
| `HUBOT_PAGERDUTY_SERVICES` | No | Provide a comma separated list of service identifiers (e.g. `PFGPBFY,AFBCGH`) to restrict queries to only those services. |
31-
| `HUBOT_PAGERDUTY_SCHEDULES` | No | Provide a comma separated list of schedules identifiers (e.g. `PFGPBFY,AFBCGH`) to restrict queries to only those schedules. |
30+
| `HUBOT_PAGERDUTY_SERVICES` | No | Provide a comma separated list of service identifiers (e.g. `PFGPBFY,AFBCGH`) to restrict queries to only those services.
31+
| `HUBOT_PAGERDUTY_SCHEDULES` | No | Provide a comma separated list of schedules identifiers (e.g. `PFGPBFY,AFBCGH`) to restrict queries to only those schedules.
32+
| `HUBOT_PAGERDUTY_DEFAULT_SCHEDULE` | No | A specific schedule that can be triggered using `pager default trigger` to reduce typing for users.
3233

3334
`*` - May be required for certain actions.
3435

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "hubot-pager-me",
33
"description": "PagerDuty integration for Hubot",
4-
"version": "4.0.4",
4+
"version": "4.1.0",
55
"author": "Josh Nichols <technicalpickles@github.com>",
66
"license": "MIT",
77
"keywords": [

src/scripts/pagerduty.js

Lines changed: 126 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
// Commands:
55
// hubot pager me as <email> - remember your pager email is <email>
66
// hubot pager forget me - forget your pager email
7-
// hubot Am I on call - return if I'm currently on call or not
7+
// hubot am I on call - return if I'm currently on call or not
88
// hubot who's on call - return a list of services and who is on call for them
99
// hubot who's on call for <schedule> - return the username of who's on call for any schedule matching <search>
1010
// hubot pager trigger <user> <msg> - create a new incident with <msg> and assign it to <user>
11+
// hubot pager default trigger <msg> - create a new incident with <msg> and assign it the user currently on call for our default schedule
1112
// hubot pager trigger <schedule> <msg> - create a new incident with <msg> and assign it the user currently on call for <schedule>
1213
// hubot pager incidents - return the current incidents
1314
// hubot pager sup - return the current incidents
@@ -45,9 +46,12 @@ const moment = require('moment-timezone');
4546
const pagerDutyUserId = process.env.HUBOT_PAGERDUTY_USER_ID;
4647
const pagerDutyServiceApiKey = process.env.HUBOT_PAGERDUTY_SERVICE_API_KEY;
4748
const pagerDutySchedules = process.env.HUBOT_PAGERDUTY_SCHEDULES;
49+
const pagerDutyDefaultSchedule = process.env.HUBOT_PAGERDUTY_DEFAULT_SCHEDULE;
50+
4851

4952
module.exports = function (robot) {
5053
let campfireUserToPagerDutyUser;
54+
5155
robot.respond(/pager( me)?$/i, function (msg) {
5256
if (pagerduty.missingEnvironmentForApi(msg)) {
5357
return;
@@ -151,110 +155,42 @@ module.exports = function (robot) {
151155
robot.respond(/(pager|major)( me)? (?:trigger|page) ([\w\-]+)$/i, (msg) =>
152156
msg.reply("Please include a user or schedule to page, like 'hubot pager infrastructure everything is on fire'.")
153157
);
158+
154159
robot.respond(
155-
/(pager|major)( me)? (?:trigger|page) ((["'])([^\4]*?)\4|([^]*?)|([^]*?)|([\.\w\-]+)) (.+)$/i,
160+
/(pager|major)( me)? default (?:trigger|page) ?(.+)?$/i,
156161
function (msg) {
157162
msg.finish();
158163

159164
if (pagerduty.missingEnvironmentForApi(msg)) {
160165
return;
161166
}
162-
167+
if (!pagerDutyDefaultSchedule) {
168+
msg.send("No default schedule configured! Cannot send a page! Please set HUBOT_PAGERDUTY_DEFAULT_SCHEDULE");
169+
return;
170+
}
163171
const fromUserName = msg.message.user.name;
164-
let query = msg.match[5] || msg.match[6] || msg.match[7] || msg.match[8];
165-
const reason = msg.match[9];
166-
const description = `${reason} - @${fromUserName}`;
167-
168-
// Figure out who we are
169-
campfireUserToPagerDutyUser(msg, msg.message.user, false, function (triggerdByPagerDutyUser) {
170-
const triggerdByPagerDutyUserId = (() => {
171-
if (triggerdByPagerDutyUser != null) {
172-
return triggerdByPagerDutyUser.id;
173-
} else if (pagerDutyUserId) {
174-
return pagerDutyUserId;
175-
}
176-
})();
177-
if (!triggerdByPagerDutyUserId) {
178-
msg.send(
179-
`Sorry, I can't figure your PagerDuty account, and I don't have my own :( Can you tell me your PagerDuty email with \`${robot.name} pager me as you@yourdomain.com\` or make sure you've set the HUBOT_PAGERDUTY_USER_ID environment variable?`
180-
);
181-
return;
182-
}
183-
184-
// Figure out what we're trying to page
185-
reassignmentParametersForUserOrScheduleOrEscalationPolicy(msg, query, function (results) {
186-
if (!(results.assigned_to_user || results.escalation_policy)) {
187-
msg.reply(`Couldn't find a user or unique schedule or escalation policy matching ${query} :/`);
188-
return;
189-
}
190-
191-
return pagerDutyIntegrationAPI(msg, 'trigger', description, function (json) {
192-
query = { incident_key: json.incident_key };
193-
194-
msg.reply(':pager: triggered! now assigning it to the right user...');
195-
196-
return setTimeout(
197-
() =>
198-
pagerduty.get('/incidents', query, function (err, json) {
199-
if (err != null) {
200-
robot.emit('error', err, msg);
201-
return;
202-
}
203-
204-
if ((json != null ? json.incidents.length : undefined) === 0) {
205-
msg.reply("Couldn't find the incident we just created to reassign. Please try again :/");
206-
} else {
207-
}
208-
209-
let data = null;
210-
if (results.escalation_policy) {
211-
data = {
212-
incidents: json.incidents.map((incident) => ({
213-
id: incident.id,
214-
type: 'incident_reference',
172+
query = pagerDutyDefaultSchedule;
173+
reason = msg.match[4] || "We Need Help!"
174+
description = `${reason} - @${fromUserName}`;
175+
robot.logger.debug(`Triggering a default page to ${pagerDutyDefaultSchedule} saying ${description}!`);
176+
incidentTrigger(msg, query, description);
177+
}
178+
);
215179

216-
escalation_policy: {
217-
id: results.escalation_policy,
218-
type: 'escalation_policy_reference',
219-
},
220-
})),
221-
};
222-
} else {
223-
data = {
224-
incidents: json.incidents.map((incident) => ({
225-
id: incident.id,
226-
type: 'incident_reference',
227-
228-
assignments: [
229-
{
230-
assignee: {
231-
id: results.assigned_to_user,
232-
type: 'user_reference',
233-
},
234-
},
235-
],
236-
})),
237-
};
238-
}
180+
robot.respond(
181+
/(pager|major)( me)? (?:trigger|page) ((["'])([^\4]*?)\4|([^]*?)|([^]*?)|([\.\w\-]+)) ?(.+)?$/i,
182+
function (msg) {
183+
msg.finish();
239184

240-
return pagerduty.put('/incidents', data, function (err, json) {
241-
if (err != null) {
242-
robot.emit('error', err, msg);
243-
return;
244-
}
245-
246-
if ((json != null ? json.incidents.length : undefined) === 1) {
247-
return msg.reply(`:pager: assigned to ${results.name}!`);
248-
} else {
249-
return msg.reply('Problem reassigning the incident :/');
250-
}
251-
});
252-
}),
253-
10000
254-
);
255-
});
256-
});
257-
});
185+
if (pagerduty.missingEnvironmentForApi(msg)) {
186+
return;
187+
}
188+
const fromUserName = msg.message.user.name;
189+
const query = msg.match[5] || msg.match[6] || msg.match[7] || msg.match[8];
190+
const reason = msg.match[9] || "We Need Help!";
191+
const description = `${reason} - @${fromUserName}`;
192+
robot.logger.debug(`Triggering a page to ${query} saying ${description}!`);
193+
incidentTrigger(msg, query, description);
258194
}
259195
);
260196

@@ -722,14 +658,14 @@ module.exports = function (robot) {
722658
);
723659
return;
724660
}
725-
726-
withScheduleMatching(msg, msg.match[2], function (matchingSchedule) {
661+
const schedule = msg.match[2].replace(/(^"|"$)/mg, '');
662+
const minutes = parseInt(msg.match[3]);
663+
withScheduleMatching(msg, schedule, function (matchingSchedule) {
727664
if (!matchingSchedule.id) {
728665
return;
729666
}
730667

731668
let start = moment().format();
732-
const minutes = parseInt(msg.match[3]);
733669
let end = moment().add(minutes, 'minutes').format();
734670
const override = {
735671
start,
@@ -1182,6 +1118,98 @@ module.exports = function (robot) {
11821118
}
11831119
});
11841120

1121+
var incidentTrigger = (msg, query, description) =>
1122+
// Figure out who we are
1123+
campfireUserToPagerDutyUser(msg, msg.message.user, false, function (triggerdByPagerDutyUser) {
1124+
const triggerdByPagerDutyUserId = (() => {
1125+
if (triggerdByPagerDutyUser != null) {
1126+
return triggerdByPagerDutyUser.id;
1127+
} else if (pagerDutyUserId) {
1128+
return pagerDutyUserId;
1129+
}
1130+
})();
1131+
if (!triggerdByPagerDutyUserId) {
1132+
msg.send(
1133+
`Sorry, I can't figure your PagerDuty account, and I don't have my own :( Can you tell me your PagerDuty email with \`${robot.name} pager me as you@yourdomain.com\` or make sure you've set the HUBOT_PAGERDUTY_USER_ID environment variable?`
1134+
);
1135+
return;
1136+
}
1137+
1138+
// Figure out what we're trying to page
1139+
reassignmentParametersForUserOrScheduleOrEscalationPolicy(msg, query, function (results) {
1140+
if (!(results.assigned_to_user || results.escalation_policy)) {
1141+
msg.reply(`Couldn't find a user or unique schedule or escalation policy matching ${query} :/`);
1142+
return;
1143+
}
1144+
1145+
return pagerDutyIntegrationAPI(msg, 'trigger', description, function (json) {
1146+
query = { incident_key: json.incident_key };
1147+
1148+
msg.reply(':pager: triggered! now assigning it to the right user...');
1149+
1150+
return setTimeout(
1151+
() =>
1152+
pagerduty.get('/incidents', query, function (err, json) {
1153+
if (err != null) {
1154+
robot.emit('error', err, msg);
1155+
return;
1156+
}
1157+
1158+
if ((json != null ? json.incidents.length : undefined) === 0) {
1159+
msg.reply("Couldn't find the incident we just created to reassign. Please try again :/");
1160+
} else {
1161+
}
1162+
1163+
let data = null;
1164+
if (results.escalation_policy) {
1165+
data = {
1166+
incidents: json.incidents.map((incident) => ({
1167+
id: incident.id,
1168+
type: 'incident_reference',
1169+
1170+
escalation_policy: {
1171+
id: results.escalation_policy,
1172+
type: 'escalation_policy_reference',
1173+
},
1174+
})),
1175+
};
1176+
} else {
1177+
data = {
1178+
incidents: json.incidents.map((incident) => ({
1179+
id: incident.id,
1180+
type: 'incident_reference',
1181+
1182+
assignments: [
1183+
{
1184+
assignee: {
1185+
id: results.assigned_to_user,
1186+
type: 'user_reference',
1187+
},
1188+
},
1189+
],
1190+
})),
1191+
};
1192+
}
1193+
1194+
return pagerduty.put('/incidents', data, function (err, json) {
1195+
if (err != null) {
1196+
robot.emit('error', err, msg);
1197+
return;
1198+
}
1199+
1200+
if ((json != null ? json.incidents.length : undefined) === 1) {
1201+
return msg.reply(`:pager: assigned to ${results.name}!`);
1202+
} else {
1203+
return msg.reply('Problem reassigning the incident :/');
1204+
}
1205+
});
1206+
}),
1207+
10000
1208+
);
1209+
});
1210+
});
1211+
});
1212+
11851213
const userEmail = (user) =>
11861214
user.pagerdutyEmail ||
11871215
user.email_address ||

test/pager-me-test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const { expect } = chai;
77
describe('pagerduty', function () {
88
before(function () {
99
this.triggerRegex =
10-
/(pager|major)( me)? (?:trigger|page) ((["'])([^\4]*?)\4|([^]*?)|([^]*?)|([\.\w\-]+)) (.+)$/i;
10+
/(pager|major)( me)? (?:trigger|page) ((["'])([^\4]*?)\4|([^]*?)|([^]*?)|([\.\w\-]+)) ?(.+)?$/i;
1111
this.schedulesRegex = /(pager|major)( me)? schedules( ((["'])([^]*?)\5|(.+)))?$/i;
1212
this.whosOnCallRegex =
1313
/who(?:s|'s|s| is|se)? (?:on call|oncall|on-call)(?:\?)?(?: (?:for )?((["'])([^]*?)\2|(.*?))(?:\?|$))?$/i;
@@ -46,6 +46,10 @@ describe('pagerduty', function () {
4646
expect(this.robot.respond).to.have.been.calledWith(/(pager|major)( me)? (?:trigger|page) ([\w\-]+)$/i);
4747
});
4848

49+
it('registers a pager default trigger with message listener', function () {
50+
expect(this.robot.respond).to.have.been.calledWith(/(pager|major)( me)? default (?:trigger|page) ?(.+)?$/i);
51+
});
52+
4953
it('registers a pager trigger with message listener', function () {
5054
expect(this.robot.respond).to.have.been.calledWith(this.triggerRegex);
5155
});

0 commit comments

Comments
 (0)