// Discordgo - Discord bindings for Go // Available at https://github.com/bwmarrin/discordgo // Copyright 2015-2016 Bruce Marriner . All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // This file contains code related to the Message struct package discordgo import ( "io" "regexp" "strings" ) // MessageType is the type of Message // https://discord.com/developers/docs/resources/channel#message-object-message-types type MessageType int // Block contains the valid known MessageType values const ( MessageTypeDefault MessageType = iota MessageTypeRecipientAdd MessageTypeRecipientRemove MessageTypeCall MessageTypeChannelNameChange MessageTypeChannelIconChange MessageTypeChannelPinnedMessage MessageTypeGuildMemberJoin MessageTypeUserPremiumGuildSubscription MessageTypeUserPremiumGuildSubscriptionTierOne MessageTypeUserPremiumGuildSubscriptionTierTwo MessageTypeUserPremiumGuildSubscriptionTierThree MessageTypeChannelFollowAdd MessageTypeGuildDiscoveryDisqualified = iota + 1 MessageTypeGuildDiscoveryRequalified MessageTypeReply = iota + 4 MessageTypeApplicationCommand ) // A Message stores all data related to a specific Discord message. type Message struct { // The ID of the message. ID string `json:"id"` // The ID of the channel in which the message was sent. ChannelID string `json:"channel_id"` // The ID of the guild in which the message was sent. GuildID string `json:"guild_id,omitempty"` // The content of the message. Content string `json:"content"` // The time at which the messsage was sent. // CAUTION: this field may be removed in a // future API version; it is safer to calculate // the creation time via the ID. Timestamp Timestamp `json:"timestamp"` // The time at which the last edit of the message // occurred, if it has been edited. EditedTimestamp Timestamp `json:"edited_timestamp"` // The roles mentioned in the message. MentionRoles []string `json:"mention_roles"` // Whether the message is text-to-speech. TTS bool `json:"tts"` // Whether the message mentions everyone. MentionEveryone bool `json:"mention_everyone"` // The author of the message. This is not guaranteed to be a // valid user (webhook-sent messages do not possess a full author). Author *User `json:"author"` // A list of attachments present in the message. Attachments []*MessageAttachment `json:"attachments"` // A list of embeds present in the message. Multiple // embeds can currently only be sent by webhooks. Embeds []*MessageEmbed `json:"embeds"` // A list of users mentioned in the message. Mentions []*User `json:"mentions"` // A list of reactions to the message. Reactions []*MessageReactions `json:"reactions"` // Whether the message is pinned or not. Pinned bool `json:"pinned"` // The type of the message. Type MessageType `json:"type"` // The webhook ID of the message, if it was generated by a webhook WebhookID string `json:"webhook_id"` // Member properties for this message's author, // contains only partial information Member *Member `json:"member"` // Channels specifically mentioned in this message // Not all channel mentions in a message will appear in mention_channels. // Only textual channels that are visible to everyone in a lurkable guild will ever be included. // Only crossposted messages (via Channel Following) currently include mention_channels at all. // If no mentions in the message meet these requirements, this field will not be sent. MentionChannels []*Channel `json:"mention_channels"` // Is sent with Rich Presence-related chat embeds Activity *MessageActivity `json:"activity"` // Is sent with Rich Presence-related chat embeds Application *MessageApplication `json:"application"` // MessageReference contains reference data sent with crossposted messages MessageReference *MessageReference `json:"message_reference"` // The flags of the message, which describe extra features of a message. // This is a combination of bit masks; the presence of a certain permission can // be checked by performing a bitwise AND between this int and the flag. Flags MessageFlags `json:"flags"` } // GetCustomEmojis pulls out all the custom (Non-unicode) emojis from a message and returns a Slice of the Emoji struct. func (m *Message) GetCustomEmojis() []*Emoji { var toReturn []*Emoji emojis := EmojiRegex.FindAllString(m.Content, -1) if len(emojis) < 1 { return toReturn } for _, em := range emojis { parts := strings.Split(em, ":") toReturn = append(toReturn, &Emoji{ ID: parts[2][:len(parts[2])-1], Name: parts[1], Animated: strings.HasPrefix(em, " mentions with the // username of the mention. func (m *Message) ContentWithMentionsReplaced() (content string) { content = m.Content for _, user := range m.Mentions { content = strings.NewReplacer( "<@"+user.ID+">", "@"+user.Username, "<@!"+user.ID+">", "@"+user.Username, ).Replace(content) } return } var patternChannels = regexp.MustCompile("<#[^>]*>") // ContentWithMoreMentionsReplaced will replace all @ mentions with the // username of the mention, but also role IDs and more. func (m *Message) ContentWithMoreMentionsReplaced(s *Session) (content string, err error) { content = m.Content if !s.StateEnabled { content = m.ContentWithMentionsReplaced() return } channel, err := s.State.Channel(m.ChannelID) if err != nil { content = m.ContentWithMentionsReplaced() return } for _, user := range m.Mentions { nick := user.Username member, err := s.State.Member(channel.GuildID, user.ID) if err == nil && member.Nick != "" { nick = member.Nick } content = strings.NewReplacer( "<@"+user.ID+">", "@"+user.Username, "<@!"+user.ID+">", "@"+nick, ).Replace(content) } for _, roleID := range m.MentionRoles { role, err := s.State.Role(channel.GuildID, roleID) if err != nil || !role.Mentionable { continue } content = strings.Replace(content, "<@&"+role.ID+">", "@"+role.Name, -1) } content = patternChannels.ReplaceAllStringFunc(content, func(mention string) string { channel, err := s.State.Channel(mention[2 : len(mention)-1]) if err != nil || channel.Type == ChannelTypeGuildVoice { return mention } return "#" + channel.Name }) return }