grammy-edit-or-reply
Version:
Exports utilities for grammy to edit a message or reply to a message based on the context
209 lines (208 loc) • 7.61 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.editOrReply = exports.deleteStaleMessage = exports.sendMedia = exports.makeInputMedia = exports.makeOther = void 0;
const assert_1 = __importDefault(require("assert"));
const types_1 = require("./types");
/**
* Creates the `other` parameter with the specified keys.
*/
function makeOther(messageData, keys) {
const other = {};
const keysMap = {
caption: 'text',
caption_entities: 'entities',
reply_markup: 'keyboard',
};
keys.forEach((key) => {
const remapped = (key in keysMap ? keysMap[key] : key);
if (remapped in messageData) {
if (remapped === 'keyboard') {
other[key] = {
inline_keyboard: messageData.keyboard,
};
}
else {
other[key] = messageData[remapped];
}
}
});
return other;
}
exports.makeOther = makeOther;
/**
* Creates the input media, adding available properties
*/
function makeInputMedia(messageData) {
const other = [
'parse_mode',
'caption',
'caption_entities',
];
if (['animation', 'photo', 'video'].includes(messageData.media.type)) {
other.push('has_spoiler', 'show_caption_above_media');
}
return {
...messageData.media,
...makeOther(messageData, other),
};
}
exports.makeInputMedia = makeInputMedia;
/**
* Sends a media to the specified chat in a new message
*/
async function sendMedia(api, messageData, oldMessageInfo) {
const { chatId } = oldMessageInfo;
const { media: { media, type: mediaType }, } = messageData;
const defaultOther = [
'business_connection_id',
'disable_notification',
'message_thread_id',
'protect_content',
'reply_markup',
'reply_parameters',
'message_effect_id',
'parse_mode',
'caption',
'caption_entities',
'allow_paid_broadcast',
];
if (mediaType === 'photo') {
return await api.sendPhoto(chatId, media, makeOther(messageData, [
...defaultOther,
'has_spoiler',
'show_caption_above_media',
]));
}
else if (mediaType === 'animation') {
return await api.sendAnimation(chatId, media, makeOther(messageData, [
...defaultOther,
'has_spoiler',
'show_caption_above_media',
]));
}
else if (mediaType === 'audio') {
return await api.sendAudio(chatId, media, makeOther(messageData, defaultOther));
}
else if (mediaType === 'document') {
return await api.sendDocument(chatId, media, makeOther(messageData, defaultOther));
}
else if (mediaType === 'video') {
return await api.sendVideo(chatId, media, makeOther(messageData, [
...defaultOther,
'has_spoiler',
'show_caption_above_media',
]));
}
else {
throw new Error(`Unsupported media type: ${mediaType}`);
}
}
exports.sendMedia = sendMedia;
/**
* Tries deleting the specified message, does **not** throw an error on failure
*/
function deleteStaleMessage(api, oldMessageInfo) {
api
.deleteMessage(oldMessageInfo.chatId, oldMessageInfo.messageId)
.catch(() => { });
}
exports.deleteStaleMessage = deleteStaleMessage;
/**
* Use this when context is not available but you still have data regarding the
* message that needs to be edited (if any).
*/
async function editOrReply(api, messageData, oldMessageInfo) {
if ((0, types_1.oldMessageIsInline)(oldMessageInfo)) {
const { inlineMessageId, hasMedia } = oldMessageInfo;
if ((0, types_1.messageDataHasMedia)(messageData)) {
// we can edit the media, if a media wasn't originally present this will
// add one
return await api.editMessageMediaInline(inlineMessageId, makeInputMedia(messageData), makeOther(messageData, ['business_connection_id', 'reply_markup']));
}
else if (hasMedia) {
// we can't remove the media, but we can still try changing the caption
return await api.editMessageCaptionInline(inlineMessageId, makeOther(messageData, [
'business_connection_id',
'reply_markup',
'parse_mode',
'caption',
'caption_entities',
]));
}
else {
// we can simply edit the text
(0, assert_1.default)(!(0, types_1.messageDataHasMedia)(messageData));
return await api.editMessageTextInline(inlineMessageId, messageData.text, makeOther(messageData, [
'business_connection_id',
'entities',
'link_preview_options',
'reply_markup',
'parse_mode',
]));
}
}
if ((0, types_1.oldMessageIsChatMessage)(oldMessageInfo)) {
const { chatId, hasMedia, messageId } = oldMessageInfo;
if ((0, types_1.messageDataHasMedia)(messageData)) {
// we can edit the media, if a media wasn't originally present this will
// add one
return await api.editMessageMedia(chatId, messageId, makeInputMedia(messageData), makeOther(messageData, ['business_connection_id', 'reply_markup']));
}
else if (hasMedia) {
// delete the existing message, send a new one without media
(0, assert_1.default)(!(0, types_1.messageDataHasMedia)(messageData));
const result = await api.sendMessage(chatId, messageData.text, makeOther(messageData, [
'business_connection_id',
'disable_notification',
'entities',
'link_preview_options',
'parse_mode',
'protect_content',
'reply_markup',
'reply_parameters',
'message_effect_id',
'allow_paid_broadcast',
]));
deleteStaleMessage(api, oldMessageInfo);
return result;
}
else {
// neither have media, we can edit the message text
(0, assert_1.default)(!(0, types_1.messageDataHasMedia)(messageData));
const { text } = messageData;
return await api.editMessageText(chatId, messageId, text, makeOther(messageData, [
'business_connection_id',
'entities',
'link_preview_options',
'parse_mode',
'reply_markup',
]));
}
}
// no option but to send the message to the chat
const { chatId } = oldMessageInfo;
if (!(0, types_1.messageDataHasMedia)(messageData)) {
// send message without media
return await api.sendMessage(chatId, messageData.text, makeOther(messageData, [
'business_connection_id',
'disable_notification',
'entities',
'link_preview_options',
'message_thread_id',
'parse_mode',
'protect_content',
'reply_markup',
'reply_parameters',
'message_effect_id',
'allow_paid_broadcast',
]));
}
else {
// send the media to the chat
return await sendMedia(api, messageData, oldMessageInfo);
}
}
exports.editOrReply = editOrReply;