Skip to content

事件系统

Luolan.QQBot 提供了一套完整的事件驱动架构。通过订阅不同的事件,你可以处理 QQ 频道的各种情况。

事件订阅方式

有两种方式订阅事件:

方式一:快捷属性(推荐)

QQBotClient 实例上直接订阅:

csharp
bot.OnAtMessageCreate += async e =>
{
    await bot.ReplyAsync(e.Message, "收到!");
};

方式二:EventDispatcher

通过 bot.Events 访问完整的事件分发器:

csharp
bot.Events.OnAtMessageCreate += async e =>
{
    // 处理逻辑
};

两种方式效果完全相同。快捷属性只是 EventDispatcher 的代理。

事件分类

消息事件

事件触发时机需要 Intents
OnAtMessageCreate频道中 @机器人(公域)PublicGuildMessages
OnMessageCreate频道中任意消息(私域)GuildMessages
OnDirectMessageCreate频道私信DirectMessage
OnGroupAtMessageCreate群聊中 @机器人GroupAtMessages
OnC2CMessageCreateC2C 私聊C2CMessages
csharp
// 公域 @消息
bot.OnAtMessageCreate += async e =>
{
    var msg = e.Message;
    var content = msg.Content;     // 消息内容
    var author = msg.Author;       // 发送者(User 对象)
    var channelId = msg.ChannelId; // 子频道 ID
    var guildId = msg.GuildId;     // 频道 ID

    if (content?.Trim() == "你好")
        await bot.ReplyAsync(msg, "你好呀!");
};

// 群 @消息
bot.OnGroupAtMessageCreate += async e =>
{
    var msg = e.Message;
    var groupId = msg.GroupOpenId; // 群 OpenId

    await bot.ReplyGroupAsync(msg, "收到群消息!");
};

// C2C 私聊消息
bot.OnC2CMessageCreate += async e =>
{
    await bot.ReplyC2CAsync(e.Message, "这是私聊回复");
};

频道事件

事件触发时机
OnGuildCreate机器人被加入频道
OnGuildDelete机器人被移出频道
csharp
bot.OnGuildCreate += async e =>
{
    Console.WriteLine($"加入新频道: {e.Guild.Name} ({e.Guild.Id})");
};

bot.OnGuildDelete += async e =>
{
    Console.WriteLine($"离开频道: {e.Guild.Id}");
};

成员事件

事件触发时机
OnGuildMemberAdd新成员加入频道
OnGuildMemberRemove成员离开频道
csharp
bot.OnGuildMemberAdd += async e =>
{
    var member = e.Member;
    Console.WriteLine($"{member.User?.Username} 加入 {e.GuildId}");
};

bot.OnGuildMemberRemove += async e =>
{
    Console.WriteLine($"{e.Member.User?.Username} 离开 {e.GuildId}");
};

群事件

事件触发时机
OnGroupAddRobot机器人被拉入群
OnGroupDelRobot机器人被移出群
csharp
bot.OnGroupAddRobot += async e =>
{
    Console.WriteLine($"被拉入群: {e.GroupOpenId}, 操作人: {e.OpMemberOpenId}");
};

bot.OnGroupDelRobot += async e =>
{
    Console.WriteLine($"被移出群: {e.GroupOpenId}");
};

好友事件

事件触发时机
OnFriendAdd用户添加机器人为好友
OnFriendDel用户删除机器人好友
csharp
bot.OnFriendAdd += async e =>
{
    Console.WriteLine($"新好友: {e.OpenId}");
};

互动事件

事件触发时机
OnInteractionCreate用户点击按钮
csharp
bot.OnInteractionCreate += async e =>
{
    var interaction = e.Interaction;
    var buttonId = interaction.Data?.Resolved?.ButtonId;

    if (buttonId == "confirm_btn")
    {
        Console.WriteLine($"用户 {interaction.UserOpenId} 点击了确认按钮");
        // 处理确认逻辑...
    }
};

连接事件

事件触发时机
OnReadyWebSocket 连接成功,机器人上线
csharp
bot.OnReady += async e =>
{
    Console.WriteLine($"机器人已上线!");
    Console.WriteLine($"  版本: {e.Version}");
    Console.WriteLine($"  用户: {e.User?.Username}");
    Console.WriteLine($"  会话ID: {e.SessionId}");
};

EventDispatcher 中的更多事件

以下事件只能通过 bot.Events 访问(没有对应的快捷属性):

事件说明
OnMessageDelete消息被删除
OnGuildUpdate频道信息更新
OnChannelCreate子频道创建
OnChannelUpdate子频道更新
OnChannelDelete子频道删除
OnGuildMemberUpdate成员信息更新
OnMessageReactionAdd表情表态添加
OnMessageReactionRemove表情表态移除
OnMessageAuditPass消息审核通过
OnMessageAuditReject消息审核拒绝
OnAudioStart / OnAudioFinish音频开始/结束
OnForumThreadCreate / OnForumThreadUpdate / OnForumThreadDelete论坛帖子事件
OnForumPostCreate / OnForumPostDelete论坛评论事件
OnResumedWebSocket 会话恢复
OnRawEvent原始事件(所有事件的底层入口)
csharp
// 访问 EventDispatcher 中的事件
bot.Events.OnMessageReactionAdd += async e =>
{
    Console.WriteLine($"{e.UserId} 对消息 {e.Target?.Id} 点了 {e.Emoji?.Id}");
};

// 原始事件 —— 所有事件的入口
bot.Events.OnRawEvent += async (eventType, data, eventId) =>
{
    // 调试用途
    Console.WriteLine($"[RAW] {eventType}: {data}");
};

Intents —— 事件开关

重要: 只有订阅了对应 Intents 才能收到事件。这类似 Discord Bot 的 Intents 机制。

csharp
var bot = new QQBotClientBuilder()
    .WithIntents(
        Intents.Default              // 公域基本事件
        | Intents.GroupAtMessages    // 群 @消息
        | Intents.C2CMessages        // C2C 私聊
        | Intents.GuildMessages      // 频道全量消息(私域权限)
        | Intents.Interaction        // 按钮互动回调
        | Intents.MessageAudit       // 消息审核
    )
    .Build();

完整 Intents 列表

Intent说明
None0不订阅任何事件
Guilds1 (1<<0)频道创建/更新/删除
GuildMembers2 (1<<1)成员加入/离开/更新
GuildMessages512 (1<<9)频道全量消息(私域)
GuildMessageReactions1024 (1<<10)表情表态事件
DirectMessage4096 (1<<12)频道私信事件
GroupAtMessages1<<25群 @消息
C2CMessages1<<25C2C 私聊消息
Interaction1<<26按钮互动回调
MessageAudit1<<27消息审核事件
Forums1<<28论坛事件
AudioAction1<<29音频事件
PublicGuildMessages1<<30公域 @消息
Default-Guilds | GuildMembers | PublicGuildMessages | GuildMessageReactions | DirectMessage | Interaction | MessageAudit
PrivateAll-Default + GuildMessages + Forums + AudioAction

只订阅需要的事件

订阅过多不需要的 Intents 会增加不必要的网络流量和处理开销。 ::

完整事件处理示例

csharp
using Luolan.QQBot.Events;

// 连接
bot.OnReady += OnReady;
// 消息
bot.OnAtMessageCreate += OnAtMessage;
bot.OnGroupAtMessageCreate += OnGroupMessage;
bot.OnC2CMessageCreate += OnC2CMessage;
// 成员
bot.OnGuildMemberAdd += OnMemberJoin;
bot.OnGuildMemberRemove += OnMemberLeave;
// 互动
bot.OnInteractionCreate += OnInteraction;

async Task OnReady(ReadyEvent e)
{
    Console.WriteLine($"上线: {e.User?.Username}");
}

async Task OnAtMessage(AtMessageCreateEvent e)
{
    var msg = e.Message;
    if (msg.Content?.Trim() == "/ping")
        await bot.ReplyAsync(msg, "pong!");
}

async Task OnGroupMessage(GroupAtMessageCreateEvent e)
{
    await bot.ReplyGroupAsync(e.Message, "群消息已收到");
}

async Task OnC2CMessage(C2CMessageCreateEvent e)
{
    await bot.ReplyC2CAsync(e.Message, "私聊消息已收到");
}

async Task OnMemberJoin(GuildMemberAddEvent e)
{
    Console.WriteLine($"欢迎新成员: {e.Member.User?.Username}");
}

async Task OnMemberLeave(GuildMemberRemoveEvent e)
{
    Console.WriteLine($"成员离开: {e.Member.User?.Username}");
}

async Task OnInteraction(InteractionCreateEvent e)
{
    var btnId = e.Interaction.Data?.Resolved?.ButtonId;
    Console.WriteLine($"按钮点击: {btnId}");
}

下一步

基于 MIT 协议发布