diff --git a/client.go b/client.go index 7274c24..2afbf9c 100644 --- a/client.go +++ b/client.go @@ -5,6 +5,7 @@ import ( "encoding/json" "net/http" + "github.com/bwmarrin/discordgo" "go.mongodb.org/mongo-driver/bson/primitive" ) @@ -35,11 +36,16 @@ func (req Request[T]) ToRaw() Request[json.RawMessage] { type OperationName string const ( - OperationNameSyncUser = "SYNC_USER" + OperationNameSyncUser = "SYNC_USER" + OperationNameSendMessage = "SEND_MESSAGE" +) + +type ( + MessageSend = discordgo.MessageSend ) type RequestPayload interface { - json.RawMessage | RequestPayloadSyncUser + json.RawMessage | RequestPayloadSyncUser | RequestPayloadSendMessage } type RequestPayloadSyncUser struct { @@ -47,9 +53,16 @@ type RequestPayloadSyncUser struct { Revoke bool `json:"revoke"` } +type RequestPayloadSendMessage struct { + Channel string `json:"channel"` + Message MessageSend `json:"message"` + Webhook bool `json:"webhook"` +} + type Instance interface { SyncUser(userID primitive.ObjectID) (*http.Response, error) RevokeUser(userID primitive.ObjectID) (*http.Response, error) + SendMessage(channel string, message MessageSend, webhook bool) (*http.Response, error) } type cdInst struct { @@ -94,3 +107,15 @@ func (inst *cdInst) RevokeUser(userID primitive.ObjectID) (*http.Response, error }, }.ToRaw()) } + +// SendMessage implements Instance +func (inst *cdInst) SendMessage(channel string, message discordgo.MessageSend, webhook bool) (*http.Response, error) { + return inst.request(Request[RequestPayloadSendMessage]{ + Operation: OperationNameSendMessage, + Data: RequestPayloadSendMessage{ + Channel: channel, + Message: message, + Webhook: webhook, + }, + }.ToRaw()) +} diff --git a/internal/api/api.go b/internal/api/api.go index e3f9e21..af37d81 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -9,7 +9,7 @@ import ( "github.com/fasthttp/router" "github.com/seventv/common/utils" "github.com/seventv/compactdisc" - "github.com/seventv/compactdisc/internal/api/handler" + "github.com/seventv/compactdisc/internal/api/commands" "github.com/seventv/compactdisc/internal/global" "github.com/valyala/fasthttp" "go.uber.org/zap" @@ -44,7 +44,9 @@ func Start(gctx global.Context) (<-chan uint8, error) { switch body.Operation { case compactdisc.OperationNameSyncUser: - err = handler.SyncUser(gctx, ctx, compactdisc.ConvertRequest[compactdisc.RequestPayloadSyncUser](body)) + err = commands.SyncUser(gctx, ctx, compactdisc.ConvertRequest[compactdisc.RequestPayloadSyncUser](body)) + case compactdisc.OperationNameSendMessage: + err = commands.SendMessage(gctx, ctx, compactdisc.ConvertRequest[compactdisc.RequestPayloadSendMessage](body)) } if err != nil { diff --git a/internal/api/commands/handler.go b/internal/api/commands/handler.go new file mode 100644 index 0000000..cdff10d --- /dev/null +++ b/internal/api/commands/handler.go @@ -0,0 +1 @@ +package commands diff --git a/internal/api/commands/post_message.go b/internal/api/commands/post_message.go new file mode 100644 index 0000000..3369075 --- /dev/null +++ b/internal/api/commands/post_message.go @@ -0,0 +1,59 @@ +package commands + +import ( + "context" + + "github.com/bwmarrin/discordgo" + "github.com/seventv/compactdisc" + "github.com/seventv/compactdisc/internal/global" + "go.uber.org/zap" +) + +func SendMessage(gctx global.Context, ctx context.Context, req compactdisc.Request[compactdisc.RequestPayloadSendMessage]) error { + channelID, ok := gctx.Config().Discord.Channels[req.Data.Channel] + if !ok { + return nil + } + + var webhook *discordgo.Webhook + + if req.Data.Webhook { + hooks, _ := gctx.Inst().Discord.Session().ChannelWebhooks(channelID) + if len(hooks) > 0 { + webhook = hooks[0] + } + } + + z := zap.S().Named("api/SendMessage").With( + "channel_id", channelID, + ) + + var ( + msg *discordgo.Message + err error + ) + + if webhook != nil { + msg, err = gctx.Inst().Discord.Session().WebhookExecute(webhook.ID, webhook.Token, false, &discordgo.WebhookParams{ + Content: req.Data.Message.Content, + Username: gctx.Inst().Discord.Identity().Username, + AvatarURL: gctx.Inst().Discord.Identity().AvatarURL("128"), + TTS: req.Data.Message.TTS, + Files: req.Data.Message.Files, + Components: req.Data.Message.Components, + Embeds: req.Data.Message.Embeds, + AllowedMentions: req.Data.Message.AllowedMentions, + }) + } else { + msg, err = gctx.Inst().Discord.Session().ChannelMessageSendComplex(channelID, &req.Data.Message) + } + + if err != nil { + z.Errorw("failed to send message", "error", err) + return err + } + + z.With("message_id", msg.ID).Info("message sent") + + return nil +} diff --git a/internal/api/handler/sync_user.go b/internal/api/commands/sync_user.go similarity index 99% rename from internal/api/handler/sync_user.go rename to internal/api/commands/sync_user.go index 48ecb19..f432cc4 100644 --- a/internal/api/handler/sync_user.go +++ b/internal/api/commands/sync_user.go @@ -1,4 +1,4 @@ -package handler +package commands import ( "context" diff --git a/internal/api/handler/handler.go b/internal/api/handler/handler.go deleted file mode 100644 index abeebd1..0000000 --- a/internal/api/handler/handler.go +++ /dev/null @@ -1 +0,0 @@ -package handler diff --git a/internal/configure/config.go b/internal/configure/config.go index b449c50..0247eb4 100644 --- a/internal/configure/config.go +++ b/internal/configure/config.go @@ -132,9 +132,10 @@ type Config struct { } `mapstructure:"k8s" json:"k8s"` Discord struct { - GuildID string `mapstructure:"guild_id" json:"guild_id"` - DefaultRoleId string `mapstructure:"default_role_id" json:"default_role_id"` - Token string `mapstructure:"token" json:"token"` + GuildID string `mapstructure:"guild_id" json:"guild_id"` + DefaultRoleId string `mapstructure:"default_role_id" json:"default_role_id"` + Token string `mapstructure:"token" json:"token"` + Channels map[string]string `mapstructure:"channels" json:"channels"` } `mapstructure:"discord" json:"discord"` Redis struct { diff --git a/k8s/production.template.yaml b/k8s/production.template.yaml index e5c7b4d..79b4847 100644 --- a/k8s/production.template.yaml +++ b/k8s/production.template.yaml @@ -102,6 +102,10 @@ data: addr: "0.0.0.0" port: 3000 + discord: + channels: + activity_feed: "817375925271527449" + health: enabled: true bind: 0.0.0.0:9200 diff --git a/k8s/staging.template.yaml b/k8s/staging.template.yaml index e5c7b4d..79b4847 100644 --- a/k8s/staging.template.yaml +++ b/k8s/staging.template.yaml @@ -102,6 +102,10 @@ data: addr: "0.0.0.0" port: 3000 + discord: + channels: + activity_feed: "817375925271527449" + health: enabled: true bind: 0.0.0.0:9200