init Discord bot

This commit is contained in:
Penguin-71630
2025-12-07 18:40:05 +08:00
parent 0fff1ed54c
commit 067e279a8b
5 changed files with 102 additions and 113 deletions

BIN
bot/assets/Vita-banner.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 KiB

BIN
bot/assets/Vita.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

@@ -18,7 +18,6 @@ type Bot struct {
type Config struct {
Token string
APIClient *api.Client
Prefix string
}
func New(cfg *config.Config) (*Bot, error) {
@@ -37,34 +36,88 @@ func New(cfg *config.Config) (*Bot, error) {
config: &Config{
Token: cfg.DiscordToken,
APIClient: apiClient,
Prefix: cfg.BotPrefix,
},
}
// Register handlers
bot.registerHandlers()
// Set intents
// Set intents - only need guild messages for the ciallo listener
session.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsDirectMessages | discordgo.IntentsMessageContent
return bot, nil
}
func (b *Bot) registerSlashCommands() error {
commands := []*discordgo.ApplicationCommand{
{
Name: "ping",
Description: "Check if bot is responsive",
},
{
Name: "greet",
Description: "Get a friendly greeting",
},
{
Name: "echo",
Description: "Bot repeats what you say",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "message",
Description: "Message to echo",
Required: true,
},
},
},
}
for _, cmd := range commands {
_, err := b.session.ApplicationCommandCreate(b.session.State.User.ID, "", cmd)
if err != nil {
return fmt.Errorf("cannot create command %s: %w", cmd.Name, err)
}
}
return nil
}
func (b *Bot) registerHandlers() {
b.session.AddHandler(b.onReady)
b.session.AddHandler(b.onMessageCreate)
b.session.AddHandler(b.onInteractionCreate)
}
func (b *Bot) onReady(s *discordgo.Session, event *discordgo.Ready) {
log.Printf("Logged in as: %v#%v", s.State.User.Username, s.State.User.Discriminator)
// Register slash commands
if err := b.registerSlashCommands(); err != nil {
log.Printf("Error registering slash commands: %v", err)
}
// Set bot status
err := s.UpdateGameStatus(0, fmt.Sprintf("%shelp for commands", b.config.Prefix))
err := s.UpdateGameStatus(0, "/ping to check status")
if err != nil {
log.Printf("Error setting status: %v", err)
}
}
func (b *Bot) onInteractionCreate(s *discordgo.Session, i *discordgo.InteractionCreate) {
if i.Type != discordgo.InteractionApplicationCommand {
return
}
switch i.ApplicationCommandData().Name {
case "ping":
b.handleSlashPing(s, i)
case "greet":
b.handleSlashGreet(s, i)
case "echo":
b.handleSlashEcho(s, i)
}
}
func (b *Bot) Start() error {
if err := b.session.Open(); err != nil {
return fmt.Errorf("error opening connection: %w", err)

View File

@@ -7,122 +7,65 @@ import (
"github.com/bwmarrin/discordgo"
)
// Message listener for "ciallo"
func (b *Bot) onMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
// Ignore messages from the bot itself
if m.Author.ID == s.State.User.ID {
return
}
// Check if message starts with prefix
if !strings.HasPrefix(m.Content, b.config.Prefix) {
return
}
// Parse command
content := strings.TrimPrefix(m.Content, b.config.Prefix)
args := strings.Fields(content)
if len(args) == 0 {
return
}
command := strings.ToLower(args[0])
commandArgs := args[1:]
// Route commands
switch command {
case "help":
b.handleHelp(s, m)
case "meme":
b.handleMeme(s, m, commandArgs)
case "upload":
b.handleUpload(s, m, commandArgs)
case "search":
b.handleSearch(s, m, commandArgs)
case "aliases":
b.handleAliases(s, m)
case "ping":
b.handlePing(s, m)
default:
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Unknown command: `%s`. Use `%shelp` for available commands.", command, b.config.Prefix))
// Check if message is "ciallo" (case insensitive)
if strings.ToLower(strings.TrimSpace(m.Content)) == "ciallo" {
s.ChannelMessageSend(m.ChannelID, "Ciallo!")
}
}
func (b *Bot) handleHelp(s *discordgo.Session, m *discordgo.MessageCreate) {
embed := &discordgo.MessageEmbed{
Title: "🤖 MemeBot Commands",
Description: "Available commands for the MemeBot",
Color: 0x00ff00,
Fields: []*discordgo.MessageEmbedField{
{
Name: fmt.Sprintf("%shelp", b.config.Prefix),
Value: "Show this help message",
Inline: false,
},
{
Name: fmt.Sprintf("%smeme <alias>", b.config.Prefix),
Value: "Get a meme by alias",
Inline: false,
},
{
Name: fmt.Sprintf("%ssearch <keyword>", b.config.Prefix),
Value: "Search for memes by keyword",
Inline: false,
},
{
Name: fmt.Sprintf("%supload <url> <aliases...>", b.config.Prefix),
Value: "Upload a meme with aliases",
Inline: false,
},
{
Name: fmt.Sprintf("%saliases", b.config.Prefix),
Value: "List all available aliases",
Inline: false,
},
{
Name: fmt.Sprintf("%sping", b.config.Prefix),
Value: "Check if bot is responsive",
Inline: false,
},
// Slash command handlers
func (b *Bot) handleSlashPing(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "pong",
},
}
s.ChannelMessageSendEmbed(m.ChannelID, embed)
})
}
func (b *Bot) handleMeme(s *discordgo.Session, m *discordgo.MessageCreate, args []string) {
if len(args) == 0 {
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Usage: `%smeme <alias>`", b.config.Prefix))
func (b *Bot) handleSlashGreet(s *discordgo.Session, i *discordgo.InteractionCreate) {
var username string
if i.Member != nil {
username = i.Member.User.Username
} else if i.User != nil {
username = i.User.Username
} else {
username = "Unknown"
}
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: fmt.Sprintf("Ciallo, %s!", username),
},
})
}
func (b *Bot) handleSlashEcho(s *discordgo.Session, i *discordgo.InteractionCreate) {
options := i.ApplicationCommandData().Options
if len(options) == 0 {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "No message provided!",
},
})
return
}
alias := strings.Join(args, " ")
message := options[0].StringValue()
// TODO: Implement API call to get meme by alias
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("🔍 Searching for meme with alias: `%s`\n(API integration pending)", alias))
}
func (b *Bot) handleSearch(s *discordgo.Session, m *discordgo.MessageCreate, args []string) {
if len(args) == 0 {
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Usage: `%ssearch <keyword>`", b.config.Prefix))
return
}
keyword := strings.Join(args, " ")
// TODO: Implement API call to search memes
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("🔍 Searching for: `%s`\n(API integration pending)", keyword))
}
func (b *Bot) handleUpload(s *discordgo.Session, m *discordgo.MessageCreate, args []string) {
// TODO: Implement meme upload functionality
s.ChannelMessageSend(m.ChannelID, "📤 Upload functionality coming soon!\n(API integration pending)")
}
func (b *Bot) handleAliases(s *discordgo.Session, m *discordgo.MessageCreate) {
// TODO: Implement API call to get all aliases
s.ChannelMessageSend(m.ChannelID, "📋 Fetching all aliases...\n(API integration pending)")
}
func (b *Bot) handlePing(s *discordgo.Session, m *discordgo.MessageCreate) {
s.ChannelMessageSend(m.ChannelID, "🏓 Pong! Bot is online.")
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: message,
},
})
}

View File

@@ -8,7 +8,6 @@ import (
type Config struct {
DiscordToken string
APIBaseURL string
BotPrefix string
}
func Load() (*Config, error) {
@@ -22,14 +21,8 @@ func Load() (*Config, error) {
apiURL = "http://localhost:8080" // Default
}
prefix := os.Getenv("BOT_PREFIX")
if prefix == "" {
prefix = "!" // Default prefix
}
return &Config{
DiscordToken: token,
APIBaseURL: apiURL,
BotPrefix: prefix,
}, nil
}