simpbot/main.go

229 lines
6.6 KiB
Go
Raw Normal View History

2021-05-21 12:45:24 -04:00
package main
import (
"fmt"
"log"
2021-10-26 14:14:26 -04:00
"net/url"
2021-08-07 13:02:50 -04:00
"os"
"os/signal"
2021-06-25 13:58:04 -04:00
"strings"
2021-08-07 13:02:50 -04:00
"syscall"
2021-05-21 12:45:24 -04:00
"time"
2021-08-07 13:02:50 -04:00
"github.com/fsnotify/fsnotify"
2021-05-21 13:39:54 -04:00
"github.com/spf13/viper"
2021-05-21 12:45:24 -04:00
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
)
2021-05-21 13:39:54 -04:00
var Homeserver string
var Username string
var Password string
var DimensionServer string
var HomeserverDomain string
2021-06-25 13:58:04 -04:00
var GitCommit string
2021-10-27 12:06:54 -04:00
var GitTag string
2021-06-25 14:05:57 -04:00
var Statefile string
2021-10-26 14:01:58 -04:00
var CurrStreamCnt int
var MostStreamCnt int
var StartTime time.Time
2021-05-21 12:45:24 -04:00
func main() {
2021-05-21 13:39:54 -04:00
viper.SetConfigName("config")
viper.AddConfigPath(".")
2021-08-07 13:36:26 -04:00
viper.AddConfigPath("/etc/simpbot")
2021-05-21 13:39:54 -04:00
err := viper.ReadInConfig()
if err != nil {
log.Fatalf("Fatal error config file: %v \n", err)
2021-05-21 12:45:24 -04:00
}
2021-05-21 13:39:54 -04:00
viper.SetConfigType("yaml")
Homeserver = viper.GetString("homeserver")
viper.SetDefault("domain", Homeserver)
2021-06-25 14:05:57 -04:00
viper.SetDefault("statefile", "simpstate")
2021-05-21 13:39:54 -04:00
Username = viper.GetString("username")
Password = viper.GetString("password")
DimensionServer = viper.GetString("dimension")
HomeserverDomain = viper.GetString("domain")
2021-06-25 14:05:57 -04:00
Statefile = viper.GetString("statefile")
2021-10-26 14:01:58 -04:00
CurrStreamCnt = 0
MostStreamCnt = 0
StartTime = time.Now()
2021-06-25 13:58:04 -04:00
var vtubers []*Vtuber
2021-05-21 13:39:54 -04:00
log.Println("Logging into", Homeserver, "as", Username)
client, err := mautrix.NewClient(Homeserver, "", "")
2021-05-21 12:45:24 -04:00
if err != nil {
panic(err)
}
2021-06-25 14:05:57 -04:00
client.Store = NewLazyMemStore(Statefile)
2021-05-21 12:45:24 -04:00
_, err = client.Login(&mautrix.ReqLogin{
Type: "m.login.password",
2021-05-21 13:39:54 -04:00
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: Username},
Password: Password,
2021-05-21 12:45:24 -04:00
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) {
2021-08-23 19:55:54 -04:00
if evt.Sender == client.UserID {
return //ignore events from self
}
2021-05-21 12:45:24 -04:00
fmt.Printf("<%[1]s> %[4]s (%[2]s/%[3]s)\n", evt.Sender, evt.Type.String(), evt.ID, evt.Content.AsMessage().Body)
2021-06-25 13:58:04 -04:00
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
}
switch body_s[1] {
case "info":
// print info page
var infomsg string
vlist := []string{}
for _, vt := range vtubers {
2021-08-23 19:49:20 -04:00
ann := ""
if vt.AnnounceLive {
ann = "*"
}
vlist = append(vlist, fmt.Sprintf("%v%v", vt.Name, ann))
2021-06-25 13:58:04 -04:00
}
infomsg = fmt.Sprintf("Currently Simping For: \n%v", strings.Join(vlist, "\n"))
client.SendText(evt.RoomID, infomsg)
2021-10-26 14:01:58 -04:00
case "stats":
var statmsg string
vlist := []string{}
t := 0
for _, vt := range vtubers {
vlist = append(vlist, fmt.Sprintf("%v Total:%v", vt.Name, vt.TotalStreams))
t = t + vt.TotalStreams
}
2021-10-27 12:06:54 -04:00
statmsg = fmt.Sprintf("Current Stats Since %v:\n%v\n\nTotal Streams: %v\nMost Concurrent: %v/%v\n", StartTime, strings.Join(vlist, "\n"), t, MostStreamCnt, len(vtubers))
2021-10-26 14:01:58 -04:00
client.SendText(evt.RoomID, statmsg)
2021-06-25 13:58:04 -04:00
case "version":
// print version
2021-10-27 12:06:54 -04:00
if GitTag != "" {
client.SendText(evt.RoomID, "SimpBot version "+GitTag)
} else {
client.SendText(evt.RoomID, "SimpBot version "+GitCommit)
}
2021-06-25 13:58:04 -04:00
case "reload":
//reload config
2021-10-26 14:01:58 -04:00
client.SendText(evt.RoomID, "Reloading config")
fmt.Println("Reload requested,reloading vtubers")
vtubers = LoadVtubers()
2021-06-25 13:58:04 -04:00
case "help":
2021-10-26 14:14:26 -04:00
client.SendText(evt.RoomID, "Supported commands: info,version,stats")
2021-06-25 13:58:04 -04:00
default:
//command not found
client.SendText(evt.RoomID, "command not recognized")
}
2021-05-21 12:45:24 -04:00
})
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 {
2021-10-26 14:14:26 -04:00
fmt.Printf("joined room %v", evt.RoomID)
2021-05-21 12:45:24 -04:00
}
}
})
2021-08-07 13:02:50 -04:00
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()
})
2021-05-21 12:45:24 -04:00
go func() {
for {
time.Sleep(30 * time.Second)
roomResp, err := client.JoinedRooms()
if err != nil {
2021-09-16 16:46:15 -04:00
log.Println("error getting joined rooms")
2021-05-21 16:00:10 -04:00
log.Println(err)
log.Println("Skipping iteration")
continue
2021-05-21 12:45:24 -04:00
}
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() {
2021-10-26 14:33:22 -04:00
2021-05-21 12:45:24 -04:00
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 {
2021-10-26 14:14:26 -04:00
if isValidUrl(v.LiveMsg) {
client.SendNotice(room, fmt.Sprintf("%v has gone live", v.Name))
} else {
client.SendNotice(room, v.LiveMsg)
}
}
client.SendNotice(room, fmt.Sprintf("%v's Title: %v", v.Name, v.CurrentStreamTitle))
2021-05-21 12:45:24 -04:00
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)
}
v.TotalStreams = v.TotalStreams + 1
CurrStreamCnt = CurrStreamCnt + 1
if CurrStreamCnt > MostStreamCnt {
MostStreamCnt = CurrStreamCnt
}
2021-10-26 14:14:26 -04:00
log.Printf("Embed stream %v for %v ", resp, v.Name)
2021-05-21 12:45:24 -04:00
}
}
} 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)
}
CurrStreamCnt = CurrStreamCnt - 1
2021-10-26 14:14:26 -04:00
log.Printf("Embed stream %v removed %v", resp, v.Name)
2021-05-21 12:45:24 -04:00
}
}
}
}
}
}()
err = client.Sync()
if err != nil {
panic(err)
}
}
2021-10-26 14:14:26 -04:00
func isValidUrl(toTest string) bool {
_, err := url.ParseRequestURI(toTest)
if err != nil {
return false
}
u, err := url.Parse(toTest)
if err != nil || u.Scheme == "" || u.Host == "" {
return false
}
return true
}