From f0649f74c1a4f356455831936343db4fc2f05af7 Mon Sep 17 00:00:00 2001 From: hitalin Date: Sun, 28 Jun 2026 03:19:56 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20roleAssigned=20=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E3=81=AB=20role=20=E6=83=85=E5=A0=B1=E3=82=92=E5=90=AB?= =?UTF-8?q?=E3=82=81=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Misskey の roleAssigned 通知に含まれる role (ロール情報) を RawNotification / NormalizedNotification に追加し、正規化で伝播する。 これまで捨てられていたためフロントでロール名を表示できなかった。 既存の specta 対応 UserRole 型を再利用。 Co-Authored-By: Claude Opus 4.8 --- src/api.rs | 35 +++++++++++++++++++++++++++++++++++ src/models.rs | 6 ++++++ 2 files changed, 41 insertions(+) diff --git a/src/api.rs b/src/api.rs index 03a3422..efaa19d 100644 --- a/src/api.rs +++ b/src/api.rs @@ -2851,6 +2851,41 @@ mod tests { assert_eq!(notifs[0].reaction.as_deref(), Some(":star:")); } + #[tokio::test] + async fn get_notifications_parses_role_assigned() { + let server = MockServer::start().await; + Mock::given(method("POST")) + .and(path("/api/i/notifications")) + .respond_with(ResponseTemplate::new(200).set_body_json(json!([{ + "id": "notif1", + "createdAt": "2025-01-01T00:00:00.000Z", + "type": "roleAssigned", + "role": { + "id": "role1", + "name": "Active", + "color": "#ff0000", + "iconUrl": "https://example.com/role.png", + "description": "active users", + "displayOrder": 0, + "isModerator": false + } + }]))) + .mount(&server) + .await; + + let client = MisskeyClient::with_base_url(&server.uri()); + let notifs = client + .get_notifications("h", "token", "acc1", TimelineOptions::default()) + .await + .unwrap(); + assert_eq!(notifs.len(), 1); + assert_eq!(notifs[0].notification_type, "roleAssigned"); + let role = notifs[0].role.as_ref().expect("role present"); + assert_eq!(role.name, "Active"); + assert_eq!(role.color.as_deref(), Some("#ff0000")); + assert_eq!(role.icon_url.as_deref(), Some("https://example.com/role.png")); + } + #[tokio::test] async fn search_notes_parses() { let server = MockServer::start().await; diff --git a/src/models.rs b/src/models.rs index a859968..c619649 100644 --- a/src/models.rs +++ b/src/models.rs @@ -366,6 +366,9 @@ pub struct NormalizedNotification { /// Grouped users (for renote:grouped type) #[serde(skip_serializing_if = "Option::is_none")] pub users: Option>, + /// Assigned role (for roleAssigned type) + #[serde(skip_serializing_if = "Option::is_none")] + pub role: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -1154,6 +1157,8 @@ pub struct RawNotification { pub reactions: Option>, /// Grouped users (for renote:grouped type from notifications-grouped API) pub users: Option>, + /// Assigned role (for roleAssigned type) + pub role: Option, } #[derive(Debug, Deserialize)] @@ -1508,6 +1513,7 @@ impl RawNotification { users: self .users .map(|us| us.into_iter().map(Into::into).collect()), + role: self.role, } } }