Skip to content

Commit

Permalink
[Telegram] Update the live online message if title changed
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed Apr 15, 2024
1 parent 1f42eb6 commit 81c3972
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 12 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ clap = { version = "4.4.16", features = ["derive"] }
const_format = "0.2.32"
headless_chrome = "1.0.9"
humantime-serde = "1.1.1"
itertools = "0.12.1"
once_cell = "1.19.0"
reqwest = { version = "0.11.23", features = ["json", "gzip"] }
scraper = "0.18.1"
Expand Down
98 changes: 86 additions & 12 deletions src/notify/telegram/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
use std::{borrow::Cow, fmt, fmt::Write, future::Future, ops::Range, pin::Pin};
use std::{
borrow::Cow,
collections::VecDeque,
fmt::{self, Write},
future::Future,
ops::Range,
pin::Pin,
};

use anyhow::{anyhow, bail};
use serde::{de::IgnoredAny, Deserialize};
Expand Down Expand Up @@ -176,8 +183,8 @@ impl Notifier {
NotificationKind::LiveOnline(live_status) => {
self.notify_live(live_status, notification.source).await
}
NotificationKind::LiveTitle(live_status, old_title) => {
self.notify_live_title(live_status, old_title, notification.source)
NotificationKind::LiveTitle(live_status, _old_title) => {
self.notify_live_title(live_status, notification.source)
.await
}
NotificationKind::Posts(posts) => self.notify_posts(posts, notification.source).await,
Expand All @@ -201,16 +208,17 @@ impl Notifier {
}
}

fn make_live_caption(
fn make_live_caption<'a>(
&self,
title_history: impl IntoIterator<Item = &'a String>,
live_status: &LiveStatus,
source: &StatusSource,
) -> (String, Vec<json::Value>) {
let caption = format!(
"[{}] {} {}",
source.platform_name,
if live_status.online { "🟢" } else { "🟠" },
live_status.title
itertools::join(title_history, " ⬅️ "),
);
let caption_entities = vec![json!({
"type": "text_link",
Expand All @@ -228,7 +236,9 @@ impl Notifier {
) -> anyhow::Result<()> {
let token = self.token()?;

let (caption, caption_entities) = self.make_live_caption(live_status, source);
let title_history = VecDeque::from([live_status.title.clone()]);
let (caption, caption_entities) =
self.make_live_caption(&title_history, live_status, source);

let body = json!(
{
Expand Down Expand Up @@ -268,6 +278,7 @@ impl Notifier {
*self.last_live_message.lock().await = Some(SentMessage {
// The doc guarantees `result` to be present if `ok` == `true`
id: resp.result.unwrap().message_id,
title_history,
});

Ok(())
Expand All @@ -281,7 +292,8 @@ impl Notifier {
if let Some(last_live_message) = self.last_live_message.lock().await.take() {
let token = self.token()?;

let (caption, caption_entities) = self.make_live_caption(live_status, source);
let (caption, caption_entities) =
self.make_live_caption(&last_live_message.title_history, live_status, source);

let body = json!(
{
Expand Down Expand Up @@ -323,19 +335,27 @@ impl Notifier {
async fn notify_live_title(
&self,
live_status: &LiveStatus,
old_title: &str,
source: &StatusSource,
) -> anyhow::Result<()> {
// Update the last message
self.notify_live_title_update(live_status, source).await?;

// Send a new message
if !self.params.notifications.live_title {
info!("live_title notification is disabled, skip notifying");
return Ok(());
}
self.notify_live_title_send(live_status, source).await
}

async fn notify_live_title_send(
&self,
live_status: &LiveStatus,
source: &StatusSource,
) -> anyhow::Result<()> {
let token = self.token()?;

let text = format!(
"[{}] ✏️ {} ⬅️ {old_title}",
source.platform_name, live_status.title
);
let text = format!("[{}] ✏️ {}", source.platform_name, live_status.title);
let body = json!(
{
"chat_id": telegram_chat_json(&self.params.chat),
Expand Down Expand Up @@ -380,6 +400,58 @@ impl Notifier {
Ok(())
}

async fn notify_live_title_update(
&self,
live_status: &LiveStatus,
source: &StatusSource,
) -> anyhow::Result<()> {
if let Some(last_live_message) = self.last_live_message.lock().await.as_mut() {
let token = self.token()?;

last_live_message
.title_history
.push_front(live_status.title.clone());

let (caption, caption_entities) =
self.make_live_caption(&last_live_message.title_history, live_status, source);

let body = json!(
{
"chat_id": telegram_chat_json(&self.params.chat),
"message_id": last_live_message.id,
"caption": caption,
"caption_entities": caption_entities
}
);
let resp = reqwest::Client::new()
.post(telegram_api(token, "editMessageCaption"))
.json(&body)
.send()
.await
.map_err(|err| anyhow!("failed to send request for Telegram: {err}"))?;

let status = resp.status();
if !status.is_success() {
bail!(
"response from Telegram status is not success. resp: {}, body: {}",
resp.text().await.unwrap_or_else(|_| "*no text*".into()),
body
);
}

let text = resp
.text()
.await
.map_err(|err| anyhow!("failed to obtain text from response of Telegram: {err}"))?;
let resp: Response<ResultMessage> = json::from_str(&text)
.map_err(|err| anyhow!("failed to deserialize response from Telegram: {err}"))?;
if !resp.ok {
bail!("response from Telegram contains error, response '{text}'");
}
}
Ok(())
}

async fn notify_posts(
&self,
posts: &PostsRef<'_>,
Expand Down Expand Up @@ -606,4 +678,6 @@ impl Notifier {

struct SentMessage {
id: i64,
// The first is the current title, the last is the oldest title
title_history: VecDeque<String>,
}

0 comments on commit 81c3972

Please sign in to comment.