use discord; use discord::Discord; use discord::model::Event; use modules::Module; use toml::Table; use event; use std::sync::Arc; use std::sync::mpsc::Receiver; use transformable_channels::mpsc::ExtSender; use {MessageSender, Message, User, Channel}; pub struct DiscordModule { token: String, playing: String } const DEFAULT_PLAYING: &'static str = "tenquestionmarks 0.0.1"; impl DiscordModule { pub fn new (configuration: &Table) -> Box { let token = configuration.get("token") .and_then(|value| value.as_str()) .unwrap_or(""); let playing = configuration.get("playing") .and_then(|value| value.as_str()) .unwrap_or(DEFAULT_PLAYING); Box::new(DiscordModule { token: String::from(token), playing: String::from(playing) }) } } pub struct DiscordMessageSender { discord: Arc, channel_id: discord::model::ChannelId } impl MessageSender for DiscordMessageSender { fn send_message (&self, message: &str) { debug!("Send message to channel id {:?}: {:?}", self.channel_id, message); match self.discord.send_message(&self.channel_id, message, "", false) { Ok(message) => { debug!("Send message succeeded: {:?}", message.id); }, Err(err) => { error!("Send message failed: {:?}", err) } } } } impl Module for DiscordModule { fn run (&self, sender: Box>, _: Receiver>) { let discord = Arc::new(Discord::from_bot_token(&self.token[..]).expect("Discord module: Login failed")); let (mut connection, _) = discord.connect().expect("Discord module: Connection failed"); info!("Playing {}", self.playing); connection.set_game_name(self.playing.clone()); loop { match connection.recv_event() { Ok(Event::MessageCreate(message)) => { let author = User { name: message.author.name.clone(), sender: Box::new(DiscordMessageSender { discord: discord.clone(), channel_id: message.channel_id }) }; let channel = Channel { name: String::from("channel"), description: String::from(""), topic: String::from(""), sender: Box::new(DiscordMessageSender { discord: discord.clone(), channel_id: message.channel_id }) }; let message = Message { author: author, content: message.content, channel: Some(channel) }; match sender.send(event::Envelope::new(event::Event::Message { message: message })) { Err(err) => error!("Error sending message event: {:?}", err), Ok(_) => {} } } Ok(_) => {} Err(discord::Error::Closed(code, body)) => { error!("Gateway closed on us with code {:?}: {}", code, body); break } Err(err) => error!("Received error: {:?}", err) } } } }