From 4ae73c3e2b9a660106030f84e06540ef1324b33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 00:25:47 +0100 Subject: initial slack --- src/main.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main.rs (limited to 'src') diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..aef3fa9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,33 @@ +use slack_api as slack; + +#[tokio::main] +async fn main() { + println!("Hello, world!"); + println!("Setting up Slack"); + + let slack_token = std::env::var("SLACK_API_TOKEN").expect("No token"); + let slack_client = slack::default_client().unwrap(); + + let slack_request = slack::rtm::StartRequest::default(); + let response = slack::rtm::start(&slack_client, &slack_token, &slack_request).await; + + if let Ok(response) = response { + if let Some(channels) = response.channels { + let channel_names = channels + .iter() + .filter_map(|c| c.name.as_ref()) + .collect::>(); + println!("Got channels {:?}", channel_names); + } + + if let Some(users) = response.users { + let user_names = users + .iter() + .filter_map(|u| u.name.as_ref()) + .collect::>(); + println!("Got users {:?}", user_names); + } + } else { + println!("{:?}", response) + } +} -- cgit v1.2.1 From 99496d745f70cc0e65bc42df01aecc7483ff1166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 10:28:57 +0100 Subject: initial discord --- src/main.rs | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index aef3fa9..fb1ee99 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,7 @@ +use discord::{ + model::Event, + Discord, +}; use slack_api as slack; #[tokio::main] @@ -5,11 +9,15 @@ async fn main() { println!("Hello, world!"); println!("Setting up Slack"); - let slack_token = std::env::var("SLACK_API_TOKEN").expect("No token"); + let slack_token = std::env::var("SLACK_API_TOKEN") + .unwrap_or("" + .to_string()); let slack_client = slack::default_client().unwrap(); let slack_request = slack::rtm::StartRequest::default(); - let response = slack::rtm::start(&slack_client, &slack_token, &slack_request).await; + let response = slack::rtm::start(&slack_client, + &slack_token, + &slack_request).await; if let Ok(response) = response { if let Some(channels) = response.channels { @@ -30,4 +38,31 @@ async fn main() { } else { println!("{:?}", response) } + + println!("Setting up Discord"); + + let discord_token = std::env::var("DISCORD_API_TOKEN") + .unwrap_or("" + .to_string()); + let discord = Discord::from_bot_token(&discord_token); + + if let Ok(discord) = discord { + let (mut connection, _) = discord.connect() .expect("discord connect failed"); + println!("Discord ready"); + loop { + match connection.recv_event() { + Ok(Event::MessageCreate(message)) => { + println!("{} says: {}", message.author.name, message.content); + } + Ok(_) => {} + Err(discord::Error::Closed(code, body)) => { + println!("Discord closed with code {:?}: {}", code, body); + break; + } + Err(err) => { + println!("Error: {:?}", err); + } + } + } + } } -- cgit v1.2.1 From d5c82532d141e3cd54ab0939b208ffe85cb854ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 10:49:32 +0100 Subject: discord and slack loop --- src/main.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index fb1ee99..962564a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,23 @@ use discord::{ model::Event, Discord, }; +use futures::join; use slack_api as slack; +use tokio::task::spawn_blocking; #[tokio::main] async fn main() { println!("Hello, world!"); + + join!( + spawn_blocking(move || { + discord_loop(); + }), + slack_loop(), + ); +} + +async fn slack_loop() { println!("Setting up Slack"); let slack_token = std::env::var("SLACK_API_TOKEN") @@ -38,7 +50,9 @@ async fn main() { } else { println!("{:?}", response) } +} +fn discord_loop() { println!("Setting up Discord"); let discord_token = std::env::var("DISCORD_API_TOKEN") -- cgit v1.2.1 From ee5bcaa0fa6deb268e5f304600d38d9a67f93f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 11:01:43 +0100 Subject: small refactoring --- src/main.rs | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 962564a..bcc2bab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,28 +8,30 @@ use tokio::task::spawn_blocking; #[tokio::main] async fn main() { + let slack_token: Option = None; + let discord_token: Option = None; + println!("Hello, world!"); join!( spawn_blocking(move || { - discord_loop(); + discord_loop(discord_token); }), - slack_loop(), + slack_loop(slack_token), ); } -async fn slack_loop() { +async fn slack_loop(token: Option) { println!("Setting up Slack"); - let slack_token = std::env::var("SLACK_API_TOKEN") - .unwrap_or("" - .to_string()); - let slack_client = slack::default_client().unwrap(); + let token = std::env::var("SLACK_API_TOKEN") + .unwrap_or(token.unwrap()); + let client = slack::default_client().unwrap(); - let slack_request = slack::rtm::StartRequest::default(); - let response = slack::rtm::start(&slack_client, - &slack_token, - &slack_request).await; + let request = slack::rtm::StartRequest::default(); + let response = slack::rtm::start(&client, + &token, + &request).await; if let Ok(response) = response { if let Some(channels) = response.channels { @@ -52,16 +54,15 @@ async fn slack_loop() { } } -fn discord_loop() { +fn discord_loop(token: Option) { println!("Setting up Discord"); - let discord_token = std::env::var("DISCORD_API_TOKEN") - .unwrap_or("" - .to_string()); - let discord = Discord::from_bot_token(&discord_token); + let token = std::env::var("DISCORD_API_TOKEN") + .unwrap_or(token.unwrap()); + let client = Discord::from_bot_token(&token); - if let Ok(discord) = discord { - let (mut connection, _) = discord.connect() .expect("discord connect failed"); + if let Ok(client) = client { + let (mut connection, _) = client.connect().expect("discord connect failed"); println!("Discord ready"); loop { match connection.recv_event() { -- cgit v1.2.1 From a6fd44ae860ce48b6a7979a2c8b380c11fa7168e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 13:06:56 +0100 Subject: send strings between async --- src/main.rs | 73 +++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index bcc2bab..2b5bb14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,13 @@ use discord::{ }; use futures::join; use slack_api as slack; -use tokio::task::spawn_blocking; +use tokio::{ + sync::mpsc, + task::{ + spawn, + spawn_blocking, + }, +}; #[tokio::main] async fn main() { @@ -13,15 +19,20 @@ async fn main() { println!("Hello, world!"); + let (from_discord, to_slack) = mpsc::unbounded_channel::(); + let (from_slack, to_discord) = mpsc::unbounded_channel::(); + join!( - spawn_blocking(move || { - discord_loop(discord_token); - }), - slack_loop(slack_token), + discord_loop(discord_token, from_discord, to_discord), + slack_loop(slack_token, from_slack, to_slack), ); } -async fn slack_loop(token: Option) { +async fn slack_loop( + token: Option, + sender: mpsc::UnboundedSender, + _receiver: mpsc::UnboundedReceiver, +) { println!("Setting up Slack"); let token = std::env::var("SLACK_API_TOKEN") @@ -39,7 +50,7 @@ async fn slack_loop(token: Option) { .iter() .filter_map(|c| c.name.as_ref()) .collect::>(); - println!("Got channels {:?}", channel_names); + sender.send(format!("Got channels {:?}", channel_names).to_string()).unwrap(); } if let Some(users) = response.users { @@ -47,14 +58,18 @@ async fn slack_loop(token: Option) { .iter() .filter_map(|u| u.name.as_ref()) .collect::>(); - println!("Got users {:?}", user_names); + sender.send(format!("Got users {:?}", user_names).to_string()).unwrap(); } - } else { + } else { //TODO NotAuth etc println!("{:?}", response) } } -fn discord_loop(token: Option) { +async fn discord_loop( + token: Option, + _sender: mpsc::UnboundedSender, + mut receiver: mpsc::UnboundedReceiver, +) { println!("Setting up Discord"); let token = std::env::var("DISCORD_API_TOKEN") @@ -62,22 +77,32 @@ fn discord_loop(token: Option) { let client = Discord::from_bot_token(&token); if let Ok(client) = client { - let (mut connection, _) = client.connect().expect("discord connect failed"); + let (mut connection, _) = client.connect().expect("discord connect failed"); //TODO println!("Discord ready"); - loop { - match connection.recv_event() { - Ok(Event::MessageCreate(message)) => { - println!("{} says: {}", message.author.name, message.content); - } - Ok(_) => {} - Err(discord::Error::Closed(code, body)) => { - println!("Discord closed with code {:?}: {}", code, body); - break; + + let (_, _) = join!( //TODO + spawn_blocking(move || { + loop { + match connection.recv_event() { + Ok(Event::MessageCreate(message)) => { + println!("{} says: {}", message.author.name, message.content); + } + Ok(_) => {} + Err(discord::Error::Closed(code, body)) => { + println!("Discord closed with code {:?}: {}", code, body); + break; + } + Err(err) => { + println!("Error: {:?}", err); + } + } } - Err(err) => { - println!("Error: {:?}", err); + }), + spawn(async move { + while let Some(s) = receiver.recv().await { + println!("Discord received '{}' from slack", s); } - } - } + }) + ); } } -- cgit v1.2.1 From c01c8716de4a91e4c60f61cf0bb6eaeca5cbf619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 13:12:32 +0100 Subject: refactor to new files --- src/discord.rs | 54 ++++++++++++++++++++++++++++++++ src/main.rs | 98 ++++------------------------------------------------------ src/slack.rs | 39 +++++++++++++++++++++++ 3 files changed, 99 insertions(+), 92 deletions(-) create mode 100644 src/discord.rs create mode 100644 src/slack.rs (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs new file mode 100644 index 0000000..06baec6 --- /dev/null +++ b/src/discord.rs @@ -0,0 +1,54 @@ +use discord::{ + model::Event, + Discord, +}; +use futures::join; +use tokio::{ + sync::mpsc, + task::{ + spawn, + spawn_blocking, + }, +}; + +pub async fn handle( + token: Option, + _sender: mpsc::UnboundedSender, + mut receiver: mpsc::UnboundedReceiver, +) { + println!("Setting up Discord"); + + let token = std::env::var("DISCORD_API_TOKEN") + .unwrap_or(token.unwrap()); + let client = Discord::from_bot_token(&token); + + if let Ok(client) = client { + let (mut connection, _) = client.connect().expect("discord connect failed"); //TODO + println!("Discord ready"); + + let (_, _) = join!( //TODO + spawn_blocking(move || { + loop { + match connection.recv_event() { + Ok(Event::MessageCreate(message)) => { + println!("{} says: {}", message.author.name, message.content); + } + Ok(_) => {} + Err(discord::Error::Closed(code, body)) => { + println!("Discord closed with code {:?}: {}", code, body); + break; + } + Err(err) => { + println!("Error: {:?}", err); + } + } + } + }), + spawn(async move { + while let Some(s) = receiver.recv().await { + println!("Discord received '{}' from slack", s); + } + }) + ); + } +} diff --git a/src/main.rs b/src/main.rs index 2b5bb14..9cdd2e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,8 @@ -use discord::{ - model::Event, - Discord, -}; +mod discord; +mod slack; + use futures::join; -use slack_api as slack; -use tokio::{ - sync::mpsc, - task::{ - spawn, - spawn_blocking, - }, -}; +use tokio::sync::mpsc; #[tokio::main] async fn main() { @@ -23,86 +15,8 @@ async fn main() { let (from_slack, to_discord) = mpsc::unbounded_channel::(); join!( - discord_loop(discord_token, from_discord, to_discord), - slack_loop(slack_token, from_slack, to_slack), + discord::handle(discord_token, from_discord, to_discord), + slack::handle(slack_token, from_slack, to_slack), ); } -async fn slack_loop( - token: Option, - sender: mpsc::UnboundedSender, - _receiver: mpsc::UnboundedReceiver, -) { - println!("Setting up Slack"); - - let token = std::env::var("SLACK_API_TOKEN") - .unwrap_or(token.unwrap()); - let client = slack::default_client().unwrap(); - - let request = slack::rtm::StartRequest::default(); - let response = slack::rtm::start(&client, - &token, - &request).await; - - if let Ok(response) = response { - if let Some(channels) = response.channels { - let channel_names = channels - .iter() - .filter_map(|c| c.name.as_ref()) - .collect::>(); - sender.send(format!("Got channels {:?}", channel_names).to_string()).unwrap(); - } - - if let Some(users) = response.users { - let user_names = users - .iter() - .filter_map(|u| u.name.as_ref()) - .collect::>(); - sender.send(format!("Got users {:?}", user_names).to_string()).unwrap(); - } - } else { //TODO NotAuth etc - println!("{:?}", response) - } -} - -async fn discord_loop( - token: Option, - _sender: mpsc::UnboundedSender, - mut receiver: mpsc::UnboundedReceiver, -) { - println!("Setting up Discord"); - - let token = std::env::var("DISCORD_API_TOKEN") - .unwrap_or(token.unwrap()); - let client = Discord::from_bot_token(&token); - - if let Ok(client) = client { - let (mut connection, _) = client.connect().expect("discord connect failed"); //TODO - println!("Discord ready"); - - let (_, _) = join!( //TODO - spawn_blocking(move || { - loop { - match connection.recv_event() { - Ok(Event::MessageCreate(message)) => { - println!("{} says: {}", message.author.name, message.content); - } - Ok(_) => {} - Err(discord::Error::Closed(code, body)) => { - println!("Discord closed with code {:?}: {}", code, body); - break; - } - Err(err) => { - println!("Error: {:?}", err); - } - } - } - }), - spawn(async move { - while let Some(s) = receiver.recv().await { - println!("Discord received '{}' from slack", s); - } - }) - ); - } -} diff --git a/src/slack.rs b/src/slack.rs new file mode 100644 index 0000000..40e465c --- /dev/null +++ b/src/slack.rs @@ -0,0 +1,39 @@ +use slack_api as slack; +use tokio::sync::mpsc; + +pub async fn handle( + token: Option, + sender: mpsc::UnboundedSender, + _receiver: mpsc::UnboundedReceiver, +) { + println!("Setting up Slack"); + + let token = std::env::var("SLACK_API_TOKEN") + .unwrap_or(token.unwrap()); + let client = slack::default_client().unwrap(); + + let request = slack::rtm::StartRequest::default(); + let response = slack::rtm::start(&client, + &token, + &request).await; + + if let Ok(response) = response { + if let Some(channels) = response.channels { + let channel_names = channels + .iter() + .filter_map(|c| c.name.as_ref()) + .collect::>(); + sender.send(format!("Got channels {:?}", channel_names).to_string()).unwrap(); + } + + if let Some(users) = response.users { + let user_names = users + .iter() + .filter_map(|u| u.name.as_ref()) + .collect::>(); + sender.send(format!("Got users {:?}", user_names).to_string()).unwrap(); + } + } else { //TODO NotAuth etc + println!("{:?}", response) + } +} -- cgit v1.2.1 From 2a3eb31fe09152729f80f9329bedfec96c8ebff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 13:17:41 +0100 Subject: send more strings between async --- src/discord.rs | 9 ++++----- src/slack.rs | 9 ++++++--- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index 06baec6..7c469b2 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -13,25 +13,24 @@ use tokio::{ pub async fn handle( token: Option, - _sender: mpsc::UnboundedSender, + sender: mpsc::UnboundedSender, mut receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Discord"); - let token = std::env::var("DISCORD_API_TOKEN") - .unwrap_or(token.unwrap()); + let token = std::env::var("DISCORD_API_TOKEN").unwrap_or(token.unwrap()); let client = Discord::from_bot_token(&token); if let Ok(client) = client { let (mut connection, _) = client.connect().expect("discord connect failed"); //TODO println!("Discord ready"); - let (_, _) = join!( //TODO + let (_, _) = join!( //TODO? spawn_blocking(move || { loop { match connection.recv_event() { Ok(Event::MessageCreate(message)) => { - println!("{} says: {}", message.author.name, message.content); + sender.send(format!("{} says: {}", message.author.name, message.content)).unwrap(); } Ok(_) => {} Err(discord::Error::Closed(code, body)) => { diff --git a/src/slack.rs b/src/slack.rs index 40e465c..9a30b49 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -4,12 +4,11 @@ use tokio::sync::mpsc; pub async fn handle( token: Option, sender: mpsc::UnboundedSender, - _receiver: mpsc::UnboundedReceiver, + mut receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Slack"); - let token = std::env::var("SLACK_API_TOKEN") - .unwrap_or(token.unwrap()); + let token = std::env::var("SLACK_API_TOKEN").unwrap_or(token.unwrap()); let client = slack::default_client().unwrap(); let request = slack::rtm::StartRequest::default(); @@ -36,4 +35,8 @@ pub async fn handle( } else { //TODO NotAuth etc println!("{:?}", response) } + + while let Some(s) = receiver.recv().await { + println!("Slack received '{}' from discord", s); + } } -- cgit v1.2.1 From 07e3d4f5f772080028f86661ed7f6e95f63207b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 13:31:17 +0100 Subject: switch to actual slack rtm api --- src/slack.rs | 73 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/slack.rs b/src/slack.rs index 9a30b49..fb4eece 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -1,42 +1,51 @@ -use slack_api as slack; -use tokio::sync::mpsc; +use futures::join; +use tokio::{ + sync::mpsc, + task::{ + spawn, + spawn_blocking, + }, +}; + +struct Handler; + +impl slack::EventHandler for Handler { + fn on_event(&mut self, _cli: &slack::RtmClient, event: slack::Event) { + println!("on_event: {:#?}", event); + } + + fn on_close(&mut self, _cli: &slack::RtmClient) { + println!("on_close") + } + + fn on_connect(&mut self, _cli: &slack::RtmClient) { + println!("on_connect"); + } +} pub async fn handle( token: Option, - sender: mpsc::UnboundedSender, + _sender: mpsc::UnboundedSender, mut receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Slack"); let token = std::env::var("SLACK_API_TOKEN").unwrap_or(token.unwrap()); - let client = slack::default_client().unwrap(); - - let request = slack::rtm::StartRequest::default(); - let response = slack::rtm::start(&client, - &token, - &request).await; - - if let Ok(response) = response { - if let Some(channels) = response.channels { - let channel_names = channels - .iter() - .filter_map(|c| c.name.as_ref()) - .collect::>(); - sender.send(format!("Got channels {:?}", channel_names).to_string()).unwrap(); - } - if let Some(users) = response.users { - let user_names = users - .iter() - .filter_map(|u| u.name.as_ref()) - .collect::>(); - sender.send(format!("Got users {:?}", user_names).to_string()).unwrap(); - } - } else { //TODO NotAuth etc - println!("{:?}", response) - } - - while let Some(s) = receiver.recv().await { - println!("Slack received '{}' from discord", s); - } + join!( + spawn_blocking(move || { + let mut handler = Handler; + match slack::RtmClient::login_and_run(&token, &mut handler) { + Ok(_) => {} + Err(e) => { + println!("Error: {}", e) + } + } + }), + spawn(async move { + while let Some(s) = receiver.recv().await { + println!("Slack received '{}' from discord", s); + } + }) + ); } -- cgit v1.2.1 From f25e22abe842f51f2f29df1f885caa0939376ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 13:44:26 +0100 Subject: send messages from slack to discord handler --- src/slack.rs | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/slack.rs b/src/slack.rs index fb4eece..564ca76 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -1,4 +1,8 @@ use futures::join; +use slack::{ + Event, + Message, +}; use tokio::{ sync::mpsc, task::{ @@ -7,11 +11,39 @@ use tokio::{ }, }; -struct Handler; +struct Handler { + sender: mpsc::UnboundedSender, +} + +impl Handler { + fn new(sender: mpsc::UnboundedSender) -> Self { + Self { + sender + } + } + + fn sender(&self) -> &mpsc::UnboundedSender { + &self.sender + } +} impl slack::EventHandler for Handler { fn on_event(&mut self, _cli: &slack::RtmClient, event: slack::Event) { println!("on_event: {:#?}", event); + match event { + Event::Message(msg) => { + match *msg { + Message::Standard(msg) => { + self.sender().send(format!("{} says: {}", + msg.user.unwrap_or("??".to_string()), + msg.text.unwrap_or("??".to_string())) + .to_string()).unwrap(); + } + _ => {} + } + } + _ => {} + } } fn on_close(&mut self, _cli: &slack::RtmClient) { @@ -25,7 +57,7 @@ impl slack::EventHandler for Handler { pub async fn handle( token: Option, - _sender: mpsc::UnboundedSender, + sender: mpsc::UnboundedSender, mut receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Slack"); @@ -34,7 +66,7 @@ pub async fn handle( join!( spawn_blocking(move || { - let mut handler = Handler; + let mut handler = Handler::new(sender); match slack::RtmClient::login_and_run(&token, &mut handler) { Ok(_) => {} Err(e) => { -- cgit v1.2.1 From 5cdc929bf8bbf2d09c097e8042eeb0068977442d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 14:08:40 +0100 Subject: send messages to discord channel --- src/discord.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index 7c469b2..62a1f9e 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -1,5 +1,8 @@ use discord::{ - model::Event, + model::{ + ChannelId, + Event, + }, Discord, }; use futures::join; @@ -30,7 +33,11 @@ pub async fn handle( loop { match connection.recv_event() { Ok(Event::MessageCreate(message)) => { - sender.send(format!("{} says: {}", message.author.name, message.content)).unwrap(); + sender.send(format!("{:?}:{} says: {}", + message.channel_id, + message.author.name, + message.content)) + .unwrap(); } Ok(_) => {} Err(discord::Error::Closed(code, body)) => { @@ -46,6 +53,11 @@ pub async fn handle( spawn(async move { while let Some(s) = receiver.recv().await { println!("Discord received '{}' from slack", s); + client.send_message(ChannelId(697057150106599488), //TODO + &s, + "", + false + ); } }) ); -- cgit v1.2.1 From ef5645df28e7cfefe4f0ad65123f48c7df38a8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 14:16:03 +0100 Subject: don't react to our own discord messages --- src/discord.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index 62a1f9e..62e5ee3 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -26,6 +26,7 @@ pub async fn handle( if let Ok(client) = client { let (mut connection, _) = client.connect().expect("discord connect failed"); //TODO + let our_id = client.get_current_user().unwrap().id; println!("Discord ready"); let (_, _) = join!( //TODO? @@ -33,11 +34,13 @@ pub async fn handle( loop { match connection.recv_event() { Ok(Event::MessageCreate(message)) => { - sender.send(format!("{:?}:{} says: {}", - message.channel_id, - message.author.name, - message.content)) - .unwrap(); + if message.author.id != our_id { + sender.send(format!("{:?}:{} says: {}", + message.channel_id, + message.author.name, + message.content)) + .unwrap(); + } } Ok(_) => {} Err(discord::Error::Closed(code, body)) => { -- cgit v1.2.1 From 1fd5df9524f84511b8d22300e5b2aa1fb2063660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 14:55:05 +0100 Subject: minor cleanup --- src/discord.rs | 9 +++++---- src/slack.rs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index 62e5ee3..b6a22ad 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -4,6 +4,7 @@ use discord::{ Event, }, Discord, + Error, }; use futures::join; use tokio::{ @@ -43,19 +44,19 @@ pub async fn handle( } } Ok(_) => {} - Err(discord::Error::Closed(code, body)) => { + Err(Error::Closed(code, body)) => { println!("Discord closed with code {:?}: {}", code, body); break; } - Err(err) => { - println!("Error: {:?}", err); + Err(e) => { + println!("Error: {:?}", e); } } } }), spawn(async move { while let Some(s) = receiver.recv().await { - println!("Discord received '{}' from slack", s); + println!("Discord received '{}'", s); client.send_message(ChannelId(697057150106599488), //TODO &s, "", diff --git a/src/slack.rs b/src/slack.rs index 564ca76..887c1f9 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -76,7 +76,7 @@ pub async fn handle( }), spawn(async move { while let Some(s) = receiver.recv().await { - println!("Slack received '{}' from discord", s); + println!("Slack received '{}'", s); } }) ); -- cgit v1.2.1 From 222acec5e5153d169ae909a8c68b382f01becff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 14:55:18 +0100 Subject: send messages to slack channel --- src/slack.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/slack.rs b/src/slack.rs index 887c1f9..feff430 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -34,7 +34,8 @@ impl slack::EventHandler for Handler { Event::Message(msg) => { match *msg { Message::Standard(msg) => { - self.sender().send(format!("{} says: {}", + self.sender().send(format!("{}:{} says: {}", + msg.channel.unwrap_or("??".to_string()), msg.user.unwrap_or("??".to_string()), msg.text.unwrap_or("??".to_string())) .to_string()).unwrap(); @@ -63,11 +64,16 @@ pub async fn handle( println!("Setting up Slack"); let token = std::env::var("SLACK_API_TOKEN").unwrap_or(token.unwrap()); + let client = spawn_blocking(move || { + slack::RtmClient::login(&token).unwrap() + }).await.unwrap(); + + let slack_sender = client.sender().clone(); join!( spawn_blocking(move || { let mut handler = Handler::new(sender); - match slack::RtmClient::login_and_run(&token, &mut handler) { + match client.run(&mut handler) { Ok(_) => {} Err(e) => { println!("Error: {}", e) @@ -77,6 +83,12 @@ pub async fn handle( spawn(async move { while let Some(s) = receiver.recv().await { println!("Slack received '{}'", s); + //TODO Sending messages is very slow sometimes. Have seen delays + // from 5 up to 20(!) seconds. + slack_sender.send_typing("CPBAA5FA7").unwrap(); + println!("Typing"); + slack_sender.send_message("CPBAA5FA7", &s).unwrap(); + println!("Sent"); } }) ); -- cgit v1.2.1 From f0f616b94ec1778e7f7b84db0a368ea83438faaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 16:07:14 +0100 Subject: refactor spawns to functions --- src/discord.rs | 80 +++++++++++++++++++++++++++++++++------------------------- src/slack.rs | 29 ++++++++++++--------- 2 files changed, 63 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index b6a22ad..c451ad7 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -18,7 +18,7 @@ use tokio::{ pub async fn handle( token: Option, sender: mpsc::UnboundedSender, - mut receiver: mpsc::UnboundedReceiver, + receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Discord"); @@ -26,44 +26,56 @@ pub async fn handle( let client = Discord::from_bot_token(&token); if let Ok(client) = client { - let (mut connection, _) = client.connect().expect("discord connect failed"); //TODO + let (connection, _) = client.connect().expect("Discord connect failed"); //TODO let our_id = client.get_current_user().unwrap().id; println!("Discord ready"); let (_, _) = join!( //TODO? - spawn_blocking(move || { - loop { - match connection.recv_event() { - Ok(Event::MessageCreate(message)) => { - if message.author.id != our_id { - sender.send(format!("{:?}:{} says: {}", - message.channel_id, - message.author.name, - message.content)) - .unwrap(); - } - } - Ok(_) => {} - Err(Error::Closed(code, body)) => { - println!("Discord closed with code {:?}: {}", code, body); - break; - } - Err(e) => { - println!("Error: {:?}", e); - } - } - } - }), - spawn(async move { - while let Some(s) = receiver.recv().await { - println!("Discord received '{}'", s); - client.send_message(ChannelId(697057150106599488), //TODO - &s, - "", - false - ); + spawn_blocking(move || receive_events(our_id, connection, sender)), + spawn(receive_from_slack(receiver, client)) + ); + } +} + +fn receive_events( + our_id: discord::model::UserId, + mut connection: discord::Connection, + sender: mpsc::UnboundedSender +) { + loop { + match connection.recv_event() { + Ok(Event::MessageCreate(message)) => { + if message.author.id != our_id { + sender.send(format!("{:?}:{} says: {}", + message.channel_id, + message.author.name, + message.content)) + .unwrap(); } - }) + } + Ok(_) => {} + Err(Error::Closed(code, body)) => { + println!("Discord closed with code {:?}: {}", code, body); + break; + } + Err(e) => { + println!("Discord error: {:?}", e); + } + } + } +} + +async fn receive_from_slack( + mut receiver: mpsc::UnboundedReceiver, + client: discord::Discord, +) { + while let Some(s) = receiver.recv().await { + println!("Discord received '{}'", s); + client.send_message(ChannelId(697057150106599488), //TODO + &s, + "", + false ); } + } diff --git a/src/slack.rs b/src/slack.rs index feff430..c13fc47 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -59,7 +59,7 @@ impl slack::EventHandler for Handler { pub async fn handle( token: Option, sender: mpsc::UnboundedSender, - mut receiver: mpsc::UnboundedReceiver, + receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Slack"); @@ -80,16 +80,21 @@ pub async fn handle( } } }), - spawn(async move { - while let Some(s) = receiver.recv().await { - println!("Slack received '{}'", s); - //TODO Sending messages is very slow sometimes. Have seen delays - // from 5 up to 20(!) seconds. - slack_sender.send_typing("CPBAA5FA7").unwrap(); - println!("Typing"); - slack_sender.send_message("CPBAA5FA7", &s).unwrap(); - println!("Sent"); - } - }) + spawn(receive_from_discord(receiver, slack_sender)) ); } + +async fn receive_from_discord( + mut receiver: mpsc::UnboundedReceiver, + sender: slack::Sender, +) { + while let Some(s) = receiver.recv().await { + println!("Slack received '{}'", s); + //TODO Sending messages is very slow sometimes. Have seen delays + // from 5 up to 20(!) seconds. + sender.send_typing("CPBAA5FA7").unwrap(); + println!("Typing"); + sender.send_message("CPBAA5FA7", &s).unwrap(); + println!("Sent"); + } +} -- cgit v1.2.1 From 6fbdede8516e6d35afbd032a2ca6fc6ef109b484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 17:31:23 +0100 Subject: send AgendaPoint instead of String between services --- src/agenda.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/discord.rs | 25 +++++++++++++------------ src/main.rs | 7 +++++-- src/slack.rs | 29 +++++++++++++++-------------- 4 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 src/agenda.rs (limited to 'src') diff --git a/src/agenda.rs b/src/agenda.rs new file mode 100644 index 0000000..3cfcfb7 --- /dev/null +++ b/src/agenda.rs @@ -0,0 +1,50 @@ +use serde::{ + Deserialize, + Serialize, +}; +use std::{ + fmt, + fs, +}; + +#[derive(Debug, Deserialize, Serialize)] +pub struct AgendaPoint { + pub title: String, + pub adder: String, +} + +impl fmt::Display for AgendaPoint { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} ({})", self.title, self.adder) + } +} + +impl AgendaPoint { + pub fn to_add_message(&self) -> String { + format!("'{}' added by {}", self.title, self.adder) + } +} + +#[derive(Deserialize, Serialize)] +pub struct Agenda { + points: Vec, +} + +pub fn read_agenda() -> Agenda { + serde_json::from_str::( + &fs::read_to_string("agenda.json") + .expect("Can't read agenda.json")) + .expect("Error parsing agenda.json") +} + +pub fn write_agenda(agenda: Agenda) { + fs::write(std::path::Path::new("agenda.json"), + serde_json::to_string_pretty(&agenda).expect("Can't serialize agenda")) + .expect("Can't write agenda.json"); +} + +pub fn add_point(point: AgendaPoint) { + let mut agenda = read_agenda(); + agenda.points.push(point); + write_agenda(agenda); +} diff --git a/src/discord.rs b/src/discord.rs index c451ad7..e422171 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -1,3 +1,5 @@ +use crate::agenda::AgendaPoint; + use discord::{ model::{ ChannelId, @@ -17,8 +19,8 @@ use tokio::{ pub async fn handle( token: Option, - sender: mpsc::UnboundedSender, - receiver: mpsc::UnboundedReceiver, + sender: mpsc::UnboundedSender, + receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Discord"); @@ -40,17 +42,16 @@ pub async fn handle( fn receive_events( our_id: discord::model::UserId, mut connection: discord::Connection, - sender: mpsc::UnboundedSender + sender: mpsc::UnboundedSender ) { loop { match connection.recv_event() { Ok(Event::MessageCreate(message)) => { if message.author.id != our_id { - sender.send(format!("{:?}:{} says: {}", - message.channel_id, - message.author.name, - message.content)) - .unwrap(); + sender.send(AgendaPoint{ + title: message.content, + adder: message.author.name, + }).unwrap(); } } Ok(_) => {} @@ -66,13 +67,13 @@ fn receive_events( } async fn receive_from_slack( - mut receiver: mpsc::UnboundedReceiver, + mut receiver: mpsc::UnboundedReceiver, client: discord::Discord, ) { - while let Some(s) = receiver.recv().await { - println!("Discord received '{}'", s); + while let Some(point) = receiver.recv().await { + println!("Discord received '{}'", point); client.send_message(ChannelId(697057150106599488), //TODO - &s, + &point.to_add_message(), "", false ); diff --git a/src/main.rs b/src/main.rs index 9cdd2e0..8d8fa5c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ +mod agenda; mod discord; mod slack; +use crate::agenda::AgendaPoint; + use futures::join; use tokio::sync::mpsc; @@ -11,8 +14,8 @@ async fn main() { println!("Hello, world!"); - let (from_discord, to_slack) = mpsc::unbounded_channel::(); - let (from_slack, to_discord) = mpsc::unbounded_channel::(); + let (from_discord, to_slack) = mpsc::unbounded_channel::(); + let (from_slack, to_discord) = mpsc::unbounded_channel::(); join!( discord::handle(discord_token, from_discord, to_discord), diff --git a/src/slack.rs b/src/slack.rs index c13fc47..91705fa 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -1,3 +1,5 @@ +use crate::agenda::AgendaPoint; + use futures::join; use slack::{ Event, @@ -12,17 +14,17 @@ use tokio::{ }; struct Handler { - sender: mpsc::UnboundedSender, + sender: mpsc::UnboundedSender, } impl Handler { - fn new(sender: mpsc::UnboundedSender) -> Self { + fn new(sender: mpsc::UnboundedSender) -> Self { Self { sender } } - fn sender(&self) -> &mpsc::UnboundedSender { + fn sender(&self) -> &mpsc::UnboundedSender { &self.sender } } @@ -34,11 +36,10 @@ impl slack::EventHandler for Handler { Event::Message(msg) => { match *msg { Message::Standard(msg) => { - self.sender().send(format!("{}:{} says: {}", - msg.channel.unwrap_or("??".to_string()), - msg.user.unwrap_or("??".to_string()), - msg.text.unwrap_or("??".to_string())) - .to_string()).unwrap(); + self.sender().send(AgendaPoint{ + title: msg.text.unwrap_or("??".to_string()), + adder: msg.user.unwrap_or("??".to_string()), + }); } _ => {} } @@ -58,8 +59,8 @@ impl slack::EventHandler for Handler { pub async fn handle( token: Option, - sender: mpsc::UnboundedSender, - receiver: mpsc::UnboundedReceiver, + sender: mpsc::UnboundedSender, + receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Slack"); @@ -85,16 +86,16 @@ pub async fn handle( } async fn receive_from_discord( - mut receiver: mpsc::UnboundedReceiver, + mut receiver: mpsc::UnboundedReceiver, sender: slack::Sender, ) { - while let Some(s) = receiver.recv().await { - println!("Slack received '{}'", s); + while let Some(point) = receiver.recv().await { + println!("Slack received '{}'", point); //TODO Sending messages is very slow sometimes. Have seen delays // from 5 up to 20(!) seconds. sender.send_typing("CPBAA5FA7").unwrap(); println!("Typing"); - sender.send_message("CPBAA5FA7", &s).unwrap(); + sender.send_message("CPBAA5FA7", &point.to_add_message()).unwrap(); println!("Sent"); } } -- cgit v1.2.1 From 233b1b39a9ea5b622148c00558fa98082d1ae184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 18:09:23 +0100 Subject: "fix" warnings --- src/discord.rs | 2 +- src/slack.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index e422171..9e6550c 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -76,7 +76,7 @@ async fn receive_from_slack( &point.to_add_message(), "", false - ); + ).unwrap(); } } diff --git a/src/slack.rs b/src/slack.rs index 91705fa..e13ac3d 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -39,7 +39,7 @@ impl slack::EventHandler for Handler { self.sender().send(AgendaPoint{ title: msg.text.unwrap_or("??".to_string()), adder: msg.user.unwrap_or("??".to_string()), - }); + }).unwrap(); } _ => {} } @@ -71,7 +71,7 @@ pub async fn handle( let slack_sender = client.sender().clone(); - join!( + let (_, _) = join!( spawn_blocking(move || { let mut handler = Handler::new(sender); match client.run(&mut handler) { -- cgit v1.2.1 From 8ff5e1295ce9e6c670dd097ab801e4ff35e94632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 11 Nov 2020 18:23:16 +0100 Subject: move service values to correct file and read more from env --- src/discord.rs | 20 ++++++++++++++------ src/main.rs | 7 ++----- src/slack.rs | 15 ++++++++------- 3 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index 9e6550c..fe64b24 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -17,14 +17,16 @@ use tokio::{ }, }; +const TOKEN: Option<&str> = None; +const CHANNEL: Option = None; + pub async fn handle( - token: Option, sender: mpsc::UnboundedSender, receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Discord"); - let token = std::env::var("DISCORD_API_TOKEN").unwrap_or(token.unwrap()); + let token = std::env::var("DISCORD_API_TOKEN").unwrap_or_else(|_| TOKEN.expect("Missing Discord token").to_string()); let client = Discord::from_bot_token(&token); if let Ok(client) = client { @@ -72,10 +74,16 @@ async fn receive_from_slack( ) { while let Some(point) = receiver.recv().await { println!("Discord received '{}'", point); - client.send_message(ChannelId(697057150106599488), //TODO - &point.to_add_message(), - "", - false + client.send_message( + ChannelId( + match std::env::var("DISCORD_CHANNEL") { + Ok(var) => var.parse().unwrap(), + Err(_) => CHANNEL.expect("Missing Discord channel"), + } + ), + &point.to_add_message(), + "", + false ).unwrap(); } diff --git a/src/main.rs b/src/main.rs index 8d8fa5c..d3a24f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,17 +9,14 @@ use tokio::sync::mpsc; #[tokio::main] async fn main() { - let slack_token: Option = None; - let discord_token: Option = None; - println!("Hello, world!"); let (from_discord, to_slack) = mpsc::unbounded_channel::(); let (from_slack, to_discord) = mpsc::unbounded_channel::(); join!( - discord::handle(discord_token, from_discord, to_discord), - slack::handle(slack_token, from_slack, to_slack), + discord::handle(from_discord, to_discord), + slack::handle(from_slack, to_slack), ); } diff --git a/src/slack.rs b/src/slack.rs index e13ac3d..b460925 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -13,6 +13,9 @@ use tokio::{ }, }; +const TOKEN: Option<&str> = None; +const CHANNEL: Option<&str> = None; + struct Handler { sender: mpsc::UnboundedSender, } @@ -58,13 +61,12 @@ impl slack::EventHandler for Handler { } pub async fn handle( - token: Option, sender: mpsc::UnboundedSender, receiver: mpsc::UnboundedReceiver, ) { println!("Setting up Slack"); - let token = std::env::var("SLACK_API_TOKEN").unwrap_or(token.unwrap()); + let token = std::env::var("SLACK_API_TOKEN").unwrap_or_else(|_| TOKEN.expect("Missing slack token").to_string()); let client = spawn_blocking(move || { slack::RtmClient::login(&token).unwrap() }).await.unwrap(); @@ -90,12 +92,11 @@ async fn receive_from_discord( sender: slack::Sender, ) { while let Some(point) = receiver.recv().await { - println!("Slack received '{}'", point); //TODO Sending messages is very slow sometimes. Have seen delays // from 5 up to 20(!) seconds. - sender.send_typing("CPBAA5FA7").unwrap(); - println!("Typing"); - sender.send_message("CPBAA5FA7", &point.to_add_message()).unwrap(); - println!("Sent"); + let channel = std::env::var("SLACK_CHANNEL").unwrap_or_else(|_| CHANNEL.expect("Missing slack channel").to_string()); + sender.send_typing(&channel).unwrap(); + sender.send_message(&channel, &point.to_add_message()).unwrap(); + println!("Slack message sent"); } } -- cgit v1.2.1 From 3b75792081e11cfeb334b45dfb41027532a8848e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Fri, 13 Nov 2020 00:59:32 +0100 Subject: basic commands and write agenda to file --- src/agenda.rs | 58 +++++++++++++++++++++++++++++++++++++++++++--------------- src/discord.rs | 58 +++++++++++++++++++++++++++++++++++++--------------------- src/main.rs | 6 ++++-- src/slack.rs | 30 ++++++++++++++++++++++-------- 4 files changed, 106 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/agenda.rs b/src/agenda.rs index 3cfcfb7..39b07a7 100644 --- a/src/agenda.rs +++ b/src/agenda.rs @@ -9,8 +9,8 @@ use std::{ #[derive(Debug, Deserialize, Serialize)] pub struct AgendaPoint { - pub title: String, - pub adder: String, + title: String, + adder: String, } impl fmt::Display for AgendaPoint { @@ -30,21 +30,49 @@ pub struct Agenda { points: Vec, } -pub fn read_agenda() -> Agenda { - serde_json::from_str::( - &fs::read_to_string("agenda.json") - .expect("Can't read agenda.json")) - .expect("Error parsing agenda.json") +impl Agenda { + fn write(&self) { + fs::write(std::path::Path::new("agenda.json"), + serde_json::to_string_pretty(&self).expect("Can't serialize agenda")) + .expect("Can't write agenda.json"); + } +} + +pub enum ParseError { + NoSuchCommand, } -pub fn write_agenda(agenda: Agenda) { - fs::write(std::path::Path::new("agenda.json"), - serde_json::to_string_pretty(&agenda).expect("Can't serialize agenda")) - .expect("Can't write agenda.json"); +pub fn parse_message(message: &str, sender: &str) -> Result, ParseError> { + if message.starts_with("!add ") { + let mut agenda = read_agenda(); + agenda.points.push(AgendaPoint { + title: message[5..].to_string(), + adder: sender.to_string(), + }); + agenda.write(); + Ok(None) + } else if message.starts_with("!agenda") { + Ok(Some(read_agenda() + .points + .iter() + .map(|p| p.to_string()) + .collect::>() + .join("\n"))) + } else if message.starts_with("!clear") { + Agenda { + points: Vec::new(), + }.write(); + Ok(None) + } else if message.starts_with("!help") { + Ok(Some("Available commands:\n !add\n !agenda\n !clear\n !help".to_string())) + } else { + Err(ParseError::NoSuchCommand) + } } -pub fn add_point(point: AgendaPoint) { - let mut agenda = read_agenda(); - agenda.points.push(point); - write_agenda(agenda); +fn read_agenda() -> Agenda { + serde_json::from_str::( + &fs::read_to_string("agenda.json") + .expect("Can't read agenda.json")) + .expect("Error parsing agenda.json") } diff --git a/src/discord.rs b/src/discord.rs index fe64b24..ea7ad03 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -1,4 +1,7 @@ -use crate::agenda::AgendaPoint; +use crate::agenda::{ + parse_message, + AgendaPoint +}; use discord::{ model::{ @@ -9,6 +12,10 @@ use discord::{ Error, }; use futures::join; +use std::sync::{ + Arc, + Mutex, +}; use tokio::{ sync::mpsc, task::{ @@ -27,16 +34,23 @@ pub async fn handle( println!("Setting up Discord"); let token = std::env::var("DISCORD_API_TOKEN").unwrap_or_else(|_| TOKEN.expect("Missing Discord token").to_string()); + let channel_id = ChannelId( + match std::env::var("DISCORD_CHANNEL") { + Ok(var) => var.parse().unwrap(), + Err(_) => CHANNEL.expect("Missing Discord channel"), + }); + let client = Discord::from_bot_token(&token); if let Ok(client) = client { let (connection, _) = client.connect().expect("Discord connect failed"); //TODO let our_id = client.get_current_user().unwrap().id; + let client = Arc::new(Mutex::new(client)); println!("Discord ready"); let (_, _) = join!( //TODO? - spawn_blocking(move || receive_events(our_id, connection, sender)), - spawn(receive_from_slack(receiver, client)) + spawn(receive_from_slack(receiver, Arc::clone(&client), channel_id)), + spawn_blocking(move || receive_events(our_id, connection, sender, client, channel_id)), ); } } @@ -44,17 +58,25 @@ pub async fn handle( fn receive_events( our_id: discord::model::UserId, mut connection: discord::Connection, - sender: mpsc::UnboundedSender + sender: mpsc::UnboundedSender, + client: Arc>, + channel_id: ChannelId, ) { loop { match connection.recv_event() { Ok(Event::MessageCreate(message)) => { - if message.author.id != our_id { - sender.send(AgendaPoint{ - title: message.content, - adder: message.author.name, - }).unwrap(); + if let Ok(Some(s)) = parse_message(&message.content, &message.author.name) { + client.lock().unwrap().send_message(channel_id, + &s, + "", + false).unwrap(); } + //if message.author.id != our_id { + // sender.send(AgendaPoint{ + // title: message.content, + // adder: message.author.name, + // }).unwrap(); + //} } Ok(_) => {} Err(Error::Closed(code, body)) => { @@ -70,21 +92,15 @@ fn receive_events( async fn receive_from_slack( mut receiver: mpsc::UnboundedReceiver, - client: discord::Discord, + client: Arc>, + channel_id: ChannelId ) { while let Some(point) = receiver.recv().await { println!("Discord received '{}'", point); - client.send_message( - ChannelId( - match std::env::var("DISCORD_CHANNEL") { - Ok(var) => var.parse().unwrap(), - Err(_) => CHANNEL.expect("Missing Discord channel"), - } - ), - &point.to_add_message(), - "", - false - ).unwrap(); + client.lock().unwrap().send_message(channel_id, + &point.to_add_message(), + "", + false).unwrap(); } } diff --git a/src/main.rs b/src/main.rs index d3a24f3..b6edd38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,10 @@ mod agenda; mod discord; mod slack; -use crate::agenda::AgendaPoint; - +use crate::agenda::{ + Agenda, + AgendaPoint, +}; use futures::join; use tokio::sync::mpsc; diff --git a/src/slack.rs b/src/slack.rs index b460925..c0d9bb8 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -1,4 +1,7 @@ -use crate::agenda::AgendaPoint; +use crate::agenda::{ + parse_message, + AgendaPoint +}; use futures::join; use slack::{ @@ -18,12 +21,20 @@ const CHANNEL: Option<&str> = None; struct Handler { sender: mpsc::UnboundedSender, + slack_sender: slack::Sender, + slack_channel: String, } impl Handler { - fn new(sender: mpsc::UnboundedSender) -> Self { + fn new( + sender: mpsc::UnboundedSender, + slack_sender: slack::Sender, + slack_channel: String + ) -> Self { Self { - sender + sender, + slack_sender, + slack_channel, } } @@ -39,10 +50,12 @@ impl slack::EventHandler for Handler { Event::Message(msg) => { match *msg { Message::Standard(msg) => { - self.sender().send(AgendaPoint{ - title: msg.text.unwrap_or("??".to_string()), - adder: msg.user.unwrap_or("??".to_string()), - }).unwrap(); + if let Ok(Some(s)) = parse_message( + &msg.text.unwrap_or("".to_string()), + &msg.user.unwrap_or("??".to_string()), + ) { + self.slack_sender.send_message(self.slack_channel.as_str(), &s).unwrap(); + } } _ => {} } @@ -67,15 +80,16 @@ pub async fn handle( println!("Setting up Slack"); let token = std::env::var("SLACK_API_TOKEN").unwrap_or_else(|_| TOKEN.expect("Missing slack token").to_string()); + let token_clone = token.clone(); let client = spawn_blocking(move || { slack::RtmClient::login(&token).unwrap() }).await.unwrap(); + let mut handler = Handler::new(sender, client.sender().clone(), token_clone); let slack_sender = client.sender().clone(); let (_, _) = join!( spawn_blocking(move || { - let mut handler = Handler::new(sender); match client.run(&mut handler) { Ok(_) => {} Err(e) => { -- cgit v1.2.1 From 00491c8005fe75a8cdf9dc06288affd2ec50fb61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Fri, 13 Nov 2020 16:05:54 +0100 Subject: print available channels if unspecified --- src/agenda.rs | 15 ++++++++--- src/discord.rs | 74 +++++++++++++++++++++++++++++++++---------------------- src/main.rs | 5 +--- src/slack.rs | 78 ++++++++++++++++++++++++++++++++++++++-------------------- 4 files changed, 109 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/agenda.rs b/src/agenda.rs index 39b07a7..1ca7bfb 100644 --- a/src/agenda.rs +++ b/src/agenda.rs @@ -6,8 +6,9 @@ use std::{ fmt, fs, }; +use tokio::sync::mpsc; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct AgendaPoint { title: String, adder: String, @@ -42,13 +43,19 @@ pub enum ParseError { NoSuchCommand, } -pub fn parse_message(message: &str, sender: &str) -> Result, ParseError> { +pub fn parse_message( + message: &str, + sender: &str, + point_sender: &mpsc::UnboundedSender +) -> Result, ParseError> { if message.starts_with("!add ") { let mut agenda = read_agenda(); - agenda.points.push(AgendaPoint { + let agenda_point = AgendaPoint { title: message[5..].to_string(), adder: sender.to_string(), - }); + }; + point_sender.send(agenda_point.clone()).unwrap(); + agenda.points.push(agenda_point); agenda.write(); Ok(None) } else if message.starts_with("!agenda") { diff --git a/src/discord.rs b/src/discord.rs index ea7ad03..3933aba 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -7,6 +7,7 @@ use discord::{ model::{ ChannelId, Event, + PossibleServer, }, Discord, Error, @@ -34,49 +35,62 @@ pub async fn handle( println!("Setting up Discord"); let token = std::env::var("DISCORD_API_TOKEN").unwrap_or_else(|_| TOKEN.expect("Missing Discord token").to_string()); - let channel_id = ChannelId( - match std::env::var("DISCORD_CHANNEL") { - Ok(var) => var.parse().unwrap(), - Err(_) => CHANNEL.expect("Missing Discord channel"), - }); - let client = Discord::from_bot_token(&token); if let Ok(client) = client { let (connection, _) = client.connect().expect("Discord connect failed"); //TODO let our_id = client.get_current_user().unwrap().id; let client = Arc::new(Mutex::new(client)); - println!("Discord ready"); + + let channel = match std::env::var("DISCORD_CHANNEL") { + Ok(channel) => Some(ChannelId(channel.parse::().unwrap())), + Err(_) => CHANNEL, + }; let (_, _) = join!( //TODO? - spawn(receive_from_slack(receiver, Arc::clone(&client), channel_id)), - spawn_blocking(move || receive_events(our_id, connection, sender, client, channel_id)), + spawn(receive_from_slack(receiver, Arc::clone(&client), channel)), + spawn_blocking(move || receive_events(our_id, connection, sender, client, channel)), ); } } fn receive_events( - our_id: discord::model::UserId, + _our_id: discord::model::UserId, mut connection: discord::Connection, sender: mpsc::UnboundedSender, client: Arc>, - channel_id: ChannelId, + channel: Option, ) { loop { match connection.recv_event() { + Ok(Event::ServerCreate(server)) => { + if let PossibleServer::Online(server) = server { + println!("Discord channels in {}: {:#?}", + server.name, + server + .channels + .iter() + .map(|channel| format!("{}: {} ({:?})", + channel.name, + channel.id, + channel.kind)) + .collect::>()); + } + } + Ok(Event::MessageCreate(message)) => { - if let Ok(Some(s)) = parse_message(&message.content, &message.author.name) { - client.lock().unwrap().send_message(channel_id, - &s, - "", - false).unwrap(); + if let Some(channel) = channel { + if let Ok(Some(s)) = parse_message( + &message.content, + &message.author.name, + &sender, + ) { + client.lock().unwrap().send_message(channel, + &s, + "", + false).unwrap(); + } } - //if message.author.id != our_id { - // sender.send(AgendaPoint{ - // title: message.content, - // adder: message.author.name, - // }).unwrap(); - //} } Ok(_) => {} Err(Error::Closed(code, body)) => { @@ -93,14 +107,16 @@ fn receive_events( async fn receive_from_slack( mut receiver: mpsc::UnboundedReceiver, client: Arc>, - channel_id: ChannelId + channel: Option ) { - while let Some(point) = receiver.recv().await { - println!("Discord received '{}'", point); - client.lock().unwrap().send_message(channel_id, - &point.to_add_message(), - "", - false).unwrap(); + if let Some(channel) = channel { + while let Some(point) = receiver.recv().await { + println!("Discord received '{}'", point); + client.lock().unwrap().send_message(channel, + &point.to_add_message(), + "", + false).unwrap(); + } } } diff --git a/src/main.rs b/src/main.rs index b6edd38..0bcf53c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,10 +2,7 @@ mod agenda; mod discord; mod slack; -use crate::agenda::{ - Agenda, - AgendaPoint, -}; +use crate::agenda::AgendaPoint; use futures::join; use tokio::sync::mpsc; diff --git a/src/slack.rs b/src/slack.rs index c0d9bb8..6ed60c4 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -22,42 +22,60 @@ const CHANNEL: Option<&str> = None; struct Handler { sender: mpsc::UnboundedSender, slack_sender: slack::Sender, - slack_channel: String, + slack_channel: Option, + print_channels: bool, } impl Handler { fn new( sender: mpsc::UnboundedSender, slack_sender: slack::Sender, - slack_channel: String + slack_channel: Option, ) -> Self { Self { sender, slack_sender, - slack_channel, + slack_channel: slack_channel.clone(), + print_channels: slack_channel.is_none() } } - - fn sender(&self) -> &mpsc::UnboundedSender { - &self.sender - } } impl slack::EventHandler for Handler { - fn on_event(&mut self, _cli: &slack::RtmClient, event: slack::Event) { + fn on_event(&mut self, cli: &slack::RtmClient, event: slack::Event) { println!("on_event: {:#?}", event); match event { + Event::Hello => { + if self.print_channels { + println!("Slack channels found: {:#?}", + cli + .start_response() + .channels + .as_ref() + .and_then(|channels| { + Some(channels + .iter() + .map(|channel| format!("{}: {}", + channel.name.as_ref().unwrap_or(&"??".to_string()), //TODO &"".to_string() ? + channel.id.as_ref().unwrap_or(&"??".to_string()))) + .collect::>()) + })); + } + } Event::Message(msg) => { - match *msg { - Message::Standard(msg) => { - if let Ok(Some(s)) = parse_message( - &msg.text.unwrap_or("".to_string()), - &msg.user.unwrap_or("??".to_string()), - ) { - self.slack_sender.send_message(self.slack_channel.as_str(), &s).unwrap(); + if let Some(channel) = &self.slack_channel { + match *msg { + Message::Standard(msg) => { + if let Ok(Some(s)) = parse_message( + &msg.text.unwrap_or("".to_string()), + &msg.user.unwrap_or("??".to_string()), + &self.sender, + ) { + self.slack_sender.send_message(channel.as_str(), &s).unwrap(); + } } + _ => {} } - _ => {} } } _ => {} @@ -80,12 +98,18 @@ pub async fn handle( println!("Setting up Slack"); let token = std::env::var("SLACK_API_TOKEN").unwrap_or_else(|_| TOKEN.expect("Missing slack token").to_string()); - let token_clone = token.clone(); + let channel = match std::env::var("SLACK_CHANNEL") { + Ok(channel) => Some(channel), + Err(_) => match CHANNEL { + Some(channel) => Some(channel.to_string()), + None => None + } + }; let client = spawn_blocking(move || { slack::RtmClient::login(&token).unwrap() }).await.unwrap(); - let mut handler = Handler::new(sender, client.sender().clone(), token_clone); + let mut handler = Handler::new(sender, client.sender().clone(), channel.clone()); let slack_sender = client.sender().clone(); let (_, _) = join!( @@ -97,20 +121,22 @@ pub async fn handle( } } }), - spawn(receive_from_discord(receiver, slack_sender)) + spawn(receive_from_discord(receiver, slack_sender, channel)) ); } async fn receive_from_discord( mut receiver: mpsc::UnboundedReceiver, sender: slack::Sender, + channel: Option, ) { - while let Some(point) = receiver.recv().await { - //TODO Sending messages is very slow sometimes. Have seen delays - // from 5 up to 20(!) seconds. - let channel = std::env::var("SLACK_CHANNEL").unwrap_or_else(|_| CHANNEL.expect("Missing slack channel").to_string()); - sender.send_typing(&channel).unwrap(); - sender.send_message(&channel, &point.to_add_message()).unwrap(); - println!("Slack message sent"); + if let Some(channel) = channel { + while let Some(point) = receiver.recv().await { + //TODO Sending messages is very slow sometimes. Have seen delays + // from 5 up to 20(!) seconds. + sender.send_typing(&channel).unwrap(); + sender.send_message(&channel, &point.to_add_message()).unwrap(); + println!("Slack message sent"); + } } } -- cgit v1.2.1 From 1d4fcb47451a9154c215c4b3bba4e559d691f7fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Fri, 13 Nov 2020 16:33:23 +0100 Subject: only listen to channels we write to --- src/discord.rs | 44 ++++++++++++++++++++++++-------------------- src/slack.rs | 29 +++++++++++++---------------- 2 files changed, 37 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index 3933aba..a41b96a 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -64,31 +64,35 @@ fn receive_events( loop { match connection.recv_event() { Ok(Event::ServerCreate(server)) => { - if let PossibleServer::Online(server) = server { - println!("Discord channels in {}: {:#?}", - server.name, - server - .channels - .iter() - .map(|channel| format!("{}: {} ({:?})", - channel.name, - channel.id, - channel.kind)) - .collect::>()); + if channel.is_none() { + if let PossibleServer::Online(server) = server { + println!("Discord channels in {}: {:#?}", + server.name, + server + .channels + .iter() + .map(|channel| format!("{}: {} ({:?})", + channel.name, + channel.id, + channel.kind)) + .collect::>()); + } } } Ok(Event::MessageCreate(message)) => { if let Some(channel) = channel { - if let Ok(Some(s)) = parse_message( - &message.content, - &message.author.name, - &sender, - ) { - client.lock().unwrap().send_message(channel, - &s, - "", - false).unwrap(); + if channel == message.channel_id { + if let Ok(Some(s)) = parse_message( + &message.content, + &message.author.name, + &sender, + ) { + client.lock().unwrap().send_message(channel, + &s, + "", + false).unwrap(); + } } } } diff --git a/src/slack.rs b/src/slack.rs index 6ed60c4..1c272cf 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -43,7 +43,6 @@ impl Handler { impl slack::EventHandler for Handler { fn on_event(&mut self, cli: &slack::RtmClient, event: slack::Event) { - println!("on_event: {:#?}", event); match event { Event::Hello => { if self.print_channels { @@ -57,7 +56,7 @@ impl slack::EventHandler for Handler { .iter() .map(|channel| format!("{}: {}", channel.name.as_ref().unwrap_or(&"??".to_string()), //TODO &"".to_string() ? - channel.id.as_ref().unwrap_or(&"??".to_string()))) + channel.id.as_ref().unwrap_or(&"??".to_string()))) //TODO .collect::>()) })); } @@ -66,29 +65,27 @@ impl slack::EventHandler for Handler { if let Some(channel) = &self.slack_channel { match *msg { Message::Standard(msg) => { - if let Ok(Some(s)) = parse_message( - &msg.text.unwrap_or("".to_string()), - &msg.user.unwrap_or("??".to_string()), - &self.sender, - ) { - self.slack_sender.send_message(channel.as_str(), &s).unwrap(); + if msg.channel.is_some() && *channel == msg.channel.unwrap() { //TODO + if let Ok(Some(s)) = parse_message( + &msg.text.unwrap_or("".to_string()), + &msg.user.unwrap_or("??".to_string()), + &self.sender, + ) { + self.slack_sender.send_message(channel.as_str(), &s).unwrap(); + } } } - _ => {} + _ => {} // message type } } } - _ => {} + _ => {} // event type } } - fn on_close(&mut self, _cli: &slack::RtmClient) { - println!("on_close") - } + fn on_close(&mut self, _cli: &slack::RtmClient) {} - fn on_connect(&mut self, _cli: &slack::RtmClient) { - println!("on_connect"); - } + fn on_connect(&mut self, _cli: &slack::RtmClient) {} } pub async fn handle( -- cgit v1.2.1 From 824d085fa3d550fd8c62d34ced50a1b38fdb7946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Mon, 16 Nov 2020 15:42:29 +0100 Subject: format help and send ack when adding to agenda --- src/agenda.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/agenda.rs b/src/agenda.rs index 1ca7bfb..d1a940d 100644 --- a/src/agenda.rs +++ b/src/agenda.rs @@ -24,6 +24,11 @@ impl AgendaPoint { pub fn to_add_message(&self) -> String { format!("'{}' added by {}", self.title, self.adder) } + + fn to_add_message_response(&self) -> String { + //TODO should add a reaction instead + format!("Added '{}'", self.title) + } } #[derive(Deserialize, Serialize)] @@ -55,9 +60,10 @@ pub fn parse_message( adder: sender.to_string(), }; point_sender.send(agenda_point.clone()).unwrap(); + let response = agenda_point.to_add_message_response(); agenda.points.push(agenda_point); agenda.write(); - Ok(None) + Ok(Some(response)) } else if message.starts_with("!agenda") { Ok(Some(read_agenda() .points @@ -71,7 +77,7 @@ pub fn parse_message( }.write(); Ok(None) } else if message.starts_with("!help") { - Ok(Some("Available commands:\n !add\n !agenda\n !clear\n !help".to_string())) + Ok(Some("Available commands:\n```!add -- Add something\n!agenda -- Print the agenda\n!clear -- Remove all items\n!help```".to_string())) } else { Err(ParseError::NoSuchCommand) } -- cgit v1.2.1 From 96b9a8f66f62e64bc4907e12de0772392f7804c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Mon, 16 Nov 2020 15:45:01 +0100 Subject: change slack channel type sig Yes, I have these commented and use hard-coded tokens. What are you going to do about it? --- src/discord.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/discord.rs b/src/discord.rs index a41b96a..0507da8 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -26,7 +26,7 @@ use tokio::{ }; const TOKEN: Option<&str> = None; -const CHANNEL: Option = None; +const CHANNEL: Option = None; pub async fn handle( sender: mpsc::UnboundedSender, -- cgit v1.2.1