From 76983ce76b224ae043dc6bc65a94b0c24f6262f7 Mon Sep 17 00:00:00 2001 From: cameronvoell Date: Fri, 10 Jan 2025 16:19:35 -0800 Subject: [PATCH] json deserialization for legacy reactions --- Cargo.lock | 2 ++ xmtp_content_types/Cargo.toml | 2 ++ xmtp_content_types/src/reaction.rs | 16 ++++++++++++++++ xmtp_mls/src/groups/mod.rs | 20 +++++++++++++++++--- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fce55ab9e..3ff761b54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7380,6 +7380,8 @@ version = "0.1.0" dependencies = [ "prost", "rand", + "serde", + "serde_json", "thiserror 2.0.6", "tonic", "xmtp_common", diff --git a/xmtp_content_types/Cargo.toml b/xmtp_content_types/Cargo.toml index 2b7c506d1..c3800557f 100644 --- a/xmtp_content_types/Cargo.toml +++ b/xmtp_content_types/Cargo.toml @@ -8,6 +8,8 @@ license.workspace = true thiserror = { workspace = true } prost = { workspace = true, features = ["prost-derive"] } rand = { workspace = true } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } # XMTP/Local xmtp_proto = { workspace = true, features = ["convert"] } diff --git a/xmtp_content_types/src/reaction.rs b/xmtp_content_types/src/reaction.rs index f70b925bc..efd2a5c31 100644 --- a/xmtp_content_types/src/reaction.rs +++ b/xmtp_content_types/src/reaction.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use crate::{CodecError, ContentCodec}; use prost::Message; +use serde::{Deserialize, Serialize}; use xmtp_proto::xmtp::mls::message_contents::{ content_types::ReactionV2, ContentTypeId, EncodedContent, }; @@ -47,6 +48,21 @@ impl ContentCodec for ReactionCodec { } } +#[derive(Debug, Serialize, Deserialize)] +pub struct LegacyReaction { + /// The message ID for the message that is being reacted to + pub reference: String, + /// The inbox ID of the user who sent the message that is being reacted to + #[serde(rename = "referenceInboxId", skip_serializing_if = "Option::is_none")] + pub reference_inbox_id: Option, + /// The action of the reaction ("added" or "removed") + pub action: String, + /// The content of the reaction + pub content: String, + /// The schema of the content ("unicode", "shortcode", or "custom") + pub schema: String, +} + #[cfg(test)] pub(crate) mod tests { #[cfg(target_arch = "wasm32")] diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index d8c4487f8..5d69e9713 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -33,9 +33,10 @@ use openmls::{ }; use openmls_traits::OpenMlsProvider; use prost::Message; +use serde::{Deserialize, Serialize}; use thiserror::Error; use tokio::sync::Mutex; -use xmtp_content_types::reaction::ReactionCodec; +use xmtp_content_types::reaction::{LegacyReaction, ReactionCodec}; use self::device_sync::DeviceSyncError; pub use self::group_permissions::PreconfiguredPolicies; @@ -357,8 +358,21 @@ impl TryFrom for QueryableContentFields { hex::decode(reaction.reference).ok() } (ReactionCodec::TYPE_ID, _) => { - // TODO: Implement JSON deserialization for legacy reaction format - None + // Try to decode the content as UTF-8 string first + if let Ok(decoded_content) = String::from_utf8(content.content) { + tracing::info!("attempting legacy json deserialization: {}", decoded_content); + // Try parsing as canonical JSON format first + if let Ok(reaction) = serde_json::from_str::(&decoded_content) { + hex::decode(reaction.reference).ok() + } else { + tracing::error!("legacy json deserialization failed"); + // If canonical format fails, try legacy format using parameters + None + } + } else { + tracing::error!("utf-8 deserialization failed"); + None + } } _ => None, };