12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
+
-
-
+
+
-
+
-
-
+
+
|
use sedregex::ReplaceCommand;
use stacked_errors::{
Result,
StackableErr,
bail,
};
use tgbot::types::{
CallbackQuery,
ChatMember,
ChatUsername,
GetChat,
GetChatAdministrators,
Message,
};
use url::Url;
lazy_static! {
static ref RE_USERNAME: Regex = Regex::new(r"^@([a-zA-Z][a-zA-Z0-9_]+)$").unwrap();
static ref RE_IV_HASH: Regex = Regex::new(r"^[a-f0-9]{14}$").unwrap();
}
/// Sends an informational message to the message's chat linking to the bot help channel.
pub async fn start (core: &Core, msg: &Message) -> Result<()> {
core.tg.send(MyMessage::text_to(
"We are open\\. Probably\\. Visit [channel](https://t.me/rsstg_bot_help/3) for details\\.",
core.tg.send(MyMessage::html_to(
"We are open. Probably. Visit <a href=\"https://t.me/rsstg_bot_help/3\">channel</a>) for details.",
msg.chat.get_id()
)).await.stack()?;
Ok(())
}
/// Send the sender's subscription list to the chat.
///
/// Retrieves the message sender's user ID, obtains their subscription list from `core`,
/// and sends the resulting reply into the message chat using MarkdownV2.
pub async fn list (core: &Core, msg: &Message) -> Result<()> {
let sender = msg.sender.get_user_id()
.stack_err("Ignoring unreal users.")?;
let reply = core.list(sender).await.stack()?;
core.tg.send(MyMessage::text_to(reply, msg.chat.get_id())).await.stack()?;
core.tg.send(MyMessage::html_to(reply, msg.chat.get_id())).await.stack()?;
Ok(())
}
pub async fn test (core: &Core, msg: &Message) -> Result<()> {
let sender: i64 = msg.sender.get_user_id()
.stack_err("Ignoring unreal users.")?.into();
let feeds = core.get_feeds(sender).await.stack()?;
let kb = get_kb(&Callback::list("", 0), feeds).await.stack()?;
core.tg.send(MyMessage::html_to_kb(format!("List of feeds owned by {:?}:", msg.sender.get_user_username()), msg.chat.get_id(), kb)).await.stack()?;
let kb = get_kb(&Callback::menu(), feeds).await.stack()?;
core.tg.send(MyMessage::html_to_kb("Main menu:", msg.chat.get_id(), kb)).await.stack()?;
Ok(())
}
/// Handle channel-management commands that operate on a single numeric source ID.
///
/// This validates that exactly one numeric argument is provided, performs the requested
/// operation (check, clean, enable, delete, disable) against the database or core,
|