发送图片

本章代码在04/发送图片分支。

消息类型枚举

// src/types/mod.rs

pub enum MsgType {
    Text(String),
    Photo(String),
}

使用消息类型枚举标识不同的消息

// src/handler/mod.rs

pub async fn hook(
    Json(payload): Json<Update>,
    Extension(state): Extension<AppState>,
) -> Result<String> {
    // ..

    let msg_text = payload.message.text.unwrap_or("".to_string());

    let msg_type = match msg_text.as_str() {
        "/website" => MsgType::Text(command::website()),
        "/logo" => MsgType::Photo(command::logo()),
        _ => MsgType::Text(echo(msg_text.clone())),
    };

    let res = match msg_type {
        MsgType::Text(reply_msg) => {
            bot::send_text_message(&state.bot.token, payload.message.chat.id, reply_msg).await
        }
        MsgType::Photo(reply_msg) => {
            bot::send_photo_message(&state.bot.token, payload.message.chat.id, reply_msg).await
        }
    }
    .map_err(log_error(msg_text));

    // ..
}

对于不同的指令,我们将其映射到不同的消息类型。然后通过消息类型来调用不同的 API,实现消息的发送。

调用发送图片消息的 API

// src/bot.rs

pub async fn send_photo_message(token: &str, chat_id: u64, photo: String) -> Result<Response> {
    let data = request::PhotoMessage { chat_id, photo };
    invoke_api(&data, "sendPhoto", token).await
}

这里使用了 request::PhotoMessage,我们还没定义它。

定义 PhotoMessage

// src/types/request.rs

#[derive(Serialize, Debug)]
pub struct PhotoMessage {
    pub chat_id: u64,
    pub photo: String,
}

定义 command::logo()

// src/handler/command.rs

pub fn logo() -> String {
    "https://axum.rs/static/img/logo.png".to_string()
}

Telegram 支持多种方式发送图片。我们使用的是直接返回一个有效的图片的 URL,其它方式还有:使用 Telegram 服务器上已存在的图片以及从本地上传。详细信息请参见官方文档。

要查看完整内容,请先登录