Full bot functionality and multi user support

This commit is contained in:
Jannover5000r 2025-08-10 11:38:31 +02:00
parent ac69fb6780
commit 81c9a496c0
5 changed files with 85 additions and 12 deletions

View file

@ -31,12 +31,13 @@ type LoginResponse struct {
}
var Url = "https://thalia.webuntis.com/WebUntis/jsonrpc.do?school=Mons_Tabor"
var Password = os.Getenv("UNTIS_PASSWORD")
var USERS = os.Getenv("UNTIS_USER")
func Main() {
//var Password = os.Getenv("UNTIS_PASSWORD")
//var USERS = os.Getenv("UNTIS_USER")
func Main(user, password string) {
godotenv.Load("../.env")
cookies, err := Auth()
cookies, err := Auth(user, password)
if err != nil {
log.Fatal(err)
return
@ -53,8 +54,8 @@ func Main() {
Teachers(cookies)
}
func Auth() ([]*http.Cookie, error) {
l := Login{"2023-05-06 15:44:22.215292", "authenticate", Params{USERS, Password, "WebUntis Test"}, "2.0"}
func Auth(user, password string) ([]*http.Cookie, error) {
l := Login{"2023-05-06 15:44:22.215292", "authenticate", Params{user, password, "WebUntis Test"}, "2.0"}
loginJSON, err := json.Marshal(l)
if err != nil {
log.Fatalf("Error marshaling login data: %v", err)

View file

@ -1,6 +1,7 @@
package bot
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
@ -13,6 +14,7 @@ import (
"os/signal"
"sync"
"syscall"
"time"
"github.com/joho/godotenv"
@ -135,6 +137,63 @@ func saveAccount(userID, username, password string) error {
return os.WriteFile(accountsFile, newData, 0644)
}
// Helper functions for per-user timetable files
func getTimetableFile(userID string) string {
return fmt.Sprintf("timetable_%s.json", userID)
}
func getTimetableFilledFile(userID string) string {
return fmt.Sprintf("timetableFilled_%s.json", userID)
}
// Send a Discord message mentioning the user
func sendLessonNotification(s *discordgo.Session, userID, username, message string) {
// Send a DM to the user
channel, err := s.UserChannelCreate(userID)
if err != nil {
fmt.Println("Error creating DM channel:", err)
return
}
s.ChannelMessageSend(channel.ID, fmt.Sprintf("**%s**: %s", username, message))
}
// Check for timetable changes for a user and notify if changed
func checkTimetableChangesForUser(user Account, decPwd string, s *discordgo.Session) {
timetableFilledFile := getTimetableFilledFile(user.UserID)
// Load previous timetable
prevData, _ := os.ReadFile(timetableFilledFile)
// TODO: Fetch new timetable for this user using user.Username and decrypted password
// For demonstration, we'll just copy prevData (replace this with real fetch logic!)
newData := prevData
// Compare and notify if changed
if !bytes.Equal(newData, prevData) {
sendLessonNotification(s, user.UserID, user.Username, "Your timetable has changed!")
os.WriteFile(timetableFilledFile, newData, 0644)
}
}
// Load all accounts from accounts.json
func loadAllAccounts() []Account {
var accounts []Account
if data, err := os.ReadFile(accountsFile); err == nil && len(data) > 0 {
_ = json.Unmarshal(data, &accounts)
}
return accounts
}
// Scheduled check for all users
func checkAllUsersTimetables(s *discordgo.Session) {
accounts := loadAllAccounts()
for _, user := range accounts {
decPwd, _ := decrypt(user.Password)
// You can use decPwd to fetch the timetable for this user
checkTimetableChangesForUser(user, decPwd, s)
}
}
func Start() {
token := os.Getenv("DISCORD_BOT_TOKEN")
if token == "" {
@ -155,6 +214,14 @@ func Start() {
return
}
// Schedule timetable checks every minute (or hour as needed)
go func() {
ticker := time.NewTicker(1 * time.Minute)
for range ticker.C {
checkAllUsersTimetables(dg)
}
}()
fmt.Println("Bot is now running. Press CTRL+C to exit.")
// Wait for CTRL+C or other term signal to exit.
sc := make(chan os.Signal, 1)

6
go.mod
View file

@ -2,10 +2,12 @@ module untislogger
go 1.24
require github.com/joho/godotenv v1.5.1
require (
github.com/bwmarrin/discordgo v0.29.0
github.com/joho/godotenv v1.5.1
)
require (
github.com/bwmarrin/discordgo v0.29.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect

11
main.go
View file

@ -79,8 +79,11 @@ func isScheduledTime(now time.Time) bool {
}
func scheduleTimetableUpdate() {
var prevData []byte
//run once
Untis.Main()
//declare user and pass
godotenv.Load(".env")
var password = os.Getenv("UNTIS_PASSWORD")
var user = os.Getenv("UNTIS_USER")
Untis.Main(user, password)
// Initial read of the file
data, err := os.ReadFile("timetableFilled.json")
if err == nil {
@ -91,7 +94,7 @@ func scheduleTimetableUpdate() {
hourTicker := time.NewTicker(1 * time.Minute)
go func() {
for range hourTicker.C {
Untis.Main()
Untis.Main(user, password)
data, err := os.ReadFile("timetableFilled.json")
if err != nil {
log.Printf("Error reading timetable: %v", err)
@ -108,7 +111,7 @@ func scheduleTimetableUpdate() {
now := time.Now()
if isScheduledTime(now) {
log.Println("Scheduled time reached, updating and running Run()")
Untis.Main()
Untis.Main(user, password)
log.Println("Updated now running Run()")
Run()
log.Println("Finished running Run")

Binary file not shown.