本章继续完善我们的机器人。收到用户的/logo
指令,我们需要把我们的 LOGO 图片发送给用户。让我们来看看如何让 Telegram 机器人发送图片信息。
由于发送图片消息和前一章说的发送文本消息的 API 不一样,所以我们需要对不同类型的消息进行识别,而 Rust 强大的枚举类型能让我们很容易的实现。
消息类型枚举
// src/types/mod.rs
pub enum MsgType {
Text(String),
Photo(String),
}
有了消息类型枚举,我们在 hook 中判断出不同指令后,就可以使用这个枚举进行标识、处理了。
使用消息类型枚举标识不同的消息
// 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 调用函数。
调用发送图片消息的 API
这里使用了 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 服务器上已存在的图片以及从本地上传。详细信息请参见官方文档。