added postgres support
This commit is contained in:
@@ -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"
|
@@ -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{
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"tags": {}
|
|
||||||
}
|
|
3
go.mod
3
go.mod
@@ -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
2
go.sum
@@ -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
16
main.go
@@ -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)
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user