grammy
Version:
The Telegram Bot Framework.
1,261 lines • 183 kB
JavaScript
const filterQueryCache = new Map();
function matchFilter(filter) {
const queries = Array.isArray(filter) ? filter : [
filter
];
const key = queries.join(",");
const predicate = filterQueryCache.get(key) ?? (()=>{
const parsed = parse(queries);
const pred = compile(parsed);
filterQueryCache.set(key, pred);
return pred;
})();
return (ctx)=>predicate(ctx);
}
function parse(filter) {
return Array.isArray(filter) ? filter.map((q)=>q.split(":")) : [
filter.split(":")
];
}
function compile(parsed) {
const preprocessed = parsed.flatMap((q)=>check(q, preprocess(q)));
const ltree = treeify(preprocessed);
const predicate = arborist(ltree);
return (ctx)=>!!predicate(ctx.update, ctx);
}
function preprocess(filter) {
const valid = UPDATE_KEYS;
const expanded = [
filter
].flatMap((q)=>{
const [l1, l2, l3] = q;
if (!(l1 in L1_SHORTCUTS)) return [
q
];
if (!l1 && !l2 && !l3) return [
q
];
const targets = L1_SHORTCUTS[l1];
const expanded = targets.map((s)=>[
s,
l2,
l3
]);
if (l2 === undefined) return expanded;
if (l2 in L2_SHORTCUTS && (l2 || l3)) return expanded;
return expanded.filter(([s])=>!!valid[s]?.[l2]);
}).flatMap((q)=>{
const [l1, l2, l3] = q;
if (!(l2 in L2_SHORTCUTS)) return [
q
];
if (!l2 && !l3) return [
q
];
const targets = L2_SHORTCUTS[l2];
const expanded = targets.map((s)=>[
l1,
s,
l3
]);
if (l3 === undefined) return expanded;
return expanded.filter(([, s])=>!!valid[l1]?.[s]?.[l3]);
});
if (expanded.length === 0) {
throw new Error(`Shortcuts in '${filter.join(":")}' do not expand to any valid filter query`);
}
return expanded;
}
function check(original, preprocessed) {
if (preprocessed.length === 0) throw new Error("Empty filter query given");
const errors = preprocessed.map(checkOne).filter((r)=>r !== true);
if (errors.length === 0) return preprocessed;
else if (errors.length === 1) throw new Error(errors[0]);
else {
throw new Error(`Invalid filter query '${original.join(":")}'. There are ${errors.length} errors after expanding the contained shortcuts: ${errors.join("; ")}`);
}
}
function checkOne(filter) {
const [l1, l2, l3, ...n] = filter;
if (l1 === undefined) return "Empty filter query given";
if (!(l1 in UPDATE_KEYS)) {
const permitted = Object.keys(UPDATE_KEYS);
return `Invalid L1 filter '${l1}' given in '${filter.join(":")}'. \
Permitted values are: ${permitted.map((k)=>`'${k}'`).join(", ")}.`;
}
if (l2 === undefined) return true;
const l1Obj = UPDATE_KEYS[l1];
if (!(l2 in l1Obj)) {
const permitted = Object.keys(l1Obj);
return `Invalid L2 filter '${l2}' given in '${filter.join(":")}'. \
Permitted values are: ${permitted.map((k)=>`'${k}'`).join(", ")}.`;
}
if (l3 === undefined) return true;
const l2Obj = l1Obj[l2];
if (!(l3 in l2Obj)) {
const permitted = Object.keys(l2Obj);
return `Invalid L3 filter '${l3}' given in '${filter.join(":")}'. ${permitted.length === 0 ? `No further filtering is possible after '${l1}:${l2}'.` : `Permitted values are: ${permitted.map((k)=>`'${k}'`).join(", ")}.`}`;
}
if (n.length === 0) return true;
return `Cannot filter further than three levels, ':${n.join(":")}' is invalid!`;
}
function treeify(paths) {
const tree = {};
for (const [l1, l2, l3] of paths){
const subtree = tree[l1] ??= {};
if (l2 !== undefined) {
const set = subtree[l2] ??= new Set();
if (l3 !== undefined) set.add(l3);
}
}
return tree;
}
function or(left, right) {
return (obj, ctx)=>left(obj, ctx) || right(obj, ctx);
}
function concat(get, test) {
return (obj, ctx)=>{
const nextObj = get(obj, ctx);
return nextObj && test(nextObj, ctx);
};
}
function leaf(pred) {
return (obj, ctx)=>pred(obj, ctx) != null;
}
function arborist(tree) {
const l1Predicates = Object.entries(tree).map(([l1, subtree])=>{
const l1Pred = (obj)=>obj[l1];
const l2Predicates = Object.entries(subtree).map(([l2, set])=>{
const l2Pred = (obj)=>obj[l2];
const l3Predicates = Array.from(set).map((l3)=>{
const l3Pred = l3 === "me" ? (obj, ctx)=>{
const me = ctx.me.id;
return testMaybeArray(obj, (u)=>u.id === me);
} : (obj)=>testMaybeArray(obj, (e)=>e[l3] || e.type === l3);
return l3Pred;
});
return l3Predicates.length === 0 ? leaf(l2Pred) : concat(l2Pred, l3Predicates.reduce(or));
});
return l2Predicates.length === 0 ? leaf(l1Pred) : concat(l1Pred, l2Predicates.reduce(or));
});
if (l1Predicates.length === 0) {
throw new Error("Cannot create filter function for empty query");
}
return l1Predicates.reduce(or);
}
function testMaybeArray(t, pred) {
const p = (x)=>x != null && pred(x);
return Array.isArray(t) ? t.some(p) : p(t);
}
const ENTITY_KEYS = {
mention: {},
hashtag: {},
cashtag: {},
bot_command: {},
url: {},
email: {},
phone_number: {},
bold: {},
italic: {},
underline: {},
strikethrough: {},
spoiler: {},
blockquote: {},
expandable_blockquote: {},
code: {},
pre: {},
text_link: {},
text_mention: {},
custom_emoji: {}
};
const USER_KEYS = {
me: {},
is_bot: {},
is_premium: {},
added_to_attachment_menu: {}
};
const FORWARD_ORIGIN_KEYS = {
user: {},
hidden_user: {},
chat: {},
channel: {}
};
const STICKER_KEYS = {
is_video: {},
is_animated: {},
premium_animation: {}
};
const REACTION_KEYS = {
emoji: {},
custom_emoji: {},
paid: {}
};
const COMMON_MESSAGE_KEYS = {
forward_origin: FORWARD_ORIGIN_KEYS,
is_topic_message: {},
is_automatic_forward: {},
business_connection_id: {},
text: {},
animation: {},
audio: {},
document: {},
paid_media: {},
photo: {},
sticker: STICKER_KEYS,
story: {},
video: {},
video_note: {},
voice: {},
contact: {},
dice: {},
game: {},
poll: {},
venue: {},
location: {},
entities: ENTITY_KEYS,
caption_entities: ENTITY_KEYS,
caption: {},
link_preview_options: {
url: {},
prefer_small_media: {},
prefer_large_media: {},
show_above_text: {}
},
effect_id: {},
paid_star_count: {},
has_media_spoiler: {},
new_chat_title: {},
new_chat_photo: {},
delete_chat_photo: {},
message_auto_delete_timer_changed: {},
pinned_message: {},
invoice: {},
proximity_alert_triggered: {},
chat_background_set: {},
giveaway_created: {},
giveaway: {
only_new_members: {},
has_public_winners: {}
},
giveaway_winners: {
only_new_members: {},
was_refunded: {}
},
giveaway_completed: {},
gift: {},
unique_gift: {},
paid_message_price_changed: {},
video_chat_scheduled: {},
video_chat_started: {},
video_chat_ended: {},
video_chat_participants_invited: {},
web_app_data: {}
};
const MESSAGE_KEYS = {
...COMMON_MESSAGE_KEYS,
direct_messages_topic: {},
new_chat_members: USER_KEYS,
left_chat_member: USER_KEYS,
group_chat_created: {},
supergroup_chat_created: {},
migrate_to_chat_id: {},
migrate_from_chat_id: {},
successful_payment: {},
refunded_payment: {},
users_shared: {},
chat_shared: {},
connected_website: {},
write_access_allowed: {},
passport_data: {},
boost_added: {},
forum_topic_created: {},
forum_topic_edited: {
name: {},
icon_custom_emoji_id: {}
},
forum_topic_closed: {},
forum_topic_reopened: {},
general_forum_topic_hidden: {},
general_forum_topic_unhidden: {},
checklist: {
others_can_add_tasks: {},
others_can_mark_tasks_as_done: {}
},
checklist_tasks_done: {},
checklist_tasks_added: {},
suggested_post_info: {},
suggested_post_approved: {},
suggested_post_approval_failed: {},
suggested_post_declined: {},
suggested_post_paid: {},
suggested_post_refunded: {},
sender_boost_count: {}
};
const CHANNEL_POST_KEYS = {
...COMMON_MESSAGE_KEYS,
channel_chat_created: {},
direct_message_price_changed: {},
is_paid_post: {}
};
const BUSINESS_CONNECTION_KEYS = {
can_reply: {},
is_enabled: {}
};
const MESSAGE_REACTION_KEYS = {
old_reaction: REACTION_KEYS,
new_reaction: REACTION_KEYS
};
const MESSAGE_REACTION_COUNT_UPDATED_KEYS = {
reactions: REACTION_KEYS
};
const CALLBACK_QUERY_KEYS = {
data: {},
game_short_name: {}
};
const CHAT_MEMBER_UPDATED_KEYS = {
from: USER_KEYS
};
const UPDATE_KEYS = {
message: MESSAGE_KEYS,
edited_message: MESSAGE_KEYS,
channel_post: CHANNEL_POST_KEYS,
edited_channel_post: CHANNEL_POST_KEYS,
business_connection: BUSINESS_CONNECTION_KEYS,
business_message: MESSAGE_KEYS,
edited_business_message: MESSAGE_KEYS,
deleted_business_messages: {},
inline_query: {},
chosen_inline_result: {},
callback_query: CALLBACK_QUERY_KEYS,
shipping_query: {},
pre_checkout_query: {},
poll: {},
poll_answer: {},
my_chat_member: CHAT_MEMBER_UPDATED_KEYS,
chat_member: CHAT_MEMBER_UPDATED_KEYS,
chat_join_request: {},
message_reaction: MESSAGE_REACTION_KEYS,
message_reaction_count: MESSAGE_REACTION_COUNT_UPDATED_KEYS,
chat_boost: {},
removed_chat_boost: {},
purchased_paid_media: {}
};
const L1_SHORTCUTS = {
"": [
"message",
"channel_post"
],
msg: [
"message",
"channel_post"
],
edit: [
"edited_message",
"edited_channel_post"
]
};
const L2_SHORTCUTS = {
"": [
"entities",
"caption_entities"
],
media: [
"photo",
"video"
],
file: [
"photo",
"animation",
"audio",
"document",
"video",
"video_note",
"voice",
"sticker"
]
};
const checker = {
filterQuery (filter) {
const pred = matchFilter(filter);
return (ctx)=>pred(ctx);
},
text (trigger) {
const hasText = checker.filterQuery([
":text",
":caption"
]);
const trg = triggerFn(trigger);
return (ctx)=>{
if (!hasText(ctx)) return false;
const msg = ctx.message ?? ctx.channelPost;
const txt = msg.text ?? msg.caption;
return match(ctx, txt, trg);
};
},
command (command) {
const hasEntities = checker.filterQuery(":entities:bot_command");
const atCommands = new Set();
const noAtCommands = new Set();
toArray(command).forEach((cmd)=>{
if (cmd.startsWith("/")) {
throw new Error(`Do not include '/' when registering command handlers (use '${cmd.substring(1)}' not '${cmd}')`);
}
const set = cmd.includes("@") ? atCommands : noAtCommands;
set.add(cmd);
});
return (ctx)=>{
if (!hasEntities(ctx)) return false;
const msg = ctx.message ?? ctx.channelPost;
const txt = msg.text ?? msg.caption;
return msg.entities.some((e)=>{
if (e.type !== "bot_command") return false;
if (e.offset !== 0) return false;
const cmd = txt.substring(1, e.length);
if (noAtCommands.has(cmd) || atCommands.has(cmd)) {
ctx.match = txt.substring(cmd.length + 1).trimStart();
return true;
}
const index = cmd.indexOf("@");
if (index === -1) return false;
const atTarget = cmd.substring(index + 1).toLowerCase();
const username = ctx.me.username.toLowerCase();
if (atTarget !== username) return false;
const atCommand = cmd.substring(0, index);
if (noAtCommands.has(atCommand)) {
ctx.match = txt.substring(cmd.length + 1).trimStart();
return true;
}
return false;
});
};
},
reaction (reaction) {
const hasMessageReaction = checker.filterQuery("message_reaction");
const normalized = typeof reaction === "string" ? [
{
type: "emoji",
emoji: reaction
}
] : (Array.isArray(reaction) ? reaction : [
reaction
]).map((emoji)=>typeof emoji === "string" ? {
type: "emoji",
emoji
} : emoji);
const emoji = new Set(normalized.filter((r)=>r.type === "emoji").map((r)=>r.emoji));
const customEmoji = new Set(normalized.filter((r)=>r.type === "custom_emoji").map((r)=>r.custom_emoji_id));
const paid = normalized.some((r)=>r.type === "paid");
return (ctx)=>{
if (!hasMessageReaction(ctx)) return false;
const { old_reaction, new_reaction } = ctx.messageReaction;
for (const reaction of new_reaction){
let isOld = false;
if (reaction.type === "emoji") {
for (const old of old_reaction){
if (old.type !== "emoji") continue;
if (old.emoji === reaction.emoji) {
isOld = true;
break;
}
}
} else if (reaction.type === "custom_emoji") {
for (const old of old_reaction){
if (old.type !== "custom_emoji") continue;
if (old.custom_emoji_id === reaction.custom_emoji_id) {
isOld = true;
break;
}
}
} else if (reaction.type === "paid") {
for (const old of old_reaction){
if (old.type !== "paid") continue;
isOld = true;
break;
}
} else {}
if (isOld) continue;
if (reaction.type === "emoji") {
if (emoji.has(reaction.emoji)) return true;
} else if (reaction.type === "custom_emoji") {
if (customEmoji.has(reaction.custom_emoji_id)) return true;
} else if (reaction.type === "paid") {
if (paid) return true;
} else {
return true;
}
}
return false;
};
},
chatType (chatType) {
const set = new Set(toArray(chatType));
return (ctx)=>ctx.chat?.type !== undefined && set.has(ctx.chat.type);
},
callbackQuery (trigger) {
const hasCallbackQuery = checker.filterQuery("callback_query:data");
const trg = triggerFn(trigger);
return (ctx)=>hasCallbackQuery(ctx) && match(ctx, ctx.callbackQuery.data, trg);
},
gameQuery (trigger) {
const hasGameQuery = checker.filterQuery("callback_query:game_short_name");
const trg = triggerFn(trigger);
return (ctx)=>hasGameQuery(ctx) && match(ctx, ctx.callbackQuery.game_short_name, trg);
},
inlineQuery (trigger) {
const hasInlineQuery = checker.filterQuery("inline_query");
const trg = triggerFn(trigger);
return (ctx)=>hasInlineQuery(ctx) && match(ctx, ctx.inlineQuery.query, trg);
},
chosenInlineResult (trigger) {
const hasChosenInlineResult = checker.filterQuery("chosen_inline_result");
const trg = triggerFn(trigger);
return (ctx)=>hasChosenInlineResult(ctx) && match(ctx, ctx.chosenInlineResult.result_id, trg);
},
preCheckoutQuery (trigger) {
const hasPreCheckoutQuery = checker.filterQuery("pre_checkout_query");
const trg = triggerFn(trigger);
return (ctx)=>hasPreCheckoutQuery(ctx) && match(ctx, ctx.preCheckoutQuery.invoice_payload, trg);
},
shippingQuery (trigger) {
const hasShippingQuery = checker.filterQuery("shipping_query");
const trg = triggerFn(trigger);
return (ctx)=>hasShippingQuery(ctx) && match(ctx, ctx.shippingQuery.invoice_payload, trg);
}
};
class Context {
update;
api;
me;
match;
constructor(update, api, me){
this.update = update;
this.api = api;
this.me = me;
}
get message() {
return this.update.message;
}
get editedMessage() {
return this.update.edited_message;
}
get channelPost() {
return this.update.channel_post;
}
get editedChannelPost() {
return this.update.edited_channel_post;
}
get businessConnection() {
return this.update.business_connection;
}
get businessMessage() {
return this.update.business_message;
}
get editedBusinessMessage() {
return this.update.edited_business_message;
}
get deletedBusinessMessages() {
return this.update.deleted_business_messages;
}
get messageReaction() {
return this.update.message_reaction;
}
get messageReactionCount() {
return this.update.message_reaction_count;
}
get inlineQuery() {
return this.update.inline_query;
}
get chosenInlineResult() {
return this.update.chosen_inline_result;
}
get callbackQuery() {
return this.update.callback_query;
}
get shippingQuery() {
return this.update.shipping_query;
}
get preCheckoutQuery() {
return this.update.pre_checkout_query;
}
get poll() {
return this.update.poll;
}
get pollAnswer() {
return this.update.poll_answer;
}
get myChatMember() {
return this.update.my_chat_member;
}
get chatMember() {
return this.update.chat_member;
}
get chatJoinRequest() {
return this.update.chat_join_request;
}
get chatBoost() {
return this.update.chat_boost;
}
get removedChatBoost() {
return this.update.removed_chat_boost;
}
get purchasedPaidMedia() {
return this.update.purchased_paid_media;
}
get msg() {
return this.message ?? this.editedMessage ?? this.channelPost ?? this.editedChannelPost ?? this.businessMessage ?? this.editedBusinessMessage ?? this.callbackQuery?.message;
}
get chat() {
return (this.msg ?? this.deletedBusinessMessages ?? this.messageReaction ?? this.messageReactionCount ?? this.myChatMember ?? this.chatMember ?? this.chatJoinRequest ?? this.chatBoost ?? this.removedChatBoost)?.chat;
}
get senderChat() {
return this.msg?.sender_chat;
}
get from() {
return (this.businessConnection ?? this.messageReaction ?? (this.chatBoost?.boost ?? this.removedChatBoost)?.source)?.user ?? (this.callbackQuery ?? this.msg ?? this.inlineQuery ?? this.chosenInlineResult ?? this.shippingQuery ?? this.preCheckoutQuery ?? this.myChatMember ?? this.chatMember ?? this.chatJoinRequest ?? this.purchasedPaidMedia)?.from;
}
get msgId() {
return this.msg?.message_id ?? this.messageReaction?.message_id ?? this.messageReactionCount?.message_id;
}
get chatId() {
return this.chat?.id ?? this.businessConnection?.user_chat_id;
}
get inlineMessageId() {
return this.callbackQuery?.inline_message_id ?? this.chosenInlineResult?.inline_message_id;
}
get businessConnectionId() {
return this.msg?.business_connection_id ?? this.businessConnection?.id ?? this.deletedBusinessMessages?.business_connection_id;
}
entities(types) {
const message = this.msg;
if (message === undefined) return [];
const text = message.text ?? message.caption;
if (text === undefined) return [];
let entities = message.entities ?? message.caption_entities;
if (entities === undefined) return [];
if (types !== undefined) {
const filters = new Set(toArray(types));
entities = entities.filter((entity)=>filters.has(entity.type));
}
return entities.map((entity)=>({
...entity,
text: text.substring(entity.offset, entity.offset + entity.length)
}));
}
reactions() {
const emoji = [];
const emojiAdded = [];
const emojiKept = [];
const emojiRemoved = [];
const customEmoji = [];
const customEmojiAdded = [];
const customEmojiKept = [];
const customEmojiRemoved = [];
let paid = false;
let paidAdded = false;
const r = this.messageReaction;
if (r !== undefined) {
const { old_reaction, new_reaction } = r;
for (const reaction of new_reaction){
if (reaction.type === "emoji") {
emoji.push(reaction.emoji);
} else if (reaction.type === "custom_emoji") {
customEmoji.push(reaction.custom_emoji_id);
} else if (reaction.type === "paid") {
paid = paidAdded = true;
}
}
for (const reaction of old_reaction){
if (reaction.type === "emoji") {
emojiRemoved.push(reaction.emoji);
} else if (reaction.type === "custom_emoji") {
customEmojiRemoved.push(reaction.custom_emoji_id);
} else if (reaction.type === "paid") {
paidAdded = false;
}
}
emojiAdded.push(...emoji);
customEmojiAdded.push(...customEmoji);
for(let i = 0; i < emojiRemoved.length; i++){
const len = emojiAdded.length;
if (len === 0) break;
const rem = emojiRemoved[i];
for(let j = 0; j < len; j++){
if (rem === emojiAdded[j]) {
emojiKept.push(rem);
emojiRemoved.splice(i, 1);
emojiAdded.splice(j, 1);
i--;
break;
}
}
}
for(let i = 0; i < customEmojiRemoved.length; i++){
const len = customEmojiAdded.length;
if (len === 0) break;
const rem = customEmojiRemoved[i];
for(let j = 0; j < len; j++){
if (rem === customEmojiAdded[j]) {
customEmojiKept.push(rem);
customEmojiRemoved.splice(i, 1);
customEmojiAdded.splice(j, 1);
i--;
break;
}
}
}
}
return {
emoji,
emojiAdded,
emojiKept,
emojiRemoved,
customEmoji,
customEmojiAdded,
customEmojiKept,
customEmojiRemoved,
paid,
paidAdded
};
}
static has = checker;
has(filter) {
return Context.has.filterQuery(filter)(this);
}
hasText(trigger) {
return Context.has.text(trigger)(this);
}
hasCommand(command) {
return Context.has.command(command)(this);
}
hasReaction(reaction) {
return Context.has.reaction(reaction)(this);
}
hasChatType(chatType) {
return Context.has.chatType(chatType)(this);
}
hasCallbackQuery(trigger) {
return Context.has.callbackQuery(trigger)(this);
}
hasGameQuery(trigger) {
return Context.has.gameQuery(trigger)(this);
}
hasInlineQuery(trigger) {
return Context.has.inlineQuery(trigger)(this);
}
hasChosenInlineResult(trigger) {
return Context.has.chosenInlineResult(trigger)(this);
}
hasPreCheckoutQuery(trigger) {
return Context.has.preCheckoutQuery(trigger)(this);
}
hasShippingQuery(trigger) {
return Context.has.shippingQuery(trigger)(this);
}
reply(text, other, signal) {
const msg = this.msg;
return this.api.sendMessage(orThrow(this.chatId, "sendMessage"), text, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
forwardMessage(chat_id, other, signal) {
const msg = this.msg;
return this.api.forwardMessage(chat_id, orThrow(this.chatId, "forwardMessage"), orThrow(this.msgId, "forwardMessage"), {
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
forwardMessages(chat_id, message_ids, other, signal) {
const msg = this.msg;
return this.api.forwardMessages(chat_id, orThrow(this.chatId, "forwardMessages"), message_ids, {
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
copyMessage(chat_id, other, signal) {
const msg = this.msg;
return this.api.copyMessage(chat_id, orThrow(this.chatId, "copyMessage"), orThrow(this.msgId, "copyMessage"), {
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
copyMessages(chat_id, message_ids, other, signal) {
const msg = this.msg;
return this.api.copyMessages(chat_id, orThrow(this.chatId, "copyMessages"), message_ids, {
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithPhoto(photo, other, signal) {
const msg = this.msg;
return this.api.sendPhoto(orThrow(this.chatId, "sendPhoto"), photo, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithAudio(audio, other, signal) {
const msg = this.msg;
return this.api.sendAudio(orThrow(this.chatId, "sendAudio"), audio, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithDocument(document1, other, signal) {
const msg = this.msg;
return this.api.sendDocument(orThrow(this.chatId, "sendDocument"), document1, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithVideo(video, other, signal) {
const msg = this.msg;
return this.api.sendVideo(orThrow(this.chatId, "sendVideo"), video, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithAnimation(animation, other, signal) {
const msg = this.msg;
return this.api.sendAnimation(orThrow(this.chatId, "sendAnimation"), animation, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithVoice(voice, other, signal) {
const msg = this.msg;
return this.api.sendVoice(orThrow(this.chatId, "sendVoice"), voice, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithVideoNote(video_note, other, signal) {
const msg = this.msg;
return this.api.sendVideoNote(orThrow(this.chatId, "sendVideoNote"), video_note, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithMediaGroup(media, other, signal) {
const msg = this.msg;
return this.api.sendMediaGroup(orThrow(this.chatId, "sendMediaGroup"), media, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithLocation(latitude, longitude, other, signal) {
const msg = this.msg;
return this.api.sendLocation(orThrow(this.chatId, "sendLocation"), latitude, longitude, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
editMessageLiveLocation(latitude, longitude, other, signal) {
const inlineId = this.inlineMessageId;
return inlineId !== undefined ? this.api.editMessageLiveLocationInline(inlineId, latitude, longitude, {
business_connection_id: this.businessConnectionId,
...other
}, signal) : this.api.editMessageLiveLocation(orThrow(this.chatId, "editMessageLiveLocation"), orThrow(this.msgId, "editMessageLiveLocation"), latitude, longitude, {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
stopMessageLiveLocation(other, signal) {
const inlineId = this.inlineMessageId;
return inlineId !== undefined ? this.api.stopMessageLiveLocationInline(inlineId, {
business_connection_id: this.businessConnectionId,
...other
}, signal) : this.api.stopMessageLiveLocation(orThrow(this.chatId, "stopMessageLiveLocation"), orThrow(this.msgId, "stopMessageLiveLocation"), {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
sendPaidMedia(star_count, media, other, signal) {
return this.api.sendPaidMedia(orThrow(this.chatId, "sendPaidMedia"), star_count, media, {
business_connection_id: this.businessConnectionId,
direct_messages_topic_id: this.msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithVenue(latitude, longitude, title, address, other, signal) {
const msg = this.msg;
return this.api.sendVenue(orThrow(this.chatId, "sendVenue"), latitude, longitude, title, address, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithContact(phone_number, first_name, other, signal) {
const msg = this.msg;
return this.api.sendContact(orThrow(this.chatId, "sendContact"), phone_number, first_name, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithPoll(question, options, other, signal) {
const msg = this.msg;
return this.api.sendPoll(orThrow(this.chatId, "sendPoll"), question, options, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
...other
}, signal);
}
replyWithChecklist(checklist, other, signal) {
return this.api.sendChecklist(orThrow(this.businessConnectionId, "sendChecklist"), orThrow(this.chatId, "sendChecklist"), checklist, other, signal);
}
editMessageChecklist(checklist, other, signal) {
const msg = orThrow(this.msg, "editMessageChecklist");
const target = msg.checklist_tasks_done?.checklist_message ?? msg.checklist_tasks_added?.checklist_message ?? msg;
return this.api.editMessageChecklist(orThrow(this.businessConnectionId, "editMessageChecklist"), orThrow(target.chat.id, "editMessageChecklist"), orThrow(target.message_id, "editMessageChecklist"), checklist, other, signal);
}
replyWithDice(emoji, other, signal) {
const msg = this.msg;
return this.api.sendDice(orThrow(this.chatId, "sendDice"), emoji, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
direct_messages_topic_id: msg?.direct_messages_topic?.topic_id,
...other
}, signal);
}
replyWithChatAction(action, other, signal) {
const msg = this.msg;
return this.api.sendChatAction(orThrow(this.chatId, "sendChatAction"), action, {
business_connection_id: this.businessConnectionId,
...msg?.is_topic_message ? {
message_thread_id: msg?.message_thread_id
} : {},
...other
}, signal);
}
react(reaction, other, signal) {
return this.api.setMessageReaction(orThrow(this.chatId, "setMessageReaction"), orThrow(this.msgId, "setMessageReaction"), typeof reaction === "string" ? [
{
type: "emoji",
emoji: reaction
}
] : (Array.isArray(reaction) ? reaction : [
reaction
]).map((emoji)=>typeof emoji === "string" ? {
type: "emoji",
emoji
} : emoji), other, signal);
}
getUserProfilePhotos(other, signal) {
return this.api.getUserProfilePhotos(orThrow(this.from, "getUserProfilePhotos").id, other, signal);
}
setUserEmojiStatus(other, signal) {
return this.api.setUserEmojiStatus(orThrow(this.from, "setUserEmojiStatus").id, other, signal);
}
getUserChatBoosts(chat_id, signal) {
return this.api.getUserChatBoosts(chat_id, orThrow(this.from, "getUserChatBoosts").id, signal);
}
getBusinessConnection(signal) {
return this.api.getBusinessConnection(orThrow(this.businessConnectionId, "getBusinessConnection"), signal);
}
getFile(signal) {
const m = orThrow(this.msg, "getFile");
const file = m.photo !== undefined ? m.photo[m.photo.length - 1] : m.animation ?? m.audio ?? m.document ?? m.video ?? m.video_note ?? m.voice ?? m.sticker;
return this.api.getFile(orThrow(file, "getFile").file_id, signal);
}
kickAuthor(...args) {
return this.banAuthor(...args);
}
banAuthor(other, signal) {
return this.api.banChatMember(orThrow(this.chatId, "banAuthor"), orThrow(this.from, "banAuthor").id, other, signal);
}
kickChatMember(...args) {
return this.banChatMember(...args);
}
banChatMember(user_id, other, signal) {
return this.api.banChatMember(orThrow(this.chatId, "banChatMember"), user_id, other, signal);
}
unbanChatMember(user_id, other, signal) {
return this.api.unbanChatMember(orThrow(this.chatId, "unbanChatMember"), user_id, other, signal);
}
restrictAuthor(permissions, other, signal) {
return this.api.restrictChatMember(orThrow(this.chatId, "restrictAuthor"), orThrow(this.from, "restrictAuthor").id, permissions, other, signal);
}
restrictChatMember(user_id, permissions, other, signal) {
return this.api.restrictChatMember(orThrow(this.chatId, "restrictChatMember"), user_id, permissions, other, signal);
}
promoteAuthor(other, signal) {
return this.api.promoteChatMember(orThrow(this.chatId, "promoteAuthor"), orThrow(this.from, "promoteAuthor").id, other, signal);
}
promoteChatMember(user_id, other, signal) {
return this.api.promoteChatMember(orThrow(this.chatId, "promoteChatMember"), user_id, other, signal);
}
setChatAdministratorAuthorCustomTitle(custom_title, signal) {
return this.api.setChatAdministratorCustomTitle(orThrow(this.chatId, "setChatAdministratorAuthorCustomTitle"), orThrow(this.from, "setChatAdministratorAuthorCustomTitle").id, custom_title, signal);
}
setChatAdministratorCustomTitle(user_id, custom_title, signal) {
return this.api.setChatAdministratorCustomTitle(orThrow(this.chatId, "setChatAdministratorCustomTitle"), user_id, custom_title, signal);
}
banChatSenderChat(sender_chat_id, signal) {
return this.api.banChatSenderChat(orThrow(this.chatId, "banChatSenderChat"), sender_chat_id, signal);
}
unbanChatSenderChat(sender_chat_id, signal) {
return this.api.unbanChatSenderChat(orThrow(this.chatId, "unbanChatSenderChat"), sender_chat_id, signal);
}
setChatPermissions(permissions, other, signal) {
return this.api.setChatPermissions(orThrow(this.chatId, "setChatPermissions"), permissions, other, signal);
}
exportChatInviteLink(signal) {
return this.api.exportChatInviteLink(orThrow(this.chatId, "exportChatInviteLink"), signal);
}
createChatInviteLink(other, signal) {
return this.api.createChatInviteLink(orThrow(this.chatId, "createChatInviteLink"), other, signal);
}
editChatInviteLink(invite_link, other, signal) {
return this.api.editChatInviteLink(orThrow(this.chatId, "editChatInviteLink"), invite_link, other, signal);
}
createChatSubscriptionInviteLink(subscription_period, subscription_price, other, signal) {
return this.api.createChatSubscriptionInviteLink(orThrow(this.chatId, "createChatSubscriptionInviteLink"), subscription_period, subscription_price, other, signal);
}
editChatSubscriptionInviteLink(invite_link, other, signal) {
return this.api.editChatSubscriptionInviteLink(orThrow(this.chatId, "editChatSubscriptionInviteLink"), invite_link, other, signal);
}
revokeChatInviteLink(invite_link, signal) {
return this.api.revokeChatInviteLink(orThrow(this.chatId, "editChatInviteLink"), invite_link, signal);
}
approveChatJoinRequest(user_id, signal) {
return this.api.approveChatJoinRequest(orThrow(this.chatId, "approveChatJoinRequest"), user_id, signal);
}
declineChatJoinRequest(user_id, signal) {
return this.api.declineChatJoinRequest(orThrow(this.chatId, "declineChatJoinRequest"), user_id, signal);
}
approveSuggestedPost(other, signal) {
return this.api.approveSuggestedPost(orThrow(this.chatId, "approveSuggestedPost"), orThrow(this.msgId, "approveSuggestedPost"), other, signal);
}
declineSuggestedPost(other, signal) {
return this.api.declineSuggestedPost(orThrow(this.chatId, "declineSuggestedPost"), orThrow(this.msgId, "declineSuggestedPost"), other, signal);
}
setChatPhoto(photo, signal) {
return this.api.setChatPhoto(orThrow(this.chatId, "setChatPhoto"), photo, signal);
}
deleteChatPhoto(signal) {
return this.api.deleteChatPhoto(orThrow(this.chatId, "deleteChatPhoto"), signal);
}
setChatTitle(title, signal) {
return this.api.setChatTitle(orThrow(this.chatId, "setChatTitle"), title, signal);
}
setChatDescription(description, signal) {
return this.api.setChatDescription(orThrow(this.chatId, "setChatDescription"), description, signal);
}
pinChatMessage(message_id, other, signal) {
return this.api.pinChatMessage(orThrow(this.chatId, "pinChatMessage"), message_id, {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
unpinChatMessage(message_id, other, signal) {
return this.api.unpinChatMessage(orThrow(this.chatId, "unpinChatMessage"), message_id, {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
unpinAllChatMessages(signal) {
return this.api.unpinAllChatMessages(orThrow(this.chatId, "unpinAllChatMessages"), signal);
}
leaveChat(signal) {
return this.api.leaveChat(orThrow(this.chatId, "leaveChat"), signal);
}
getChat(signal) {
return this.api.getChat(orThrow(this.chatId, "getChat"), signal);
}
getChatAdministrators(signal) {
return this.api.getChatAdministrators(orThrow(this.chatId, "getChatAdministrators"), signal);
}
getChatMembersCount(...args) {
return this.getChatMemberCount(...args);
}
getChatMemberCount(signal) {
return this.api.getChatMemberCount(orThrow(this.chatId, "getChatMemberCount"), signal);
}
getAuthor(signal) {
return this.api.getChatMember(orThrow(this.chatId, "getAuthor"), orThrow(this.from, "getAuthor").id, signal);
}
getChatMember(user_id, signal) {
return this.api.getChatMember(orThrow(this.chatId, "getChatMember"), user_id, signal);
}
setChatStickerSet(sticker_set_name, signal) {
return this.api.setChatStickerSet(orThrow(this.chatId, "setChatStickerSet"), sticker_set_name, signal);
}
deleteChatStickerSet(signal) {
return this.api.deleteChatStickerSet(orThrow(this.chatId, "deleteChatStickerSet"), signal);
}
createForumTopic(name, other, signal) {
return this.api.createForumTopic(orThrow(this.chatId, "createForumTopic"), name, other, signal);
}
editForumTopic(other, signal) {
const message = orThrow(this.msg, "editForumTopic");
const thread = orThrow(message.message_thread_id, "editForumTopic");
return this.api.editForumTopic(message.chat.id, thread, other, signal);
}
closeForumTopic(signal) {
const message = orThrow(this.msg, "closeForumTopic");
const thread = orThrow(message.message_thread_id, "closeForumTopic");
return this.api.closeForumTopic(message.chat.id, thread, signal);
}
reopenForumTopic(signal) {
const message = orThrow(this.msg, "reopenForumTopic");
const thread = orThrow(message.message_thread_id, "reopenForumTopic");
return this.api.reopenForumTopic(message.chat.id, thread, signal);
}
deleteForumTopic(signal) {
const message = orThrow(this.msg, "deleteForumTopic");
const thread = orThrow(message.message_thread_id, "deleteForumTopic");
return this.api.deleteForumTopic(message.chat.id, thread, signal);
}
unpinAllForumTopicMessages(signal) {
const message = orThrow(this.msg, "unpinAllForumTopicMessages");
const thread = orThrow(message.message_thread_id, "unpinAllForumTopicMessages");
return this.api.unpinAllForumTopicMessages(message.chat.id, thread, signal);
}
editGeneralForumTopic(name, signal) {
return this.api.editGeneralForumTopic(orThrow(this.chatId, "editGeneralForumTopic"), name, signal);
}
closeGeneralForumTopic(signal) {
return this.api.closeGeneralForumTopic(orThrow(this.chatId, "closeGeneralForumTopic"), signal);
}
reopenGeneralForumTopic(signal) {
return this.api.reopenGeneralForumTopic(orThrow(this.chatId, "reopenGeneralForumTopic"), signal);
}
hideGeneralForumTopic(signal) {
return this.api.hideGeneralForumTopic(orThrow(this.chatId, "hideGeneralForumTopic"), signal);
}
unhideGeneralForumTopic(signal) {
return this.api.unhideGeneralForumTopic(orThrow(this.chatId, "unhideGeneralForumTopic"), signal);
}
unpinAllGeneralForumTopicMessages(signal) {
return this.api.unpinAllGeneralForumTopicMessages(orThrow(this.chatId, "unpinAllGeneralForumTopicMessages"), signal);
}
answerCallbackQuery(other, signal) {
return this.api.answerCallbackQuery(orThrow(this.callbackQuery, "answerCallbackQuery").id, typeof other === "string" ? {
text: other
} : other, signal);
}
setChatMenuButton(other, signal) {
return this.api.setChatMenuButton(other, signal);
}
getChatMenuButton(other, signal) {
return this.api.getChatMenuButton(other, signal);
}
setMyDefaultAdministratorRights(other, signal) {
return this.api.setMyDefaultAdministratorRights(other, signal);
}
getMyDefaultAdministratorRights(other, signal) {
return this.api.getMyDefaultAdministratorRights(other, signal);
}
editMessageText(text, other, signal) {
const inlineId = this.inlineMessageId;
return inlineId !== undefined ? this.api.editMessageTextInline(inlineId, text, {
business_connection_id: this.businessConnectionId,
...other
}, signal) : this.api.editMessageText(orThrow(this.chatId, "editMessageText"), orThrow(this.msg?.message_id ?? this.messageReaction?.message_id ?? this.messageReactionCount?.message_id, "editMessageText"), text, {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
editMessageCaption(other, signal) {
const inlineId = this.inlineMessageId;
return inlineId !== undefined ? this.api.editMessageCaptionInline(inlineId, {
business_connection_id: this.businessConnectionId,
...other
}, signal) : this.api.editMessageCaption(orThrow(this.chatId, "editMessageCaption"), orThrow(this.msg?.message_id ?? this.messageReaction?.message_id ?? this.messageReactionCount?.message_id, "editMessageCaption"), {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
editMessageMedia(media, other, signal) {
const inlineId = this.inlineMessageId;
return inlineId !== undefined ? this.api.editMessageMediaInline(inlineId, media, {
business_connection_id: this.businessConnectionId,
...other
}, signal) : this.api.editMessageMedia(orThrow(this.chatId, "editMessageMedia"), orThrow(this.msg?.message_id ?? this.messageReaction?.message_id ?? this.messageReactionCount?.message_id, "editMessageMedia"), media, {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
editMessageReplyMarkup(other, signal) {
const inlineId = this.inlineMessageId;
return inlineId !== undefined ? this.api.editMessageReplyMarkupInline(inlineId, {
business_connection_id: this.businessConnectionId,
...other
}, signal) : this.api.editMessageReplyMarkup(orThrow(this.chatId, "editMessageReplyMarkup"), orThrow(this.msg?.message_id ?? this.messageReaction?.message_id ?? this.messageReactionCount?.message_id, "editMessageReplyMarkup"), {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
stopPoll(other, signal) {
return this.api.stopPoll(orThrow(this.chatId, "stopPoll"), orThrow(this.msg?.message_id ?? this.messageReaction?.message_id ?? this.messageReactionCount?.message_id, "stopPoll"), {
business_connection_id: this.businessConnectionId,
...other
}, signal);
}
deleteMessage(signal) {
return this.api.deleteMessage(orThrow(this.chatId, "deleteMessage"), orThrow(this.msg?.message_id ?? this.messageReaction?.message_id ?? this.messageReactionCount?.message_id, "deleteMessage"), signal);
}
deleteMessages(message_ids, signal) {
return this.api.deleteMessages(orThrow(this.chatId, "deleteMessages"), message_ids, signal);
}
deleteBusinessMessages(message_ids, signal) {
return this.api.deleteBusinessMessages(orThrow(this.businessConnectionId, "deleteBusinessMessages"), message_ids, signal);
}
setBusinessAccountName(first_name, other, signal) {
return this.api.setBusinessAccountName(orThrow(this.businessConnectionId, "setBusinessAccountName"), first_name, other, signal);
}
setBusinessAccountUsername(username, signal) {
return this.api.setBusinessAccountUsername(orThrow(this.businessConnectionId, "setBusinessAccountUsername"), username, signal);
}
setBusinessAccountBio(bio, signal) {
return this.api.se