* Bump to v0.17.0
* Add members from GuildMembersChunk to state (#454)
* Revert "Add members from GuildMembersChunk to state (#454)" (#455)
This reverts commit e4487b30d4
.
* added clarification when initializing discordgo
from the code I ran on my system with the latest changes this seems to be the syntax for the authentication tokens. I'm guessing it was just never updated.
Let me know if this is incorrect.
Thanks!
* travis: update go versions
* Add Pinned member to message struct
Pinned member was missing.
* Missed an :
* Update README.md
* Removed space
294 lines
8.6 KiB
Go
294 lines
8.6 KiB
Go
// Discordgo - Discord bindings for Go
|
|
// Available at https://github.com/bwmarrin/discordgo
|
|
|
|
// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>. 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"`
|
|
|
|
// 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"`
|
|
}
|
|
|
|
// 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 @<id> 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 @<id> 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
|
|
}
|