Skip to main content

aster/auto_reply/
message.rs

1//! 消息和结果类型
2//!
3//! 定义入站消息、触发结果和触发上下文。
4
5use std::collections::HashMap;
6use std::time::Duration;
7
8use chrono::{DateTime, Utc};
9use serde::{Deserialize, Serialize};
10
11use crate::auto_reply::keyword_matcher::KeywordMatchResult;
12use crate::auto_reply::registry::AutoReplyTrigger;
13use crate::auto_reply::types::TriggerType;
14
15/// 入站消息
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct IncomingMessage {
18    /// 消息 ID
19    pub id: String,
20    /// 发送者 ID
21    pub sender_id: String,
22    /// 发送者名称
23    #[serde(default)]
24    pub sender_name: Option<String>,
25    /// 消息内容
26    pub content: String,
27    /// 渠道类型
28    pub channel: String,
29    /// 群组 ID(如果是群组消息)
30    #[serde(default)]
31    pub group_id: Option<String>,
32    /// 是否是私聊
33    #[serde(default)]
34    pub is_direct_message: bool,
35    /// 是否包含 @提及
36    #[serde(default)]
37    pub mentions_bot: bool,
38    /// 消息时间戳
39    pub timestamp: DateTime<Utc>,
40    /// 附加元数据
41    #[serde(default)]
42    pub metadata: HashMap<String, serde_json::Value>,
43}
44
45/// 拒绝原因
46#[derive(Debug, Clone)]
47pub enum RejectionReason {
48    /// 用户不在白名单
49    NotInWhitelist,
50    /// 在冷却时间内
51    InCooldown { remaining: Duration },
52    /// 群组未激活
53    GroupNotActivated,
54    /// 群组要求 @提及
55    RequiresMention,
56    /// 触发器已禁用
57    TriggerDisabled,
58}
59
60/// 触发上下文
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct TriggerContext {
63    /// 触发器 ID
64    pub trigger_id: String,
65    /// 触发类型
66    pub trigger_type: TriggerType,
67    /// 原始消息
68    pub message: IncomingMessage,
69    /// 匹配详情(关键词匹配时)
70    #[serde(default, skip)]
71    pub match_details: Option<KeywordMatchResult>,
72    /// 触发时间
73    pub triggered_at: DateTime<Utc>,
74    /// 附加数据
75    #[serde(default)]
76    pub extra: HashMap<String, serde_json::Value>,
77}
78
79/// 触发结果
80#[derive(Debug, Clone)]
81pub enum TriggerResult {
82    /// 触发成功
83    Triggered {
84        trigger: Box<AutoReplyTrigger>,
85        context: Box<TriggerContext>,
86    },
87    /// 触发被拒绝
88    Rejected { reason: RejectionReason },
89    /// 无匹配触发器
90    NoMatch,
91}