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) } }