
Telegram Bot API 不直接提供 UserJoined 或 UserLeft 布尔字段;实际通过 NewChatMembers 和 LeftChatMember 字段以用户列表形式传递事件,需正确解析结构体并判空处理。
telegram bot api 不直接提供 `userjoined` 或 `userleft` 布尔字段;实际通过 `newchatmembers` 和 `leftchatmember` 字段以用户列表形式传递事件,需正确解析结构体并判空处理。
在使用 telebot(v2)开发 Telegram 机器人时,用户加入群组(user_joined)或离开群组(user_left)并非通过布尔标志触发,而是由 Telegram 服务端以特定消息类型推送:
- ✅ 用户加入 → 消息中包含非空的 message.NewChatMembers 切片(类型为 []*tb.User);
- ✅ 用户离开 → 消息中 message.LeftChatMember 字段为非 nil 的 *tb.User(注意:仅当用户主动退出或被踢出时触发;机器人被移除时也可能收到此字段);
- ❌ message.UserJoined 并非 telebot v2 的有效字段 —— 你看到的错误 invalid operation: message.UserJoined == true (mismatched types telebot.User and bool) 正是因为旧版文档或误读源码导致:该字段在早期 fork 或非标准分支中可能存在,但官方 tucnak/telebot v2 已弃用该命名,统一使用 NewChatMembers 和 LeftChatMember。
✅ 正确监听方式(telebot v2 示例)
package main
import (
"log"
"gopkg.in/tucnak/telebot.v2"
)
func main() {
bot, err := tb.NewBot(tb.Settings{
Token: "YOUR_BOT_TOKEN",
Poller: &tb.LongPoller{Timeout: 10 * time.Second},
})
if err != nil {
log.Fatal(err)
}
// 监听所有消息(含系统事件)
bot.Handle(tb.OnText, func(m *tb.Message) {
// 用户加入:检查 NewChatMembers 是否非空
if len(m.NewChatMembers) > 0 {
for _, user := range m.NewChatMembers {
log.Printf("? 用户加入群组: %s (@%s)", user.FirstName, user.Username)
_, _ = bot.Send(m.Chat,
fmt.Sprintf("欢迎 %s 加入群组!?",
tb.Me(user).FirstNameOr("新朋友")),
&tb.SendOptions{ParseMode: tb.ModeHTML})
}
}
// 用户离开:检查 LeftChatMember 是否非 nil
if m.LeftChatMember != nil {
log.Printf("? 用户离开群组: %s (@%s)",
m.LeftChatMember.FirstName, m.LeftChatMember.Username)
_, _ = bot.Send(m.Chat,
fmt.Sprintf("很遗憾,%s 已离开群组。",
tb.Me(m.LeftChatMember).FirstNameOr("这位用户")),
&tb.SendOptions{DisableNotification: true})
}
})
bot.Start()
}⚠️ 注意事项
- 仅限群组/频道生效:NewChatMembers 和 LeftChatMember 仅在超级群组(supergroup)或频道中可靠触发;普通群组(basic group)支持有限,且 Telegram 可能因隐私设置不发送某些事件(如用户开启“隐藏加入/离开通知”)。
- Bot 权限要求:确保机器人在目标群组中拥有 can_invite_users 权限(非必需),但更重要的是 必须启用「群组权限」中的 “All Members” 可见性(即 Bot 需为管理员或至少能接收系统消息)。
- 避免重复响应:NewChatMembers 是切片,可能一次加入多人(如批量邀请),务必遍历处理;LeftChatMember 恒为单个用户。
- 空值安全:始终用 len(m.NewChatMembers) > 0 或 m.LeftChatMember != nil 判定,切勿使用 m.UserJoined == true 等不存在字段。
✅ 总结
不要依赖虚构的 UserJoined 布尔字段 —— 它在标准 telebot v2 中不存在。请始终检查:
- m.NewChatMembers([]*tb.User)→ 用户加入;
- m.LeftChatMember(*tb.User)→ 用户离开。
结合日志调试与结构体打印(如 log.Printf("%+v", m)),可快速验证事件是否到达及字段状态,大幅提升开发效率。


















