This repository has been archived by the owner on Feb 5, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
xkcd.js
122 lines (99 loc) · 3.12 KB
/
xkcd.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
'use strict';
const { bot } = require('./bot');
const _ = require('lodash');
const request = require('request-promise-native');
const throttle = _.flip(_.throttle);
const { XKCD_CACHE_TIME, NODE_ENV } = process.env;
const cacheTime = Number(XKCD_CACHE_TIME || (NODE_ENV === 'development'? 0: 3600));
const maxInlineResults = 50;
const LATEST_XKCD_CACHE_TIME = 600 * 1000; // 10 minutes in ms
function revelantXkcd(query) {
return request({
url: 'https://relevantxkcd.appspot.com/process',
qs: { action: 'xkcd', query },
}).then(text => text.split(/[\r\n]+/g).slice(2, -1));
}
const latestXkcd = throttle({ leading: true, trailing: false }, LATEST_XKCD_CACHE_TIME, () => {
return request({
url: 'https://xkcd.com/info.0.json',
json: true,
});
});
const getXkcd = _.memoize(num =>
request({
url: `https://xkcd.com/${num}/info.0.json`,
json: true,
}).catch(err => {
getXkcd.cache.delete(num);
throw err;
})
);
function results() {
return JSON.stringify(this.list);
}
function replyMarkupForXkcd(num) {
return bot.inlineKeyboard([[
{
text: 'Hover text',
callback_data: `alt ${num}`
}, {
text: 'Explanation...',
url: `https://www.explainxkcd.com/wiki/index.php/${num}`,
}
]]);
}
function inlineImage({num, img}) {
return {
type: 'photo',
id: String(num),
photo_url: img,
thumb_url: img,
caption: `https://xkcd.com/${num}`,
reply_markup: replyMarkupForXkcd(num),
}
}
function replyXkcd(msg, num) {
const replyMarkup = replyMarkupForXkcd(num);
return msg.reply.text(`https://xkcd.com/${num}`, { replyMarkup } );
}
exports.handler = async (msg) => {
if (msg.entities[0].type !== 'bot_command') {
return;
}
msg.args = msg.text.slice(msg.entities[0].length + 1);
if (!msg.args) {
const latest = await latestXkcd();
return replyXkcd(msg, latest.num);
} else if (/^\d+$/.test(msg.args)) {
return replyXkcd(msg, msg.args);
} else {
const [ revelant ] = await revelantXkcd(msg.args);
const [ id ] = revelant.split(' ');
return replyXkcd(msg, id);
}
};
exports.randomHandler = async (msg) => {
const latest = await latestXkcd();
const random = _.random(1, latest.num);
return replyXkcd(msg, random);
}
exports.inlineHandler = async (inlineQuery) => {
const { query, id } = inlineQuery;
const list = query
? (await revelantXkcd(query))
.slice(0, maxInlineResults)
.map(line => line.split(' '))
.map(([num, url]) => inlineImage({
num,
img:`https://www.explainxkcd.com${url}`
}))
: [inlineImage(await latestXkcd())]
return bot.answerInlineQuery({ id, list, cacheTime, results });
}
exports.callbackHandler = async ({ data, id }) => {
let [ , num ] = /^alt (\d+)$/.exec(data) || [];
if (num) {
const { alt } = await getXkcd(num);
return bot.answerCallbackQuery(id, { text: alt, showAlert: true, cacheTime: 604800 });
}
}