Recieving messages via the external link
This commit is contained in:
parent
b252d5e62e
commit
77d41bb945
30
app/bot.go
30
app/bot.go
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/yeslayla/birdbot/core"
|
"github.com/yeslayla/birdbot/core"
|
||||||
"github.com/yeslayla/birdbot/discord"
|
"github.com/yeslayla/birdbot/discord"
|
||||||
"github.com/yeslayla/birdbot/mastodon"
|
"github.com/yeslayla/birdbot/mastodon"
|
||||||
|
"github.com/yeslayla/birdbot/persistence"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version string
|
var Version string
|
||||||
@ -17,6 +18,8 @@ type Bot struct {
|
|||||||
Session *discord.Discord
|
Session *discord.Discord
|
||||||
Mastodon *mastodon.Mastodon
|
Mastodon *mastodon.Mastodon
|
||||||
|
|
||||||
|
Database persistence.Database
|
||||||
|
|
||||||
// Discord Objects
|
// Discord Objects
|
||||||
guildID string
|
guildID string
|
||||||
eventCategoryID string
|
eventCategoryID string
|
||||||
@ -31,7 +34,7 @@ type Bot struct {
|
|||||||
onEventUpdatedHandlers [](func(common.Event) error)
|
onEventUpdatedHandlers [](func(common.Event) error)
|
||||||
onEventCompletedHandlers [](func(common.Event) error)
|
onEventCompletedHandlers [](func(common.Event) error)
|
||||||
|
|
||||||
gameModules []common.ChatSyncModule
|
channelChats map[string][]common.ExternalChatModule
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initalize creates the discord session and registers handlers
|
// Initalize creates the discord session and registers handlers
|
||||||
@ -57,7 +60,7 @@ func (app *Bot) Initialize(cfg *core.Config) error {
|
|||||||
cfg.Mastodon.Username, cfg.Mastodon.Password)
|
cfg.Mastodon.Username, cfg.Mastodon.Password)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Session = discord.New(cfg.Discord.ApplicationID, app.guildID, cfg.Discord.Token)
|
app.Session = discord.New(cfg.Discord.ApplicationID, app.guildID, cfg.Discord.Token, app.Database)
|
||||||
|
|
||||||
// Register Event Handlers
|
// Register Event Handlers
|
||||||
app.Session.OnReady(app.onReady)
|
app.Session.OnReady(app.onReady)
|
||||||
@ -65,6 +68,10 @@ func (app *Bot) Initialize(cfg *core.Config) error {
|
|||||||
app.Session.OnEventDelete(app.onEventDelete)
|
app.Session.OnEventDelete(app.onEventDelete)
|
||||||
app.Session.OnEventUpdate(app.onEventUpdate)
|
app.Session.OnEventUpdate(app.onEventUpdate)
|
||||||
|
|
||||||
|
if len(app.channelChats) > 0 {
|
||||||
|
app.Session.OnMessageRecieved(app.onMessageRecieved)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +167,20 @@ func (app *Bot) onEventComplete(d *discord.Discord, event common.Event) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBot creates a new bot instance
|
func (app *Bot) onMessageRecieved(d *discord.Discord, channel string, user common.User, message string) {
|
||||||
func NewBot() *Bot {
|
chats, ok := app.channelChats[channel]
|
||||||
return &Bot{}
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, chat := range chats {
|
||||||
|
chat.RecieveMessage(user, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBot creates a new bot instance
|
||||||
|
func NewBot(db persistence.Database) *Bot {
|
||||||
|
return &Bot{
|
||||||
|
Database: db,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ func (loader *ComponentLoader) OnEventComplete(handler func(common.Event) error)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (loader *ComponentLoader) RegisterChatSyncModule(ID string, plugin common.ChatSyncModule) error {
|
func (loader *ComponentLoader) RegisterExternalChat(ID string, plugin common.ExternalChatModule) error {
|
||||||
return fmt.Errorf("unimplemented")
|
return fmt.Errorf("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
package common
|
|
||||||
|
|
||||||
type ChatSyncModule interface {
|
|
||||||
SendMessage(user string, message string)
|
|
||||||
RecieveMessage(user User, message string)
|
|
||||||
}
|
|
11
common/external_chat.go
Normal file
11
common/external_chat.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
type ExternalChatManager interface {
|
||||||
|
SendMessage(user string, message string)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExternalChatModule interface {
|
||||||
|
Initialize(ExternalChatManager)
|
||||||
|
|
||||||
|
RecieveMessage(user User, message string)
|
||||||
|
}
|
@ -24,5 +24,5 @@ type ModuleManager interface {
|
|||||||
// Commands
|
// Commands
|
||||||
RegisterCommand(string, ChatCommandConfiguration, func(User, map[string]any) string)
|
RegisterCommand(string, ChatCommandConfiguration, func(User, map[string]any) string)
|
||||||
|
|
||||||
RegisterChatSyncModule(ID string, plugin ChatSyncModule) error
|
RegisterExternalChat(ID string, chat ExternalChatModule) error
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/yeslayla/birdbot/common"
|
"github.com/yeslayla/birdbot/common"
|
||||||
|
"github.com/yeslayla/birdbot/persistence"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Discord struct {
|
type Discord struct {
|
||||||
@ -21,12 +22,14 @@ type Discord struct {
|
|||||||
commands map[string]*discordgo.ApplicationCommand
|
commands map[string]*discordgo.ApplicationCommand
|
||||||
commandHandlers map[string]func(session *discordgo.Session, i *discordgo.InteractionCreate)
|
commandHandlers map[string]func(session *discordgo.Session, i *discordgo.InteractionCreate)
|
||||||
|
|
||||||
|
db persistence.Database
|
||||||
|
|
||||||
// Signal for shutdown
|
// Signal for shutdown
|
||||||
stop chan os.Signal
|
stop chan os.Signal
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Discord session
|
// New creates a new Discord session
|
||||||
func New(applicationID string, guildID string, token string) *Discord {
|
func New(applicationID string, guildID string, token string, db persistence.Database) *Discord {
|
||||||
|
|
||||||
// Create Discord Session
|
// Create Discord Session
|
||||||
session, err := discordgo.New(fmt.Sprint("Bot ", token))
|
session, err := discordgo.New(fmt.Sprint("Bot ", token))
|
||||||
@ -35,6 +38,8 @@ func New(applicationID string, guildID string, token string) *Discord {
|
|||||||
}
|
}
|
||||||
session.ShouldReconnectOnError = true
|
session.ShouldReconnectOnError = true
|
||||||
return &Discord{
|
return &Discord{
|
||||||
|
db: db,
|
||||||
|
|
||||||
session: session,
|
session: session,
|
||||||
applicationID: applicationID,
|
applicationID: applicationID,
|
||||||
guildID: guildID,
|
guildID: guildID,
|
||||||
@ -117,6 +122,17 @@ func (discord *Discord) OnEventUpdate(handler func(*Discord, common.Event)) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnMessageRecieved registers a handler when a message is recieved
|
||||||
|
func (discord *Discord) OnMessageRecieved(handler func(*Discord, string, common.User, string)) {
|
||||||
|
discord.session.AddHandler(func(s *discordgo.Session, r *discordgo.MessageCreate) {
|
||||||
|
if r.GuildID != discord.guildID {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
handler(discord, r.ChannelID, NewUser(r.Author), r.Content)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (discord *Discord) SetStatus(status string) {
|
func (discord *Discord) SetStatus(status string) {
|
||||||
if err := discord.session.UpdateGameStatus(0, status); err != nil {
|
if err := discord.session.UpdateGameStatus(0, status); err != nil {
|
||||||
log.Fatal("Failed to update status: ", err)
|
log.Fatal("Failed to update status: ", err)
|
||||||
|
45
discord/message.go
Normal file
45
discord/message.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package discord
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
"github.com/yeslayla/birdbot/core"
|
||||||
|
"github.com/yeslayla/birdbot/persistence"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (discord *Discord) WebhookSendMessage(channel *core.Channel, displayName string, message string) {
|
||||||
|
|
||||||
|
webhookData, err := discord.db.GetDiscordWebhook(channel.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error getting webhook from DB: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if webhookData == nil {
|
||||||
|
webhook, err := discord.session.WebhookCreate(channel.ID, "BirdBot", "")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error creating webhook: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
webhookData = &persistence.DBDiscordWebhook{
|
||||||
|
ID: webhook.ID,
|
||||||
|
Token: webhook.Token,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := discord.db.SetDiscordWebhook(channel.ID, webhookData); err != nil {
|
||||||
|
log.Fatalf("Error failed to store webhook in DB: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = discord.session.WebhookExecute(webhookData.ID, webhookData.Token, false, &discordgo.WebhookParams{
|
||||||
|
Content: message,
|
||||||
|
Username: displayName,
|
||||||
|
}); err != nil {
|
||||||
|
log.Printf("Failed to send message over webhook: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
2
main.go
2
main.go
@ -59,7 +59,7 @@ func main() {
|
|||||||
log.Fatal("Failed to migrate db: ", err)
|
log.Fatal("Failed to migrate db: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bot := app.NewBot()
|
bot := app.NewBot(db)
|
||||||
|
|
||||||
if err := bot.Initialize(cfg); err != nil {
|
if err := bot.Initialize(cfg); err != nil {
|
||||||
log.Fatal("Failed to initialize: ", err)
|
log.Fatal("Failed to initialize: ", err)
|
||||||
|
@ -4,4 +4,12 @@ package persistence
|
|||||||
type Database interface {
|
type Database interface {
|
||||||
GetDiscordMessage(id string) (string, error)
|
GetDiscordMessage(id string) (string, error)
|
||||||
SetDiscordMessage(id string, messageID string) error
|
SetDiscordMessage(id string, messageID string) error
|
||||||
|
|
||||||
|
GetDiscordWebhook(id string) (*DBDiscordWebhook, error)
|
||||||
|
SetDiscordWebhook(id string, data *DBDiscordWebhook) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type DBDiscordWebhook struct {
|
||||||
|
ID string
|
||||||
|
Token string
|
||||||
}
|
}
|
||||||
|
9
persistence/sql/20230617-webhooks.sql
Normal file
9
persistence/sql/20230617-webhooks.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
-- +migrate Up
|
||||||
|
CREATE TABLE IF NOT EXISTS discord_webhooks (
|
||||||
|
id TEXT NOT NULL PRIMARY KEY,
|
||||||
|
webhook_id TEXT NOT NULL,
|
||||||
|
webhook_token TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- +migrate Down
|
||||||
|
DROP TABLE discord_webhooks;
|
@ -120,3 +120,49 @@ func (db *Sqlite3Database) SetDiscordMessage(id string, messageID string) error
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDiscordWebhook finds a discord webhook based on a given local id
|
||||||
|
func (db *Sqlite3Database) GetDiscordWebhook(id string) (*DBDiscordWebhook, error) {
|
||||||
|
|
||||||
|
var data DBDiscordWebhook = DBDiscordWebhook{}
|
||||||
|
row := db.db.QueryRow("SELECT webhook_id, webhook_token FROM discord_webhooks WHERE id = $1", id)
|
||||||
|
|
||||||
|
if err := row.Scan(&data.ID, &data.Token); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("failed to get discord webhook from sqlite3: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDiscordWebhook stores a discord webhook based on a given local id
|
||||||
|
func (db *Sqlite3Database) SetDiscordWebhook(id string, data *DBDiscordWebhook) error {
|
||||||
|
|
||||||
|
statement, err := db.db.Prepare("INSERT OR IGNORE INTO discord_webhooks (id, webhook_id, webhook_token) VALUES (?, ?)")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := statement.Exec(id, data.ID, data.Token)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
n, _ := result.RowsAffected()
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
statement, err := db.db.Prepare("UPDATE discord_webhooks SET webhook_id = (?), webhook_token = (?) WHERE id = (?)")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := statement.Exec(data.ID, data.Token, id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user