use open_lark::prelude::*;
use std::env;
use tracing::{info, warn};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let app_id = env::var("LARK_APP_ID").expect("LARK_APP_ID must be set");
let app_secret = env::var("LARK_APP_SECRET").expect("LARK_APP_SECRET must be set");
let _client = LarkClient::builder(&app_id, &app_secret)
.with_app_type(AppType::SelfBuild)
.build();
info!("đ Starting Lark Event Handler Example");
info!("This example demonstrates how to handle various Lark/Feishu events");
let _dispatcher = create_event_dispatcher()
.await
.map_err(|e| anyhow::anyhow!("Failed to create dispatcher: {}", e))?;
info!("â
Event dispatcher created successfully");
info!("đ Event handlers registered for:");
info!(" âĸ IM Events: Message received, recalled, chat created/updated/disbanded, member added/removed");
info!(" âĸ Contact Events: User created/updated/deleted, department created/updated/deleted");
info!(" âĸ Drive Events: File created/updated/deleted");
info!(" âĸ Calendar Events: Event created");
info!(" âĸ VC Events: Meeting started/ended, participant joined/left");
info!(" âĸ Approval Events: Instance created/approved/rejected");
info!("đ¯ Event dispatcher is ready to handle incoming events!");
info!("đĄ To use this in your application:");
info!(" 1. Establish a WebSocket connection to Lark");
info!(" 2. When you receive an event, call dispatcher.dispatch(payload)");
info!(" 3. Your registered event handlers will be executed automatically");
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
info!("đ Example completed successfully");
Ok(())
}
async fn create_event_dispatcher() -> Result<EventDispatcherHandler, String> {
let mut dispatcher = EventDispatcherHandler::builder();
info!("đ§ Registering IM event handlers...");
dispatcher = dispatcher.register_p2_im_message_receive_v1(|event| {
info!(
"đ¨ Message received: {} from {}",
event.event.message.content, event.event.sender.sender_id.user_id
);
})?;
dispatcher = dispatcher.register_p2_im_message_recalled_v1(|event| {
warn!(
"âŠī¸ Message recalled: {} by {}",
event.event.message_id,
event
.event
.operator
.operator_id
.user_id
.unwrap_or_else(|| "".to_string())
);
})?;
dispatcher = dispatcher.register_p2_im_chat_created_v1(|event| {
info!(
"đŦ New chat created: {} by {}",
event.event.name.unwrap_or("Unnamed chat".to_string()),
event
.event
.creator
.user_id
.user_id
.unwrap_or_else(|| "".to_string())
);
})?;
dispatcher = dispatcher.register_p2_im_chat_updated_v1(|event| {
info!("đ Chat updated: {}", event.event.chat_id);
})?;
dispatcher = dispatcher.register_p2_im_chat_disbanded_v1(|event| {
warn!(
"â Chat disbanded: {} by {}",
event.event.chat_id,
event
.event
.operator
.operator_id
.user_id
.unwrap_or_else(|| "".to_string())
);
})?;
dispatcher = dispatcher.register_p2_im_chat_member_user_added_v1(|event| {
info!(
"â Member added to chat {}: {} users",
event.event.chat_id,
event.event.users.len()
);
})?;
dispatcher = dispatcher.register_p2_im_chat_member_user_deleted_v1(|event| {
info!(
"â Member removed from chat {}: {} users",
event.event.chat_id,
event.event.users.len()
);
})?;
info!("đ§ Registering Contact event handlers...");
dispatcher = dispatcher.register_p2_contact_user_created_v3(|event| {
info!(
"đ¤ New user created: {} ({})",
event
.event
.object
.user
.name
.unwrap_or_else(|| "Unknown".to_string()),
event.event.object.user.user_id
);
})?;
dispatcher = dispatcher.register_p2_contact_user_updated_v3(|event| {
info!("đ User updated: {}", event.event.object.user.user_id);
})?;
dispatcher = dispatcher.register_p2_contact_user_deleted_v3(|event| {
warn!("đī¸ User deleted: {}", event.event.object.user.user_id);
})?;
dispatcher = dispatcher.register_p2_contact_department_created_v3(|event| {
info!(
"đĸ Department created: {} ({})",
event.event.object.department.name, event.event.object.department.department_id
);
})?;
dispatcher = dispatcher.register_p2_contact_department_updated_v3(|event| {
info!(
"đ Department updated: {}",
event.event.object.department.department_id
);
})?;
dispatcher = dispatcher.register_p2_contact_department_deleted_v3(|event| {
warn!(
"đī¸ Department deleted: {}",
event.event.object.department.department_id
);
})?;
info!("đ§ Registering Drive event handlers...");
dispatcher = dispatcher.register_p2_drive_file_created_v1(|event| {
info!(
"đ File created: {} ({})",
event.event.object.file.name, event.event.object.file.file_token
);
})?;
dispatcher = dispatcher.register_p2_drive_file_updated_v1(|event| {
info!("đ File updated: {}", event.event.object.file.file_token);
})?;
dispatcher = dispatcher.register_p2_drive_file_deleted_v1(|event| {
warn!(
"đī¸ File deleted: {} ({})",
event.event.object.file.name, event.event.object.file.file_token
);
})?;
info!("đ§ Registering Calendar event handlers...");
dispatcher = dispatcher.register_p2_calendar_event_created_v4(|event| {
info!(
"đ
Calendar event created: {} at {}",
event.event.object.calendar_event.summary,
event
.event
.object
.calendar_event
.start_time
.timestamp
.unwrap_or_else(|| "".to_string())
);
})?;
info!("đ§ Registering VC event handlers...");
dispatcher = dispatcher.register_p2_vc_meeting_started_v1(|event| {
info!(
"đĨ Meeting started: {} hosted by {}",
event.event.object.meeting.topic,
event
.event
.object
.meeting
.host
.display_name
.unwrap_or_else(|| "Unknown".to_string())
);
})?;
dispatcher = dispatcher.register_p2_vc_meeting_ended_v1(|event| {
info!(
"đ Meeting ended: {} (Duration: {} seconds)",
event.event.object.meeting.topic,
event.event.object.meeting.duration.unwrap_or(0)
);
})?;
dispatcher = dispatcher.register_p2_vc_meeting_participant_joined_v1(|event| {
info!(
"đ Participant joined meeting {}: {}",
event.event.object.meeting.meeting_id,
event
.event
.object
.participant
.display_name
.unwrap_or_else(|| "Unknown".to_string())
);
})?;
dispatcher = dispatcher.register_p2_vc_meeting_participant_left_v1(|event| {
info!(
"đ Participant left meeting {}: {} (Duration: {} seconds)",
event.event.object.meeting.meeting_id,
event
.event
.object
.participant
.display_name
.unwrap_or_else(|| "Unknown".to_string()),
event.event.object.participant.total_duration.unwrap_or(0)
);
})?;
info!("đ§ Registering Approval event handlers...");
dispatcher = dispatcher.register_p2_approval_instance_created_v4(|event| {
info!(
"đ Approval instance created: {} by {}",
event
.event
.object
.instance
.approval_name
.unwrap_or_else(|| "Unknown".to_string()),
event.event.object.instance.user_id
);
})?;
dispatcher = dispatcher.register_p2_approval_instance_approved_v4(|event| {
info!(
"â
Approval instance approved: {} ({})",
event
.event
.object
.instance
.approval_name
.unwrap_or_else(|| "Unknown".to_string()),
event.event.object.instance.instance_id
);
})?;
dispatcher = dispatcher.register_p2_approval_instance_rejected_v4(|event| {
warn!(
"â Approval instance rejected: {} ({})",
event
.event
.object
.instance
.approval_name
.unwrap_or_else(|| "Unknown".to_string()),
event.event.object.instance.instance_id
);
})?;
info!("â
All event handlers registered successfully!");
Ok(dispatcher.build())
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_event_dispatcher_creation() {
let result = create_event_dispatcher().await;
assert!(result.is_ok(), "Event dispatcher creation should succeed");
}
#[test]
fn test_event_handler_completeness() {
let implemented_events = vec![
"p2_im_message_receive_v1",
"p2_im_message_recalled_v1",
"p2_im_chat_created_v1",
"p2_im_chat_updated_v1",
"p2_im_chat_disbanded_v1",
"p2_im_chat_member_user_added_v1",
"p2_im_chat_member_user_deleted_v1",
"p2_contact_user_created_v3",
"p2_contact_user_updated_v3",
"p2_contact_user_deleted_v3",
"p2_contact_department_created_v3",
"p2_contact_department_updated_v3",
"p2_contact_department_deleted_v3",
"p2_drive_file_created_v1",
"p2_drive_file_updated_v1",
"p2_drive_file_deleted_v1",
"p2_calendar_event_created_v4",
"p2_vc_meeting_started_v1",
"p2_vc_meeting_ended_v1",
"p2_vc_meeting_participant_joined_v1",
"p2_vc_meeting_participant_left_v1",
"p2_approval_instance_created_v4",
"p2_approval_instance_approved_v4",
"p2_approval_instance_rejected_v4",
];
assert_eq!(
implemented_events.len(),
20,
"We should have 20 implemented events"
);
println!(
"Successfully implemented {} events",
implemented_events.len()
);
}
}