-
Notifications
You must be signed in to change notification settings - Fork 1
/
bot_command.js
262 lines (241 loc) · 6.63 KB
/
bot_command.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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/**
* @author IITII <ccmejx@gmail.com>
* @date 2022/06/29
*/
'use strict'
const {ids, db, clip} = require('./config/config')
const {Markup} = require('telegraf'),
{uniq} = require('lodash'),
LocalSession = require('telegraf-session-local'),
localSession = new LocalSession(db)
const {loggerMiddleware, logger} = require('./middlewares/logger'),
{clean, send_action, img_or_tags_arr, default_session, done_arr} = require('./services/utils/msg_utils'),
{message_decode} = require('./services/utils/service_utils'),
TaskRunner = require('./services/tasks/TaskRunner'),
picMsgRec = require('./services/msg/UserMsgReceiver'),
{searchMsgRec} = require('./services/msg/UnionSearch.js'),
{redis_add_sub, redis_remove_sub} = require('./services/utils/redis_utils')
const commands = [
['/start', hello,],
['/unset', unset,],
['/clean', cleanTmp,],
['/copy_del', copy,],
['/download', download,],
['/sub', start_end_sub,],
['/u_sub', start_end_sub,],
['/search', search,],
['/run', TaskRunner.run,],
['/exit', exit,],
]
const actions = [
// ...img_or_tags_arr.map(([_, ac]) => [ac, action_img_or_tags]),
[/.+/, action_async_handler],
]
function init_session(ctx) {
let {curr, pic, sub, search, opts} = ctx.session || default_session
ctx.session = {
curr: curr || default_session.curr,
pic: {
...default_session.pic,
...pic,
},
sub: {
...default_session.sub,
...sub,
},
search: {
...default_session.search,
...search,
},
opts: {
...default_session.opts,
...opts,
},
}
return ctx
}
function pic_init(ctx) {
ctx = init_session(ctx)
ctx.session.curr = 'pic'
return ctx
}
function sub_init(ctx) {
ctx = init_session(ctx)
ctx.session.curr = 'sub'
return ctx
}
// basic commands
async function hello(ctx) {
const {from} = ctx.update.message,
{first_name, last_name} = from,
name = `${first_name || ''}${last_name || ''}`
return ctx.reply(`Hello ${name}`)
}
async function unset(ctx) {
ctx.session = undefined
return ctx.reply('Set cleaned')
}
// pic commands
async function cleanTmp(ctx) {
const uid = ctx.from.id
if (uid === ids.adminId) {
return clean(ctx.chat.id, clip.baseDir)
} else {
return ctx.reply('你又不是狗管理')
}
}
async function copy(ctx) {
ctx = pic_init(ctx)
ctx.session.pic = {mode: 'copy'}
ctx.session.opts.img_or_tags = 'img'
return img_or_tags(ctx, '看看看')
}
async function download(ctx) {
ctx = pic_init(ctx)
ctx.session.pic = {mode: 'download'}
return img_or_tags(ctx, '下下下')
}
// share actions
async function img_or_tags(ctx, msg) {
// const selected = '✅'
// const arr_selected = img_or_tags_arr.map(([t, d]) => {
// if (d === ctx.session.opts.img_or_tags) {
// t = `${t} ${selected}`
// }
// return [t, d]
// })
return ctx.reply(msg, {
parse_mode: 'Markdown',
...Markup.inlineKeyboard([
// ...arr_selected.map(([hint, t]) => {
...img_or_tags_arr.map(([hint, t]) => {
return Markup.button.callback(hint, t)
})
])
})
}
async function action_img_or_tags(ctx) {
ctx.session.opts.img_or_tags = ctx.match[0]
const [text, _] = img_or_tags_arr.find(([_, ac]) => ac === ctx.match[0])
return ctx.answerCbQuery(`${text || '我要什么来着???'}!!!`)
}
async function action_async_handler(ctx) {
const {match, update} = ctx
const message = update?.callback_query?.message
// const message = update?.callback_query
// send all action to action_handler
await send_action({match, message})
let text = done_arr.find(([_, ac]) => ac === match[0]) || []
text = text[0]
return ctx.answerCbQuery(`${text || match[0]}!!!`)
}
async function search(ctx) {
ctx = init_session(ctx)
if (ctx.session.curr === 'search') {
ctx = pic_init(ctx)
return ctx.reply('退出搜索模式...')
} else {
ctx.session.curr = 'search'
return ctx.reply('输入关键词以搜索...')
}
}
// sub commands
async function start_end_sub(ctx) {
ctx = sub_init(ctx)
const message = ctx.message || ctx.update.message
const commands = message.entities.filter(_ => _.type === 'bot_command')
.map(({offset, length}) => message.text.substring(offset, offset + length)),
command = commands[0],
mode = command === '/sub' ? 'add' : 'remove',
remove_hint = command === '/sub' ? '' : '取消'
let msg
if (ctx.session.sub.mode === mode) {
msg = await end_sub(ctx)
} else {
ctx.session.sub = {mode, urls: []}
msg = `输入链接以${remove_hint}订阅, 重发命令以提交...`
}
return ctx.reply(msg)
}
function exit(ctx) {
setTimeout(() => {
process.exit(0)
}, 2000)
return ctx.reply(`尝试重启...`)
}
const subMap = new Map()
async function end_sub(ctx) {
ctx = sub_init(ctx)
const isSub = ctx.session.sub.mode === 'add'
const uid = ctx.message.from.id
let urls = subMap.get(uid) || []
urls = uniq(urls)
// encode url for request
urls = urls.map(u => u.includes('%') ? u : encodeURI(u))
let s = `${isSub ? '' : '取消'}订阅 ${urls.length} 条链接`
for (const url of urls) {
const redis_handle = isSub ? redis_add_sub : redis_remove_sub
await redis_handle(url, uid)
}
subMap.delete(uid)
ctx.session.sub = default_session.sub
// 订阅后默认回滚 pic_init
ctx = pic_init(ctx)
return s
}
async function add_to_sub(ctx) {
ctx = sub_init(ctx)
const message = ctx.message || ctx.update.message
const uid = ctx.message.from.id
let urls = message_decode(message, 'mix')
urls = TaskRunner.filterTagsOnly(urls)
const preUrls = subMap.get(uid) || []
logger.debug(`${uid} add ${urls.length}, pre: ${preUrls.length}`, urls)
subMap.set(uid, [...preUrls, ...urls])
}
// message forwarding
// const map = new Map()
async function message_forward(ctx) {
ctx = init_session(ctx)
// const uid = ctx.from.id
switch (ctx.session.curr) {
case 'pic':
await picMsgRec(ctx)
break
case 'sub':
await add_to_sub(ctx)
break
case 'search':
await searchMsgRec(ctx)
break
case 'init':
case 'opts':
default:
// let timer = map.get(uid)
// if (timer) {
// clearTimeout(timer)
// }
// timer = setTimeout(() => {
// map.delete(uid)
// ctx.reply('不要玩了')
// }, 1000)
return ctx.reply('不要玩了')
}
}
async function start(bot) {
bot.use(localSession.middleware())
bot.use(loggerMiddleware)
commands.forEach(([cmd, handler]) => {
bot.command(cmd, handler)
})
actions.forEach(([action, handler]) => {
bot.action(action, handler)
})
bot.on('message', message_forward)
}
module.exports = {
start,
actions,
commands,
default_session,
}