Upload images from Matrix to Discord

legacy
Charlotte Som 2021-10-04 17:37:22 +01:00
parent ee5e9611cf
commit 4f9e2f5b5c
5 changed files with 71 additions and 21 deletions

View File

@ -4,9 +4,11 @@ use sled::Db;
use crate::{ use crate::{
channels::ChannelReference, channels::ChannelReference,
discord::{self, delete_on_discord, edit_on_discord, forward_to_discord}, discord::{
self, delete_on_discord, edit_on_discord, forward_image_to_discord, forward_to_discord,
},
matrix::{self, delete_on_matrix, edit_on_matrix, forward_to_matrix}, matrix::{self, delete_on_matrix, edit_on_matrix, forward_to_matrix},
messages::{DeletedMessage, EditedMessage, MessageReference, SentMediaMessage, SentMessage}, messages::{DeletedMessage, EditedMessage, MessageReference, SentImageMessage, SentMessage},
}; };
pub struct Bridgers { pub struct Bridgers {
@ -278,21 +280,26 @@ impl Bridgers {
} }
} }
pub async fn send_media(&self, message: SentMediaMessage) { pub async fn send_image(&self, message: SentImageMessage) {
if self.get_related_messages(&message.source).is_some() { if self.get_related_messages(&message.source).is_some() {
return; return;
} }
if let Some(_discord) = self.discord.lock().unwrap().borrow().as_ref() { let mut related_messages = vec![message.source.clone()];
if let Some(_discord_channel) = self.get_linked_discord_channel(&message.source) {
// TODO: Send the media if let Some(discord) = self.discord.lock().unwrap().borrow().as_ref() {
if let Some(discord_channel) = self.get_linked_discord_channel(&message.source) {
if let Some(m) = forward_image_to_discord(discord, discord_channel, &message).await
{
related_messages.push(m);
}
} }
} }
if let Some(_matrix) = self.matrix.lock().unwrap().borrow().as_ref() { if let Some(_matrix) = self.matrix.lock().unwrap().borrow().as_ref() {
if let Some(_room_id) = self.get_linked_matrix_room(&message.source) { if let Some(_room_id) = self.get_linked_matrix_room(&message.source) {}
// TODO: Send the media
}
} }
self.store_related_messages(&related_messages);
} }
} }

View File

@ -1,12 +1,13 @@
use log::info; use log::info;
use serenity::{async_trait, model::prelude::*, prelude::*}; use serenity::{async_trait, http::AttachmentType, model::prelude::*, prelude::*};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use crate::{ use crate::{
channels::ChannelReference, channels::ChannelReference,
message_ast::{self, format_discord}, message_ast::{self, format_discord},
messages::{ messages::{
DeletedMessage, EditedMessage, MessageAuthor, MessageEvent, MessageReference, SentMessage, DeletedMessage, EditedMessage, MessageAuthor, MessageEvent, MessageReference,
SentImageMessage, SentMessage,
}, },
}; };
@ -250,7 +251,12 @@ pub async fn forward_to_discord(
channel channel
.send_message(discord_ctx, |m| { .send_message(discord_ctx, |m| {
let content = format_discord(&message.content); let content = format!(
"{} ({}): {}",
&message.author.display_name,
&message.author.service_name,
format_discord(&message.content)
);
if let Some((channel_id, message_id)) = reply { if let Some((channel_id, message_id)) = reply {
m.content(&content) m.content(&content)
@ -311,6 +317,42 @@ pub async fn delete_on_discord(
.is_ok() .is_ok()
} }
pub async fn forward_image_to_discord(
discord_ctx: &Context,
channel_id: ChannelId,
image: &SentImageMessage,
) -> Option<MessageReference> {
if let Some(webhook) = get_or_create_webhook_for_channel(discord_ctx, &channel_id).await {
return webhook
.execute(discord_ctx, true, |w| {
w.add_file(AttachmentType::Image(&image.image_url))
.username(format!(
"{} ({})",
&image.author.display_name, &image.author.service_name
))
.avatar_url(&image.author.avatar_url)
})
.await
.ok()
.flatten()
.as_ref()
.map(MessageReference::from);
}
channel_id
.send_message(discord_ctx, |m| {
m.add_file(AttachmentType::Image(&image.image_url))
.content(format!(
"{} ({}):",
&image.author.display_name, &image.author.service_name
))
})
.await
.as_ref()
.ok()
.map(MessageReference::from)
}
pub async fn create_discord_client( pub async fn create_discord_client(
ctx_tx: mpsc::UnboundedSender<Context>, ctx_tx: mpsc::UnboundedSender<Context>,
message_tx: mpsc::UnboundedSender<MessageEvent>, message_tx: mpsc::UnboundedSender<MessageEvent>,

View File

@ -96,8 +96,8 @@ async fn main() {
MessageEvent::Delete(deleted_message) => { MessageEvent::Delete(deleted_message) => {
bridgers.delete_message(*deleted_message).await; bridgers.delete_message(*deleted_message).await;
} }
MessageEvent::SendMedia(sent_media) => { MessageEvent::SendImage(sent_media) => {
bridgers.send_media(*sent_media).await; bridgers.send_image(*sent_media).await;
} }
MessageEvent::AdminLinkChannels(channels) => { MessageEvent::AdminLinkChannels(channels) => {

View File

@ -38,7 +38,7 @@ use crate::{
}, },
messages::{ messages::{
DeletedMessage, EditedMessage, MessageAuthor, MessageEvent, MessageReference, DeletedMessage, EditedMessage, MessageAuthor, MessageEvent, MessageReference,
SentMediaMessage, SentMessage, SentImageMessage, SentMessage,
}, },
}; };
@ -211,21 +211,22 @@ async fn on_message_sent(
if let Some((server_name, hash)) = uri.parts() { if let Some((server_name, hash)) = uri.parts() {
let server_name = server_name.as_str(); let server_name = server_name.as_str();
let media_url = format!( let image_url = format!(
"https://{}/_matrix/media/r0/download/{}/{}", "https://{}/_matrix/media/r0/download/{}/{}",
server_name, server_name, hash server_name, server_name, hash
); );
Some(MessageEvent::SendMedia(Box::new(SentMediaMessage { Some(MessageEvent::SendImage(Box::new(SentImageMessage {
source: message_ref, source: message_ref,
author, author,
media_url, image_url,
}))) })))
} else { } else {
None None
} }
} }
// TODO: Handle encrypted image uploads (we will have to decrypt it and upload it somewhere)
matrix_sdk::media::MediaType::Encrypted(_encrypted_file) => None, matrix_sdk::media::MediaType::Encrypted(_encrypted_file) => None,
} }
} else { } else {

View File

@ -28,10 +28,10 @@ pub struct EditedMessage {
pub author: MessageAuthor, pub author: MessageAuthor,
} }
pub struct SentMediaMessage { pub struct SentImageMessage {
pub source: MessageReference, pub source: MessageReference,
pub author: MessageAuthor, pub author: MessageAuthor,
pub media_url: String, pub image_url: String,
} }
pub struct DeletedMessage { pub struct DeletedMessage {
@ -42,6 +42,6 @@ pub enum MessageEvent {
AdminLinkChannels(Vec<ChannelReference>), AdminLinkChannels(Vec<ChannelReference>),
SendText(Box<SentMessage>), SendText(Box<SentMessage>),
EditText(Box<EditedMessage>), EditText(Box<EditedMessage>),
SendMedia(Box<SentMediaMessage>), SendImage(Box<SentImageMessage>),
Delete(Box<DeletedMessage>), Delete(Box<DeletedMessage>),
} }