forked from ServiceNowDevProgram/SlackerBot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFind a relevant XKCD comic.js
164 lines (143 loc) · 5.14 KB
/
Find a relevant XKCD comic.js
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
activation_example:!xkcd wisdom of the ancients
regex:!xkcd
flags:g
*/
function buildComicOutput(xkcdPayload, comicFound, additionalComics) {
var blockArr = [];
if (!comicFound) {
blockArr.push({
"type": "section",
"text": {
"type": "plain_text",
"text": gs.getMessage("No relevant XKCD found, here is a random one")
}
});
}
blockArr.push({
"type": "header",
"text": {
"type": "plain_text",
"text": xkcdPayload.safe_title + ""
}
});
blockArr.push({
"type": "image",
"image_url": xkcdPayload.img,
"alt_text": xkcdPayload.alt
});
blockArr.push({
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "*Alt-text:* " + xkcdPayload.alt
}
]
});
if(additionalComics !== null){
var msgArr = [];
for(var i = 0; i < additionalComics.length; i++){
additionalComics[i] != xkcdPayload.num ? msgArr.push(additionalComics[i]) : null;
}
blockArr.push({
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "*Other matching comics:* " + msgArr.join(', ')
}
]
});
}
return {
"text": xkcdPayload.safe_title,
"blocks": blockArr
};
}
function getComicNumbers(body) {
var regex = /title="([0-9]+): .+"/gm;
var matches;
var comicNumbers = []; // store the search results, just the comic number
while ((matches = regex.exec(body)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (matches.index === regex.lastIndex) {
regex.lastIndex++;
}
// push the actual match to the array
comicNumbers.push(matches[1]);
}
return comicNumbers;
}
// if no parameters, display latest
// if number, display that number if valid otherwise random
// if -random then find a random
// anything else, do a search and return one of the search results
var terms = current.text.replace(/!xkcd/g, '').trim();
var comicNumProvided = /^-?\d+$/.test(terms);
var endPoint = 'https://xkcd.com/info.0.json';
var comicFound = (terms == "");
var msg;
// we need the number of comics to be able to handle random, number, and negative path
var restMsg = new sn_ws.RESTMessageV2();
restMsg.setHttpMethod('GET');
restMsg.setEndpoint(endPoint);
restMsg.setRequestHeader('User-Agent', 'servicenow');
var response = restMsg.execute();
var jsonBody = JSON.parse(response.getBody());
if (terms != "" && (terms == "-random" || comicNumProvided)) {
if (comicNumProvided && parseInt(terms) > 0 && parseInt(terms) <= jsonBody.num) {
// a comic number was provided and it's within the range of available comics
endPoint = "https://xkcd.com/" + terms + "/info.0.json";
comicFound = true;
} else {
// otherwise just work out
var randomComic = Math.floor(Math.random() * parseInt(jsonBody.num));
endPoint = "https://xkcd.com/" + randomComic + "/info.0.json";
comicFound = !comicNumProvided; // set comic found to true only if a random one was selected on purpose
}
} else if (terms != "") {
// assume it's a search, so use the search facility of explainxkcd
// the search results don't give us an indication of relevance, so to clean the results
// up we'll remove punctuation and insignificant words
var littleWords = ['of', 'the', "in", "on", "at", "to", "a", "is"];
terms = terms.split(' ')
.filter(function (_x) {
return _x != '' && littleWords.indexOf(_x.toLowerCase()) == -1;
})
.join('+');
var searchEndPoint = "https://www.explainxkcd.com/wiki/index.php?search=" + terms + "&title=Special%3ASearch&profile=default&fulltext=1";
var searchMsg = new sn_ws.RESTMessageV2();
searchMsg.setHttpMethod('GET');
searchMsg.setEndpoint(searchEndPoint);
searchMsg.setRequestHeader('User-Agent', 'servicenow');
response = searchMsg.execute();
var body = response.getBody();
// search the body in two passes, first the section that contains the page title matches
// if nothing found there, we'll search the page text section which is a search of body text
var pageTitleBody = body.substr(0, body.indexOf('Page text matches'));
var pageTextBody = body.substr(body.indexOf('Page text matches'));
var comicNumbers = getComicNumbers(pageTitleBody);
comicNumbers = comicNumbers.length > 0 ? comicNumbers : getComicNumbers(pageTextBody);
if (comicNumbers.length > 0) {
// we have some comics so get a random one
var randomComic = Math.floor(Math.random() * comicNumbers.length);
endPoint = "https://xkcd.com/" + comicNumbers[randomComic] + "/info.0.json";
comicFound = true;
} else {
var randomComic = Math.floor(Math.random() * parseInt(jsonBody.num));
endPoint = "https://xkcd.com/" + randomComic + "/info.0.json";
}
}
var comicDataMsg = new sn_ws.RESTMessageV2();
comicDataMsg.setHttpMethod('GET');
comicDataMsg.setEndpoint(endPoint);
comicDataMsg.setRequestHeader('User-Agent', 'servicenow');
var response = comicDataMsg.execute();
var body = JSON.parse(response.getBody());
if(comicNumbers && comicNumbers.length > 1){
msg = buildComicOutput(body, comicFound, comicNumbers);
} else {
msg = buildComicOutput(body, comicFound, null);
}
var sendIt = new x_snc_slackerbot.Slacker().send_chat(current, msg, false);