135 lines
4.9 KiB
Rust

use discord;
use discord::Discord;
use discord::model::{Event, PossibleServer};
use modules::Module;
use toml::Table;
use event;
use event::Envelope;
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 (_: &Table, configuration: &Table) -> Box<Module> {
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<Discord>,
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<ExtSender<event::Envelope>>, _: Receiver<Arc<event::Envelope>>) {
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 {
let event = connection.recv_event();
debug!("Received event: {:?}", event);
match event {
Ok(Event::ServerCreate(server)) => {
match server {
PossibleServer::Online(server) => {
info!("Joined server: {}", server.name);
for channel in server.channels {
info!(" - Joined channel: {}", channel.name);
match sender.send(Envelope::new(event::Event::SelfJoin {
channel: Channel {
name: channel.name,
description: String::from(""),
topic: channel.topic.unwrap_or_else(|| String::from("")),
sender: Box::new(DiscordMessageSender {
discord: discord.clone(),
channel_id: channel.id
})
}
})) {
Err(err) => error!("Error sending selfjoin event: {:?}", err),
Ok(_) => {}
}
}
},
_ => {}
}
},
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(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)
}
}
}
}