zynko 0.1.0

Biblioteca oficial para bots do Zynko: API, gateway e voz.
Documentation
//! A message, with shortcuts to answer it, react, edit and delete.

use crate::client::Client;
use crate::error::Result;
use crate::rest::{EditOptions, SendOptions};
use crate::types::*;

/// A message. `message_create` and `message_update` hand these out; [`Client::send`] returns one.
///
/// A MESSAGE_UPDATE is partial (an edit brings the text, a link preview brings `embeds`): the
/// fields it does not carry are left empty.
#[derive(Clone, Debug)]
pub struct Message {
    pub id: Id,
    pub channel_id: Id,
    pub author: User,
    pub content: String,
    pub timestamp: i64,
    pub edited_timestamp: Option<i64>,
    pub reply_to: Option<MessageRef>,
    pub attachments: Vec<Attachment>,
    pub reactions: Vec<ReactionCount>,
    pub embeds: Vec<Embed>,
    pub cards: Vec<Card>,
    pub components: Components,
    /// The command or click this (bot) message answers.
    pub interaction: Option<InteractionRef>,
    /// Only its reader sees it, and it is not kept.
    pub ephemeral: bool,
    pub nonce: Option<String>,
    client: Client,
}

impl Message {
    pub(crate) fn new(client: Client, d: MessageData) -> Self {
        Self {
            id: d.id,
            channel_id: d.channel_id,
            author: d.author,
            content: d.content,
            timestamp: d.timestamp,
            edited_timestamp: d.edited_timestamp,
            reply_to: d.reply_to,
            attachments: d.attachments,
            reactions: d.reactions,
            embeds: d.embeds,
            cards: d.cards,
            components: d.components,
            interaction: d.interaction,
            ephemeral: d.ephemeral,
            nonce: d.nonce,
            client,
        }
    }

    /// The client that saw it.
    pub fn client(&self) -> &Client {
        &self.client
    }

    /// The channel, when the client has seen it.
    pub fn channel(&self) -> Option<Channel> {
        self.client.channel(&self.channel_id)
    }

    /// The server the message is in; `None` in a DM.
    pub fn guild_id(&self) -> Option<Id> {
        self.client
            .cache()
            .channels
            .get(&self.channel_id)
            .and_then(|c| c.guild_id.clone())
    }

    /// The author as a member of the server (nickname, roles); `None` in DMs.
    pub fn member(&self) -> Option<Member> {
        let cache = self.client.cache();
        let guild_id = cache.channels.get(&self.channel_id)?.guild_id.as_ref()?;
        cache
            .guilds
            .get(guild_id)?
            .members
            .get(&self.author.id)
            .cloned()
    }

    /// Whether the author is the bot itself.
    pub fn mine(&self) -> bool {
        self.client
            .cache()
            .user
            .as_ref()
            .is_some_and(|u| u.id == self.author.id)
    }

    /// Answers in the same channel, as a reply to this message.
    pub async fn reply(&self, message: impl Into<SendOptions>) -> Result<Message> {
        let mut opts = message.into();
        opts.reply_to = Some(self.id.clone());
        self.client.send(&self.channel_id, opts).await
    }

    pub async fn react(&self, emoji: &str) -> Result<()> {
        self.client
            .rest()
            .react(&self.channel_id, &self.id, emoji)
            .await
    }

    pub async fn unreact(&self, emoji: &str) -> Result<()> {
        self.client
            .rest()
            .unreact(&self.channel_id, &self.id, emoji)
            .await
    }

    /// Only the author edits: a bot edits its own messages (text, cards, buttons).
    pub async fn edit(&self, edit: impl Into<EditOptions>) -> Result<Message> {
        let d = self
            .client
            .rest()
            .edit_message(&self.channel_id, &self.id, edit)
            .await?;
        Ok(Message::new(self.client.clone(), d))
    }

    /// Deletes it: the bot's own, or others' with **Gerenciar mensagens**.
    pub async fn delete(&self) -> Result<()> {
        self.client
            .rest()
            .delete_message(&self.channel_id, &self.id)
            .await
    }
}