made a lot of changes for the workflow of the bot

- Timezone handling got updated
- Logs have been deleted to avoid duplicates and clean up the terminal
- removed unused code
- fixed an issue where the updating time threw errors
- improvements to the updateting of timetable data, only using a single api call now
- improved init to intitialize all needed files (classrooms, subjects etc.)
This commit is contained in:
Jannover5000r 2026-08-25 22:53:59 +02:00
parent ae5b1f7b28
commit 1d57e8a867
8 changed files with 72 additions and 96 deletions

View file

@ -42,33 +42,33 @@ func Classes(cookies []*http.Cookie) {
log.Fatalf("Error creatingrequest: %v", err)
return
}
//log.Println("prompt without extra header or cookie ", prompt)
//log.Println("Cookie: ", cookies)
// log.Println("prompt without extra header or cookie ", prompt)
// log.Println("Cookie: ", cookies)
prompt.Header.Set("Content-Type", "application/json")
prompt.Header.Set("User-Agent", "Webuntis Test")
for _, cookie := range cookies {
//if cookie.Name == "JSESSIONID" {
// if cookie.Name == "JSESSIONID" {
prompt.AddCookie(cookie)
//log.Printf("Added JSESSIONID cookie: %s=%s", cookie.Name, cookie.Value)
//}
}
//log.Println("Request JSON:", string(ClassesJson))
// log.Println("Request JSON:", string(ClassesJson))
out, err := http.DefaultClient.Do(prompt)
if err != nil {
log.Printf("Error during request: %v", err)
return
}
defer out.Body.Close()
//log.Println(out.Status)
// log.Println(out.Status)
response, err := io.ReadAll(out.Body)
if err != nil {
log.Printf("Error reading response body: %v", err)
return
}
//responseString := string(response)
//log.Println("Repsonse ", responseString)
// responseString := string(response)
// log.Println("Repsonse ", responseString)
var Response ClassesResponse
err = json.Unmarshal(response, &Response)
if err != nil {
@ -78,9 +78,9 @@ func Classes(cookies []*http.Cookie) {
if err != nil {
log.Fatal(err)
}
err = os.WriteFile("classes.json", data, 0644)
err = os.WriteFile("classes.json", data, 0o644)
if err != nil {
log.Fatal(err)
}
log.Println("Updated Classes")
// log.Println("Updated Classes")//dont need log anymore
}

View file

@ -31,7 +31,7 @@ type Room struct {
}
func Rooms(cookies []*http.Cookie) {
//log.Println("Abrufen der Stunden")
// log.Println("Abrufen der Stunden")
g := getRooms{"2023-05-06 15:44:22.215292", "getRooms", map[string]interface{}{}, "2.0"}
roomsJson, err := json.Marshal(g)
if err != nil {
@ -45,33 +45,33 @@ func Rooms(cookies []*http.Cookie) {
log.Fatalf("Error creatingrequest: %v", err)
return
}
//log.Println("prompt without extra header or cookie ", prompt)
//log.Println("Cookie: ", cookies)
// log.Println("prompt without extra header or cookie ", prompt)
// log.Println("Cookie: ", cookies)
prompt.Header.Set("Content-Type", "application/json")
prompt.Header.Set("User-Agent", "Webuntis Test")
for _, cookie := range cookies {
//if cookie.Name == "JSESSIONID" {
// if cookie.Name == "JSESSIONID" {
prompt.AddCookie(cookie)
// log.Printf("Added JSESSIONID cookie: %s=%s", cookie.Name, cookie.Value)
//}
}
//log.Println("Request JSON:", string(roomsJson))
// log.Println("Request JSON:", string(roomsJson))
out, err := http.DefaultClient.Do(prompt)
if err != nil {
log.Printf("Error during request: %v", err)
return
}
defer out.Body.Close()
//log.Println(out.Status)
// log.Println(out.Status)
response, err := io.ReadAll(out.Body)
if err != nil {
log.Printf("Error reading response body: %v", err)
return
}
//responseString := string(response)
//log.Println("Repsonse ", responseString)
// responseString := string(response)
// log.Println("Repsonse ", responseString)
var Response RoomsResponse
err = json.Unmarshal(response, &Response)
if err != nil {
@ -82,9 +82,9 @@ func Rooms(cookies []*http.Cookie) {
if err != nil {
log.Fatal(err)
}
err = os.WriteFile("rooms.json", data, 0644)
err = os.WriteFile("rooms.json", data, 0o644)
if err != nil {
log.Fatal(err)
}
log.Println("Updated Rooms")
// log.Println("Updated Rooms")//dont need log anymore
}

View file

@ -42,33 +42,33 @@ func Subjects(cookies []*http.Cookie) {
log.Fatalf("Error creatingrequest: %v", err)
return
}
//log.Println("prompt without extra header or cookie ", prompt)
//log.Println("Cookie: ", cookies)
// log.Println("prompt without extra header or cookie ", prompt)
// log.Println("Cookie: ", cookies)
prompt.Header.Set("Content-Type", "application/json")
prompt.Header.Set("User-Agent", "Webuntis Test")
for _, cookie := range cookies {
//if cookie.Name == "JSESSIONID" {
// if cookie.Name == "JSESSIONID" {
prompt.AddCookie(cookie)
//log.Printf("Added JSESSIONID cookie: %s=%s", cookie.Name, cookie.Value)
//}
}
//log.Println("Request JSON:", string(SubjectsJson))
// log.Println("Request JSON:", string(SubjectsJson))
out, err := http.DefaultClient.Do(prompt)
if err != nil {
log.Printf("Error during request: %v", err)
return
}
defer out.Body.Close()
//log.Println(out.Status)
// log.Println(out.Status)
response, err := io.ReadAll(out.Body)
if err != nil {
log.Printf("Error reading response body: %v", err)
return
}
//responseString := string(response)
//log.Println("Repsonse ", responseString)
// responseString := string(response)
// log.Println("Repsonse ", responseString)
var Response SubjectsResponse
err = json.Unmarshal(response, &Response)
if err != nil {
@ -78,9 +78,9 @@ func Subjects(cookies []*http.Cookie) {
if err != nil {
log.Fatal(err)
}
err = os.WriteFile("subjects.json", data, 0644)
err = os.WriteFile("subjects.json", data, 0o644)
if err != nil {
log.Fatal(err)
}
log.Println("Updated Subjects")
// log.Println("Updated Subjects")//dont need log anymore
}

View file

@ -42,33 +42,33 @@ func Teachers(cookies []*http.Cookie) {
log.Fatalf("Error creatingrequest: %v", err)
return
}
//log.Println("prompt without extra header or cookie ", prompt)
//log.Println("Cookie: ", cookies)
// log.Println("prompt without extra header or cookie ", prompt)
// log.Println("Cookie: ", cookies)
prompt.Header.Set("Content-Type", "application/json")
prompt.Header.Set("User-Agent", "Webuntis Test")
for _, cookie := range cookies {
//if cookie.Name == "JSESSIONID" {
// if cookie.Name == "JSESSIONID" {
prompt.AddCookie(cookie)
//log.Printf("Added JSESSIONID cookie: %s=%s", cookie.Name, cookie.Value)
//}
}
//log.Println("Request JSON:", string(TeachersJson))
// log.Println("Request JSON:", string(TeachersJson))
out, err := http.DefaultClient.Do(prompt)
if err != nil {
log.Printf("Error during request: %v", err)
return
}
defer out.Body.Close()
//log.Println(out.Status)
// log.Println(out.Status)
response, err := io.ReadAll(out.Body)
if err != nil {
log.Printf("Error reading response body: %v", err)
return
}
//responseString := string(response)
//log.Println("Repsonse ", responseString)
// responseString := string(response)
// log.Println("Repsonse ", responseString)
var Response TeachersResponse
err = json.Unmarshal(response, &Response)
if err != nil {
@ -78,9 +78,9 @@ func Teachers(cookies []*http.Cookie) {
if err != nil {
log.Fatal(err)
}
err = os.WriteFile("teachers.json", data, 0644)
err = os.WriteFile("teachers.json", data, 0o644)
if err != nil {
log.Fatal(err)
}
log.Println("Updated Teachers")
// log.Println("Updated Teachers")//dont need log anymore
}

View file

@ -152,7 +152,7 @@ func Timetable(cookies []*http.Cookie, userID string) {
return
}
log.Printf("Updated timetable for user %s", userID)
// log.Printf("Updated timetable for user %s", userID) // dont need log anymore
setTimetable(userID)
}
@ -249,5 +249,5 @@ func setTimetable(userID string) {
log.Printf("Error writing timetableFilled file: %v", err)
return
}
log.Printf("Filled timetable for user %s", userID)
// log.Printf("Filled timetable for user %s", userID)//log not needed
}

View file

@ -44,6 +44,7 @@ func Main(user, password, userID string) {
Subjects(cookies)
Timetable(cookies, userID)
Teachers(cookies)
log.Printf("updated everything for user: %s ", user)
}
func Update(user, password, userID string) {
@ -54,6 +55,7 @@ func Update(user, password, userID string) {
return
}
Timetable(cookies, userID)
log.Printf("Updated info for user: %s ", user)
}
func Auth(user, password, userID string) ([]*http.Cookie, error) {
@ -73,7 +75,7 @@ func Auth(user, password, userID string) ([]*http.Cookie, error) {
defer LoginOut.Body.Close()
cookies := LoginOut.Cookies()
log.Printf("Login successful for user: %s", user)
// log.Printf("Login successful for user: %s", user)//log not needed
response, err := io.ReadAll(LoginOut.Body)
if err != nil {

View file

@ -1,9 +1,24 @@
package Untis
import "time"
import (
"log"
"os"
"time"
var Location *time.Location
"github.com/joho/godotenv"
)
var (
locerr error
Location *time.Location
)
func GetTime() time.Time {
godotenv.Load("../.env")
timezone := os.Getenv("LOCATION_ENV")
Location, locerr = time.LoadLocation(timezone)
if locerr != nil {
log.Fatalf("Failed to load Timezone: %v", locerr)
}
return time.Now().In(Location)
}

67
main.go
View file

@ -4,7 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"io"
"log"
"net/http"
"os"
@ -93,7 +93,7 @@ func init() {
}
discordWebhookURL = os.Getenv("DISCORD_WEBHOOK_URL")
log.Println("Initializing application...")
log.Printf("DISCORD_WEBHOOK_URL: %q", discordWebhookURL)
// log.Printf("DISCORD_WEBHOOK_URL: %q", discordWebhookURL) //Debug info, not needed at the moment
// Check if Discord webhook is configured
if discordWebhookURL != "" {
@ -101,36 +101,19 @@ func init() {
} else {
log.Println("No Discord webhook provided, Discord notifications will be disabled")
}
locEnv := os.Getenv("LOCATION_ENV")
var locerr error
Untis.Location, locerr = time.LoadLocation(locEnv)
if locerr != nil {
log.Fatalf("Failed to load Timezone: %v", locerr)
}
log.Printf("Timezone set to: %s", location)
initUpdate()
}
func main() {
godotenv.Load(".env")
go BotStart.Start()
go scheduleTimetableUpdate()
scheduleTimetableUpdate()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
log.Println("Program is running. Press Ctrl+C to stop.")
// Start logging
// Run()
// Block until we receive a signal
<-sigChan
log.Println("Shutting down...")
}
func getTime() time.Time {
return time.Now().In(location)
}
func isScheduledTime(now time.Time) bool {
scheduled := []string{"07:45", "08:35", "09:35", "10:25", "11:25", "12:15", "13:40", "14:25", "15:20", "16:00"}
current := now.Format("15:04")
@ -143,29 +126,9 @@ func isScheduledTime(now time.Time) bool {
}
func initUpdate() {
// Load all registered users
accounts, err := BotStart.LoadAndDecryptAccounts()
if err != nil {
log.Printf("Error loading accounts: %v", err)
}
// Add the default user from .env
defaultUser := os.Getenv("UNTIS_USER")
defaultPassword := os.Getenv("UNTIS_PASSWORD")
if defaultUser != "" && defaultPassword != "" {
accounts = append(accounts, BotStart.DecryptedAccount{
UserID: "default",
Username: defaultUser,
DecryptedPassword: defaultPassword,
})
}
// Process each user
for _, acc := range accounts {
// Fetch the latest timetable and only timetable
Untis.Main(acc.Username, acc.DecryptedPassword, acc.UserID)
time.Sleep(3 * time.Second)
}
Untis.Main(defaultUser, defaultPassword, "default")
}
func scheduleTimetableUpdate() {
@ -178,7 +141,6 @@ func scheduleTimetableUpdate() {
if err != nil {
log.Printf("Error loading accounts: %v", err)
}
// Add the default user from .env
defaultUser := os.Getenv("UNTIS_USER")
defaultPassword := os.Getenv("UNTIS_PASSWORD")
@ -194,7 +156,6 @@ func scheduleTimetableUpdate() {
for _, acc := range accounts {
// Fetch the latest timetable and only timetable
Untis.Update(acc.Username, acc.DecryptedPassword, acc.UserID)
time.Sleep(3 * time.Second)
// Check for changes
timetableFile := fmt.Sprintf("timetableFilled_%s.json", acc.UserID)
@ -230,10 +191,10 @@ func scheduleTimetableUpdate() {
prevTimeslotMap := make(map[string]NamedTimetableEntry)
// Get current date to filter out new day changes
today := getTime().Format("02-01-2006")
today := Untis.GetTime().Format("02-01-2006")
// Get current time to filter any changes to Timetable before 3am so the new day changes stop
//
now := getTime()
now := Untis.GetTime()
// If before 1am stop and update userdata
if now.Hour() < 1 {
prevData[acc.UserID] = data
@ -337,14 +298,11 @@ func scheduleTimetableUpdate() {
sendUpdateDiscordWebhookWithDetails(changes)
}
}
} else {
// First run — no previous data, so don't notify
log.Printf("First timetable fetch for user %s", acc.Username)
}
// Always update prevData
prevData[acc.UserID] = data
}
time.Sleep(3 * time.Second)
}
// Initial update
@ -360,7 +318,7 @@ func scheduleTimetableUpdate() {
// Ticker for scheduled lesson notifications
startMinuteTicker(func() {
now := getTime()
now := Untis.GetTime()
if isScheduledTime(now) {
log.Println("Scheduled time reached, running notifications...")
accounts, _ := BotStart.LoadAndDecryptAccounts()
@ -372,10 +330,11 @@ func scheduleTimetableUpdate() {
log.Println("Finished running notifications.")
}
})
log.Println("Updated all users")
}
func startMinuteTicker(f func()) {
now := getTime()
now := Untis.GetTime()
next := now.Truncate(time.Minute).Add(time.Minute)
time.Sleep(time.Until(next))
ticker := time.NewTicker(1 * time.Minute)
@ -404,7 +363,7 @@ func Run(userID string) {
roomByStartTime, _ := MapTimeToRoom(timetableFile)
subjectByStartTime, _ := MapTimeToSubject(timetableFile)
now := getTime().Format("15:04")
now := Untis.GetTime().Format("15:04")
nextTime, room, foundRoom := NextRoomForTime(roomByStartTime, now)
if !foundRoom {
@ -653,7 +612,7 @@ func sendDiscordWebhook(subject string, room string, nextTime string, Status str
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
log.Println("Discord webhook notification sent successfully")
} else {
body, _ := ioutil.ReadAll(resp.Body)
body, _ := io.ReadAll(resp.Body)
log.Printf("Discord webhook failed with status %d: %s", resp.StatusCode, string(body))
}
}
@ -684,7 +643,7 @@ func sendUpdateDiscordWebhookWithDetails(changes []string) {
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
log.Println("Detailed Discord webhook sent successfully")
} else {
body, _ := ioutil.ReadAll(resp.Body)
body, _ := io.ReadAll(resp.Body)
log.Printf("Discord webhook failed with status %d: %s", resp.StatusCode, string(body))
}
}