xmtp_api_d14n/protocol/extractors/
group_message_metadata.rs

1use 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/// Extractor for converting GetNewestEnvelopeResponse results to GroupMessage responses
12#[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}