added postgres support

This commit is contained in:
2024-02-18 19:04:32 +01:00
parent 38971a9c50
commit 15b79f3fc5
7 changed files with 94 additions and 62 deletions

View File

@@ -1 +1,6 @@
BOT_TOKEN="<Your bot token>" BOT_TOKEN="<Your bot token>"
DB_USER="postgres"
DB_PASSWORD="<Your db password>"
DB_SERVER="localhost"
DB_PORT=0000
DB_NAME="postgres"

View File

@@ -1,6 +1,8 @@
package main package main
import ( import (
"log"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/iancoleman/strcase" "github.com/iancoleman/strcase"
) )
@@ -63,7 +65,7 @@ var short_get_tag_command Command = Command{
func GetTagCommand(s *discordgo.Session, i *discordgo.InteractionCreate, option *discordgo.ApplicationCommandInteractionDataOption) { func GetTagCommand(s *discordgo.Session, i *discordgo.InteractionCreate, option *discordgo.ApplicationCommandInteractionDataOption) {
if i.Type == discordgo.InteractionApplicationCommandAutocomplete { if i.Type == discordgo.InteractionApplicationCommandAutocomplete {
choices := generateDynamicChoices() choices := generateDynamicChoices(i.GuildID)
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionApplicationCommandAutocompleteResult, Type: discordgo.InteractionApplicationCommandAutocompleteResult,
Data: &discordgo.InteractionResponseData{ Data: &discordgo.InteractionResponseData{
@@ -83,15 +85,26 @@ func GetTagCommand(s *discordgo.Session, i *discordgo.InteractionCreate, option
} }
} }
func generateDynamicChoices() []*discordgo.ApplicationCommandOptionChoice { func generateDynamicChoices(guildID string) []*discordgo.ApplicationCommandOptionChoice {
choices := []*discordgo.ApplicationCommandOptionChoice{} choices := []*discordgo.ApplicationCommandOptionChoice{}
keys := tags.getTagKeys() keys, err := getTagKeys(guildID)
for i := 0; i <= len(keys)-1; i++ { if err != nil {
log.Println("Error getting tag keys:", err)
return choices // Return empty choices if there's an error
}
for _, key := range keys {
tagContent, err := getTag(guildID, key) // Assuming you have a getTag function
if err != nil {
log.Println("Error getting tag content:", err)
continue // Skip this tag if there's an error
}
choices = append(choices, &discordgo.ApplicationCommandOptionChoice{ choices = append(choices, &discordgo.ApplicationCommandOptionChoice{
Name: keys[i], Name: key,
Value: tags.Tags[keys[i]], Value: tagContent,
}) })
} }
return choices return choices
} }
@@ -101,7 +114,7 @@ func (tag_command Command) Interaction(s *discordgo.Session, i *discordgo.Intera
GetTagCommand(s, i, i.ApplicationCommandData().Options[0].Options[0]) GetTagCommand(s, i, i.ApplicationCommandData().Options[0].Options[0])
case "add": case "add":
option := i.ApplicationCommandData().Options[0] option := i.ApplicationCommandData().Options[0]
addTag(&tags, strcase.ToSnake(option.Options[0].StringValue()) /*TODO: tag regex*/, option.Options[1].StringValue()) addTag(i.GuildID, strcase.ToSnake(option.Options[0].StringValue()) /*TODO: tag regex*/, option.Options[1].StringValue())
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource, Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{ Data: &discordgo.InteractionResponseData{

View File

@@ -1,3 +0,0 @@
{
"tags": {}
}

3
go.mod
View File

@@ -1,4 +1,4 @@
module github.com/vaporvee/tag-bot module github.com/vaporvee/acecore
go 1.21.6 go 1.21.6
@@ -10,6 +10,7 @@ require (
require ( require (
github.com/gorilla/websocket v1.4.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect
github.com/lib/pq v1.10.9 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
) )

2
go.sum
View File

@@ -6,6 +6,8 @@ github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSAS
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=

16
main.go
View File

@@ -2,21 +2,35 @@ package main
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"database/sql"
"net/url"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/joho/godotenv" "github.com/joho/godotenv"
_ "github.com/lib/pq"
) )
type Command struct { type Command struct {
Definition discordgo.ApplicationCommand Definition discordgo.ApplicationCommand
} }
var db *sql.DB
func main() { func main() {
godotenv.Load() godotenv.Load()
debugTags()
var err error
connStr := "postgresql://" + os.Getenv("DB_USER") + ":" + url.QueryEscape(os.Getenv("DB_PASSWORD")) + "@" + os.Getenv("DB_SERVER") + ":" + string(os.Getenv("DB_PORT")) + "/" + os.Getenv("DB_NAME") + "?sslmode=disable"
db, err = sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
discord, err := discordgo.New("Bot " + os.Getenv("BOT_TOKEN")) discord, err := discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
if err != nil { if err != nil {
fmt.Println("error creating Discord session,", err) fmt.Println("error creating Discord session,", err)

View File

@@ -1,69 +1,69 @@
package main package main
import ( import (
"encoding/json"
"log" "log"
"os"
) )
//DATA WILL ONLY BE USED AS JSON FILE FOR TESTING. SYSTEM WILL BE REPLACED func addTag(guildID, tagName, tagContent string) bool {
var exists bool
type Tags struct { err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM tags WHERE guild_id = $1 AND tag_name = $2)", guildID, tagName).Scan(&exists)
Tags map[string]string `json:"tags"`
}
var tags Tags
var filename string = "data.json"
func readTags() {
bytes, err := os.ReadFile(filename)
if err != nil { if err != nil {
log.Fatalf("Failed to read tags: %v", err) log.Println(err)
} }
err = json.Unmarshal(bytes, &tags) // If the tag exists it updates it but TODO: needs to return a discord message to use the modify command with autocomplete
if exists {
_, err = db.Exec("UPDATE tags SET tag_content = $1 WHERE guild_id = $2 AND tag_name = $3", tagContent, guildID, tagName)
if err != nil { if err != nil {
log.Fatalf("Failed to read tags: %v", err) log.Println(err)
} }
} } else {
_, err = db.Exec("INSERT INTO tags (guild_id, tag_name, tag_content) VALUES ($1, $2, $3)", guildID, tagName, tagContent)
func writeTags() {
jsonBytes, err := json.MarshalIndent(&tags, "", " ")
if err != nil { if err != nil {
log.Fatalf("Failed to write tags: %v", err) log.Println(err)
} }
err = os.WriteFile(filename, jsonBytes, 0644) }
return exists
}
func removeTag(guildID, tagName string) {
var exists bool
err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM tags WHERE guild_id = $1 AND tag_name = $2)", guildID, tagName).Scan(&exists)
if err != nil { if err != nil {
log.Fatalf("Failed to write tags: %v", err) log.Println(err)
}
if exists {
_, err = db.Exec("DELETE FROM tags WHERE guild_id = $1 AND tag_name = $2", guildID, tagName)
if err != nil {
log.Println(err)
}
} }
} }
func addTag(tags *Tags, tagKey string, tagValue string) { func getTagKeys(guildID string) ([]string, error) {
readTags() var keys []string
tags.Tags[tagKey] = tagValue rows, err := db.Query("SELECT tag_name FROM tags WHERE guild_id = $1", guildID)
writeTags() if err != nil {
} return nil, err
func removeTag(tags *Tags, tagKey string) {
readTags()
delete(tags.Tags, tagKey)
writeTags()
}
func (tags Tags) getTagKeys() []string {
readTags()
keys := make([]string, 0, len(tags.Tags))
for k := range tags.Tags {
keys = append(keys, k)
} }
return keys defer rows.Close()
}
func modifyTag(tags *Tags, tagKey string, newTagValue string) { for rows.Next() {
if _, exists := tags.Tags[tagKey]; exists { var key string
tags.Tags[tagKey] = newTagValue if err := rows.Scan(&key); err != nil {
return nil, err
} }
keys = append(keys, key)
}
if err := rows.Err(); err != nil {
return nil, err
}
return keys, nil
} }
func debugTags() { func getTag(guildID, tagName string) (string, error) {
addTag(&tags, "new_command", "a new command description") var tagContent string
err := db.QueryRow("SELECT tag_content FROM tags WHERE guild_id = $1 AND tag_name = $2", guildID, tagName).Scan(&tagContent)
return tagContent, err
} }