Skip to main content

wx_sdk/mp/
event.rs

1use roxmltree::{Document, Node};
2
3use crate::{error::SdkError, SdkResult};
4
5use msg_image::ImageMessage;
6use msg_text::TextMessage;
7
8use self::{
9    msg_event::EventMessage, msg_link::LinkMessage, msg_location::LocationMessage,
10    msg_video::VideoMessage, msg_voice::VoiceMessage,
11};
12
13pub mod crypto;
14pub mod msg_event;
15pub mod msg_image;
16pub mod msg_link;
17pub mod msg_location;
18pub mod msg_text;
19pub mod msg_video;
20pub mod msg_voice;
21pub mod signature;
22pub mod xmlutil;
23
24const MSG_TEXT: &'static str = "text";
25const MSG_IMAGE: &'static str = "image";
26const MSG_VOICE: &'static str = "voice";
27const MSG_VIDEO: &'static str = "video";
28const MSG_SHORTVIDEO: &'static str = "shortvideo";
29const MSG_LOCATION: &'static str = "location"; // 地理位置消息
30const MSG_LINK: &'static str = "link";
31const MSG_EVENT: &'static str = "event";
32
33pub trait ReceivedMessageParser {
34    type ReceivedMessage;
35    fn from_xml(node: &Node) -> SdkResult<Self::ReceivedMessage>;
36}
37
38pub struct ReceivedEvent {
39    pub from: String,
40
41    pub to: String,
42
43    pub create_time: u64,
44
45    pub msg_type: String,
46
47    pub body: ReceivedMessage,
48}
49
50pub enum ReceivedMessage {
51    UnhandledMessage(String),
52    Text(TextMessage),
53    Image(ImageMessage),
54    Voice(VoiceMessage),
55    Video(VideoMessage),
56    ShortVideo(VideoMessage),
57    Location(LocationMessage),
58    Link(LinkMessage),
59    Event(EventMessage),
60}
61
62impl ReceivedEvent {
63    pub fn parse(input: &str) -> SdkResult<Self> {
64        let xml = Document::parse(input)?;
65        let root = xml.root();
66        let msg_type = root
67            .descendants()
68            .find(|n| n.has_tag_name("MsgType"))
69            .map(|n| n.text())
70            .flatten()
71            .ok_or_else(|| SdkError::InvalidParams("parse xml need `MsgType` params".to_owned()))?;
72        let from = root
73            .descendants()
74            .find(|n| n.has_tag_name("FromUserName"))
75            .map(|n| n.text())
76            .flatten()
77            .ok_or_else(|| {
78                SdkError::InvalidParams("parse xml need `FromUserName` params".to_owned())
79            })?;
80        let to = root
81            .descendants()
82            .find(|n| n.has_tag_name("ToUserName"))
83            .map(|n| n.text())
84            .flatten()
85            .ok_or_else(|| {
86                SdkError::InvalidParams("parse xml need `ToUserName` params".to_owned())
87            })?;
88        let create_time = root
89            .descendants()
90            .find(|n| n.has_tag_name("CreateTime"))
91            .map(|n| n.text())
92            .flatten()
93            .ok_or_else(|| {
94                SdkError::InvalidParams("parse xml need CreateTime params".to_owned())
95            })?;
96        let create_time = create_time.parse::<u64>().map_err(|_e| {
97            SdkError::InvalidParams(
98                "Parse XML msg from wechat error: tag `CreateTime` should be number".to_string(),
99            )
100        })?;
101
102        let body = match msg_type {
103            MSG_TEXT => ReceivedMessage::Text(TextMessage::from_xml(&root)?),
104            MSG_IMAGE => ReceivedMessage::Image(ImageMessage::from_xml(&root)?),
105            MSG_VOICE => ReceivedMessage::Voice(VoiceMessage::from_xml(&root)?),
106            MSG_VIDEO | MSG_SHORTVIDEO => {
107                if msg_type == MSG_VIDEO {
108                    ReceivedMessage::Video(VideoMessage::from_xml(&root)?)
109                } else {
110                    ReceivedMessage::ShortVideo(VideoMessage::from_xml(&root)?)
111                }
112            }
113            MSG_LOCATION => ReceivedMessage::Location(LocationMessage::from_xml(&root)?),
114            MSG_LINK => ReceivedMessage::Link(LinkMessage::from_xml(&root)?),
115            MSG_EVENT => ReceivedMessage::Event(EventMessage::from_xml(&root)?),
116            _ => ReceivedMessage::UnhandledMessage(format!(
117                "Havent' handle for this message type `{}`",
118                msg_type
119            )),
120        };
121        Ok(ReceivedEvent {
122            from: from.to_owned(),
123            to: to.to_owned(),
124            msg_type: msg_type.to_owned(),
125            create_time,
126            body,
127        })
128    }
129}