xmtp_api_d14n/protocol/extractors/
group_message_metadata.rs1use chrono::DateTime;
2use xmtp_proto::{
3 mls_v1::group_message::Version,
4 types::{Cursor, GroupId, GroupMessageMetadata},
5};
6
7use crate::protocol::{
8 EnvelopeError, EnvelopeVisitor, Extractor, GroupMessageExtractor, ProtocolEnvelope,
9};
10
11#[derive(Default, Clone)]
13pub struct MessageMetadataExtractor {
14 metadata: Vec<Option<GroupMessageMetadata>>,
15}
16
17impl MessageMetadataExtractor {
18 pub fn new() -> Self {
19 Default::default()
20 }
21}
22
23impl Extractor for MessageMetadataExtractor {
24 type Output = Vec<Option<GroupMessageMetadata>>;
25
26 fn get(self) -> Self::Output {
27 self.metadata
28 }
29}
30
31impl EnvelopeVisitor<'_> for MessageMetadataExtractor {
32 type Error = EnvelopeError;
33
34 fn visit_newest_envelope_response(
35 &mut self,
36 response: &xmtp_proto::xmtp::xmtpv4::message_api::get_newest_envelope_response::Response,
37 ) -> Result<(), Self::Error> {
38 let message_metadata = if let Some(envelope) = &response.originator_envelope {
39 let mut extractor = GroupMessageExtractor::default();
40 envelope.accept(&mut extractor)?;
41 let group_message = extractor.get()?;
42 Some(
43 GroupMessageMetadata::builder()
44 .created_ns(group_message.created_ns)
45 .cursor(group_message.cursor)
46 .group_id(group_message.group_id)
47 .build()?,
48 )
49 } else {
50 None
51 };
52
53 self.metadata.push(message_metadata);
54
55 Ok(())
56 }
57
58 fn visit_v3_group_message(
59 &mut self,
60 v1_message: &xmtp_proto::xmtp::mls::api::v1::group_message::V1,
61 ) -> Result<(), Self::Error> {
62 let cursor = if v1_message.is_commit {
63 Cursor::mls_commits(v1_message.id)
64 } else {
65 Cursor::v3_messages(v1_message.id)
66 };
67
68 let group_id: GroupId = v1_message.group_id.clone().into();
69
70 let metadata = GroupMessageMetadata::builder()
71 .created_ns(DateTime::from_timestamp_nanos(v1_message.created_ns as i64))
72 .cursor(cursor)
73 .group_id(group_id)
74 .build()?;
75
76 self.metadata.push(Some(metadata));
77
78 Ok(())
79 }
80
81 fn visit_newest_group_message_response(
82 &mut self,
83 response: &xmtp_proto::xmtp::mls::api::v1::get_newest_group_message_response::Response,
84 ) -> Result<(), Self::Error> {
85 if let Some(xmtp_proto::mls_v1::GroupMessage {
86 version: Some(Version::V1(v1_message)),
87 }) = &response.group_message
88 {
89 self.visit_v3_group_message(v1_message)?
90 } else {
91 self.metadata.push(None)
92 }
93
94 Ok(())
95 }
96}