diff --git a/.example.env b/.example.env index 4586f11..9c95865 100644 --- a/.example.env +++ b/.example.env @@ -1,5 +1,6 @@ APP_DISCORD_TOKEN= APP_ENV=development +APP_API_URL=http://localhost:3000 # POSTGRES DB_HOST=localhost diff --git a/.gitignore b/.gitignore index fd8bfd6..0100f36 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .env -*.DS_STORE \ No newline at end of file +*.DS_STORE +microservices/* \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..359ff83 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM golang:alpine +RUN mkdir /app +ADD . /app/ +WORKDIR /app +COPY go.mod . +COPY go.sum . +RUN go mod download +RUN go build -o main . +RUN adduser -S -D -H -h /app appuser +USER appuser +CMD ["./main"] \ No newline at end of file diff --git a/config/app.go b/config/app.go index 0b81aa9..f2abe58 100644 --- a/config/app.go +++ b/config/app.go @@ -12,6 +12,7 @@ type AppConfig struct { Env string RootPath string DiscordToken string `split_words:"true" json:"APP_DISCORD_TOKEN"` + ApiUrl string `split_words:"true" json:"APP_API_URL"` } var App *AppConfig diff --git a/docker-compose.yml b/docker-compose.yml index e65718a..217c04b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,5 +13,18 @@ services: networks: - dev_network + # main: + # depends_on: + # - postgres + # build: . + # container_name: main + # restart: always + # env_file: + # - .env + # stdin_open: true + # tty: true + # networks: + # - dev_network + networks: dev_network: diff --git a/pkg/commands/application_commands/modules/utility/ping.go b/pkg/commands/application_commands/modules/utility/ping.go index e0959ec..ab478b6 100644 --- a/pkg/commands/application_commands/modules/utility/ping.go +++ b/pkg/commands/application_commands/modules/utility/ping.go @@ -28,7 +28,7 @@ func (p PingCommand) Run(ctx context.Context, s disgord.Session, interaction *di // Record the current time. t1 := time.Now() - loadingEmbed, _ := utility_embeds.GetPingEmbed(0, 0) + loadingEmbed, _ := utility_embeds.GetPingEmbed(0) // Send a message to measure the time taken to edit it. if err := interaction.Reply(ctx, s, &disgord.CreateInteractionResponse{ @@ -43,13 +43,10 @@ func (p PingCommand) Run(ctx context.Context, s disgord.Session, interaction *di // Record the new time. // Record the time taken to send the message and edit it. t2 := time.Now() - latency := t2.Sub(t1).Milliseconds() - - // Calculate the websocket ping. - ping, _ := s.AvgHeartbeatLatency() + latency := t2.Sub(t1) // Create the embed. - _, updatedEmbed := utility_embeds.GetPingEmbed(latency, ping) + _, updatedEmbed := utility_embeds.GetPingEmbed(latency) // Edit the message with the new embed. if err := interaction.Edit(ctx, s, &disgord.UpdateMessage{ diff --git a/pkg/commands/message_commands/modules/action/baka.go b/pkg/commands/message_commands/modules/action/baka.go new file mode 100644 index 0000000..fa03941 --- /dev/null +++ b/pkg/commands/message_commands/modules/action/baka.go @@ -0,0 +1,48 @@ +package action + +import ( + "context" + + "github.com/BearTS/Tamako/pkg/common/embed_maps/action_embeds" + "github.com/andersfylling/disgord" +) + +// BakaCommand struct +type BakaCommand struct{} + +func (a BakaCommand) Name() string { + return "baka" +} + +func (a BakaCommand) Aliases() []string { + return []string{} +} + +func (a BakaCommand) Help() string { + return "Sends a baka gif" +} + +func (a BakaCommand) Description() string { + return "Sends a baka gif" +} + +func (a BakaCommand) Category() string { + return "action" +} + +func (a BakaCommand) Run(ctx context.Context, s disgord.Session, msg *disgord.Message) error { + var embed *disgord.Embed + + if len(msg.Mentions) > 0 { + embed = action_embeds.GetBakaEmbed(msg.Mentions[0]) + } else { + embed = action_embeds.GetBakaEmbed(msg.Author) + } + + // Send the reply + if _, err := msg.Reply(context.Background(), s, embed); err != nil { + return err + } + + return nil +} diff --git a/pkg/commands/message_commands/modules/enabledModules.go b/pkg/commands/message_commands/modules/enabledModules.go index 940d3b5..39c687e 100644 --- a/pkg/commands/message_commands/modules/enabledModules.go +++ b/pkg/commands/message_commands/modules/enabledModules.go @@ -1,6 +1,7 @@ package modules import ( + "github.com/BearTS/Tamako/pkg/commands/message_commands/modules/action" "github.com/BearTS/Tamako/pkg/commands/message_commands/modules/utility" "github.com/BearTS/Tamako/pkg/interfaces" ) @@ -12,4 +13,7 @@ var CommandsMap = map[string]interfaces.MessageCommand{ utility.HelpCommand{}.Name(): utility.HelpCommand{}, utility.UserInfoCommand{}.Name(): utility.UserInfoCommand{}, utility.ServerinfoCommand{}.Name(): utility.ServerinfoCommand{}, + + // action Commands + action.BakaCommand{}.Name(): action.BakaCommand{}, } diff --git a/pkg/commands/message_commands/modules/utility/ping.go b/pkg/commands/message_commands/modules/utility/ping.go index c200e66..b8d3ecc 100644 --- a/pkg/commands/message_commands/modules/utility/ping.go +++ b/pkg/commands/message_commands/modules/utility/ping.go @@ -2,7 +2,6 @@ package utility import ( "context" - "time" "github.com/BearTS/Tamako/pkg/common/embed_maps/utility_embeds" @@ -33,10 +32,9 @@ func (p PingCommand) Category() string { } func (p PingCommand) Run(ctx context.Context, s disgord.Session, msg *disgord.Message) error { - // Record the current time. - t1 := time.Now() - loadingEmbed, _ := utility_embeds.GetPingEmbed(0, 0) + // Create the loading embed. + loadingEmbed, _ := utility_embeds.GetPingEmbed(0) // Send a message to measure the time taken to edit it. editMsg, err := msg.Reply(context.Background(), s, loadingEmbed) @@ -44,15 +42,11 @@ func (p PingCommand) Run(ctx context.Context, s disgord.Session, msg *disgord.Me return err } - // Record the time taken to send the message and edit it. - t2 := time.Now() - latency := t2.Sub(t1).Milliseconds() - - // Calculate the websocket ping. - ping, _ := s.AvgHeartbeatLatency() + // Check difference between the two times. + ping := editMsg.Timestamp.Time.Sub(msg.Timestamp.Time) // Create the embed. - _, embed := utility_embeds.GetPingEmbed(latency, ping) + _, embed := utility_embeds.GetPingEmbed(ping) // delete the original message. if err = s.Channel(editMsg.ChannelID).Message(editMsg.ID).Delete(); err != nil { @@ -60,24 +54,18 @@ func (p PingCommand) Run(ctx context.Context, s disgord.Session, msg *disgord.Me } // Edit the message with the embed. - editMsg, err = editMsg.Reply(context.Background(), s, embed) + _, err = editMsg.Reply(context.Background(), s, embed) if err != nil { return err } - // Delete the message after 5 seconds. - go deleteMessageAfterDelay(s, editMsg, 5*time.Second) - - // delete the user message after 5 seconds. - go deleteMessageAfterDelay(s, msg, 5*time.Second) - return nil } -func deleteMessageAfterDelay(s disgord.Session, msg *disgord.Message, delay time.Duration) { - <-time.After(delay) - if err := s.Channel(msg.ChannelID).Message(msg.ID).Delete(); err != nil { - return - } -} +// func deleteMessageAfterDelay(s disgord.Session, msg *disgord.Message, delay time.Duration) { +// <-time.After(delay) +// if err := s.Channel(msg.ChannelID).Message(msg.ID).Delete(); err != nil { +// return +// } +// } diff --git a/pkg/commands/message_commands/modules/utility/userinfo.go b/pkg/commands/message_commands/modules/utility/userinfo.go index 8a3641c..96839c3 100644 --- a/pkg/commands/message_commands/modules/utility/userinfo.go +++ b/pkg/commands/message_commands/modules/utility/userinfo.go @@ -2,7 +2,6 @@ package utility import ( "context" - "fmt" "github.com/BearTS/Tamako/pkg/common/embed_maps/utility_embeds" "github.com/BearTS/Tamako/services/logger" @@ -34,7 +33,6 @@ func (u UserInfoCommand) Category() string { func (u UserInfoCommand) Run(ctx context.Context, s disgord.Session, msg *disgord.Message) error { var embed *disgord.Embed - fmt.Println(msg.Mentions) if len(msg.Mentions) > 0 { embed = utility_embeds.GetUserinfoEmbed(msg.Mentions[0]) } else { diff --git a/pkg/common/embed_maps/action_embeds/baka.go b/pkg/common/embed_maps/action_embeds/baka.go new file mode 100644 index 0000000..91c8fff --- /dev/null +++ b/pkg/common/embed_maps/action_embeds/baka.go @@ -0,0 +1,32 @@ +package action_embeds + +import ( + "github.com/BearTS/Tamako/pkg/extensions/main_api/roleplay" + "github.com/BearTS/Tamako/services/logger" + "github.com/andersfylling/disgord" +) + +func GetBakaEmbed(user *disgord.User) *disgord.Embed { + + roleplay, err := roleplay.GetRoleplayData("baka") + if err != nil { + logger.Error("Failed to get roleplay data: %v", err) + } + + url := roleplay.URL + + finalEmbed := &disgord.Embed{ + Title: "Baka~", + Color: 0x00ff00, + Image: &disgord.EmbedImage{ + URL: url, + }, + } + + if user != nil { + description := user.Mention() + " Baka~" + finalEmbed.Description = description + } + + return finalEmbed +} diff --git a/pkg/common/embed_maps/utility_embeds/utility_embeds.go b/pkg/common/embed_maps/utility_embeds/utility_embeds.go index 4d87edf..7fefe47 100644 --- a/pkg/common/embed_maps/utility_embeds/utility_embeds.go +++ b/pkg/common/embed_maps/utility_embeds/utility_embeds.go @@ -4,15 +4,27 @@ import ( "context" "encoding/json" "fmt" + "math/rand" "time" "github.com/BearTS/Tamako/pkg/structs" + "github.com/BearTS/Tamako/services/logger" "github.com/BearTS/Tamako/services/registry" "github.com/andersfylling/disgord" ) // GetPingEmbed returns an embed with the given latency and ping. -func GetPingEmbed(latency int64, ping time.Duration) (*disgord.Embed, *disgord.Embed) { +func GetPingEmbed(ping time.Duration) (*disgord.Embed, *disgord.Embed) { + + pingResponse := []string{ + "I-It\"s not like I wanted to say pong or anything...", + "Pong...", + "Woo! A secret command!", + "Ping! ...I mean **pong!**", + "Does anyone even use this?", + "At your service!", + "Testing, testing, 1, 2, 3!", + } loadingEmbed := &disgord.Embed{ Title: "Pinging...", @@ -21,20 +33,21 @@ func GetPingEmbed(latency int64, ping time.Duration) (*disgord.Embed, *disgord.E } finalEmbed := &disgord.Embed{ - Title: "Pong!", - Color: 0x00ff00, - Fields: []*disgord.EmbedField{ - { - Name: "API Latency", - Value: fmt.Sprintf("%d ms", latency), - Inline: true, - }, - { - Name: "Websocket Ping", - Value: fmt.Sprintf("%d ms", ping), - Inline: true, - }, - }, + Color: 0x00ff00, + Description: fmt.Sprintf("Latency: %d ms", ping.Milliseconds()), + } + + rand.Seed(time.Now().UnixNano()) + randomNumber := rand.Intn(len(pingResponse)) + + // finalEmbed.Fields = append(finalEmbed.Fields, &disgord.EmbedField{ + // Name: "\u200b", + // Value: pingResponse[randomNumber], + // Inline: true, + // }) + + finalEmbed.Footer = &disgord.EmbedFooter{ + Text: pingResponse[randomNumber], } return loadingEmbed, finalEmbed @@ -86,7 +99,7 @@ func GetHelpEmbed(ctx context.Context) *disgord.Embed { // Get From Registry commandsFromRegistry, _ := registry.GetInstance().GetValue("commands") if err := json.Unmarshal(commandsFromRegistry, &commandMap); err != nil { - fmt.Println(err) + logger.Error("Failed to unmarshal commands from registry: %v", err) } for _, command := range commandMap { diff --git a/pkg/events/guild_create.go b/pkg/events/guild_create.go index ab0d30f..63e3951 100644 --- a/pkg/events/guild_create.go +++ b/pkg/events/guild_create.go @@ -2,42 +2,35 @@ package events import ( "context" - "fmt" - "github.com/BearTS/Tamako/pkg/database/postgres" - "github.com/BearTS/Tamako/pkg/database/postgres/gorm/guilds" - "github.com/BearTS/Tamako/pkg/database/postgres/tables" - "github.com/BearTS/Tamako/services/logger" "github.com/andersfylling/disgord" ) func guildCreate(ctx context.Context, client *disgord.Client) { - gormDB, _ := postgres.GetConnection() + // gormDB, _ := postgres.GetConnection() - guildsGorm := guilds.Gorm(gormDB) - - fmt.Println(disgord.AllEvents()) + // guildsGorm := guilds.Gorm(gormDB) // ! This does not work for some reason // Needs further debugging - client.Gateway().GuildCreate(func(session disgord.Session, evt *disgord.GuildCreate) { - logger.Info(fmt.Sprintf("Joined guild %s", evt.Guild.Name)) - _, err := guildsGorm.GetGuildByGuildID(evt.Guild.ID.String()) - if err != nil { - // Guild does not exist in database - // Create guild record + // client.Gateway().GuildCreate(func(session disgord.Session, evt *disgord.GuildCreate) { + // logger.Info(fmt.Sprintf("Joined guild %s", evt.Guild.Name)) + // _, err := guildsGorm.GetGuildByGuildID(evt.Guild.ID.String()) + // if err != nil { + // // Guild does not exist in database + // // Create guild record - var guildRecord tables.Guilds + // var guildRecord tables.Guilds - guildRecord.GuildID = evt.Guild.ID.String() + // guildRecord.GuildID = evt.Guild.ID.String() - _, err := guildsGorm.CreateGuildRecord(guildRecord) - if err != nil { - logger.Error(err, "Error creating guild record") - } - } + // _, err := guildsGorm.CreateGuildRecord(guildRecord) + // if err != nil { + // logger.Error(err, "Error creating guild record") + // } + // } - }) + // }) // This works, but I don't need it right now // client.Gateway().MessageCreate(func(session disgord.Session, evt *disgord.MessageCreate) { diff --git a/pkg/extensions/main_api/roleplay/roleplay.go b/pkg/extensions/main_api/roleplay/roleplay.go new file mode 100644 index 0000000..6d7ac6e --- /dev/null +++ b/pkg/extensions/main_api/roleplay/roleplay.go @@ -0,0 +1,86 @@ +package roleplay + +import ( + "encoding/json" + "io" + "net/http" + + "github.com/BearTS/Tamako/config" + "github.com/BearTS/Tamako/services/logger" + "github.com/pkg/errors" +) + +type roleplayResponse struct { + API string `json:"Api"` + Type string `json:"Type"` + URL string `json:"url"` +} + +var AvailableRoleplayTypes = []string{ + "baka", + "blush", + "bite", + "celebrate", + "cry", + "dance", + "disgust", + "eat", + "explode", + "feed", + "fistbump", + "happy", + "highfive", + "holdhands", + "hug", + "hug", + "inhale", + "kill", + "kiss", + "lick", + "midfing", + "pat", + "poke", + "punch", + "slap", + "sleep", + "smile", + "smug", + "suicide", + "tickle", + "wave", + "wink", +} + +func GetRoleplayData(roleplayType string) (roleplayResponse, error) { + var res roleplayResponse + + url := config.App.ApiUrl + "/roleplay/" + roleplayType + + req, _ := http.NewRequest("GET", url, nil) + + response, err := http.DefaultClient.Do(req) + if err != nil { + err = errors.Wrap(err, "[GetRoleplayData]") + logger.Error(err) + return res, err + } + + if response.StatusCode != 200 { + err = errors.Wrap(err, "Error getting roleplay data") + logger.Error(err) + return res, err + } + + defer response.Body.Close() + body, err := io.ReadAll(response.Body) + if err != nil { + return res, errors.Wrap(err, "[GetRoleplayData][ReadAll]") + } + + err = json.Unmarshal(body, &res) + if err != nil { + return res, errors.Wrap(err, "[GetRoleplayData][Unmarshal]") + } + + return res, nil +}