Some checks failed
BotServer CI / build (push) Failing after 1m34s
Split 20+ files over 1000 lines into focused subdirectories for better maintainability and code organization. All changes maintain backward compatibility through re-export wrappers. Major splits: - attendance/llm_assist.rs (2074→7 modules) - basic/keywords/face_api.rs → face_api/ (7 modules) - basic/keywords/file_operations.rs → file_ops/ (8 modules) - basic/keywords/hear_talk.rs → hearing/ (6 modules) - channels/wechat.rs → wechat/ (10 modules) - channels/youtube.rs → youtube/ (5 modules) - contacts/mod.rs → contacts_api/ (6 modules) - core/bootstrap/mod.rs → bootstrap/ (5 modules) - core/shared/admin.rs → admin_*.rs (5 modules) - designer/canvas.rs → canvas_api/ (6 modules) - designer/mod.rs → designer_api/ (6 modules) - docs/handlers.rs → handlers_api/ (11 modules) - drive/mod.rs → drive_handlers.rs, drive_types.rs - learn/mod.rs → types.rs - main.rs → main_module/ (7 modules) - meet/webinar.rs → webinar_api/ (8 modules) - paper/mod.rs → (10 modules) - security/auth.rs → auth_api/ (7 modules) - security/passkey.rs → (4 modules) - sources/mod.rs → sources_api/ (5 modules) - tasks/mod.rs → task_api/ (5 modules) Stats: 38,040 deletions, 1,315 additions across 318 files Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
92 lines
2.7 KiB
Rust
92 lines
2.7 KiB
Rust
pub use crate::core::bot::channels::instagram::*;
|
|
|
|
use crate::core::shared::state::AppState;
|
|
use axum::{
|
|
extract::{Query, State},
|
|
http::StatusCode,
|
|
response::IntoResponse,
|
|
routing::{get, post},
|
|
Json, Router,
|
|
};
|
|
use serde::Deserialize;
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct WebhookVerifyQuery {
|
|
#[serde(rename = "hub.mode")]
|
|
pub mode: Option<String>,
|
|
#[serde(rename = "hub.verify_token")]
|
|
pub verify_token: Option<String>,
|
|
#[serde(rename = "hub.challenge")]
|
|
pub challenge: Option<String>,
|
|
}
|
|
|
|
pub fn configure() -> Router<Arc<AppState>> {
|
|
Router::new()
|
|
.route(
|
|
"/api/instagram/webhook",
|
|
get(verify_webhook).post(handle_webhook),
|
|
)
|
|
.route("/api/instagram/send", post(send_message))
|
|
}
|
|
|
|
async fn verify_webhook(Query(query): Query<WebhookVerifyQuery>) -> impl IntoResponse {
|
|
let adapter = InstagramAdapter::new();
|
|
|
|
match (
|
|
query.mode.as_deref(),
|
|
query.verify_token.as_deref(),
|
|
query.challenge,
|
|
) {
|
|
(Some(mode), Some(token), Some(challenge)) => adapter
|
|
.handle_webhook_verification(mode, token, &challenge)
|
|
.map_or_else(
|
|
|| (StatusCode::FORBIDDEN, "Verification failed".to_string()),
|
|
|response| (StatusCode::OK, response),
|
|
),
|
|
_ => (StatusCode::BAD_REQUEST, "Missing parameters".to_string()),
|
|
}
|
|
}
|
|
|
|
async fn handle_webhook(
|
|
State(_state): State<Arc<AppState>>,
|
|
Json(payload): Json<InstagramWebhookPayload>,
|
|
) -> impl IntoResponse {
|
|
for entry in payload.entry {
|
|
if let Some(messaging_list) = entry.messaging {
|
|
for messaging in messaging_list {
|
|
if let Some(message) = messaging.message {
|
|
if let Some(text) = message.text {
|
|
log::info!(
|
|
"Instagram message from={} text={}",
|
|
messaging.sender.id,
|
|
text
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StatusCode::OK
|
|
}
|
|
|
|
async fn send_message(
|
|
State(_state): State<Arc<AppState>>,
|
|
Json(request): Json<serde_json::Value>,
|
|
) -> impl IntoResponse {
|
|
let adapter = InstagramAdapter::new();
|
|
let recipient = request.get("to").and_then(|v| v.as_str()).unwrap_or("");
|
|
let message = request
|
|
.get("message")
|
|
.and_then(|v| v.as_str())
|
|
.unwrap_or("");
|
|
|
|
match adapter.send_instagram_message(recipient, message).await {
|
|
Ok(_) => (StatusCode::OK, Json(serde_json::json!({"success": true}))),
|
|
Err(e) => (
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
Json(serde_json::json!({"success": false, "error": e.to_string()})),
|
|
),
|
|
}
|
|
}
|