simpbot/main.go

180 lines
5.3 KiB
Go

package main
import (
"fmt"
"log"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
)
var Homeserver string
var Username string
var Password string
var DimensionServer string
var HomeserverDomain string
var GitCommit string
var Statefile string
func main() {
viper.SetConfigName("config")
viper.AddConfigPath(".")
viper.AddConfigPath("/etc/simpbot")
err := viper.ReadInConfig()
if err != nil {
log.Fatalf("Fatal error config file: %v \n", err)
}
viper.SetConfigType("yaml")
Homeserver = viper.GetString("homeserver")
viper.SetDefault("domain", Homeserver)
viper.SetDefault("statefile", "simpstate")
Username = viper.GetString("username")
Password = viper.GetString("password")
DimensionServer = viper.GetString("dimension")
HomeserverDomain = viper.GetString("domain")
Statefile = viper.GetString("statefile")
var vtubers []*Vtuber
log.Println("Logging into", Homeserver, "as", Username)
client, err := mautrix.NewClient(Homeserver, "", "")
if err != nil {
panic(err)
}
client.Store = NewLazyMemStore(Statefile)
_, err = client.Login(&mautrix.ReqLogin{
Type: "m.login.password",
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: Username},
Password: Password,
StoreCredentials: true,
})
if err != nil {
panic(err)
}
fmt.Println("Login successful")
syncer := client.Syncer.(*mautrix.DefaultSyncer)
syncer.OnEventType(event.EventMessage, func(source mautrix.EventSource, evt *event.Event) {
fmt.Printf("<%[1]s> %[4]s (%[2]s/%[3]s)\n", evt.Sender, evt.Type.String(), evt.ID, evt.Content.AsMessage().Body)
body := evt.Content.AsMessage().Body
body_s := strings.Split(body, " ")
if body_s[0] != "!simp" {
return
}
if len(body_s) < 2 {
return //nothing to parse
}
if evt.Sender == client.UserID {
return //ignore events from self
}
switch body_s[1] {
case "info":
// print info page
var infomsg string
vlist := []string{}
for _, vt := range vtubers {
ann := ""
if vt.AnnounceLive {
ann = "*"
}
vlist = append(vlist, fmt.Sprintf("%v%v", vt.Name, ann))
}
infomsg = fmt.Sprintf("Currently Simping For: \n%v", strings.Join(vlist, "\n"))
client.SendText(evt.RoomID, infomsg)
case "version":
// print version
client.SendText(evt.RoomID, "SimpBot version "+GitCommit)
case "reload":
//reload config
client.SendText(evt.RoomID, "unimplemented")
case "help":
client.SendText(evt.RoomID, "Supported commands: info,version")
default:
//command not found
client.SendText(evt.RoomID, "command not recognized")
}
})
syncer.OnEventType(event.StateMember, func(source mautrix.EventSource, evt *event.Event) {
fmt.Printf("<%[1]s> %[4]s (%[2]s/%[3]s)\n", evt.Sender, evt.Type.String(), evt.ID, evt.Content.AsMessage().Body)
if evt.Content.AsMember().Membership.IsInviteOrJoin() {
_, err = client.JoinRoomByID(evt.RoomID)
if err != nil {
fmt.Printf("error joining room %v", evt.RoomID)
} else {
fmt.Println("joined room")
}
}
})
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGUSR1)
vtubers = LoadVtubers()
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed,reloading vtubers:", e.Name)
vtubers = LoadVtubers()
})
go func() {
for {
time.Sleep(30 * time.Second)
roomResp, err := client.JoinedRooms()
if err != nil {
log.Println("error gettting joined rooms")
log.Println(err)
log.Println("Skipping iteration")
continue
}
rooms := roomResp.JoinedRooms
// We're going to assume they're only stream one video at a time
for _, v := range vtubers {
v.Update()
if v.IsLive() {
for _, room := range rooms {
//check to see if already embeded
var content YoutubeWidget
err = client.StateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, &content)
if content.ID == "" {
if v.AnnounceLive {
client.SendText(room, v.LiveMsg)
} else {
client.SendNotice(room, v.LiveMsg)
}
client.SendNotice(room, fmt.Sprintf("%v's Title: %v", v.Name, v.CurrentStreamTitle))
resp, err := client.SendStateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, NewYT(v.Name+"'s stream", v.CurrentStream, string(room)))
if err != nil {
log.Println("error embeding video")
log.Println(err)
}
log.Printf("Embed event %v", resp)
}
}
} else {
//Not live, check to see if there's any embeds and remove them
for _, room := range rooms {
var content YoutubeWidget
err = client.StateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, &content)
if err == nil && content.ID != "" {
//event found, kill it
resp, err := client.SendStateEvent(room, event.NewEventType("im.vector.modular.widgets"), "dimension-m.video-simp-"+v.Name, struct{}{})
if err != nil {
log.Println("error removed video embed")
log.Println(err)
}
log.Printf("Emebed remove %v", resp)
}
}
}
}
}
}()
err = client.Sync()
if err != nil {
panic(err)
}
}