Skip to content
This repository has been archived by the owner on Jun 17, 2023. It is now read-only.

Commit

Permalink
add /toggle_mention command
Browse files Browse the repository at this point in the history
  • Loading branch information
EAimTY committed Oct 29, 2021
1 parent 5e8565d commit bbbc158
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 58 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "bing-dict-telegram-bot"
description = "A Telegram bot uses Bing Dictionary to translate words from Chinese to English or English to Chinese"
version = "0.2.1"
version = "0.2.2"
authors = ["EAimTY <ea.imty@gmail.com>"]
edition = "2021"
readme = "README.md"
Expand Down
239 changes: 182 additions & 57 deletions src/bot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use futures_util::future::BoxFuture;
use std::{collections::HashSet, sync::Arc};
use tgbot::{
longpoll::LongPoll,
methods::SendMessage,
types::{Command, Update, UpdateKind},
methods::{GetMe, SendMessage},
types::{Command, Me, MessageKind, Update, UpdateKind},
webhook::{self, HyperError},
Api, ApiError, Config as ApiConfig, ParseProxyError, UpdateHandler,
Api, ApiError, Config as ApiConfig, ExecuteError, ParseProxyError, UpdateHandler,
};
use thiserror::Error;
use tokio::sync::RwLock;
Expand All @@ -20,28 +20,41 @@ pub async fn run(config: &Config) -> Result<(), Error> {

let api = Api::new(api_config)?;

let bot_info = api.execute(GetMe).await?;

if config.webhook == 0 {
LongPoll::new(api.clone(), Handler::new(api)).run().await;
LongPoll::new(api.clone(), Handler::new(api, bot_info))
.run()
.await;
} else {
webhook::run_server(([0, 0, 0, 0], config.webhook), "/", Handler::new(api)).await?;
webhook::run_server(
([0, 0, 0, 0], config.webhook),
"/",
Handler::new(api, bot_info),
)
.await?;
}

Ok(())
}

struct Context {
api: Api,
bot_username: String,
command_toggle: RwLock<HashSet<i64>>,
mention_toggle: RwLock<HashSet<i64>>,
}

#[derive(Clone)]
struct Handler(Arc<Context>);

impl Handler {
fn new(api: Api) -> Self {
fn new(api: Api, bot_info: Me) -> Self {
Self(Arc::new(Context {
api,
bot_username: format!("@{}", bot_info.username),
command_toggle: RwLock::new(HashSet::new()),
mention_toggle: RwLock::new(HashSet::new()),
}))
}
}
Expand All @@ -58,77 +71,187 @@ impl UpdateHandler for Handler {
let chat_id = message.get_chat_id();
let mut result = None;

if text.data.starts_with('/') {
if !text.data.starts_with('/') {
let command_toggle = context.command_toggle.read().await;
if command_toggle.contains(&chat_id) {
let text = text.data.trim();
let mut input = None;

let mention_toggle = context.mention_toggle.read().await;
if mention_toggle.contains(&chat_id)
|| (!matches!(message.kind, MessageKind::Group { .. })
&& !matches!(message.kind, MessageKind::Supergroup { .. }))
{
input = Some(text);
}

if text.starts_with(&context.bot_username) {
input = Some(text[context.bot_username.len()..].trim());
} else if text.ends_with(&context.bot_username) {
input =
Some(text[..text.len() - context.bot_username.len()].trim());
}

if let Some(input) = input {
if !input.is_empty() {
result = match bing_dict::translate(input).await {
Ok(result) => Some(result.unwrap_or_else(|| {
String::from("No paraphrase found")
})),
Err(err) => {
eprintln!("{}", err);
return;
}
};
} else {
result = Some(String::from("No input"));
}
}
}
} else {
if let Ok(command) = Command::try_from(message) {
match command.get_name() {
"/dict" => {
let input =
command.get_message().get_text().unwrap().data[5..].trim();
if !input.is_empty() {
result = match bing_dict::translate(input).await {
Ok(result) => Some(result.unwrap_or_else(|| {
String::from("No paraphrase found")
})),
Err(err) => {
eprintln!("{}", err);
return;
#[derive(PartialEq)]
enum ArgPos {
Left,
Right,
None,
}

let mut pos = ArgPos::None;

if command.get_args().first() == Some(&context.bot_username) {
pos = ArgPos::Left;
} else if command.get_args().last() == Some(&context.bot_username) {
pos = ArgPos::Right;
}

if pos != ArgPos::None
|| (!matches!(
command.get_message().kind,
MessageKind::Group { .. }
) && !matches!(
command.get_message().kind,
MessageKind::Supergroup { .. }
))
{
match command.get_name() {
"/dict" => {
let input;

match pos {
ArgPos::Left => {
input = Some(
command.get_message().get_text().unwrap().data
[5..]
.trim()
.trim_start_matches(&context.bot_username)
.trim(),
)
}
ArgPos::Right => {
input = Some(
command.get_message().get_text().unwrap().data
[5..]
.trim()
.trim_end_matches(&context.bot_username)
.trim(),
)
}
ArgPos::None => {
input = Some(
command.get_message().get_text().unwrap().data
[5..]
.trim(),
)
}
}

if let Some(input) = input {
if !input.is_empty() {
result = match bing_dict::translate(input).await {
Ok(result) => {
Some(result.unwrap_or_else(|| {
String::from("No paraphrase found")
}))
}
Err(err) => {
eprintln!("{}", err);
return;
}
};
} else {
result = Some(String::from("No input"));
}
};
}
}
}
"/toggle" => {
let mut command_toggle = context.command_toggle.write().await;
if command_toggle.insert(chat_id) {
result = Some(String::from("OK. I will translate all non-command messages you send"));
} else {
command_toggle.remove(&chat_id);
result = Some(String::from("OK. I will only translate the words after the /dict command"));

"/toggle_command" => {
let mut command_toggle =
context.command_toggle.write().await;
if command_toggle.insert(chat_id) {
result = Some(String::from("Okay. I will translate all non-command messages you send"));
} else {
command_toggle.remove(&chat_id);
result = Some(String::from("OK. I will only translate the words after the /dict command"));
}
}
}
"/start" => {
result = Some(String::from(
r#"

"/toggle_mention" => {
if matches!(
command.get_message().kind,
MessageKind::Group { .. }
) || matches!(
command.get_message().kind,
MessageKind::Supergroup { .. }
) {
let mut mention_toggle =
context.mention_toggle.write().await;
if mention_toggle.insert(chat_id) {
result = Some(String::from("Okay. Now you don't need to @ me to trigger a non-command message translation anymore"));
} else {
mention_toggle.remove(&chat_id);
result = Some(String::from("Fine. I will only react to non-command messages that mentioned me"));
}
} else {
result = Some(String::from("This is not a group chat"));
}
}

"/start" => {
result = Some(String::from(
r#"
This is a Telegram bot uses Bing Dictionary to translate words from Chinese to English or English to Chinese.
/dict [word] - translate a word
/toggle - toggle translate-all-messages mode for current chat
Use "/help" to get more information.
"#,
));
}
"/about" => {
result = Some(String::from(
r#"
));
}

"/about" => {
result = Some(String::from(
r#"
A Telegram bot uses Bing Dictionary to translate words from Chinese to English or English to Chinese.
https://github.com/EAimTY/bing-dict-telegram-bot
"#,
));
}
"/help" => {
result = Some(String::from(
r#"
));
}

"/help" => {
result = Some(String::from(
r#"
/dict [word] - translate a word
/toggle - toggle translate-all-messages mode for current chat
/about - About this bot
/help - Get this help message
"#,
));
}
_ => {}
}
}
} else {
let command_toggle = context.command_toggle.read().await;
if command_toggle.contains(&chat_id) {
result = match bing_dict::translate(&text.data).await {
Ok(result) => Some(
result.unwrap_or_else(|| String::from("No paraphrase found")),
),
Err(err) => {
eprintln!("{}", err);
return;
));
}

_ => {}
}
}
}
Expand All @@ -151,6 +274,8 @@ pub enum Error {
#[error(transparent)]
Api(#[from] ApiError),
#[error(transparent)]
Execute(#[from] ExecuteError),
#[error(transparent)]
Hyper(#[from] HyperError),
#[error(transparent)]
ParseProxy(#[from] ParseProxyError),
Expand Down

0 comments on commit bbbc158

Please sign in to comment.