@codebam/cf-workers-telegram-bot 7.19.0 → 7.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +30 -0
- package/dist/api.js +37 -0
- package/dist/ctx.d.ts +19 -0
- package/dist/ctx.js +109 -0
- package/dist/main/src/TelegramBot.1.d.ts +0 -0
- package/dist/main/src/TelegramBot.1.js +1 -0
- package/dist/main/src/TelegramBot.d.ts +0 -0
- package/dist/main/src/TelegramBot.js +1 -0
- package/dist/main/src/api.d.ts +14 -0
- package/dist/main/src/api.js +21 -0
- package/dist/main/src/bot_api.d.ts +10 -0
- package/dist/main/src/bot_api.js +11 -0
- package/dist/main/src/commands/ban.d.ts +5 -0
- package/dist/main/src/commands/ban.js +8 -0
- package/dist/main/src/commands/bored.d.ts +5 -0
- package/dist/main/src/commands/bored.js +7 -0
- package/dist/main/src/commands/clear.d.ts +5 -0
- package/dist/main/src/commands/clear.js +14 -0
- package/dist/main/src/commands/code.d.ts +5 -0
- package/dist/main/src/commands/code.js +4 -0
- package/dist/main/src/commands/commandlist.d.ts +5 -0
- package/dist/main/src/commands/commandlist.js +1 -0
- package/dist/main/src/commands/dog.d.ts +5 -0
- package/dist/main/src/commands/dog.js +7 -0
- package/dist/main/src/commands/duckduckgo.d.ts +5 -0
- package/dist/main/src/commands/duckduckgo.js +42 -0
- package/dist/main/src/commands/epoch.d.ts +5 -0
- package/dist/main/src/commands/epoch.js +4 -0
- package/dist/main/src/commands/getchatinfo.d.ts +5 -0
- package/dist/main/src/commands/getchatinfo.js +1 -0
- package/dist/main/src/commands/image.d.ts +5 -0
- package/dist/main/src/commands/image.js +19 -0
- package/dist/main/src/commands/joke.d.ts +5 -0
- package/dist/main/src/commands/joke.js +7 -0
- package/dist/main/src/commands/kanye.d.ts +5 -0
- package/dist/main/src/commands/kanye.js +8 -0
- package/dist/main/src/commands/mute.d.ts +5 -0
- package/dist/main/src/commands/mute.js +8 -0
- package/dist/main/src/commands/ping.d.ts +5 -0
- package/dist/main/src/commands/ping.js +1 -0
- package/dist/main/src/commands/question.d.ts +5 -0
- package/dist/main/src/commands/question.js +74 -0
- package/dist/main/src/commands/roll.d.ts +5 -0
- package/dist/main/src/commands/roll.js +6 -0
- package/dist/main/src/commands/sean.d.ts +5 -0
- package/dist/main/src/commands/sean.js +76 -0
- package/dist/main/src/commands/start.d.ts +5 -0
- package/dist/main/src/commands/start.js +1 -0
- package/dist/main/src/commands/toss.d.ts +5 -0
- package/dist/main/src/commands/toss.js +1 -0
- package/dist/main/src/commands/translate.d.ts +5 -0
- package/dist/main/src/commands/translate.js +26 -0
- package/dist/main/src/handler.d.ts +12 -0
- package/dist/main/src/handler.js +40 -0
- package/dist/main/src/libs.d.ts +5 -0
- package/dist/main/src/libs.js +7 -0
- package/dist/main/src/main.d.ts +4 -0
- package/dist/main/src/main.js +4 -0
- package/dist/main/src/telegram_api.d.ts +34 -0
- package/dist/main/src/telegram_api.js +192 -0
- package/dist/main/src/telegram_bot.d.ts +20 -0
- package/dist/main/src/telegram_bot.js +116 -0
- package/dist/main/src/telegram_commands.d.ts +22 -0
- package/dist/main/src/telegram_commands.js +21 -0
- package/dist/main/src/telegram_webhook.d.ts +10 -0
- package/dist/main/src/telegram_webhook.js +20 -0
- package/dist/main/src/types/Balance.d.ts +6 -0
- package/dist/main/src/types/Balance.js +1 -0
- package/dist/main/src/types/Bored.d.ts +10 -0
- package/dist/main/src/types/Bored.js +1 -0
- package/dist/main/src/types/ChatPermissions.d.ts +17 -0
- package/dist/main/src/types/ChatPermissions.js +1 -0
- package/dist/main/src/types/Command.d.ts +5 -0
- package/dist/main/src/types/Command.js +1 -0
- package/dist/main/src/types/CommandArgs.d.ts +5 -0
- package/dist/main/src/types/CommandArgs.js +1 -0
- package/dist/main/src/types/Commands.d.ts +3 -0
- package/dist/main/src/types/Commands.js +1 -0
- package/dist/main/src/types/Config.d.ts +20 -0
- package/dist/main/src/types/Config.js +33 -0
- package/dist/main/src/types/DDGQueryResponse.d.ts +12 -0
- package/dist/main/src/types/DDGQueryResponse.js +1 -0
- package/dist/main/src/types/DataTypes.d.ts +2 -0
- package/dist/main/src/types/DataTypes.js +1 -0
- package/dist/main/src/types/Joke.d.ts +20 -0
- package/dist/main/src/types/Joke.js +1 -0
- package/dist/main/src/types/Kanye.d.ts +4 -0
- package/dist/main/src/types/Kanye.js +1 -0
- package/dist/main/src/types/Kv.d.ts +3 -0
- package/dist/main/src/types/Kv.js +1 -0
- package/dist/main/src/types/PartialTelegramUpdate.d.ts +11 -0
- package/dist/main/src/types/PartialTelegramUpdate.js +1 -0
- package/dist/main/src/types/TelegramChat.d.ts +21 -0
- package/dist/main/src/types/TelegramChat.js +1 -0
- package/dist/main/src/types/TelegramCommand.d.ts +5 -0
- package/dist/main/src/types/TelegramCommand.js +1 -0
- package/dist/main/src/types/TelegramFrom.d.ts +8 -0
- package/dist/main/src/types/TelegramFrom.js +1 -0
- package/dist/main/src/types/TelegramInlineQuery.d.ts +9 -0
- package/dist/main/src/types/TelegramInlineQuery.js +1 -0
- package/dist/main/src/types/TelegramInlineQueryResult.d.ts +6 -0
- package/dist/main/src/types/TelegramInlineQueryResult.js +8 -0
- package/dist/main/src/types/TelegramInlineQueryResultArticle.d.ts +8 -0
- package/dist/main/src/types/TelegramInlineQueryResultArticle.js +15 -0
- package/dist/main/src/types/TelegramInlineQueryResultPhoto.d.ts +13 -0
- package/dist/main/src/types/TelegramInlineQueryResultPhoto.js +19 -0
- package/dist/main/src/types/TelegramInlineQueryType.d.ts +2 -0
- package/dist/main/src/types/TelegramInlineQueryType.js +1 -0
- package/dist/main/src/types/TelegramInputMessageContent.d.ts +5 -0
- package/dist/main/src/types/TelegramInputMessageContent.js +1 -0
- package/dist/main/src/types/TelegramMessage.d.ts +43 -0
- package/dist/main/src/types/TelegramMessage.js +1 -0
- package/dist/main/src/types/TelegramMessageEntity.d.ts +10 -0
- package/dist/main/src/types/TelegramMessageEntity.js +1 -0
- package/dist/main/src/types/TelegramPhotoSize.d.ts +8 -0
- package/dist/main/src/types/TelegramPhotoSize.js +1 -0
- package/dist/main/src/types/TelegramUpdate.d.ts +13 -0
- package/dist/main/src/types/TelegramUpdate.js +36 -0
- package/dist/main/src/types/TelegramUser.d.ts +12 -0
- package/dist/main/src/types/TelegramUser.js +1 -0
- package/dist/main/src/types/Update.d.ts +3 -0
- package/dist/main/src/types/Update.js +2 -0
- package/dist/main/src/types/WebhookCommands.d.ts +4 -0
- package/dist/main/src/types/WebhookCommands.js +2 -0
- package/dist/main/src/types/localhost.d.ts +3 -0
- package/dist/main/src/types/localhost.js +1 -0
- package/dist/main/src/types/types.d.ts +1 -0
- package/dist/main/src/types/types.js +1 -0
- package/dist/main/src/types.d.ts +26 -0
- package/dist/main/src/types.js +8 -0
- package/dist/main/src/webhook.d.ts +10 -0
- package/dist/main/src/webhook.js +15 -0
- package/dist/telegram_api.js +8 -1
- package/dist/worker/src/worker.d.ts +18 -0
- package/dist/worker/src/worker.js +81 -0
- package/package.json +3 -5
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { TelegramInlineQueryResultArticle } from '../types';
|
|
2
|
+
export default async (self, update, args) => {
|
|
3
|
+
if (self.ai === undefined) {
|
|
4
|
+
return new Response('ok');
|
|
5
|
+
}
|
|
6
|
+
let _prompt;
|
|
7
|
+
if (args[0][0] === '/') {
|
|
8
|
+
_prompt = args.slice(1).join(' ');
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
_prompt = args.join(' ');
|
|
12
|
+
}
|
|
13
|
+
if (_prompt === '') {
|
|
14
|
+
_prompt = '';
|
|
15
|
+
}
|
|
16
|
+
const results = await (async () => {
|
|
17
|
+
if (self.db) {
|
|
18
|
+
const { results } = await self.db
|
|
19
|
+
.prepare('SELECT * FROM Messages WHERE userId=?')
|
|
20
|
+
.bind(update.inline_query ? update.inline_query.from.id : update.message?.from.id)
|
|
21
|
+
.all();
|
|
22
|
+
return results;
|
|
23
|
+
}
|
|
24
|
+
})();
|
|
25
|
+
const old_messages = (() => {
|
|
26
|
+
if (results) {
|
|
27
|
+
return results.map((col) => ({
|
|
28
|
+
role: 'system',
|
|
29
|
+
content: col.content,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
return [];
|
|
33
|
+
})();
|
|
34
|
+
const system_prompt = '<s>' +
|
|
35
|
+
[
|
|
36
|
+
`Your name is ${self.bot_name}.`,
|
|
37
|
+
`You are talking to ${update.message?.from.first_name}.`,
|
|
38
|
+
`Your source code is at https://github.com/codebam/cf-workers-telegram-bot .`,
|
|
39
|
+
`the current date is ${new Date().toString()}`,
|
|
40
|
+
'Sean Behan is a full stack developer who goes by the username codebam.',
|
|
41
|
+
'Sean Behan likes programming and video games.',
|
|
42
|
+
"Pretend to be Sean Behan but don't make things up.",
|
|
43
|
+
].reduce((acc, cur) => {
|
|
44
|
+
return acc + cur + '\n';
|
|
45
|
+
}) +
|
|
46
|
+
old_messages.reduce((acc, cur) => {
|
|
47
|
+
return acc + cur.content + '\n';
|
|
48
|
+
}, '') +
|
|
49
|
+
'</s>';
|
|
50
|
+
const p = system_prompt + '[INST]' + _prompt + '[/INST]';
|
|
51
|
+
const prompt = p.slice(p.length - 4096, p.length);
|
|
52
|
+
const response = await self.ai
|
|
53
|
+
// @ts-expect-error model might not match
|
|
54
|
+
.run(self.chat_model, {
|
|
55
|
+
prompt,
|
|
56
|
+
max_tokens: 596,
|
|
57
|
+
})
|
|
58
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
59
|
+
.then(({ response }) => response
|
|
60
|
+
.replace(/(\[|)(\/|)INST(S|)(s|)(\]|)/, '')
|
|
61
|
+
.replace(/<<(\/|)SYS>>/, '')
|
|
62
|
+
.replace(/[OUT]/, ''));
|
|
63
|
+
if (self.db) {
|
|
64
|
+
const { success } = await self.db
|
|
65
|
+
.prepare('INSERT INTO Messages (id, userId, content) VALUES (?, ?, ?)')
|
|
66
|
+
.bind(crypto.randomUUID(), update.inline_query ? update.inline_query.from.id : update.message?.from.id, '[INST] ' + _prompt + ' [/INST]' + '\n' + response)
|
|
67
|
+
.run();
|
|
68
|
+
if (!success) {
|
|
69
|
+
console.log('failed to insert data into d1');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (update.inline_query) {
|
|
73
|
+
return self.answerInlineQuery(update.inline_query.id, [new TelegramInlineQueryResultArticle(response)]);
|
|
74
|
+
}
|
|
75
|
+
return self.sendMessage(update.message?.chat.id ?? 0, response, '', false, false, update.message?.message_id);
|
|
76
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default async (self, update) => self.sendMessage(update.message?.chat.id ?? 0, `Hello, send me a message to start chatting with ${self.chat_model}`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default async (self, update) => self.sendMessage(update.message?.chat.id ?? 0, Math.floor(Math.random() * 2) == 0 ? 'heads' : 'tails');
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
import TelegramBot from '../telegram_bot';
|
|
3
|
+
import { TelegramUpdate } from '../types';
|
|
4
|
+
declare const _default: (self: TelegramBot, update: TelegramUpdate, args: string[]) => Promise<Response>;
|
|
5
|
+
export default _default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TelegramInlineQueryResultArticle } from '../types';
|
|
2
|
+
export default async (self, update, args) => {
|
|
3
|
+
if (self.ai === undefined) {
|
|
4
|
+
return new Response('ok');
|
|
5
|
+
}
|
|
6
|
+
let _prompt;
|
|
7
|
+
if (args[0][0] === '/') {
|
|
8
|
+
_prompt = args.slice(1).join(' ');
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
_prompt = args.join(' ');
|
|
12
|
+
}
|
|
13
|
+
if (_prompt === '') {
|
|
14
|
+
_prompt = '';
|
|
15
|
+
}
|
|
16
|
+
const langs = ['french'];
|
|
17
|
+
const inline_articles = await Promise.all(langs.map(async (lang) => {
|
|
18
|
+
const response = await self.ai.run('@cf/meta/m2m100-1.2b', {
|
|
19
|
+
text: _prompt,
|
|
20
|
+
source_lang: lang,
|
|
21
|
+
target_lang: 'english',
|
|
22
|
+
});
|
|
23
|
+
return new TelegramInlineQueryResultArticle(response.translated_text, response.translated_text);
|
|
24
|
+
}));
|
|
25
|
+
return self.answerInlineQuery(update.inline_query?.id ?? 0, inline_articles);
|
|
26
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
import BotApi from './bot_api';
|
|
3
|
+
import { Config } from './types';
|
|
4
|
+
export default class Handler {
|
|
5
|
+
configs: Partial<Config>[];
|
|
6
|
+
constructor(configs: Partial<Config>[]);
|
|
7
|
+
getResponse: (_request?: Request, _bot?: BotApi) => Promise<Response>;
|
|
8
|
+
postResponse: (_request?: Request, _bot?: BotApi) => Promise<Response>;
|
|
9
|
+
responses: Record<string, (_request?: Request, _bot?: BotApi) => Promise<Response>>;
|
|
10
|
+
getAccessKeys: (configs: Partial<Config>[]) => Promise<Record<string, Config> | Record<string, never>>;
|
|
11
|
+
handle: (request: Request) => Promise<Response>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { sha256, log } from './libs';
|
|
2
|
+
import { Config, localhost } from './types';
|
|
3
|
+
export default class Handler {
|
|
4
|
+
configs;
|
|
5
|
+
constructor(configs) {
|
|
6
|
+
this.configs = configs;
|
|
7
|
+
}
|
|
8
|
+
getResponse = async (_request, _bot) => {
|
|
9
|
+
this.getAccessKeys(this.configs).then((access_keys) => Object.keys(access_keys).forEach((key) => log(`${access_keys[key].bot_name} ${((request_url) => `${request_url.origin}${request_url.pathname}`)(new URL(_request?.url ?? localhost))}${key}`)));
|
|
10
|
+
if (_bot?.webhook.token) {
|
|
11
|
+
return _bot.webhook.process(new URL(_request?.url ?? localhost));
|
|
12
|
+
}
|
|
13
|
+
return this.responses.default();
|
|
14
|
+
};
|
|
15
|
+
postResponse = async (_request, _bot) => _bot?.webhook.token === ''
|
|
16
|
+
? this.responses.default()
|
|
17
|
+
: _request
|
|
18
|
+
? _request.json().then((update) => _bot.update(update))
|
|
19
|
+
: this.responses.default();
|
|
20
|
+
responses = {
|
|
21
|
+
GET: this.getResponse,
|
|
22
|
+
POST: this.postResponse,
|
|
23
|
+
default: () => new Promise(() => new Response()),
|
|
24
|
+
};
|
|
25
|
+
getAccessKeys = async (configs) => Promise.all(configs.map((bot_config) => sha256(bot_config.webhook?.token ?? '').then((hash) => {
|
|
26
|
+
console.log(hash);
|
|
27
|
+
return [hash, bot_config];
|
|
28
|
+
}))).then((result) => Object.fromEntries(result));
|
|
29
|
+
// handles the request
|
|
30
|
+
handle = async (request) => this.getAccessKeys(this.configs).then((access_keys) => Object.keys(this.responses).includes(request.method)
|
|
31
|
+
? this.responses[request.method](request, ((key) => {
|
|
32
|
+
return new access_keys[key].api({
|
|
33
|
+
...new Config(),
|
|
34
|
+
...access_keys[key],
|
|
35
|
+
url: new URL(new URL(request.url).origin), // worker url
|
|
36
|
+
handler: this,
|
|
37
|
+
});
|
|
38
|
+
})(new URL(request.url).pathname.substring(1)))
|
|
39
|
+
: this.responses.default());
|
|
40
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
export declare const sha256: (text: string) => Promise<string>;
|
|
3
|
+
export declare const log: (obj: any) => any;
|
|
4
|
+
export declare const addSearchParams: (url: URL, params?: Record<string, string>) => URL;
|
|
5
|
+
export declare const undefinedEmpty: <T>(obj: T) => (T & ({} | null))[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const sha256 = async (text) => crypto.subtle.digest('SHA-256', new TextEncoder().encode(text)).then((array_buffer) => Array.from(new Uint8Array(array_buffer))
|
|
2
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
3
|
+
.join(''));
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
+
export const log = (obj) => console.log(obj) === undefined && obj;
|
|
6
|
+
export const addSearchParams = (url, params = {}) => new URL(`${url.origin}${url.pathname}?${new URLSearchParams(Object.entries(Object.fromEntries([...Array.from(url.searchParams.entries()), ...Object.entries(params)]))).toString()}`);
|
|
7
|
+
export const undefinedEmpty = (obj) => (obj === undefined ? [] : [obj]);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
import BotApi from './bot_api';
|
|
3
|
+
import { Commands, TelegramInlineQueryResult, TelegramUpdate, Webhook, Update, ChatPermissions } from './types';
|
|
4
|
+
import Handler from './handler';
|
|
5
|
+
export default class TelegramApi extends BotApi {
|
|
6
|
+
constructor(commands: Commands, webhook: Webhook, handler: Handler);
|
|
7
|
+
inlineQueryUpdate: (update: TelegramUpdate) => Promise<Response>;
|
|
8
|
+
messageUpdate: (update: TelegramUpdate) => Promise<Response>;
|
|
9
|
+
updates: {
|
|
10
|
+
inline_query: (update: TelegramUpdate) => Promise<Response>;
|
|
11
|
+
message: (update: TelegramUpdate) => Promise<Response>;
|
|
12
|
+
default: Response;
|
|
13
|
+
};
|
|
14
|
+
update: (update: Update) => Promise<Response>;
|
|
15
|
+
greetUsers: (update: TelegramUpdate) => Promise<Response>;
|
|
16
|
+
getCommand: (args: string[]) => string;
|
|
17
|
+
_executeCommand: (update: TelegramUpdate, text: string, args?: string[]) => Promise<any>;
|
|
18
|
+
executeInlineCommand: (update: TelegramUpdate) => Promise<Response>;
|
|
19
|
+
executeCommand: (update: TelegramUpdate) => Promise<Response>;
|
|
20
|
+
answerInlineQuery: (inline_query_id: number, results: TelegramInlineQueryResult[], cache_time?: number) => Promise<Response>;
|
|
21
|
+
editMessageText: (chat_id: number, message_id: number, text: string) => Promise<Response>;
|
|
22
|
+
sendMessage: (chat_id: number, text: string, parse_mode?: string, disable_web_page_preview?: boolean, disable_notification?: boolean, reply_to_message_id?: number) => Promise<Response>;
|
|
23
|
+
forwardMessage: (chat_id: number, from_chat_id: number, disable_notification: boolean | undefined, message_id: number) => Promise<Response>;
|
|
24
|
+
sendPhotoRaw: (chat_id: number, photo: File, caption?: string, parse_mode?: string, disable_notification?: boolean, reply_to_message_id?: number) => Promise<any>;
|
|
25
|
+
sendPhoto: (chat_id: number, photo: string, caption?: string, parse_mode?: string, disable_notification?: boolean, reply_to_message_id?: number) => Promise<Response>;
|
|
26
|
+
sendVideo: (chat_id: number, video: Blob, duration?: number, width?: number, height?: number, thumb?: string, caption?: string, parse_mode?: string, supports_streaming?: boolean, disable_notification?: boolean, reply_to_message_id?: number) => Promise<Response>;
|
|
27
|
+
sendAnimation: (chat_id: number, animation: Blob, duration?: number, width?: number, height?: number, thumb?: string, caption?: string, parse_mode?: string, disable_notification?: boolean, reply_to_message_id?: number) => Promise<Response>;
|
|
28
|
+
sendLocation: (chat_id: number, latitude: number, longitude: number, live_period?: number, disable_notification?: boolean, reply_to_message_id?: number) => Promise<Response>;
|
|
29
|
+
sendPoll: (chat_id: number, question: string, options: string[], is_anonymous?: boolean, type?: string, allows_multiple_answers?: boolean, correct_option_id?: number, explanation?: string, explanation_parse_mode?: string, open_period?: number, close_date?: number, is_closed?: boolean, disable_notification?: boolean, reply_to_message_id?: number) => Promise<Response>;
|
|
30
|
+
sendDice: (chat_id: number, emoji?: string, disable_notification?: boolean, reply_to_message_id?: number) => Promise<Response>;
|
|
31
|
+
getUserProfilePhotos: (user_id: number, offset?: number, limit?: number) => Promise<Response>;
|
|
32
|
+
banChatMember: (chat_id: number | string, user_id: number, until_date?: number, revoke_messages?: boolean) => Promise<Response>;
|
|
33
|
+
restrictChatMember: (chat_id: number | string, user_id: number, permissions: ChatPermissions, use_independent_chat_permissions: boolean, until_date: number) => Promise<Response>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import BotApi from './bot_api';
|
|
2
|
+
import { addSearchParams, log } from './libs';
|
|
3
|
+
export default class TelegramApi extends BotApi {
|
|
4
|
+
constructor(commands, webhook, handler) {
|
|
5
|
+
super({ commands, webhook, handler });
|
|
6
|
+
}
|
|
7
|
+
inlineQueryUpdate = async (update) => this.executeInlineCommand(update);
|
|
8
|
+
messageUpdate = async (update) => {
|
|
9
|
+
if (update.message) {
|
|
10
|
+
await this.greetUsers(update);
|
|
11
|
+
await this.executeCommand(update);
|
|
12
|
+
}
|
|
13
|
+
return this.updates.default;
|
|
14
|
+
};
|
|
15
|
+
updates = {
|
|
16
|
+
inline_query: this.inlineQueryUpdate,
|
|
17
|
+
message: this.messageUpdate,
|
|
18
|
+
default: new Response(),
|
|
19
|
+
};
|
|
20
|
+
update = async (update) => {
|
|
21
|
+
console.log({ update });
|
|
22
|
+
if (update) {
|
|
23
|
+
if (update.inline_query) {
|
|
24
|
+
if (update.inline_query.query !== '') {
|
|
25
|
+
return this.updates.inline_query(update);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
if (update.message) {
|
|
30
|
+
return this.updates.message(update);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return this.updates.default;
|
|
35
|
+
};
|
|
36
|
+
// greet new users who join
|
|
37
|
+
greetUsers = async (update) => update.message?.new_chat_members
|
|
38
|
+
? this.sendMessage(update.message.chat.id, `Welcome to ${update.message.chat.title}, @${update.message.new_chat_member?.username}`)
|
|
39
|
+
: this.updates.default;
|
|
40
|
+
getCommand = (args) => args[0]?.split('@')[0];
|
|
41
|
+
// run command passed from executeCommand
|
|
42
|
+
_executeCommand = async (update, text, args = []) => log({ execute: { text, args } })
|
|
43
|
+
? ((text_args) => ((command) => this.commands[command]
|
|
44
|
+
? this.commands[command]?.(this, update, [...text_args, ...args])
|
|
45
|
+
: log({
|
|
46
|
+
error: `command '${command}' does not exist, using default`,
|
|
47
|
+
}) && this.commands['default']?.(this, update, [...text_args, ...args]))(
|
|
48
|
+
// run the command
|
|
49
|
+
this.getCommand(text_args)))(
|
|
50
|
+
// get the command to run
|
|
51
|
+
text
|
|
52
|
+
.trimStart()
|
|
53
|
+
.replace(/^([^\s]*\s)\s*/gm, '$1')
|
|
54
|
+
.split(' '))
|
|
55
|
+
: this.updates.default;
|
|
56
|
+
// execute the inline custom bot commands from bot configurations
|
|
57
|
+
executeInlineCommand = async (update) => this._executeCommand(update, update.inline_query?.query ?? '').then(async (command_response) => command_response
|
|
58
|
+
? this._executeCommand(update, 'inline', update.inline_query?.query.trimStart().split(' ')).then((_command_response) => _command_response)
|
|
59
|
+
: this.updates.default);
|
|
60
|
+
// execute the custom bot commands from bot configurations
|
|
61
|
+
executeCommand = async (update) => this._executeCommand(update, update.message?.text ?? '') ?? this.updates.default;
|
|
62
|
+
// trigger answerInlineQuery command of BotAPI
|
|
63
|
+
answerInlineQuery = async (inline_query_id, results, cache_time = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/answerInlineQuery`), {
|
|
64
|
+
inline_query_id: inline_query_id.toString(),
|
|
65
|
+
results: JSON.stringify(results),
|
|
66
|
+
cache_time: cache_time.toString(),
|
|
67
|
+
}).href));
|
|
68
|
+
// trigger editMessage command of BotAPI
|
|
69
|
+
editMessageText = async (chat_id, message_id, text) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/editMessageText`), {
|
|
70
|
+
chat_id: chat_id.toString(),
|
|
71
|
+
message_id: message_id.toString(),
|
|
72
|
+
text,
|
|
73
|
+
}).href));
|
|
74
|
+
// trigger sendMessage command of BotAPI
|
|
75
|
+
sendMessage = async (chat_id, text, parse_mode = '', disable_web_page_preview = false, disable_notification = false, reply_to_message_id = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendMessage`), {
|
|
76
|
+
chat_id: chat_id.toString(),
|
|
77
|
+
text,
|
|
78
|
+
parse_mode: parse_mode,
|
|
79
|
+
disable_web_page_preview: disable_web_page_preview.toString(),
|
|
80
|
+
disable_notification: disable_notification.toString(),
|
|
81
|
+
reply_to_message_id: reply_to_message_id.toString(),
|
|
82
|
+
}).href));
|
|
83
|
+
// trigger forwardMessage command of BotAPI
|
|
84
|
+
forwardMessage = async (chat_id, from_chat_id, disable_notification = false, message_id) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendMessage`), {
|
|
85
|
+
chat_id: chat_id.toString(),
|
|
86
|
+
from_chat_id: from_chat_id.toString(),
|
|
87
|
+
message_id: message_id.toString(),
|
|
88
|
+
disable_notification: disable_notification.toString(),
|
|
89
|
+
}).href));
|
|
90
|
+
// trigger sendPhoto command of BotAPI
|
|
91
|
+
sendPhotoRaw = async (chat_id, photo, caption = '', parse_mode = '', disable_notification = false, reply_to_message_id = 0) => {
|
|
92
|
+
const formdata = new FormData();
|
|
93
|
+
formdata.set('file', photo);
|
|
94
|
+
return fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendPhoto`), {
|
|
95
|
+
chat_id: chat_id.toString(),
|
|
96
|
+
caption,
|
|
97
|
+
parse_mode,
|
|
98
|
+
disable_notification: disable_notification.toString(),
|
|
99
|
+
reply_to_message_id: reply_to_message_id.toString(),
|
|
100
|
+
}).href), { method: 'POST', body: formdata })
|
|
101
|
+
.then((resp) => resp.text())
|
|
102
|
+
.then(log);
|
|
103
|
+
};
|
|
104
|
+
// trigger sendPhoto command of BotAPI
|
|
105
|
+
sendPhoto = async (chat_id, photo, caption = '', parse_mode = '', disable_notification = false, reply_to_message_id = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendPhoto`), {
|
|
106
|
+
chat_id: chat_id.toString(),
|
|
107
|
+
photo,
|
|
108
|
+
caption,
|
|
109
|
+
parse_mode,
|
|
110
|
+
disable_notification: disable_notification.toString(),
|
|
111
|
+
reply_to_message_id: reply_to_message_id.toString(),
|
|
112
|
+
}).href));
|
|
113
|
+
// trigger sendVideo command of BotAPI
|
|
114
|
+
sendVideo = async (chat_id, video, duration = 0, width = 0, height = 0, thumb = '', caption = '', parse_mode = '', supports_streaming = false, disable_notification = false, reply_to_message_id = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendVideo`), {
|
|
115
|
+
chat_id: chat_id.toString(),
|
|
116
|
+
video: JSON.stringify(video),
|
|
117
|
+
duration: duration.toString(),
|
|
118
|
+
width: width.toString(),
|
|
119
|
+
height: height.toString(),
|
|
120
|
+
thumb: thumb,
|
|
121
|
+
caption: caption,
|
|
122
|
+
parse_mode: parse_mode,
|
|
123
|
+
supports_streaming: supports_streaming.toString(),
|
|
124
|
+
disable_notification: disable_notification.toString(),
|
|
125
|
+
reply_to_message_id: reply_to_message_id.toString(),
|
|
126
|
+
}).href));
|
|
127
|
+
// trigger sendAnimation command of BotAPI
|
|
128
|
+
sendAnimation = async (chat_id, animation, duration = 0, width = 0, height = 0, thumb = '', caption = '', parse_mode = '', disable_notification = false, reply_to_message_id = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendAnimation`), {
|
|
129
|
+
chat_id: chat_id.toString(),
|
|
130
|
+
animation: JSON.stringify(animation),
|
|
131
|
+
duration: duration.toString(),
|
|
132
|
+
width: width.toString(),
|
|
133
|
+
height: height.toString(),
|
|
134
|
+
thumb,
|
|
135
|
+
caption,
|
|
136
|
+
parse_mode,
|
|
137
|
+
disable_notification: disable_notification.toString(),
|
|
138
|
+
reply_to_message_id: reply_to_message_id.toString(),
|
|
139
|
+
}).href));
|
|
140
|
+
// trigger sendLocation command of BotAPI
|
|
141
|
+
sendLocation = async (chat_id, latitude, longitude, live_period = 0, disable_notification = false, reply_to_message_id = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendLocation`), {
|
|
142
|
+
chat_id: chat_id.toString(),
|
|
143
|
+
latitude: latitude.toString(),
|
|
144
|
+
longitude: longitude.toString(),
|
|
145
|
+
live_period: live_period.toString(),
|
|
146
|
+
disable_notification: disable_notification.toString(),
|
|
147
|
+
reply_to_message_id: reply_to_message_id.toString(),
|
|
148
|
+
}).href));
|
|
149
|
+
// trigger senPoll command of BotAPI
|
|
150
|
+
sendPoll = async (chat_id, question, options, is_anonymous = false, type = '', allows_multiple_answers = false, correct_option_id = 0, explanation = '', explanation_parse_mode = '', open_period = 0, close_date = 0, is_closed = false, disable_notification = false, reply_to_message_id = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendPoll`), {
|
|
151
|
+
chat_id: chat_id.toString(),
|
|
152
|
+
question,
|
|
153
|
+
options: options.toString(),
|
|
154
|
+
is_anonymous: is_anonymous.toString(),
|
|
155
|
+
type,
|
|
156
|
+
allows_multiple_answers: allows_multiple_answers.toString(),
|
|
157
|
+
correct_option_id: correct_option_id.toString(),
|
|
158
|
+
explanation: explanation,
|
|
159
|
+
explanation_parse_mode: explanation_parse_mode,
|
|
160
|
+
open_period: open_period.toString(),
|
|
161
|
+
close_date: close_date.toString(),
|
|
162
|
+
is_closed: is_closed.toString(),
|
|
163
|
+
disable_notification: disable_notification.toString(),
|
|
164
|
+
reply_to_message_id: reply_to_message_id.toString(),
|
|
165
|
+
}).href));
|
|
166
|
+
// trigger senDice command of BotAPI
|
|
167
|
+
sendDice = async (chat_id, emoji = '', disable_notification = false, reply_to_message_id = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/sendDice`), {
|
|
168
|
+
chat_id: chat_id.toString(),
|
|
169
|
+
emoji,
|
|
170
|
+
disable_notification: disable_notification.toString(),
|
|
171
|
+
reply_to_message_id: reply_to_message_id.toString(),
|
|
172
|
+
}).href));
|
|
173
|
+
// bot api command to get user profile photos
|
|
174
|
+
getUserProfilePhotos = async (user_id, offset = 0, limit = 0) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/getUserProfilePhotos`), {
|
|
175
|
+
user_id: user_id.toString(),
|
|
176
|
+
offset: offset.toString(),
|
|
177
|
+
limit: limit.toString(),
|
|
178
|
+
}).href));
|
|
179
|
+
banChatMember = async (chat_id, user_id, until_date = 0, revoke_messages = false) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/banChatMember`), {
|
|
180
|
+
chat_id: chat_id.toString(),
|
|
181
|
+
user_id: user_id.toString(),
|
|
182
|
+
until_date: until_date.toString(),
|
|
183
|
+
revoke_messages: revoke_messages.toString(),
|
|
184
|
+
}).href));
|
|
185
|
+
restrictChatMember = async (chat_id, user_id, permissions, use_independent_chat_permissions, until_date) => fetch(log(addSearchParams(new URL(`${this.webhook.api.origin}${this.webhook.api.pathname}/restrictChatMember`), {
|
|
186
|
+
chat_id: chat_id.toString(),
|
|
187
|
+
user_id: user_id.toString(),
|
|
188
|
+
permissions: JSON.stringify(permissions),
|
|
189
|
+
use_independent_chat_permissions: use_independent_chat_permissions.toString(),
|
|
190
|
+
until_date: until_date.toString(),
|
|
191
|
+
}).href));
|
|
192
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
import { TelegramUpdate } from './types';
|
|
3
|
+
export default class TelegramBot {
|
|
4
|
+
token: string;
|
|
5
|
+
webhook: Webhook;
|
|
6
|
+
update: TelegramUpdate;
|
|
7
|
+
api: URL;
|
|
8
|
+
update_type: string;
|
|
9
|
+
constructor(token: string);
|
|
10
|
+
on(event: string, callback: () => Promise<Response>): this;
|
|
11
|
+
handle(request: Request): Promise<any>;
|
|
12
|
+
reply(message: string): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
declare class Webhook {
|
|
15
|
+
api: URL;
|
|
16
|
+
webhook: URL;
|
|
17
|
+
constructor(token: string, request: Request);
|
|
18
|
+
set(): Promise<Response>;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { TelegramInlineQueryResultArticle, TelegramUpdate } from './types';
|
|
2
|
+
export default class TelegramBot {
|
|
3
|
+
token;
|
|
4
|
+
webhook;
|
|
5
|
+
update;
|
|
6
|
+
api;
|
|
7
|
+
update_type;
|
|
8
|
+
constructor(token) {
|
|
9
|
+
this.token = token;
|
|
10
|
+
this.webhook = new Webhook('', new Request('http://127.0.0.1'));
|
|
11
|
+
this.update = new TelegramUpdate({});
|
|
12
|
+
this.api = new URL('https://api.telegram.org/bot' + token);
|
|
13
|
+
this.update_type = '';
|
|
14
|
+
}
|
|
15
|
+
on(event, callback) {
|
|
16
|
+
if (event !== 'on') {
|
|
17
|
+
// eslint-disable-next-line
|
|
18
|
+
// @ts-ignore TS7053
|
|
19
|
+
this[event] = callback;
|
|
20
|
+
}
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
async handle(request) {
|
|
24
|
+
this.webhook = new Webhook(this.token, request);
|
|
25
|
+
if (request.method === 'POST') {
|
|
26
|
+
this.update = await request.json();
|
|
27
|
+
}
|
|
28
|
+
const url = new URL(request.url);
|
|
29
|
+
if (`/${this.token}` === url.pathname) {
|
|
30
|
+
switch (url.searchParams.get('command')) {
|
|
31
|
+
case 'set':
|
|
32
|
+
return this.webhook.set();
|
|
33
|
+
default:
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
console.log(this.update);
|
|
37
|
+
if (this.update.message?.text) {
|
|
38
|
+
this.update_type = 'message';
|
|
39
|
+
}
|
|
40
|
+
else if (this.update.inline_query?.query) {
|
|
41
|
+
this.update_type = 'inline';
|
|
42
|
+
}
|
|
43
|
+
let command = 'default';
|
|
44
|
+
let args = [];
|
|
45
|
+
switch (this.update_type) {
|
|
46
|
+
case 'message': {
|
|
47
|
+
// @ts-expect-error already checked above
|
|
48
|
+
args = this.update.message.text.split(' ');
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case 'inline': {
|
|
52
|
+
// @ts-expect-error already checked above
|
|
53
|
+
args = this.update.inline_query.query.split(' ');
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
default:
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
if (args.at(0)?.startsWith('/')) {
|
|
60
|
+
// @ts-expect-error already checked above
|
|
61
|
+
command = args.at(0).slice(1);
|
|
62
|
+
}
|
|
63
|
+
// eslint-disable-next-line
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
if (!this[command] || command === 'on') {
|
|
66
|
+
command = 'default';
|
|
67
|
+
}
|
|
68
|
+
// eslint-disable-next-line
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
return this[command]?.();
|
|
71
|
+
}
|
|
72
|
+
return new Response('ok');
|
|
73
|
+
}
|
|
74
|
+
async reply(message) {
|
|
75
|
+
switch (this.update_type) {
|
|
76
|
+
case 'message': {
|
|
77
|
+
const request = new URL(this.api + '/sendMessage');
|
|
78
|
+
const params = new URLSearchParams();
|
|
79
|
+
params.append('chat_id', this.update.message?.chat.id.toString() ?? '');
|
|
80
|
+
params.append('reply_to_message_id', this.update.message?.message_id.toString() ?? '');
|
|
81
|
+
params.append('text', message);
|
|
82
|
+
console.log(`${request}?${params}`);
|
|
83
|
+
await fetch(`${request}?${params}`);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case 'inline': {
|
|
87
|
+
const inline_request = new URL(this.api + '/answerInlineQuery');
|
|
88
|
+
const inline_params = new URLSearchParams();
|
|
89
|
+
inline_params.append('inline_query_id', this.update.inline_query?.id.toString() ?? '');
|
|
90
|
+
inline_params.append('results', JSON.stringify([new TelegramInlineQueryResultArticle(message)]));
|
|
91
|
+
console.log(`${inline_request}?${inline_params}`);
|
|
92
|
+
await fetch(`${inline_request}?${inline_params}`);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
default:
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
class Webhook {
|
|
101
|
+
api;
|
|
102
|
+
webhook;
|
|
103
|
+
constructor(token, request) {
|
|
104
|
+
this.api = new URL('https://api.telegram.org/bot' + token);
|
|
105
|
+
this.webhook = new URL(new URL(request.url).origin + `/${token}`);
|
|
106
|
+
}
|
|
107
|
+
async set() {
|
|
108
|
+
const url = new URL(`${this.api.origin}${this.api.pathname}/setWebhook`);
|
|
109
|
+
const params = url.searchParams;
|
|
110
|
+
params.append('url', this.webhook.toString());
|
|
111
|
+
params.append('max_connections', '100');
|
|
112
|
+
params.append('allowed_updates', JSON.stringify(['message', 'inline_query']));
|
|
113
|
+
params.append('drop_pending_updates', 'true');
|
|
114
|
+
return await fetch(`${url}?${params}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { TelegramCommand } from './types';
|
|
2
|
+
export default class TelegramCommands {
|
|
3
|
+
static ping: TelegramCommand;
|
|
4
|
+
static toss: TelegramCommand;
|
|
5
|
+
static epoch: TelegramCommand;
|
|
6
|
+
static kanye: TelegramCommand;
|
|
7
|
+
static bored: TelegramCommand;
|
|
8
|
+
static joke: TelegramCommand;
|
|
9
|
+
static dog: TelegramCommand;
|
|
10
|
+
static roll: TelegramCommand;
|
|
11
|
+
static duckduckgo: TelegramCommand;
|
|
12
|
+
static question: TelegramCommand;
|
|
13
|
+
static sean: TelegramCommand;
|
|
14
|
+
static clear: TelegramCommand;
|
|
15
|
+
static code: TelegramCommand;
|
|
16
|
+
static commandList: TelegramCommand;
|
|
17
|
+
static image: TelegramCommand;
|
|
18
|
+
static translate: TelegramCommand;
|
|
19
|
+
static start: TelegramCommand;
|
|
20
|
+
static ban: TelegramCommand;
|
|
21
|
+
static mute: TelegramCommand;
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default class TelegramCommands {
|
|
2
|
+
static ping = async (bot, update, args) => bot.ping(bot, update, args);
|
|
3
|
+
static toss = async (bot, update) => bot.toss(bot, update);
|
|
4
|
+
static epoch = async (bot, update) => bot.epoch(bot, update);
|
|
5
|
+
static kanye = async (bot, update) => bot.kanye(bot, update);
|
|
6
|
+
static bored = async (bot, update) => bot.bored(bot, update);
|
|
7
|
+
static joke = async (bot, update) => bot.joke(bot, update);
|
|
8
|
+
static dog = async (bot, update) => bot.dog(bot, update);
|
|
9
|
+
static roll = async (bot, update, args) => bot.roll(bot, update, args);
|
|
10
|
+
static duckduckgo = async (bot, update, args) => bot.duckduckgo(bot, update, args);
|
|
11
|
+
static question = async (bot, update, args) => bot.question(bot, update, args);
|
|
12
|
+
static sean = async (bot, update, args) => bot.sean(bot, update, args);
|
|
13
|
+
static clear = async (bot, update) => bot.clear(bot, update);
|
|
14
|
+
static code = async (bot, update) => bot.code(bot, update);
|
|
15
|
+
static commandList = async (bot, update) => bot.commandList(bot, update);
|
|
16
|
+
static image = async (bot, update, args) => bot.image(bot, update, args);
|
|
17
|
+
static translate = async (bot, update, args) => bot.translate(bot, update, args);
|
|
18
|
+
static start = async (bot, update) => bot.start(bot, update);
|
|
19
|
+
static ban = async (bot, update) => bot.ban(bot, update);
|
|
20
|
+
static mute = async (bot, update) => bot.mute(bot, update);
|
|
21
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
import Webhook from './webhook';
|
|
3
|
+
import { WebhookCommands } from './types';
|
|
4
|
+
export default class TelegramWebhook extends Webhook {
|
|
5
|
+
constructor(api: URL, token: string, url: URL);
|
|
6
|
+
set: (drop_pending_updates?: boolean) => Promise<Response>;
|
|
7
|
+
get: () => Promise<Response>;
|
|
8
|
+
delete: () => Promise<Response>;
|
|
9
|
+
commands: WebhookCommands;
|
|
10
|
+
}
|