// 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 type MessageType int // Block contains the valid known MessageType values const ( MessageTypeDefault MessageType = iota MessageTypeRecipientAdd MessageTypeRecipientRemove MessageTypeCall MessageTypeChannelNameChange MessageTypeChannelIconChange MessageTypeChannelPinnedMessage MessageTypeGuildMemberJoin ) // 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"` // 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"` } // File stores info about files you e.g. send in messages. type File struct { Name string ContentType string Reader io.Reader } // MessageSend stores all parameters you can send with ChannelMessageSendComplex. type MessageSend struct { Content string `json:"content,omitempty"` Embed *MessageEmbed `json:"embed,omitempty"` Tts bool `json:"tts"` Files []*File `json:"-"` // TODO: Remove this when compatibility is not required. File *File `json:"-"` } // MessageEdit is used to chain parameters via ChannelMessageEditComplex, which // is also where you should get the instance from. type MessageEdit struct { Content *string `json:"content,omitempty"` Embed *MessageEmbed `json:"embed,omitempty"` ID string Channel string } // NewMessageEdit returns a MessageEdit struct, initialized // with the Channel and ID. func NewMessageEdit(channelID string, messageID string) *MessageEdit { return &MessageEdit{ Channel: channelID, ID: messageID, } } // SetContent is the same as setting the variable Content, // except it doesn't take a pointer. func (m *MessageEdit) SetContent(str string) *MessageEdit { m.Content = &str return m } // SetEmbed is a convenience function for setting the embed, // so you can chain commands. func (m *MessageEdit) SetEmbed(embed *MessageEmbed) *MessageEdit { m.Embed = embed return m } // A MessageAttachment stores data for message attachments. type MessageAttachment struct { ID string `json:"id"` URL string `json:"url"` ProxyURL string `json:"proxy_url"` Filename string `json:"filename"` Width int `json:"width"` Height int `json:"height"` Size int `json:"size"` } // MessageEmbedFooter is a part of a MessageEmbed struct. type MessageEmbedFooter struct { Text string `json:"text,omitempty"` IconURL string `json:"icon_url,omitempty"` ProxyIconURL string `json:"proxy_icon_url,omitempty"` } // MessageEmbedImage is a part of a MessageEmbed struct. type MessageEmbedImage struct { URL string `json:"url,omitempty"` ProxyURL string `json:"proxy_url,omitempty"` Width int `json:"width,omitempty"` Height int `json:"height,omitempty"` } // MessageEmbedThumbnail is a part of a MessageEmbed struct. type MessageEmbedThumbnail struct { URL string `json:"url,omitempty"` ProxyURL string `json:"proxy_url,omitempty"` Width int `json:"width,omitempty"` Height int `json:"height,omitempty"` } // MessageEmbedVideo is a part of a MessageEmbed struct. type MessageEmbedVideo struct { URL string `json:"url,omitempty"` ProxyURL string `json:"proxy_url,omitempty"` Width int `json:"width,omitempty"` Height int `json:"height,omitempty"` } // MessageEmbedProvider is a part of a MessageEmbed struct. type MessageEmbedProvider struct { URL string `json:"url,omitempty"` Name string `json:"name,omitempty"` } // MessageEmbedAuthor is a part of a MessageEmbed struct. type MessageEmbedAuthor struct { URL string `json:"url,omitempty"` Name string `json:"name,omitempty"` IconURL string `json:"icon_url,omitempty"` ProxyIconURL string `json:"proxy_icon_url,omitempty"` } // MessageEmbedField is a part of a MessageEmbed struct. type MessageEmbedField struct { Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` Inline bool `json:"inline,omitempty"` } // An MessageEmbed stores data for message embeds. type MessageEmbed struct { URL string `json:"url,omitempty"` Type string `json:"type,omitempty"` Title string `json:"title,omitempty"` Description string `json:"description,omitempty"` Timestamp string `json:"timestamp,omitempty"` Color int `json:"color,omitempty"` Footer *MessageEmbedFooter `json:"footer,omitempty"` Image *MessageEmbedImage `json:"image,omitempty"` Thumbnail *MessageEmbedThumbnail `json:"thumbnail,omitempty"` Video *MessageEmbedVideo `json:"video,omitempty"` Provider *MessageEmbedProvider `json:"provider,omitempty"` Author *MessageEmbedAuthor `json:"author,omitempty"` Fields []*MessageEmbedField `json:"fields,omitempty"` } // MessageReactions holds a reactions object for a message. type MessageReactions struct { Count int `json:"count"` Me bool `json:"me"` Emoji *Emoji `json:"emoji"` } // ContentWithMentionsReplaced will replace all @ 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 }