Layla
6cbe4df36c
Co-authored-by: Layla <layla@layla.gg> Reviewed-on: https://gitea.sumulayla.synology.me/layla/birdbot/pulls/5
221 lines
5.4 KiB
Go
221 lines
5.4 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/yeslayla/birdbot-common/common"
|
|
"github.com/yeslayla/birdbot/core"
|
|
"github.com/yeslayla/birdbot/discord"
|
|
"github.com/yeslayla/birdbot/mastodon"
|
|
"github.com/yeslayla/birdbot/persistence"
|
|
)
|
|
|
|
var Version string
|
|
var Build string
|
|
|
|
type Bot struct {
|
|
Session *discord.Discord
|
|
Mastodon *mastodon.Mastodon
|
|
|
|
Database persistence.Database
|
|
|
|
// Discord Objects
|
|
guildID string
|
|
eventCategoryID string
|
|
archiveCategoryID string
|
|
notificationChannelID string
|
|
|
|
onReadyHandlers [](func() error)
|
|
onNotifyHandlers [](func(string) error)
|
|
|
|
onEventCreatedHandlers [](func(common.Event) error)
|
|
onEventDeletedHandlers [](func(common.Event) error)
|
|
onEventUpdatedHandlers [](func(common.Event) error)
|
|
onEventCompletedHandlers [](func(common.Event) error)
|
|
|
|
chatLinks map[string][]string
|
|
chatHandlers map[string]common.ExternalChatModule
|
|
channelChats map[string][]common.ExternalChatModule
|
|
}
|
|
|
|
// Initalize creates the discord session and registers handlers
|
|
func (app *Bot) Initialize(cfg *core.Config) error {
|
|
|
|
// Load directly from config
|
|
app.guildID = cfg.Discord.GuildID
|
|
app.eventCategoryID = cfg.Discord.EventCategory
|
|
app.archiveCategoryID = cfg.Discord.ArchiveCategory
|
|
app.notificationChannelID = cfg.Discord.NotificationChannel
|
|
app.chatLinks = cfg.Discord.ChatLinks
|
|
|
|
if app.guildID == "" {
|
|
return fmt.Errorf("discord Guild ID is not set")
|
|
}
|
|
if cfg.Discord.ApplicationID == "" {
|
|
return fmt.Errorf("discord Application ID is not set")
|
|
}
|
|
|
|
if cfg.Mastodon.ClientID != "" && cfg.Mastodon.ClientSecret != "" &&
|
|
cfg.Mastodon.Username != "" && cfg.Mastodon.Password != "" &&
|
|
cfg.Mastodon.Server != "" {
|
|
app.Mastodon = mastodon.NewMastodon(cfg.Mastodon.Server, cfg.Mastodon.ClientID, cfg.Mastodon.ClientSecret,
|
|
cfg.Mastodon.Username, cfg.Mastodon.Password)
|
|
}
|
|
|
|
app.Session = discord.New(cfg.Discord.ApplicationID, app.guildID, cfg.Discord.Token, app.Database)
|
|
|
|
// Register Event Handlers
|
|
app.Session.OnReady(app.onReady)
|
|
app.Session.OnEventCreate(app.onEventCreate)
|
|
app.Session.OnEventDelete(app.onEventDelete)
|
|
app.Session.OnEventUpdate(app.onEventUpdate)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Run opens the session with Discord until exit
|
|
func (app *Bot) Run() error {
|
|
|
|
// Intialize submodules
|
|
app.prepareChat()
|
|
|
|
return app.Session.Run()
|
|
}
|
|
|
|
// Stop triggers a graceful shutdown of the app
|
|
func (app *Bot) Stop() {
|
|
log.Print("Shuting down...")
|
|
app.Session.Stop()
|
|
}
|
|
|
|
// Notify sends a message to the notification channe;
|
|
func (app *Bot) Notify(message string) {
|
|
if app.notificationChannelID == "" {
|
|
log.Println(message)
|
|
return
|
|
}
|
|
|
|
log.Print("Notification: ", message)
|
|
|
|
channel := app.Session.NewChannelFromID(app.notificationChannelID)
|
|
if channel == nil {
|
|
log.Printf("Failed notification: channel was not found with ID '%v'", app.notificationChannelID)
|
|
}
|
|
|
|
err := app.Session.SendMessage(channel, message)
|
|
if err != nil {
|
|
log.Print("Failed notification: ", err)
|
|
}
|
|
|
|
for _, handler := range app.onNotifyHandlers {
|
|
if err := handler(message); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (app *Bot) onReady(d *discord.Discord) {
|
|
app.Session.SetStatus(fmt.Sprintf("with fire! (%s)", Version))
|
|
|
|
for _, handler := range app.onReadyHandlers {
|
|
if err := handler(); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (app *Bot) onEventCreate(d *discord.Discord, event common.Event) {
|
|
|
|
log.Print("Event Created: '", event.Name, "':'", event.Location, "'")
|
|
for _, handler := range app.onEventCreatedHandlers {
|
|
if err := handler(event); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func (app *Bot) onEventDelete(d *discord.Discord, event common.Event) {
|
|
|
|
for _, handler := range app.onEventDeletedHandlers {
|
|
if err := handler(event); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func (app *Bot) onEventUpdate(d *discord.Discord, event common.Event) {
|
|
|
|
for _, handler := range app.onEventUpdatedHandlers {
|
|
if err := handler(event); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
// Pass event onwards
|
|
if event.Completed {
|
|
app.onEventComplete(d, event)
|
|
}
|
|
}
|
|
|
|
func (app *Bot) onEventComplete(d *discord.Discord, event common.Event) {
|
|
|
|
for _, handler := range app.onEventCompletedHandlers {
|
|
if err := handler(event); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func (app *Bot) onMessageRecieved(d *discord.Discord, channelID string, user common.User, message string) {
|
|
chats, ok := app.channelChats[channelID]
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
for _, chat := range chats {
|
|
chat.RecieveMessage(user, message)
|
|
}
|
|
}
|
|
|
|
func (app *Bot) prepareChat() {
|
|
|
|
// Associate channels with chat modules
|
|
for channelID, chatHandelerIDs := range app.chatLinks {
|
|
if _, ok := app.channelChats[channelID]; !ok {
|
|
app.channelChats[channelID] = []common.ExternalChatModule{}
|
|
}
|
|
|
|
for _, chatHandlerID := range chatHandelerIDs {
|
|
if handler, ok := app.chatHandlers[chatHandlerID]; ok {
|
|
app.channelChats[channelID] = append(app.channelChats[channelID], handler)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Initialize chat modules
|
|
for channelID, chats := range app.channelChats {
|
|
channel := app.Session.NewChannelFromID(channelID)
|
|
for _, chat := range chats {
|
|
app.InitalizeExternalChat(channel, chat)
|
|
}
|
|
}
|
|
|
|
// Register listener if needed
|
|
if len(app.channelChats) > 0 {
|
|
app.Session.OnMessageRecieved(app.onMessageRecieved)
|
|
}
|
|
}
|
|
|
|
// NewBot creates a new bot instance
|
|
func NewBot(db persistence.Database) *Bot {
|
|
return &Bot{
|
|
Database: db,
|
|
channelChats: make(map[string][]common.ExternalChatModule),
|
|
chatHandlers: make(map[string]common.ExternalChatModule),
|
|
}
|
|
}
|