import { Context, NarrowedContext, Telegraf } from 'telegraf'; import { message } from 'telegraf/filters'; import { ChatFromGetChat, Update } from 'telegraf/typings/core/types/typegram'; import { ioc } from './utils/ioc'; import { AudienceChangeController, audienceChangeSymbol } from './controllers/audienceChange'; import { log } from './utils/log'; export type ChannelInfo = { chatId: number, memberCount: number, }; export type MessageInfo = { }; export class ChannelBot { private readonly bot: Telegraf; constructor( private readonly token: string, ) { this.bot = new Telegraf( process.env.TELEGRAM_BOT_TOKEN ?? '', ); } public async connect(): Promise { process.once('SIGINT', () => this.bot.stop('SIGINT')); process.once('SIGTERM', () => this.bot.stop('SIGTERM')); this.bot.on('chat_member', this.handleChatMemberUpdate.bind(this)); this.bot.launch( { allowedUpdates: [ 'chat_join_request', 'chat_member', 'channel_post', 'edited_channel_post', 'poll', 'poll_answer' ], }, ); } private async handleChatMemberUpdate(ctx: NarrowedContext, Update.ChatMemberUpdate>): Promise { try { log.bot.info('chat_member event', JSON.stringify(ctx.chatMember)); const change = ctx.chatMember; const status = change.new_chat_member.status; const statusBefore = change.old_chat_member.status; const role = ['restricted', 'left', 'kicked'].includes(status) ? statusBefore : status; const ctrl = ioc.get(audienceChangeSymbol); const chatMemberCount = await this.bot.telegram.getChatMembersCount(change.chat.id); ctrl.add({ channelId: change.chat.id, user: { id: change.new_chat_member.user.id, username: change.new_chat_member.user.username, firstName: change.new_chat_member.user.first_name, lastName: change.new_chat_member.user.last_name, isBot: change.new_chat_member.user.is_bot, isPremium: change.new_chat_member.user.is_premium ? true : false, role, }, timestamp: new Date(change.date * 1000), status, statusBefore, invitedByLink: change.invite_link?.invite_link ?? undefined, memberCountAfter: chatMemberCount, }); } catch (err) { log.bot.error('chat member change processing error', err); } } public async getChannelInfo(channelId: number): Promise { const memberCount = await this.bot.telegram.getChatMembersCount(channelId); const info: ChatFromGetChat = await this.bot.telegram.getChat(channelId); return { chatId: info.id, memberCount, }; } } // bot.on('channel_post', async (ctx) => { // console.log('channel_post'); // console.dir(ctx.channelPost.chat.id); // await sendChannelStats(ctx.chat.id); // });