-
Notifications
You must be signed in to change notification settings - Fork 15
/
index.js
117 lines (95 loc) · 2.94 KB
/
index.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
const bluebird = require('bluebird');
const assert = require('assert');
const Telegraf = require('telegraf');
const createBitcoinRpc = require('./bitcoinRpc');
const commands = require('./commands');
const { each } = require('lodash');
const redis = require('redis');
const debug = require('debug')('tipmebch');
const { printErrorAndExit } = require('panik');
const createIntro = require('./intro');
const createZombie = require('./zombie');
const { maybeReplyFromStickerSet } = require('./utils');
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
const {
BITCOIND_URL,
TELEGRAM_BOT_TOKEN,
REDIS_URL = 'redis://localhost',
NODE_ENV,
STAFF_USER_ID,
DEFAULT_STICKER_SET = 'pepe',
} = process.env;
assert(REDIS_URL, 'REDIS_URL');
assert(BITCOIND_URL, 'BITCOIND_URL');
assert(TELEGRAM_BOT_TOKEN, 'TELEGRAM_BOT_TOKEN');
const redisClient = redis.createClient(REDIS_URL);
const botUserId = TELEGRAM_BOT_TOKEN.split(/:/)[0];
const { fetchRpc, lockBitcoind } = createBitcoinRpc({
bitcoindUrl: BITCOIND_URL,
redisClient,
});
const bot = new Telegraf(TELEGRAM_BOT_TOKEN);
bot.telegram.getMe().then(botInfo => {
bot.options.username = botInfo.username;
});
bot.use(async (ctx, next) => {
const stickerSet =
(await redisClient.getAsync(
`telegram.chat.settings:${ctx.chat.id}.sticker_set`
)) || DEFAULT_STICKER_SET;
// TODO: Migrate other properties into ctx
Object.assign(ctx, {
stickerSet,
maybeReplyFromStickerSet: stickerName =>
maybeReplyFromStickerSet(ctx, stickerSet, stickerName),
});
await next();
});
bot.use(createZombie());
bot.use(createIntro({ redisClient, fetchRpc, lockBitcoind }));
const handleCommandError = (ctx, error) => {
console.error(`Unhandled error when processing message`);
console.error(ctx.message);
console.error(error.stack);
ctx.reply(`Something crashed and I'm not sure why. Sorry!`);
if (NODE_ENV !== 'production') {
ctx.reply(error.stack);
}
};
const handleCommand = async (handler, ctx) => {
const isPm = ctx.chat.id > 0;
// TODO: Extract and use p-memoize. Maybe ctx contains admin status?
const isAdmin =
isPm ||
(await ctx.getChat(ctx.chat.id)).all_members_are_administrators ||
(await ctx
.getChatAdministrators(ctx.chat.id)
.then(admins => !!admins.find(_ => _.user.id === ctx.from.id)));
return handler({
ctx,
fetchRpc,
lockBitcoind,
userId: ctx.from.id.toString(),
botUserId,
username: ctx.from.username,
isPm,
isStaff: ctx.from.id === +STAFF_USER_ID,
isAdmin,
reply: _ => ctx.reply(_),
params:
console.log(ctx.message) ||
ctx.message.text
.split(' ')
.slice(1)
.filter(_ => _.length),
redisClient,
});
};
each(commands, (handler, name) => {
debug(`Registering command, ${name}`);
bot.command(name, ctx =>
handleCommand(handler, ctx).catch(error => handleCommandError(ctx, error))
);
});
bot.startPolling();