1
iBugOne 304 天前 via Android
这个功能叫 Inline Keyboard [1](不知道 TG 怎么起的这么个名字),你提供一系列 buttons ,每个 button 带上不同的 callback_data ,用户点击某个按钮的时候,你的 bot 就会收到一条 callback query [2]
[1]: https://core.telegram.org/bots/features#inline-keyboards [2]: https://core.telegram.org/bots/api#callbackquery P.S. 可以邮件发我支付宝口令红包的口令 |
2
forQ 304 天前
button1 = Button.url('1', 'https://www.baidu.com')
button2 = Button.url('2', 'https://www.google.com') button3 = Button.url('3', 'https://www.facebook.com') button = [[button1, button2], [button3]] |
3
coinbase 304 天前
可以个用户加个状态
|
4
mapleisaac 304 天前
用中国手机好像收不到验证码了.
|
5
killerzhangsan OP @iBugOne 这个我知道。最后一步,用户输入信息后,怎样知道他点击的是哪个按钮?
|
6
SingeeKing 304 天前
@killerzhangsan 那就得自己维护上下文了
|
7
drymonfidelia 304 天前
@killerzhangsan 你发消息的时候给每个按钮起个名字,点击事件里就会带上用户点的按钮的这个名字,你就可以知道是哪个按钮了
|
8
iBugOne 304 天前 via Android
@killerzhangsan Telegram 没有提供这个功能,你需要自己搞个数据库记录这个状态。反正每个用户就一个对话,而且私聊的 chat_id 就是 user_id ,也不会太麻烦
|
9
killerzhangsan OP @drymonfidelia 没有懂我的意思。callback query 都实现完了。现在是我不知道他更改的是点击编辑 name 或者编辑 about 后,用户输入内容,到底是修改 name 还是 about,没有找到怎么关联上下文
|
10
vacuitym 304 天前
@killerzhangsan 点之后去后台发个请求标识下他要改什么?然后准备接收那个数据
|
11
446ENzu91KZ73A33 304 天前
@killerzhangsan 点编辑 name 返回一个提示比如"请输入新名称",然后强制用户自动回复这个提示,bot 收到消息可能根据 replay_message 里面内容匹配,如果匹配到是"请输入新名称",就是修改名称
|
12
killerzhangsan OP @iBugOne 只能自己做么,每个用户维护一个操作集合。每次用户给 bot 发送消息的时候,都要先去数据库查询一下?好低效。
|
13
killerzhangsan OP @mu666 怎么个强制法?
|
14
killerzhangsan OP @mu666 强制它必须使用消息转发? bot father 这也没有强制哦
|
15
446ENzu91KZ73A33 304 天前
@killerzhangsan python 的 telegram 库里面 send_message 有个 reply_markup 等于 ForceReply(selective=True)),这样收到消息就会自动引用(回复),你可以试下。之前是这样,不知道现在还能不能了
|
16
446ENzu91KZ73A33 304 天前
@killerzhangsan 强制回复你的提示信息,才能知道他回的是哪个消息,点的哪个选项啊
|
17
446ENzu91KZ73A33 304 天前
@killerzhangsan 也不能说是强制,就是用 bot 发消息给用户,会自动 replay 那条消息。用户要是自己主动点叉掉,就是没了,
|
18
446ENzu91KZ73A33 304 天前
@mu666 也不能说是强制,就是加了那个之后用 bot 发消息给用户,用户那边会自动 replay 那条消息。用户要是自己主动点叉掉,就是没了,
|
19
killerzhangsan OP @mu666 嗯。你这应该是最接近 bot father 功能的实现。虽然 bot father 这里没有所谓的强制回复。
等我晚上回去试试,成功后就兑现,不白嫖。 |
20
446ENzu91KZ73A33 304 天前
@killerzhangsan 可以,大佬要是需要 bot 开发,也可以留 tg 号我加你
|
21
GooMS 304 天前 via Android
这个做个会话就好了,热门库看文档基本都有
|
22
killerzhangsan OP @GooMS 比如说那个库来做会话? java 有么?会话怎么关联到对应的按钮?
|
23
drymonfidelia 304 天前
@killerzhangsan 我知道你的意思了,在数据库里存用户最后一次点的按钮名字啊,不想用数据库就用 redis
微信公众号也是这么开发的 |
24
WordTian 304 天前
@killerzhangsan CallbackQuery 里面有个 data 字段,这个字段的值就是你自定义按钮时写的 callback_data 的值
https://docs.python-telegram-bot.org/en/v13.2/telegram.callbackquery.html#telegram.CallbackQuery.data |
25
killerzhangsan OP @WordTian 不是这个问题。看上面回复。
|
26
drymonfidelia 304 天前
@killerzhangsan botfather 100%也是这么做的,每次点击按钮的时候把用户 id 字段和 callback_data 随便找个地方存起来,每次收到文字消息的时候检查是否有存起来的 callback_data ,有就进行对应操作,然后把存起来的 callback_data 删掉。为了防止用户很久以前点的按钮忘记了,通常还要存一个点击时间,超过一段时间就废弃。
|
27
y1y1 304 天前
难道是我理解能力有问题,看不懂你的描述
|
28
devliu1 303 天前 via Android
从 im 的角度,没必要帮你管理上下文。自己管理是正解,存个 redis 或者内存,带 ttl ,没那么麻烦
|
29
icoming 303 天前
确实要靠自己维护当前输入的状态。比如用户绑定 uuid ,点击"绑定"按钮后,服务端保存当前操作为"waiting_for_uuid",接下来的输入就是绑定 uuid 。
对应的 golang 代码如下: ```go var ( // 在状态管理中跟踪用户的操作状态。 以 chatID 为键,存储用户状态 usersState = make(map[int64]string) ) // 用户状态的值 const ( stateWaitUUID = "waiting_for_uuid" ) // ... for update := range updates { if update.Message == nil { continue } logger.Info.Printf("%s [%s] %s", tag, update.Message.From.UserName, update.Message.Text) switch update.Message.Text { case "/bind": // 处理用户绑定逻辑 // 更新用户操作状态为“等待 UUID” usersState[update.Message.Chat.ID] = stateWaitUUID reply := "😘 请输入您的 UUID" sendMessage(reply, update.Message.Chat.ID) case "/queryflow": // 处理查询流量逻辑 handleQuery(update.Message) default: // 如果用户状态为等待 UUID ,则获取输入文本作为 UUID if state, ok := usersState[update.Message.Chat.ID]; ok && state == stateWaitUUID { // 在这里处理绑定逻辑,将 uuid 存储到数据库或进行其他操作 handleBinding(update.Message) // 清除用户状态 delete(usersState, update.Message.Chat.ID) break } // 处理其他文本消息 msg := "😪 请通过菜单选择操作" sendMessage(msg, update.Message.Chat.ID) } } ``` |
30
icoming 303 天前
@killerzhangsan "bot father 这里没有所谓的强制回复",是因为你执行了其它命令,服务端更新了新的状态。详细可以看我上面的代码
|
31
icoming 303 天前
另外,这玩意用 GPT4 会非常容易实现。。
|