Skip to content
This repository was archived by the owner on Feb 22, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/seventv/common/redis"
"github.com/seventv/common/structures/v3/query"
"github.com/seventv/compactdisc/internal/api"
"github.com/seventv/compactdisc/internal/commands"
"github.com/seventv/compactdisc/internal/configure"
"github.com/seventv/compactdisc/internal/discord"
"github.com/seventv/compactdisc/internal/global"
Expand Down Expand Up @@ -110,6 +111,10 @@ func main() {
}

handler.Register(gctx, gctx.Inst().Discord.Session())
if err := commands.Setup(gctx); err != nil {
zap.S().Fatalw("failed to setup commands", "error", err)
}

zap.S().Infow("discord, ok")
}

Expand Down
24 changes: 12 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ go 1.18

require (
github.com/bugsnag/panicwrap v1.3.4
github.com/bwmarrin/discordgo v0.25.0
github.com/bwmarrin/discordgo v0.26.1
github.com/prometheus/client_golang v1.12.2
github.com/seventv/common v0.0.0-20220723113936-4f27199129f8
github.com/seventv/common v0.0.0-20220830173401-fd12c2bf2f2b
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.12.0
go.uber.org/zap v1.21.0
go.uber.org/zap v1.23.0
)

require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/montanaflynn/stats v0.6.6 // indirect
github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
)
Expand All @@ -26,15 +27,14 @@ require (
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-redsync/redsync/v4 v4.5.1 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/klauspost/compress v1.15.1 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
Expand All @@ -54,15 +54,15 @@ require (
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.mongodb.org/mongo-driver v1.9.0
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
go.mongodb.org/mongo-driver v1.10.1
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
69 changes: 27 additions & 42 deletions go.sum

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/fasthttp/router"
"github.com/seventv/common/utils"
"github.com/seventv/compactdisc"
"github.com/seventv/compactdisc/internal/api/commands"
"github.com/seventv/compactdisc/internal/api/operations"
"github.com/seventv/compactdisc/internal/global"
"github.com/valyala/fasthttp"
"go.uber.org/zap"
Expand Down Expand Up @@ -44,9 +44,9 @@ func Start(gctx global.Context) (<-chan uint8, error) {

switch body.Operation {
case compactdisc.OperationNameSyncUser:
err = commands.SyncUser(gctx, ctx, compactdisc.ConvertRequest[compactdisc.RequestPayloadSyncUser](body))
err = operations.SyncUser(gctx, ctx, compactdisc.ConvertRequest[compactdisc.RequestPayloadSyncUser](body))
case compactdisc.OperationNameSendMessage:
err = commands.SendMessage(gctx, ctx, compactdisc.ConvertRequest[compactdisc.RequestPayloadSendMessage](body))
err = operations.SendMessage(gctx, ctx, compactdisc.ConvertRequest[compactdisc.RequestPayloadSendMessage](body))
}

if err != nil {
Expand Down
1 change: 0 additions & 1 deletion internal/api/commands/handler.go

This file was deleted.

1 change: 1 addition & 0 deletions internal/api/operations/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package operations
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package commands
package operations

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package commands
package operations

import (
"context"
Expand Down Expand Up @@ -126,7 +126,9 @@ func SyncUser(gctx global.Context, ctx context.Context, req compactdisc.Request[
return nil
}

if err := dis.GuildMemberEdit(gctx.Config().Discord.GuildID, member.User.ID, finalRoles); err != nil {
if _, err := dis.GuildMemberEdit(gctx.Config().Discord.GuildID, member.User.ID, &discordgo.GuildMemberParams{
Roles: &finalRoles,
}); err != nil {
z.Errorw("failed to update discord roles")
return err
}
Expand Down
63 changes: 63 additions & 0 deletions internal/commands/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package commands

import (
"github.com/bwmarrin/discordgo"
"github.com/seventv/compactdisc/internal/global"
"go.uber.org/zap"
)

type Command struct {
Data *discordgo.ApplicationCommand
Handler CommandHandler
}

func DefineCommand(data *discordgo.ApplicationCommand, handler CommandHandler) *Command {
return &Command{
Data: data,
Handler: handler,
}
}

type CommandHandler func(session *discordgo.Session, interaction *discordgo.InteractionCreate) error

func Setup(gctx global.Context) error {
disc := gctx.Inst().Discord.Session()
appID := gctx.Inst().Discord.Identity().ID
guildID := gctx.Config().Discord.GuildID

registeredCommands, _ := disc.ApplicationCommands(appID, guildID)
for _, cmd := range registeredCommands {
_ = disc.ApplicationCommandDelete(appID, guildID, cmd.ID)
}

commands := []*Command{
UserInfo(gctx, appID, guildID),
}

for _, cmd := range commands {
_, err := disc.ApplicationCommandCreate(appID, gctx.Config().Discord.GuildID, cmd.Data)
if err != nil {
zap.S().Errorw("failed to setup commands", "error", err)
}

disc.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
if err := cmd.Handler(s, i); err != nil {
zap.S().Errorw("failed to handle command", "command", cmd.Data.Name, "error", err)

err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: err.Error(),
AllowedMentions: &discordgo.MessageAllowedMentions{},
Flags: discordgo.MessageFlagsEphemeral,
},
})
if err != nil {
zap.S().Errorw("failed to respond to command about the failure to handle the command", "error", err)
}
}
})
}

return nil
}
138 changes: 138 additions & 0 deletions internal/commands/user_info.cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package commands

import (
"fmt"
"strings"
"time"

"github.com/bwmarrin/discordgo"
"github.com/seventv/common/structures/v3"
"github.com/seventv/common/utils"
"github.com/seventv/compactdisc/internal/global"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)

// UserInfo retrieves information about a 7TV user via their Discord connection
func UserInfo(gctx global.Context, appID string, guildID string) *Command {
return DefineCommand(
&discordgo.ApplicationCommand{
ID: appID,
ApplicationID: appID,
GuildID: guildID,
Type: discordgo.UserApplicationCommand,
Name: "User Info",
DefaultMemberPermissions: utils.PointerOf(int64(discordgo.PermissionManageRoles)),
DescriptionLocalizations: &map[discordgo.Locale]string{},
},
func(session *discordgo.Session, interaction *discordgo.InteractionCreate) error {
data := interaction.ApplicationCommandData()
userID := data.TargetID

// Fetch the user
user, err := gctx.Inst().Query.Users(gctx, bson.M{
"connections": bson.M{"$elemMatch": bson.M{
"platform": structures.UserConnectionPlatformDiscord,
"id": userID,
}},
}).First()
if err != nil {
return err
}

avatarURL := ""
if user.AvatarID != "" {
avatarURL = fmt.Sprintf("https://%s/pp/%s/%s", gctx.Config().CdnURL, user.ID.Hex(), user.AvatarID)
} else {
for _, con := range user.Connections {
if con.Platform == structures.UserConnectionPlatformTwitch {
if con, err := structures.ConvertUserConnection[structures.UserConnectionDataTwitch](con); err == nil {
avatarURL = con.Data.ProfileImageURL
}
} else if con.Platform == structures.UserConnectionPlatformDiscord {
if con, err := structures.ConvertUserConnection[structures.UserConnectionDataDiscord](con); err == nil {
avatarURL = fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s.png", con.Data.ID, con.Data.Avatar)
}
}
}
}

// Format an embed
embed := &discordgo.MessageEmbed{
Type: discordgo.EmbedTypeRich,
Title: fmt.Sprintf("%s (%s)", user.DisplayName, user.Username),
URL: user.WebURL(gctx.Config().WebsiteURL),
Description: user.Biography,
Author: &discordgo.MessageEmbedAuthor{
URL: user.WebURL(gctx.Config().WebsiteURL),
Name: user.DisplayName,
IconURL: avatarURL,
},
Timestamp: user.ID.Timestamp().Format(time.RFC3339),
Color: int(user.GetHighestRole().Color),
Fields: func() []*discordgo.MessageEmbedField {
fields := make([]*discordgo.MessageEmbedField, 0)

// Add the user's connections
for _, con := range user.Connections {
fields = append(fields, &discordgo.MessageEmbedField{
Name: string(con.Platform),
Value: con.ID,
Inline: true,
})
}

// Add the user's roles
fields = append(fields, &discordgo.MessageEmbedField{
Name: "Roles",
Value: func() string {
roleList := make([]string, len(user.Roles))
for i, role := range user.Roles {
roleList[i] = role.Name
}

return strings.Join(roleList, "\n")
}(),
Inline: false,
})

editorIDs := make([]primitive.ObjectID, len(user.Editors))
for i, editor := range user.Editors {
editorIDs[i] = editor.ID
}

editors, err := gctx.Inst().Query.Users(gctx, bson.M{"_id": bson.M{"$in": editorIDs}}).Items()

if err == nil {
fields = append(fields, &discordgo.MessageEmbedField{
Name: "Editors",
Value: func() string {
editorList := make([]string, len(user.Editors))
for i, u := range editors {
editorList[i] = fmt.Sprintf("[%s (%s)](%s)", u.DisplayName, u.Username, u.WebURL(gctx.Config().WebsiteURL))
}

if len(editorList) == 0 {
return "None"
}

return strings.Join(editorList, "\n")
}(),
Inline: false,
})
}

return fields
}(),
}

return session.InteractionRespond(interaction.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: fmt.Sprintf("**[user]** [%s (%s)](%s)", user.DisplayName, user.Username, user.WebURL(gctx.Config().WebsiteURL)),
Embeds: []*discordgo.MessageEmbed{embed},
},
})
},
)
}
2 changes: 1 addition & 1 deletion internal/discord/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func New(ctx context.Context, token string) (Instance, error) {
}

// Open connection to discord gateway
ses.Identify.Intents = discordgo.MakeIntent(ses.Identify.Intents | discordgo.IntentsGuildMembers | discordgo.IntentDirectMessages)
ses.Identify.Intents = discordgo.MakeIntent(ses.Identify.Intents | discordgo.IntentMessageContent | discordgo.IntentsGuildMembers | discordgo.IntentDirectMessages)
if err := ses.Open(); err != nil {
return nil, err
}
Expand Down
Loading