我正在尝试构建一个电报机器人,它将帮助用户私下准备事件创建,然后将其发布到群组。
流程是初始化群组中的机器人,然后它将显示一个按钮,将用户重定向到私人聊天。
在这里,我需要以某种方式保存群组的聊天 ID,稍后将使用该 ID 来发布事件。
我尝试过使用会话,但没有成功:
这是在群聊中调用的命令:
bot.command('event', checkIfGroup, checkIfAdmin, async (ctx) => {
ctx.session.groupId = ctx.chat.id;
const message = await ctx.reply('Welcome!', {
reply_markup: {
inline_keyboard: [
[{ text: 'Start', url: 'https://t.me/bot_name?start=true' }]
]
}
});
});
然后启动命令如下所示:
bot.command('start', checkIfPrivate, async (ctx) => {
await ctx.reply('...');
await ctx.reply('Write the event name:');
});
然后在消息中构建事件:
bot.on('message', checkIfPrivate, async (ctx) => {
const builder = ctx.session.builder;
...
builder.setTitle(text);
...
const script = builder.formatEvent();
await ctx.reply(script, {
parse_mode: 'MarkdownV2', link_preview_options: { is_disabled: true }, reply_markup: {
inline_keyboard: [
[
{
text: 'Publish',
callback_data: 'publish'
},
{
text: 'Cancel',
callback_data: 'cancel'
}
]
]
}
});
}
然后发布回调如下所示:
bot.callbackQuery('publish', async (ctx) => {
if (!ctx.callbackQuery.message?.chat.id) {
return;
}
const chatId = ctx.session.groupId;
const builder = ctx.session.builder;
const script = builder.formatEvent();
const photoId = builder.getPhotoId();
const message = await ctx.api.sendMessage(chatId, script, { parse_mode: 'MarkdownV2', link_preview_options: { is_disabled: true } });
...
});
我可以看到你可以通过两种稍微不同的方式来解决它 - 但都使用会话。我更喜欢
Solution #2
。这是详细信息。
根据 grammY 文档,您可能错过了一件关键的事情。这就是 grammY 创建会话密钥的方式。您可以参考本文档并查看创建会话密钥的不同方法 - 而默认情况下群聊和个人聊天的密钥是不同的。因此,即使您在群组中通过
ctx.session.groupId
命令设置 /event
,默认情况下您也可能无法在个人聊天中访问它。
根据文档,您可以添加并指定以下方法来获取会话密钥以轻松实现您的目标。
bot.use(session({ initial, getSessionKey }));
// Stores data per user.
function getSessionKey(ctx) {
// Give every user their personal session storage
// (will be shared across groups and in their private chat)
return ctx.from?.id.toString();
}
现在您可以简单地从发送到组的
Context.session.groupId
命令中设置 /event
,如下代码:
bot.command('event', checkIfGroup, async (ctx) => {
ctx.session.groupId = ctx.chat.id;
await ctx.reply('Welcome!', {
reply_markup: {
inline_keyboard: [
[{ text: 'Start', url: `https://t.me/botusername?start=true` }]
]
}
});
});
这是因为,有时 - 如果用户是匿名的或启用了隐私设置,
ctx.from
将是 undefined
,因此 grammy 将无法将 groupId 保存到群组的共享会话中。
此时,您可以利用start参数来更有效地处理它。这是一些代码:
bot.command('event', checkIfGroup, async (ctx) => {
await ctx.reply('Welcome!', {
reply_markup: {
inline_keyboard: [
[{ text: 'Start', url: `https://t.me/botusername?start=${ctx.chat.id}` }]
]
}
});
});
现在,当按下
Start
按钮时,ctx.match
将填充实际的组 ID。您可以将其保存到会话中并继续您的工作流程。
bot.command('start', checkIfPrivate, async (ctx) => {
ctx.session.groupId = ctx.match;
await ctx.reply('...');
await ctx.reply('Write the event name:');
});
希望这有帮助!