mirror of
https://github.com/diamondburned/cchat-discord.git
synced 2025-01-23 18:56:39 +00:00
Mostly finished.
Commits will be more descriptive from here on out.
This commit is contained in:
parent
d93cf981a1
commit
87688060e9
141
channel.go
141
channel.go
|
@ -1,9 +1,14 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/segments"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Channel struct {
|
||||
|
@ -13,7 +18,17 @@ type Channel struct {
|
|||
session *Session
|
||||
}
|
||||
|
||||
func NewChannel(s *Session, ch *discord.Channel) *Channel {
|
||||
var (
|
||||
_ cchat.Server = (*Channel)(nil)
|
||||
_ cchat.ServerMessage = (*Channel)(nil)
|
||||
_ cchat.ServerMessageSender = (*Channel)(nil)
|
||||
// _ cchat.ServerMessageSendCompleter = (*Channel)(nil)
|
||||
_ cchat.ServerNickname = (*Channel)(nil)
|
||||
// _ cchat.ServerMessageEditor = (*Channel)(nil)
|
||||
// _ cchat.ServerMessageActioner = (*Channel)(nil)
|
||||
)
|
||||
|
||||
func NewChannel(s *Session, ch discord.Channel) *Channel {
|
||||
return &Channel{
|
||||
id: ch.ID,
|
||||
guildID: ch.GuildID,
|
||||
|
@ -30,6 +45,128 @@ func (ch *Channel) Name() text.Rich {
|
|||
return text.Rich{Content: "#" + ch.name}
|
||||
}
|
||||
|
||||
func (ch *Channel) Nickname(labeler cchat.LabelContainer) error {
|
||||
func (ch *Channel) Nickname(ctx context.Context, labeler cchat.LabelContainer) error {
|
||||
// We don't have a nickname if we're not in a guild.
|
||||
if !ch.guildID.Valid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
state := ch.session.WithContext(ctx)
|
||||
|
||||
// MemberColor should fill up the state cache.
|
||||
c, err := state.MemberColor(ch.guildID, ch.session.userID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to get self member color")
|
||||
}
|
||||
|
||||
m, err := state.Member(ch.guildID, ch.session.userID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to get self member")
|
||||
}
|
||||
|
||||
var rich = text.Rich{Content: m.User.Username}
|
||||
if m.Nick != "" {
|
||||
rich.Content = m.Nick
|
||||
}
|
||||
if c > 0 {
|
||||
rich.Segments = []text.Segment{
|
||||
segments.NewColored(len(rich.Content), c.Uint32()),
|
||||
}
|
||||
}
|
||||
|
||||
labeler.SetLabel(rich)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ch *Channel) JoinServer(ctx context.Context, ct cchat.MessagesContainer) (func(), error) {
|
||||
state := ch.session.WithContext(ctx)
|
||||
|
||||
m, err := state.Messages(ch.id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var addcancel = newCancels()
|
||||
|
||||
if ch.guildID.Valid() {
|
||||
// Create the backlog without any member information.
|
||||
g, err := state.Guild(ch.guildID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to get guild")
|
||||
}
|
||||
|
||||
// Listen to new members before creating the backlog and requesting members.
|
||||
addcancel(ch.session.AddHandler(func(c *gateway.GuildMembersChunkEvent) {
|
||||
m, err := ch.session.Store.Messages(ch.id)
|
||||
if err != nil {
|
||||
// TODO: log
|
||||
return
|
||||
}
|
||||
|
||||
g, err := ch.session.Store.Guild(c.GuildID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, member := range c.Members {
|
||||
// Loop over all messages and replace the author.
|
||||
for _, msg := range m {
|
||||
if msg.Author.ID != member.User.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
ct.UpdateMessage(NewMessageUpdateAuthor(msg, member, *g))
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
for _, m := range m {
|
||||
ct.CreateMessage(NewBacklogMessage(m, ch.session, *g))
|
||||
}
|
||||
|
||||
} else {
|
||||
for _, m := range m {
|
||||
ct.CreateMessage(NewDirectMessage(m))
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the handler.
|
||||
addcancel(
|
||||
ch.session.AddHandler(func(m *gateway.MessageCreateEvent) {
|
||||
ct.CreateMessage(NewMessageWithMember(m.Message, ch.session, m.Member))
|
||||
}),
|
||||
ch.session.AddHandler(func(m *gateway.MessageUpdateEvent) {
|
||||
// If the updated content is empty. TODO: add embed support.
|
||||
if m.Content == "" {
|
||||
return
|
||||
}
|
||||
ct.UpdateMessage(NewMessageUpdateContent(m.Message))
|
||||
}),
|
||||
ch.session.AddHandler(func(m *gateway.MessageDeleteEvent) {
|
||||
ct.DeleteMessage(NewHeaderDelete(m))
|
||||
}),
|
||||
)
|
||||
|
||||
return joinCancels(addcancel()), nil
|
||||
}
|
||||
|
||||
func (ch *Channel) SendMessage(msg cchat.SendableMessage) error {
|
||||
_, err := ch.session.SendText(ch.id, msg.Content())
|
||||
return err
|
||||
}
|
||||
|
||||
func newCancels() func(...func()) []func() {
|
||||
var cancels []func()
|
||||
return func(appended ...func()) []func() {
|
||||
cancels = append(cancels, appended...)
|
||||
return cancels
|
||||
}
|
||||
}
|
||||
|
||||
func joinCancels(cancellers []func()) func() {
|
||||
return func() {
|
||||
for _, c := range cancellers {
|
||||
c()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
3
go.mod
3
go.mod
|
@ -4,6 +4,7 @@ go 1.14
|
|||
|
||||
require (
|
||||
github.com/diamondburned/arikawa v0.9.4
|
||||
github.com/diamondburned/cchat v0.0.26
|
||||
github.com/diamondburned/cchat v0.0.28
|
||||
github.com/diamondburned/ningen v0.0.0-20200610212436-159f7105a2be
|
||||
github.com/pkg/errors v0.9.1
|
||||
)
|
||||
|
|
8
go.sum
8
go.sum
|
@ -1,13 +1,21 @@
|
|||
github.com/diamondburned/arikawa v0.8.7-0.20200522214036-530bff74a2c6/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660=
|
||||
github.com/diamondburned/arikawa v0.9.4 h1:Mrp0Vz9R2afbvhWS6m/oLIQy22/uxXb459LUv7qrZPA=
|
||||
github.com/diamondburned/arikawa v0.9.4/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660=
|
||||
github.com/diamondburned/cchat v0.0.26 h1:QBt4d65uzUPJz3jF8b2pJ09Jz8LeBRyG2ol47FOy0g0=
|
||||
github.com/diamondburned/cchat v0.0.26/go.mod h1:+zXktogE45A0om4fT6B/z6Ii7FXNafjxsNspI0rlhbU=
|
||||
github.com/diamondburned/cchat v0.0.28 h1:+1VnltW0rl8/NZTUP+x89jVhi3YTTR+e6iLprZ7HcwM=
|
||||
github.com/diamondburned/cchat v0.0.28/go.mod h1:+zXktogE45A0om4fT6B/z6Ii7FXNafjxsNspI0rlhbU=
|
||||
github.com/diamondburned/ningen v0.0.0-20200610212436-159f7105a2be h1:mUw8X/YzJGFSdL8y3Q/XqyzqPyIMNVSDyZGOP3JXgJA=
|
||||
github.com/diamondburned/ningen v0.0.0-20200610212436-159f7105a2be/go.mod h1:B2hq2B4va1MlnMmXuv9vXmyu9gscxJLmwrmcSB1Les8=
|
||||
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/twmb/murmur3 v1.1.3 h1:D83U0XYKcHRYwYIpBKf3Pks91Z0Byda/9SJ8B6EMRcA=
|
||||
github.com/twmb/murmur3 v1.1.3/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
||||
github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
|
|
51
guild.go
51
guild.go
|
@ -1,37 +1,78 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Guild struct {
|
||||
id discord.Snowflake
|
||||
name string
|
||||
session *Session
|
||||
}
|
||||
|
||||
var (
|
||||
_ cchat.Server = (*Guild)(nil)
|
||||
_ cchat.Icon = (*Guild)(nil)
|
||||
_ cchat.Server = (*Guild)(nil)
|
||||
_ cchat.ServerList = (*Guild)(nil)
|
||||
)
|
||||
|
||||
func NewGuild(s *Session, g *discord.Guild) *Guild {
|
||||
return &Guild{
|
||||
id: g.ID,
|
||||
name: g.Name,
|
||||
session: s,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Guild) self(ctx context.Context) (*discord.Guild, error) {
|
||||
return g.session.WithContext(ctx).Guild(g.id)
|
||||
}
|
||||
|
||||
func (g *Guild) selfState() (*discord.Guild, error) {
|
||||
return g.session.Store.Guild(g.id)
|
||||
}
|
||||
|
||||
func (g *Guild) ID() string {
|
||||
return g.id.String()
|
||||
}
|
||||
|
||||
func (g *Guild) Name() text.Rich {
|
||||
return text.Rich{Content: g.name}
|
||||
s, err := g.selfState()
|
||||
if err != nil {
|
||||
// This shouldn't happen.
|
||||
return text.Rich{Content: g.id.String()}
|
||||
}
|
||||
|
||||
return text.Rich{Content: s.Name}
|
||||
}
|
||||
|
||||
func (g *Guild) Guilds(container cchat.ServersContainer) error {
|
||||
func (g *Guild) Icon(ctx context.Context, iconer cchat.IconContainer) error {
|
||||
s, err := g.self(ctx)
|
||||
if err != nil {
|
||||
// This shouldn't happen.
|
||||
return errors.Wrap(err, "Failed to get guild")
|
||||
}
|
||||
|
||||
if s.Icon != "" {
|
||||
iconer.SetIcon(s.IconURL() + "?size=64")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Guild) Servers(container cchat.ServersContainer) error {
|
||||
c, err := g.session.Channels(g.id)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to get channels")
|
||||
}
|
||||
|
||||
var channels = make([]cchat.Server, len(c))
|
||||
for i := range c {
|
||||
channels[i] = NewChannel(g.session, c[i])
|
||||
}
|
||||
|
||||
container.SetServers(channels)
|
||||
return nil
|
||||
}
|
||||
|
|
193
message.go
Normal file
193
message.go
Normal file
|
@ -0,0 +1,193 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/segments"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
)
|
||||
|
||||
type messageHeader struct {
|
||||
id discord.Snowflake
|
||||
time discord.Timestamp
|
||||
channelID discord.Snowflake
|
||||
guildID discord.Snowflake
|
||||
nonce string
|
||||
}
|
||||
|
||||
var _ cchat.MessageHeader = (*messageHeader)(nil)
|
||||
|
||||
func newHeader(msg discord.Message) messageHeader {
|
||||
var h = messageHeader{
|
||||
id: msg.ID,
|
||||
time: msg.Timestamp,
|
||||
channelID: msg.ChannelID,
|
||||
guildID: msg.GuildID,
|
||||
nonce: msg.Nonce,
|
||||
}
|
||||
if msg.EditedTimestamp.Valid() {
|
||||
h.time = msg.EditedTimestamp
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func NewHeaderDelete(d *gateway.MessageDeleteEvent) messageHeader {
|
||||
return messageHeader{
|
||||
id: d.ID,
|
||||
time: discord.Timestamp(time.Now()),
|
||||
channelID: d.ChannelID,
|
||||
guildID: d.GuildID,
|
||||
}
|
||||
}
|
||||
|
||||
func (m messageHeader) ID() string {
|
||||
return m.id.String()
|
||||
}
|
||||
|
||||
func (m messageHeader) Time() time.Time {
|
||||
return m.time.Time()
|
||||
}
|
||||
|
||||
type Author struct {
|
||||
id discord.Snowflake
|
||||
name text.Rich
|
||||
avatar string
|
||||
}
|
||||
|
||||
func NewUser(u discord.User) Author {
|
||||
return Author{
|
||||
id: u.ID,
|
||||
name: text.Rich{Content: u.Username},
|
||||
avatar: u.AvatarURL() + "?size=128",
|
||||
}
|
||||
}
|
||||
|
||||
func NewGuildMember(m discord.Member, g discord.Guild) Author {
|
||||
var name = text.Rich{
|
||||
Content: m.User.Username,
|
||||
}
|
||||
|
||||
// Update the nickname.
|
||||
if m.Nick != "" {
|
||||
name.Content = m.Nick
|
||||
}
|
||||
|
||||
// Update the color.
|
||||
if c := discord.MemberColor(g, m); c > 0 {
|
||||
name.Segments = []text.Segment{
|
||||
segments.NewColored(len(name.Content), c.Uint32()),
|
||||
}
|
||||
}
|
||||
|
||||
return Author{
|
||||
id: m.User.ID,
|
||||
name: name,
|
||||
avatar: m.User.AvatarURL() + "?size=128",
|
||||
}
|
||||
}
|
||||
|
||||
func (a Author) ID() string {
|
||||
return a.id.String()
|
||||
}
|
||||
|
||||
func (a Author) Name() text.Rich {
|
||||
return a.name
|
||||
}
|
||||
|
||||
func (a Author) Avatar() string {
|
||||
return a.avatar
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
messageHeader
|
||||
|
||||
author Author
|
||||
content text.Rich
|
||||
|
||||
// TODO
|
||||
mentioned bool
|
||||
}
|
||||
|
||||
func NewMessageUpdateContent(msg discord.Message) Message {
|
||||
return Message{
|
||||
messageHeader: newHeader(msg),
|
||||
content: text.Rich{Content: msg.Content},
|
||||
}
|
||||
}
|
||||
|
||||
func NewMessageUpdateAuthor(msg discord.Message, member discord.Member, g discord.Guild) Message {
|
||||
return Message{
|
||||
messageHeader: newHeader(msg),
|
||||
author: NewGuildMember(member, g),
|
||||
}
|
||||
}
|
||||
|
||||
// NewMessageWithSession uses the session to create a message. It does not do
|
||||
// API calls. Member is optional.
|
||||
func NewMessageWithMember(m discord.Message, s *Session, mem *discord.Member) Message {
|
||||
// This should not error.
|
||||
g, err := s.Store.Guild(m.GuildID)
|
||||
if err != nil {
|
||||
return NewMessage(m, NewUser(m.Author))
|
||||
}
|
||||
|
||||
if mem == nil {
|
||||
mem, _ = s.Store.Member(m.GuildID, m.Author.ID)
|
||||
}
|
||||
if mem == nil {
|
||||
s.Members.RequestMember(m.GuildID, m.Author.ID)
|
||||
return NewMessage(m, NewUser(m.Author))
|
||||
}
|
||||
|
||||
return NewMessage(m, NewGuildMember(*mem, *g))
|
||||
}
|
||||
|
||||
// NewBacklogMessage uses the session to create a message fetched from the
|
||||
// backlog. It takes in an existing guild and tries to fetch a new member, if
|
||||
// it's nil.
|
||||
func NewBacklogMessage(m discord.Message, s *Session, g discord.Guild) Message {
|
||||
// If the message doesn't have a guild, then we don't need all the
|
||||
// complicated member fetching process.
|
||||
if !m.GuildID.Valid() {
|
||||
return NewMessage(m, NewUser(m.Author))
|
||||
}
|
||||
|
||||
mem, err := s.Store.Member(m.GuildID, m.Author.ID)
|
||||
if err != nil {
|
||||
s.Members.RequestMember(m.GuildID, m.Author.ID)
|
||||
return NewMessage(m, NewUser(m.Author))
|
||||
}
|
||||
|
||||
return NewMessage(m, NewGuildMember(*mem, g))
|
||||
}
|
||||
|
||||
func NewDirectMessage(m discord.Message) Message {
|
||||
return NewMessage(m, NewUser(m.Author))
|
||||
}
|
||||
|
||||
func NewMessage(m discord.Message, author Author) Message {
|
||||
return Message{
|
||||
messageHeader: newHeader(m),
|
||||
author: author,
|
||||
content: text.Rich{Content: m.Content},
|
||||
}
|
||||
}
|
||||
|
||||
func (m Message) Author() cchat.MessageAuthor {
|
||||
return m.author
|
||||
}
|
||||
|
||||
func (m Message) Content() text.Rich {
|
||||
return m.content
|
||||
}
|
||||
|
||||
func (m Message) Nonce() string {
|
||||
return m.nonce
|
||||
}
|
||||
|
||||
func (m Message) Mentioned() bool {
|
||||
return m.mentioned
|
||||
}
|
25
segments/segments.go
Normal file
25
segments/segments.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package segments
|
||||
|
||||
import "github.com/diamondburned/cchat/text"
|
||||
|
||||
type Colored struct {
|
||||
strlen int
|
||||
color uint32
|
||||
}
|
||||
|
||||
var (
|
||||
_ text.Colorer = (*Colored)(nil)
|
||||
_ text.Segment = (*Colored)(nil)
|
||||
)
|
||||
|
||||
func NewColored(strlen int, color uint32) Colored {
|
||||
return Colored{strlen, color}
|
||||
}
|
||||
|
||||
func (color Colored) Bounds() (start, end int) {
|
||||
return 0, color.strlen
|
||||
}
|
||||
|
||||
func (color Colored) Color() uint32 {
|
||||
return color.color
|
||||
}
|
57
service.go
57
service.go
|
@ -1,24 +1,28 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/state"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/ningen"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Service struct{}
|
||||
|
||||
var (
|
||||
_ cchat.Service = (*Service)(nil)
|
||||
_ cchat.Icon = (*Service)(nil)
|
||||
_ cchat.Service = (*Service)(nil)
|
||||
)
|
||||
|
||||
func (Service) Name() text.Rich {
|
||||
return text.Rich{Content: "Discord"}
|
||||
}
|
||||
|
||||
func (Service) Icon(iconer cchat.IconContainer) error {
|
||||
func (Service) Icon(ctx context.Context, iconer cchat.IconContainer) error {
|
||||
iconer.SetIcon("https://discord.com/assets/2c21aeda16de354ba5334551a883b481.png")
|
||||
return nil
|
||||
}
|
||||
|
@ -51,33 +55,60 @@ func (Authenticator) Authenticate(form []string) (cchat.Session, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return NewSession(s)
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
*ningen.State
|
||||
userID discord.Snowflake
|
||||
}
|
||||
|
||||
var (
|
||||
_ cchat.Icon = (*Session)(nil)
|
||||
_ cchat.Session = (*Session)(nil)
|
||||
_ cchat.ServerList = (*Session)(nil)
|
||||
_ cchat.SessionSaver = (*Session)(nil)
|
||||
)
|
||||
|
||||
func NewSession(s *state.State) (*Session, error) {
|
||||
// Prefetch user.
|
||||
_, err = s.Me()
|
||||
u, err := s.Me()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to get current user")
|
||||
}
|
||||
|
||||
n, err := ningen.FromState(s)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to create a state wrapper")
|
||||
}
|
||||
|
||||
return &Session{
|
||||
State: s,
|
||||
userID: u.ID,
|
||||
State: n,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
*state.State
|
||||
}
|
||||
|
||||
func (s *Session) ID() string {
|
||||
u, _ := s.Store.Me()
|
||||
return u.ID.String()
|
||||
return s.userID.String()
|
||||
}
|
||||
|
||||
func (s *Session) Name() text.Rich {
|
||||
u, _ := s.Store.Me()
|
||||
u, err := s.Store.Me()
|
||||
if err != nil {
|
||||
// This shouldn't happen, ever.
|
||||
return text.Rich{Content: "<@" + s.userID.String() + ">"}
|
||||
}
|
||||
|
||||
return text.Rich{Content: u.Username + "#" + u.Discriminator}
|
||||
}
|
||||
|
||||
func (s *Session) Icon(iconer cchat.IconContainer) error {
|
||||
u, _ := s.Store.Me()
|
||||
func (s *Session) Icon(ctx context.Context, iconer cchat.IconContainer) error {
|
||||
u, err := s.Store.Me()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to get the current user")
|
||||
}
|
||||
|
||||
// Thanks to arikawa, AvatarURL is never empty.
|
||||
iconer.SetIcon(u.AvatarURL())
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue