Message router refactor
+ Created the WoxlfMessage struct to streamline interface + Message tasks are now joined at once instead of sequentially + Clippy + fmtmsg_refactor^2
parent
ca80846e0d
commit
90ec453b70
|
@ -2304,6 +2304,7 @@ dependencies = [
|
|||
name = "woxlf"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"chrono",
|
||||
"config",
|
||||
"futures",
|
||||
|
|
|
@ -16,6 +16,7 @@ regex = "1.5.5"
|
|||
futures = "0.3.21"
|
||||
reqwest = "0.11.10"
|
||||
tera = "1.15.0"
|
||||
bitflags = "1.3.2"
|
||||
|
||||
[dependencies.serenity]
|
||||
version = "0.11.5"
|
||||
|
|
|
@ -10,14 +10,16 @@ use serenity::framework::standard::{
|
|||
use serenity::framework::StandardFramework;
|
||||
use serenity::model::guild::Member;
|
||||
use serenity::model::id::ChannelId;
|
||||
use serenity::model::prelude::{GuildId, Message, UserId};
|
||||
use serenity::model::prelude::{Message, UserId};
|
||||
use serenity::prelude::Context;
|
||||
use serenity::utils::MessageBuilder;
|
||||
|
||||
use crate::discord::helper::{add_user_to_game, parse_duration_arg};
|
||||
use crate::error::{Result, WoxlfError};
|
||||
use crate::game::global_data::GlobalData;
|
||||
use crate::game::message_router::{dispatch_message, MessageDest, MessageSource};
|
||||
use crate::game::message_router::{
|
||||
dispatch_message, Median, MessageDest, MessageSource, WoxlfMessage,
|
||||
};
|
||||
use crate::game::player_data::PlayerData;
|
||||
use crate::game::Phase;
|
||||
use crate::messages::DiscordUser;
|
||||
|
@ -161,23 +163,20 @@ async fn end(ctx: &Context, msg: &Message, mut _args: Args) -> CommandResult {
|
|||
#[command]
|
||||
#[only_in(guilds)]
|
||||
#[allowed_roles("wolfx host")]
|
||||
async fn say(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||
let mut data = ctx.data.write().await;
|
||||
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||
let guild = msg.guild(&ctx.cache).unwrap();
|
||||
async fn say(ctx: &Context, _msg: &Message, args: Args) -> CommandResult {
|
||||
let data = ctx.data.read().await;
|
||||
let global_data = data.get::<GlobalData>().unwrap();
|
||||
|
||||
let mut global_data = global_data.lock().await;
|
||||
let global_data = global_data.lock().await;
|
||||
|
||||
dispatch_message(
|
||||
ctx,
|
||||
&guild,
|
||||
&mut global_data,
|
||||
MessageSource::Host,
|
||||
MessageDest::Broadcast,
|
||||
args.rest(),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
let msg = WoxlfMessage::default()
|
||||
.source(MessageSource::Host)
|
||||
.dest(MessageDest::Broadcast)
|
||||
.median(Median::Webhook)
|
||||
.content(args.rest())
|
||||
.clone();
|
||||
|
||||
dispatch_message(ctx, &global_data, msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -185,27 +184,24 @@ async fn say(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||
#[command]
|
||||
#[only_in(guilds)]
|
||||
#[allowed_roles("wolfx host")]
|
||||
async fn broadcast(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||
let mut data = ctx.data.write().await;
|
||||
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||
let guild = msg.guild(&ctx.cache).unwrap();
|
||||
async fn broadcast(ctx: &Context, _msg: &Message, args: Args) -> CommandResult {
|
||||
let data = ctx.data.read().await;
|
||||
let global_data = data.get::<GlobalData>().unwrap();
|
||||
|
||||
let mut global_data = global_data.lock().await;
|
||||
let global_data = global_data.lock().await;
|
||||
|
||||
let msg = global_data
|
||||
let broadcast = global_data
|
||||
.templates()?
|
||||
.build_announcement(&global_data, args.rest())?;
|
||||
|
||||
dispatch_message(
|
||||
ctx,
|
||||
&guild,
|
||||
&mut global_data,
|
||||
MessageSource::Automated,
|
||||
MessageDest::Broadcast,
|
||||
&msg,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
let woxlf_msg = WoxlfMessage::default()
|
||||
.source(MessageSource::Automated)
|
||||
.dest(MessageDest::Broadcast)
|
||||
.content(&broadcast)
|
||||
.median(Median::Webhook)
|
||||
.clone();
|
||||
|
||||
dispatch_message(ctx, &global_data, woxlf_msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -234,16 +230,14 @@ async fn next_phase(ctx: &Context, msg: &Message, mut args: Args) -> CommandResu
|
|||
.templates()?
|
||||
.build_announcement(&global_data, &broadcast)?;
|
||||
|
||||
dispatch_message(
|
||||
ctx,
|
||||
&guild,
|
||||
&mut global_data,
|
||||
MessageSource::Automated,
|
||||
MessageDest::Broadcast,
|
||||
&broadcast,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
let woxlf_msg = WoxlfMessage::default()
|
||||
.source(MessageSource::Automated)
|
||||
.dest(MessageDest::Broadcast)
|
||||
.median(Median::Webhook)
|
||||
.content(&broadcast)
|
||||
.clone();
|
||||
|
||||
dispatch_message(ctx, &global_data, woxlf_msg).await?;
|
||||
|
||||
if global_data.game_state_mut()?.current_phase == Phase::Day {
|
||||
let vote_channel = guild
|
||||
|
@ -311,7 +305,6 @@ async fn kill(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||
async fn add_time(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
let mut data = ctx.data.write().await;
|
||||
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||
let guild = msg.guild(&ctx.cache).unwrap();
|
||||
|
||||
let mut global_data = global_data.lock().await;
|
||||
|
||||
|
@ -335,16 +328,14 @@ async fn add_time(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
|
|||
.templates()?
|
||||
.build_announcement(&global_data, &broadcast)?;
|
||||
|
||||
dispatch_message(
|
||||
ctx,
|
||||
&guild,
|
||||
&mut global_data,
|
||||
MessageSource::Automated,
|
||||
MessageDest::Broadcast,
|
||||
&broadcast,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
let woxlf_msg = WoxlfMessage::default()
|
||||
.source(MessageSource::Automated)
|
||||
.dest(MessageDest::Broadcast)
|
||||
.median(Median::Webhook)
|
||||
.content(&broadcast)
|
||||
.clone();
|
||||
|
||||
dispatch_message(ctx, &global_data, woxlf_msg).await?;
|
||||
|
||||
msg.reply(&ctx.http, "Phase has been updated")
|
||||
.await
|
||||
|
@ -651,13 +642,9 @@ async fn whisper(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
|
|||
msg.reply(&ctx.http, "Need a recipient and message!")
|
||||
.await?;
|
||||
} else {
|
||||
let data = ctx.data.write().await;
|
||||
let data = ctx.data.read().await;
|
||||
let global_data = data.get::<GlobalData>().unwrap();
|
||||
let mut global_data = global_data.lock().await;
|
||||
|
||||
let guild = GuildId::from(global_data.cfg.discord_config.guild_id)
|
||||
.to_guild_cached(&ctx.cache)
|
||||
.unwrap();
|
||||
let global_data = global_data.lock().await;
|
||||
|
||||
let target = args.single::<String>()?;
|
||||
let pm = args.rest();
|
||||
|
@ -680,9 +667,14 @@ async fn whisper(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let msg_src = MessageSource::Player(Box::new(src_player.clone()));
|
||||
let msg_dest = MessageDest::PlayerDm(Box::new(target_player.clone()));
|
||||
dispatch_message(ctx, &guild, &mut global_data, msg_src, msg_dest, pm, None).await?;
|
||||
let woxlf_msg = WoxlfMessage::default()
|
||||
.source(MessageSource::Player(Box::new(src_player.clone())))
|
||||
.dest(MessageDest::Player(Box::new(target_player.clone())))
|
||||
.median(Median::DirectMessage)
|
||||
.content(pm)
|
||||
.clone();
|
||||
|
||||
dispatch_message(ctx, &global_data, woxlf_msg).await?;
|
||||
} else {
|
||||
msg.reply(
|
||||
&ctx.http,
|
||||
|
|
|
@ -6,8 +6,8 @@ use serenity::model::prelude::AttachmentType;
|
|||
use serenity::utils::parse_emoji;
|
||||
|
||||
use crate::game::global_data::GlobalData;
|
||||
use crate::game::message_router::MessageSource;
|
||||
use crate::game::message_router::{dispatch_message, MessageDest};
|
||||
use crate::game::message_router::{Median, MessageSource, WoxlfMessage};
|
||||
|
||||
pub struct Handler {}
|
||||
|
||||
|
@ -26,7 +26,7 @@ impl EventHandler for Handler {
|
|||
|
||||
let global_data = data.get::<GlobalData>().unwrap();
|
||||
|
||||
let mut global_data = global_data.lock().await;
|
||||
let global_data = global_data.lock().await;
|
||||
|
||||
if global_data.game_state.is_none() {
|
||||
// no game in progress
|
||||
|
@ -43,7 +43,6 @@ impl EventHandler for Handler {
|
|||
return;
|
||||
}
|
||||
|
||||
let guild = msg.guild(&ctx.cache).unwrap();
|
||||
let user_msg = msg.content.clone();
|
||||
|
||||
let re = regex::Regex::new(r"<a?:.+:\d+>").unwrap();
|
||||
|
@ -68,19 +67,17 @@ impl EventHandler for Handler {
|
|||
.map(|a| AttachmentType::Image((a.url).parse().unwrap()))
|
||||
.collect();
|
||||
|
||||
let msg_source = MessageSource::Player(Box::new(player_data.clone()));
|
||||
let woxlf_msg = WoxlfMessage::default()
|
||||
.source(MessageSource::Player(Box::new(player_data.clone())))
|
||||
.dest(MessageDest::Broadcast)
|
||||
.median(Median::Webhook)
|
||||
.content(&user_msg)
|
||||
.attachments(attachments)
|
||||
.clone();
|
||||
|
||||
dispatch_message(
|
||||
&ctx,
|
||||
&guild,
|
||||
&mut global_data,
|
||||
msg_source,
|
||||
MessageDest::Broadcast,
|
||||
&user_msg,
|
||||
Some(attachments),
|
||||
)
|
||||
.await
|
||||
.expect("Unable to send message to players");
|
||||
dispatch_message(&ctx, &global_data, woxlf_msg)
|
||||
.await
|
||||
.expect("Unable to send message to players");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
use crate::error;
|
||||
use crate::error::WoxlfError;
|
||||
use crate::game::global_data::GlobalData;
|
||||
use crate::game::player_data::PlayerData;
|
||||
use bitflags::bitflags;
|
||||
use serenity::client::Context;
|
||||
use serenity::http::Http;
|
||||
use serenity::http::{CacheHttp, Http};
|
||||
use serenity::model::guild::Guild;
|
||||
use serenity::model::id::UserId;
|
||||
use serenity::model::prelude::AttachmentType;
|
||||
use serenity::model::id::{ChannelId, UserId};
|
||||
use serenity::model::prelude::{AttachmentType, GuildId, WebhookId};
|
||||
use serenity::utils::MessageBuilder;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -15,13 +17,111 @@ pub enum MessageSource {
|
|||
Automated,
|
||||
}
|
||||
|
||||
impl Default for MessageSource {
|
||||
fn default() -> Self {
|
||||
Self::Automated
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub enum MessageDest {
|
||||
PlayerChannel(Box<PlayerData>),
|
||||
PlayerDm(Box<PlayerData>),
|
||||
Player(Box<PlayerData>),
|
||||
Host,
|
||||
Broadcast,
|
||||
}
|
||||
|
||||
impl Default for MessageDest {
|
||||
fn default() -> Self {
|
||||
Self::Broadcast
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub enum Median {
|
||||
DirectMessage,
|
||||
Webhook,
|
||||
StandardMessage,
|
||||
}
|
||||
|
||||
impl Default for Median {
|
||||
fn default() -> Self {
|
||||
Self::Webhook
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Default)]
|
||||
pub struct MsgFlags: u32 {
|
||||
const PIN_MSG = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct WoxlfMessage<'a> {
|
||||
pub source: MessageSource,
|
||||
pub dest: MessageDest,
|
||||
pub median: Median,
|
||||
pub content: String,
|
||||
pub attachments: Option<Vec<AttachmentType<'a>>>,
|
||||
pub flags: MsgFlags,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl<'a> WoxlfMessage<'a> {
|
||||
pub fn get_profile_pic(&self, global_data: &GlobalData) -> Result<String, WoxlfError> {
|
||||
Ok(match &self.source {
|
||||
MessageSource::Player(p) => p.profile_pic_url.clone(),
|
||||
MessageSource::Host | MessageSource::Automated => {
|
||||
global_data.game_cfg()?.bot_profile_pic.clone()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_message_username(&self, global_data: &GlobalData) -> Result<String, WoxlfError> {
|
||||
Ok(match &self.source {
|
||||
MessageSource::Player(p) => p.codename.clone(),
|
||||
MessageSource::Host => global_data.game_cfg()?.bot_name.clone(),
|
||||
MessageSource::Automated => "Woxlf System Message".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn source(mut self, source: MessageSource) -> Self {
|
||||
self.source = source;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn dest(mut self, dest: MessageDest) -> Self {
|
||||
self.dest = dest;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn median(mut self, median: Median) -> Self {
|
||||
self.median = median;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn content(mut self, content: &str) -> Self {
|
||||
self.content = content.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn attachments(mut self, attachments: Vec<AttachmentType<'a>>) -> Self {
|
||||
self.attachments = Some(attachments);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn flags(mut self, flags: MsgFlags) -> Self {
|
||||
self.flags = flags;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn pin(mut self) -> Self {
|
||||
self.flags |= MsgFlags::PIN_MSG;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_source_channel(player_data: &&PlayerData, msg_source: &MessageSource) -> bool {
|
||||
if let MessageSource::Player(source_player) = &msg_source {
|
||||
|
@ -34,13 +134,13 @@ fn filter_source_channel(player_data: &&PlayerData, msg_source: &MessageSource)
|
|||
|
||||
async fn send_webhook_msg(
|
||||
http: &Http,
|
||||
webhook_id: u64,
|
||||
webhook_id: WebhookId,
|
||||
username: &str,
|
||||
profile_pic_url: Option<String>,
|
||||
msg: &str,
|
||||
attachments: &Option<Vec<AttachmentType<'_>>>,
|
||||
) -> error::Result<()> {
|
||||
let webhook = http.get_webhook(webhook_id).await?;
|
||||
let webhook = http.get_webhook(webhook_id.0).await?;
|
||||
|
||||
webhook
|
||||
.execute(http, false, move |w| {
|
||||
|
@ -93,15 +193,10 @@ async fn send_private_message(
|
|||
async fn send_to_host_channel(
|
||||
http: &Http,
|
||||
guild: &Guild,
|
||||
global_data: &mut GlobalData,
|
||||
msg_username: &str,
|
||||
msg_source: MessageSource,
|
||||
msg_dest: MessageDest,
|
||||
profile_pic_url: Option<String>,
|
||||
msg: &str,
|
||||
attachments: &Option<Vec<AttachmentType<'_>>>,
|
||||
global_data: &GlobalData,
|
||||
msg: WoxlfMessage<'_>,
|
||||
) -> error::Result<()> {
|
||||
let source = match &msg_source {
|
||||
let source = match &msg.source {
|
||||
MessageSource::Player(player_data) => {
|
||||
let name = guild
|
||||
.members
|
||||
|
@ -115,113 +210,106 @@ async fn send_to_host_channel(
|
|||
MessageSource::Automated => "Automated".to_string(),
|
||||
};
|
||||
|
||||
let dest = match &msg_dest {
|
||||
MessageDest::PlayerChannel(p) | MessageDest::PlayerDm(p) => {
|
||||
let name = guild
|
||||
.members
|
||||
.get(&UserId::from(p.discord_id))
|
||||
.unwrap()
|
||||
.display_name();
|
||||
|
||||
format!(" to {} ({})", p.codename, name)
|
||||
let dest = match &msg.median {
|
||||
Median::DirectMessage => {
|
||||
if let MessageDest::Player(dest_player) = &msg.dest {
|
||||
let name = guild
|
||||
.members
|
||||
.get(&UserId::from(dest_player.discord_id))
|
||||
.unwrap()
|
||||
.display_name();
|
||||
format!(" to {} ({})", dest_player.codename, name)
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
}
|
||||
MessageDest::Broadcast => "".to_string(),
|
||||
_ => "".to_string(),
|
||||
};
|
||||
|
||||
let host_channel_username = format!("{} ({}){}", msg_username, source, dest);
|
||||
let host_channel_username = format!(
|
||||
"{} ({}){}",
|
||||
msg.get_message_username(global_data)?,
|
||||
source,
|
||||
dest
|
||||
);
|
||||
|
||||
send_webhook_msg(
|
||||
http,
|
||||
global_data.cfg.discord_config.host_webhook_id,
|
||||
WebhookId::from(global_data.cfg.discord_config.host_webhook_id),
|
||||
&host_channel_username,
|
||||
profile_pic_url,
|
||||
msg,
|
||||
attachments,
|
||||
Some(msg.get_profile_pic(global_data)?),
|
||||
&msg.content,
|
||||
&msg.attachments,
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn send_message(
|
||||
ctx: &Context,
|
||||
global_data: &GlobalData,
|
||||
msg: &WoxlfMessage<'_>,
|
||||
dest_player: &PlayerData,
|
||||
) -> Result<(), WoxlfError> {
|
||||
match &msg.median {
|
||||
Median::Webhook => {
|
||||
send_webhook_msg(
|
||||
&ctx.http,
|
||||
WebhookId::from(dest_player.channel_webhook_id),
|
||||
&msg.get_message_username(global_data)?,
|
||||
Some(msg.get_profile_pic(global_data)?),
|
||||
&msg.content,
|
||||
&msg.attachments,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Median::DirectMessage => {
|
||||
send_private_message(
|
||||
&ctx.http,
|
||||
&msg.get_message_username(global_data)?,
|
||||
UserId(dest_player.discord_id),
|
||||
&msg.content,
|
||||
&msg.attachments,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Median::StandardMessage => {
|
||||
let channel = ChannelId::from(dest_player.channel);
|
||||
channel.say(&ctx.http(), &msg.content).await?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn dispatch_message(
|
||||
ctx: &Context,
|
||||
guild: &Guild,
|
||||
global_data: &mut GlobalData,
|
||||
msg_source: MessageSource,
|
||||
msg_dest: MessageDest,
|
||||
msg: &str,
|
||||
attachments: Option<Vec<AttachmentType<'_>>>,
|
||||
global_data: &GlobalData,
|
||||
msg: WoxlfMessage<'_>,
|
||||
) -> error::Result<()> {
|
||||
let msg_username = match &msg_source {
|
||||
MessageSource::Player(p) => p.codename.clone(),
|
||||
MessageSource::Host => "Woxlf".to_string(),
|
||||
MessageSource::Automated => "Woxlf System Message".to_string(),
|
||||
};
|
||||
let guild_id = global_data.cfg.discord_config.guild_id;
|
||||
let guild = GuildId::from(guild_id).to_guild_cached(&ctx.cache).unwrap();
|
||||
|
||||
let profile_pic = match &msg_source {
|
||||
MessageSource::Player(p) => Some(p.profile_pic_url.clone()),
|
||||
MessageSource::Host | MessageSource::Automated => {
|
||||
Some(global_data.game_cfg()?.bot_profile_pic.clone())
|
||||
}
|
||||
};
|
||||
|
||||
let msg_tasks: Vec<&PlayerData> = global_data
|
||||
.game_state_mut()?
|
||||
let msg_tasks = global_data
|
||||
.game_state()?
|
||||
.player_data
|
||||
.iter()
|
||||
.filter(|player| filter_source_channel(player, &msg_source))
|
||||
.filter(|player| filter_source_channel(player, &msg.source))
|
||||
.filter(|player| match &msg.dest {
|
||||
MessageDest::Player(dest_user) => dest_user.discord_id == player.discord_id,
|
||||
MessageDest::Host => false,
|
||||
MessageDest::Broadcast => true,
|
||||
})
|
||||
.map(|p| send_message(ctx, global_data, &msg, p));
|
||||
|
||||
let results: Result<(), WoxlfError> = futures::future::join_all(msg_tasks)
|
||||
.await
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
for player_data in msg_tasks {
|
||||
match &msg_dest {
|
||||
MessageDest::PlayerChannel(dest_player) => {
|
||||
if dest_player.discord_id == player_data.discord_id {
|
||||
send_webhook_msg(
|
||||
&ctx.http,
|
||||
player_data.channel_webhook_id,
|
||||
&msg_username,
|
||||
profile_pic.clone(),
|
||||
msg,
|
||||
&attachments,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
MessageDest::PlayerDm(dest_player) => {
|
||||
send_private_message(
|
||||
&ctx.http,
|
||||
&msg_username,
|
||||
UserId(dest_player.discord_id),
|
||||
msg,
|
||||
&attachments,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
MessageDest::Broadcast => {
|
||||
send_webhook_msg(
|
||||
&ctx.http,
|
||||
player_data.channel_webhook_id,
|
||||
&msg_username,
|
||||
profile_pic.clone(),
|
||||
msg,
|
||||
&attachments,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
}
|
||||
}
|
||||
results?;
|
||||
|
||||
send_to_host_channel(
|
||||
&ctx.http,
|
||||
guild,
|
||||
global_data,
|
||||
&msg_username,
|
||||
msg_source,
|
||||
msg_dest,
|
||||
profile_pic,
|
||||
msg,
|
||||
&attachments,
|
||||
)
|
||||
.await?;
|
||||
send_to_host_channel(&ctx.http, &guild, global_data, msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue