use serde_json::{json, Value};
use crate::error::ImError;
use crate::outbound::registry::{require_str, OutboundCommand, OutboundRegistration};
struct MemberRoleCommand;
impl OutboundCommand for MemberRoleCommand {
fn name(&self) -> &'static str {
"im_channel_member_role"
}
fn build(&self, args: &Value) -> Result<(&'static str, Value), ImError> {
let channel_id = require_str(args, "channel_id", self.name())?;
let user_ids = args
.get("user_ids")
.and_then(Value::as_array)
.filter(|a| !a.is_empty() && a.iter().all(Value::is_string))
.cloned()
.map(Value::Array)
.ok_or_else(|| {
ImError::Parse(format!("{}: 缺/空 user_ids(非空字符串数组)", self.name()))
})?;
let role = require_str(args, "role", self.name())?;
if !matches!(role, "ADMIN" | "MEMBER") {
return Err(ImError::Parse(format!(
"{}: role 必须是 ADMIN/MEMBER",
self.name()
)));
}
Ok((
"channel/member/change/role",
json!({ "channelId": channel_id, "userIds": user_ids, "role": role }),
))
}
}
static MEMBER_ROLE: MemberRoleCommand = MemberRoleCommand;
inventory::submit! {
OutboundRegistration {
name: "im_channel_member_role",
command: &MEMBER_ROLE,
}
}
struct MemberNotifyCommand;
impl OutboundCommand for MemberNotifyCommand {
fn name(&self) -> &'static str {
"im_channel_member_notify"
}
fn build(&self, args: &Value) -> Result<(&'static str, Value), ImError> {
let channel_id = require_str(args, "channel_id", self.name())?;
let notify = args
.get("notify")
.and_then(Value::as_str)
.filter(|value| matches!(*value, "NORMAL" | "STRONG" | "IGNORE"))
.ok_or_else(|| {
ImError::Parse(format!(
"{}: notify 必须是 NORMAL/STRONG/IGNORE",
self.name()
))
})?;
Ok((
"channel/member/change/notify",
json!({ "channelId": channel_id, "notify": notify }),
))
}
}
static MEMBER_NOTIFY: MemberNotifyCommand = MemberNotifyCommand;
inventory::submit! {
OutboundRegistration {
name: "im_channel_member_notify",
command: &MEMBER_NOTIFY,
}
}