sparkle_impostor/
constructor.rs1use twilight_http::Client;
2use twilight_model::channel::{
3 message::{MessageFlags, MessageType},
4 Message,
5};
6
7use crate::{
8 attachment_sticker, avatar, component, error::Error, later_messages, reaction, reference,
9 thread, MessageSource,
10};
11
12impl<'a> MessageSource<'a> {
13 pub fn from_message(message: &'a Message, http: &'a Client) -> Result<Self, Error> {
39 if message.activity.is_some() || message.application.is_some() {
40 return Err(Error::RichPresence);
41 }
42 if message
43 .flags
44 .is_some_and(|flags| flags.contains(MessageFlags::IS_VOICE_MESSAGE))
45 {
46 return Err(Error::Voice);
47 }
48 if !matches!(message.kind, MessageType::Regular | MessageType::Reply)
49 || message.role_subscription_data.is_some()
50 {
51 return Err(Error::System);
52 }
53 twilight_validate::message::content(&message.content).map_err(|_| Error::ContentInvalid)?;
54
55 let guild_id = message.guild_id.ok_or(Error::NotInGuild)?;
56
57 let url_components = component::filter_valid(&message.components);
58 let has_invalid_components = message.components != url_components;
59
60 let reference_info = message.referenced_message.as_ref().map_or_else(
61 || {
62 if message.kind == MessageType::Reply {
63 reference::Info::UnknownOrDeleted
64 } else {
65 reference::Info::None
66 }
67 },
68 |referenced_message| reference::Info::Reference(referenced_message),
69 );
70
71 let thread_info = message
72 .thread
73 .as_ref()
74 .map_or(thread::Info::Unknown, |thread| {
75 thread::Info::CreatedUnknown(Box::new(thread.clone()))
76 });
77
78 Ok(MessageSource {
79 source_id: message.id,
80 source_channel_id: message.channel_id,
81 source_thread_id: thread_info.id(),
82 content: message.content.clone(),
83 embeds: message.embeds.clone(),
84 tts: message.tts,
85 flags: message.flags,
86 channel_id: message.channel_id,
87 guild_id,
88 guild_emoji_ids: None,
89 username: message
90 .member
91 .as_ref()
92 .and_then(|member| member.nick.as_ref())
93 .unwrap_or(&message.author.name)
94 .clone(),
95 reference_info,
96 avatar_info: avatar::Info {
97 url: None,
98 user_id: message.author.id,
99 guild_id,
100 user_discriminator: message.author.discriminator,
101 user_avatar: message.author.avatar,
102 member_avatar: message.member.as_ref().and_then(|member| member.avatar),
103 },
104 webhook_name: "Message Cloner".to_owned(),
105 reaction_info: reaction::Info {
106 reactions: &message.reactions,
107 },
108 attachment_sticker_info: attachment_sticker::Info {
109 stickers: &message.sticker_items,
110 attachments: &message.attachments,
111 #[cfg(feature = "upload")]
112 attachments_upload: vec![],
113 },
114 component_info: component::Info {
115 url_components,
116 has_invalid_components,
117 },
118 thread_info,
119 webhook: None,
120 later_messages: later_messages::Info {
121 messages: vec![],
122 is_complete: false,
123 is_source_created: false,
124 is_later_message_sources_created: false,
125 },
126 response: None,
127 http,
128 })
129 }
130}