UNPKG

dograma

Version:

NodeJS/Browser MTProto API Telegram client library,

267 lines (253 loc) 8.56 kB
import { _intoIdSet, DefaultEventInterface, EventBuilder, EventCommon, } from "./common"; import type { Entity, EntityLike } from "../define"; import type { TelegramClient } from ".."; import { Api } from "../tl"; import bigInt from "big-integer"; import { LogLevel } from "../extensions/Logger"; export interface NewMessageInterface extends DefaultEventInterface { func?: { (event: NewMessageEvent): boolean }; /** * If set to `true`, only **incoming** messages will be handled. Mutually exclusive with ``outgoing`` (can only set one of either). */ incoming?: boolean; /** * If set to `true`, only **outgoing** messages will be handled. * Mutually exclusive with ``incoming`` (can only set one of either). */ outgoing?: boolean; /** * Unlike `chats`, this parameter filters the *senders* of the * message. That is, only messages *sent by these users* will be * handled. Use `chats` if you want private messages with this/these * users. `from_users` lets you filter by messages sent by *one or * more* users across the desired chats (doesn't need a list). */ fromUsers?: EntityLike[]; /** * Whether forwarded messages should be handled or not. By default, * both forwarded and normal messages are included. If it's `True` * **only** forwards will be handled. If it's `False` only messages * that are *not* forwards will be handled. */ forwards?: boolean; /** * If set, only messages matching this pattern will be handled. */ pattern?: RegExp; } /** * Occurs whenever a new text message or a message with media arrives. * @example * ```ts * async function eventPrint(event: NewMessageEvent) { * const message = event.message; * * // Checks if it's a private message (from user or bot) * if (event.isPrivate){ * // prints sender id * console.log(message.senderId); * // read message * if (message.text == "hello"){ * const sender = await message.getSender(); * console.log("sender is",sender); * await client.sendMessage(sender,{ * message:`hi your id is ${message.senderId}` * }); * } * } * } * // adds an event handler for new messages * client.addEventHandler(eventPrint, new NewMessage({})); * ``` */ export class NewMessage extends EventBuilder { func?: { (event: NewMessageEvent): boolean }; incoming?: boolean; outgoing?: boolean; fromUsers?: EntityLike[]; forwards?: boolean; pattern?: RegExp; /** @hidden */ private readonly _noCheck: boolean; constructor(newMessageParams: NewMessageInterface = {}) { let { chats, func, incoming, outgoing, fromUsers, forwards, pattern, blacklistChats = false, } = newMessageParams; if (incoming && outgoing) { incoming = outgoing = undefined; } else if (incoming != undefined && outgoing == undefined) { outgoing = !incoming; } else if (outgoing != undefined && incoming == undefined) { incoming = !outgoing; } else if (outgoing == false && incoming == false) { throw new Error( "Don't create an event handler if you don't want neither incoming nor outgoing!" ); } super({ chats, blacklistChats, func }); this.incoming = incoming; this.outgoing = outgoing; this.fromUsers = fromUsers; this.forwards = forwards; this.pattern = pattern; this._noCheck = [ incoming, outgoing, chats, pattern, fromUsers, forwards, func, ].every((v) => v == undefined); } async _resolve(client: TelegramClient) { await super._resolve(client); this.fromUsers = await _intoIdSet(client, this.fromUsers); } build( update: Api.TypeUpdate | Api.TypeUpdates, callback: undefined, selfId: bigInt.BigInteger ) { if ( update instanceof Api.UpdateNewMessage || update instanceof Api.UpdateNewChannelMessage ) { if (!(update.message instanceof Api.Message)) { return undefined; } const event = new NewMessageEvent(update.message, update); this.addAttributes(event); return event; } else if (update instanceof Api.UpdateShortMessage) { return new NewMessageEvent( new Api.Message({ out: update.out, mentioned: update.mentioned, mediaUnread: update.mediaUnread, silent: update.silent, id: update.id, peerId: new Api.PeerUser({ userId: update.userId }), fromId: new Api.PeerUser({ userId: update.out ? selfId : update.userId, }), message: update.message, date: update.date, fwdFrom: update.fwdFrom, viaBotId: update.viaBotId, replyTo: update.replyTo, entities: update.entities, ttlPeriod: update.ttlPeriod, }), update ); } else if (update instanceof Api.UpdateShortChatMessage) { return new NewMessageEvent( new Api.Message({ out: update.out, mentioned: update.mentioned, mediaUnread: update.mediaUnread, silent: update.silent, id: update.id, peerId: new Api.PeerChat({ chatId: update.chatId }), fromId: new Api.PeerUser({ userId: update.out ? selfId : update.fromId, }), message: update.message, date: update.date, fwdFrom: update.fwdFrom, viaBotId: update.viaBotId, replyTo: update.replyTo, entities: update.entities, ttlPeriod: update.ttlPeriod, }), update ); } } filter(event: NewMessageEvent) { if (this._noCheck) { return event; } if (this.incoming && event.message.out) { return; } if (this.outgoing && !event.message.out) { return; } if (this.forwards != undefined) { if (this.forwards != !!event.message.fwdFrom) { return; } } if (this.fromUsers != undefined) { if ( !event.message.senderId || !this.fromUsers.includes(event.message.senderId.toString()) ) { return; } } if (this.pattern) { const match = event.message.message?.match(this.pattern); if (!match) { return; } event.message.patternMatch = match; } return super.filter(event); } addAttributes(update: any) { //update.patternMatch = } } export class NewMessageEvent extends EventCommon { message: Api.Message; originalUpdate: (Api.TypeUpdate | Api.TypeUpdates) & { _entities?: Map<number, Entity>; }; constructor( message: Api.Message, originalUpdate: Api.TypeUpdate | Api.TypeUpdates ) { super({ msgId: message.id, chatPeer: message.peerId, broadcast: message.post, }); this.originalUpdate = originalUpdate; this.message = message; } _setClient(client: TelegramClient) { super._setClient(client); const m = this.message; try { // todo make sure this never fails m._finishInit( client, this.originalUpdate._entities || new Map(), undefined ); } catch (e) { client._log.error( "Got error while trying to finish init message with id " + m.id ); if (client._log.canSend(LogLevel.ERROR)) { console.error(e); } } } }