use std::collections::HashMap;
use reqwest::Method;
use serde::{Deserialize, Serialize};
use crate::core::{
config::Config,
constants::AccessTokenType,
request_executor::RequestExecutor,
req_option::RequestOption,
api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
SDKResult,
};
pub struct ModernMessageService {
pub config: Config,
}
impl ModernMessageService {
pub async fn create_message_modern(
&self,
receive_id_type: &str,
body: CreateMessageRequestBody,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<Message>> {
let mut query_params = HashMap::new();
query_params.insert("receive_id_type", receive_id_type.to_string());
RequestExecutor::execute(
&self.config,
Method::POST,
"/open-apis/im/v1/messages",
vec![AccessTokenType::Tenant, AccessTokenType::User],
Some(query_params),
Some(body),
option,
)
.await
}
pub async fn create_message_simple(
&self,
receive_id_type: &str,
body: CreateMessageRequestBody,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<Message>> {
let path = format!("/open-apis/im/v1/messages?receive_id_type={}", receive_id_type);
RequestExecutor::json_request(&self.config, Method::POST, &path, &body, option).await
}
pub async fn list_messages_modern(
&self,
container_id: &str,
container_id_type: &str,
start_time: Option<&str>,
end_time: Option<&str>,
page_token: Option<&str>,
page_size: Option<i32>,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<ListMessageRespData>> {
let mut query_params = HashMap::new();
query_params.insert("container_id", container_id.to_string());
query_params.insert("container_id_type", container_id_type.to_string());
if let Some(start) = start_time {
query_params.insert("start_time", start.to_string());
}
if let Some(end) = end_time {
query_params.insert("end_time", end.to_string());
}
if let Some(token) = page_token {
query_params.insert("page_token", token.to_string());
}
if let Some(size) = page_size {
query_params.insert("page_size", size.to_string());
}
RequestExecutor::query_request(
&self.config,
"/open-apis/im/v1/messages",
Some(query_params),
option,
)
.await
}
pub async fn get_message_by_id(
&self,
message_id: &str,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<Message>> {
let path_params = HashMap::from([("message_id", message_id)]);
RequestExecutor::execute_with_path_params(
&self.config,
Method::GET,
"/open-apis/im/v1/messages/{message_id}",
path_params,
vec![AccessTokenType::Tenant, AccessTokenType::User],
None,
None::<()>,
option,
)
.await
}
pub async fn delete_message(
&self,
message_id: &str,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<EmptyResponse>> {
let path_params = HashMap::from([("message_id", message_id)]);
RequestExecutor::execute_with_path_params(
&self.config,
Method::DELETE,
"/open-apis/im/v1/messages/{message_id}",
path_params,
vec![AccessTokenType::Tenant, AccessTokenType::User],
None,
None::<()>,
option,
)
.await
}
pub async fn update_message(
&self,
message_id: &str,
body: UpdateMessageRequestBody,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<Message>> {
let path_params = HashMap::from([("message_id", message_id)]);
RequestExecutor::execute_with_path_params(
&self.config,
Method::PUT,
"/open-apis/im/v1/messages/{message_id}",
path_params,
vec![AccessTokenType::Tenant, AccessTokenType::User],
None,
Some(body),
option,
)
.await
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateMessageRequestBody {
pub receive_id: String,
pub msg_type: String,
pub content: String,
pub uuid: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct UpdateMessageRequestBody {
pub content: String,
pub msg_type: String,
}
#[derive(Debug, Deserialize)]
pub struct Message {
pub message_id: String,
pub root_id: Option<String>,
pub parent_id: Option<String>,
pub thread_id: Option<String>,
pub msg_type: String,
pub create_time: String,
pub update_time: String,
pub deleted: bool,
pub updated: bool,
pub chat_id: String,
pub sender: MessageSender,
pub body: MessageBody,
}
#[derive(Debug, Deserialize)]
pub struct MessageSender {
pub id: String,
pub id_type: String,
pub sender_type: String,
pub tenant_key: String,
}
#[derive(Debug, Deserialize)]
pub struct MessageBody {
pub content: String,
}
#[derive(Debug, Deserialize)]
pub struct ListMessageRespData {
pub has_more: bool,
pub page_token: Option<String>,
pub items: Vec<Message>,
}
#[derive(Debug, Deserialize)]
pub struct EmptyResponse {}
impl ApiResponseTrait for Message {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
impl ApiResponseTrait for ListMessageRespData {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
impl ApiResponseTrait for EmptyResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use crate::core::config::Config;
#[tokio::test]
async fn test_modern_message_service_api() {
let config = Config::default(); let service = ModernMessageService { config };
let body = CreateMessageRequestBody {
receive_id: "ou_test123".to_string(),
msg_type: "text".to_string(),
content: r#"{"text":"Hello, World!"}"#.to_string(),
uuid: Some("test-uuid".to_string()),
};
println!("Modern API example:");
println!("service.create_message_modern('open_id', body, None).await");
}
}
pub struct BulkMessageOperations;
impl BulkMessageOperations {
pub async fn send_bulk_messages(
config: &Config,
messages: Vec<(String, CreateMessageRequestBody)>, option: Option<RequestOption>,
) -> Vec<SDKResult<BaseResponse<Message>>> {
let mut results = Vec::new();
for (receive_id_type, body) in messages {
let mut query_params = HashMap::new();
query_params.insert("receive_id_type", receive_id_type);
let result = RequestExecutor::execute(
config,
Method::POST,
"/open-apis/im/v1/messages",
vec![AccessTokenType::Tenant, AccessTokenType::User],
Some(query_params),
Some(body),
option.clone(),
)
.await;
results.push(result);
}
results
}
}