Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
711c014bda | ||
|
|
e334aaf413 |
12 changed files with 128 additions and 170 deletions
|
|
@ -15,6 +15,7 @@ import (
|
|||
"path/filepath"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"untislogger/Untis"
|
||||
|
||||
|
|
@ -224,6 +225,7 @@ 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -251,6 +253,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)
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@
|
|||
- DISCORD_BOT_TOKEN
|
||||
- ENC_KEY (generated via head -c 32 /dev/urandom | base64)
|
||||
- URL
|
||||
- TIMEZONE (will default to UTC if empty)
|
||||
|
||||
### URL can be found by following this structure
|
||||
### URL can be found by following this structure: "<https://[SchoolName].webuntis.com/WebUntis/jsonrpc.do?school=[SchholName]" while SchoolName can be found by visiting the official website, going to the login for your school and it will be: "<https://[SchoolName].webuntis.com/WebUntis/?school=[SchoolName]#/basic/login>"
|
||||
|
||||
"<https://[SchoolName].webuntis.com/WebUntis/jsonrpc.do?school=[SchholName]"
|
||||
while SchoolName can be found by visiting the official website, going to the login for your school and it will be:
|
||||
"<https://[SchoolName].webuntis.com/WebUntis/?school=[SchoolName]#/basic/login>"
|
||||
# This is a project for me, issues will be resolved as i find the motivation to do so, improvements may follow in the future
|
||||
|
||||
## I will try to maintain this project as best as possible. Maybe add a better security to it than to trust the host but for now it is working and that was my goal. Please report any errors you find while using this bot
|
||||
|
||||
# Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ func Classes(cookies []*http.Cookie) {
|
|||
g := getClasses{"2023-05-06 15:44:22.215292", "getKlassen", map[string]interface{}{}, "2.0"}
|
||||
ClassesJson, err := json.Marshal(g)
|
||||
if err != nil {
|
||||
log.Printf("Error marshaling login data: %v", err)
|
||||
log.Fatalf("Error marshaling login data: %v", err)
|
||||
return
|
||||
}
|
||||
classes := bytes.NewReader(ClassesJson)
|
||||
|
||||
prompt, err := http.NewRequest("POST", Url, classes)
|
||||
if err != nil {
|
||||
log.Printf("Error creatingrequest: %v", err)
|
||||
log.Fatalf("Error creatingrequest: %v", err)
|
||||
return
|
||||
}
|
||||
//log.Println("prompt without extra header or cookie ", prompt)
|
||||
|
|
@ -72,17 +72,15 @@ func Classes(cookies []*http.Cookie) {
|
|||
var Response ClassesResponse
|
||||
err = json.Unmarshal(response, &Response)
|
||||
if err != nil {
|
||||
log.Printf("Error unmarshaling response: %v", err)
|
||||
log.Fatalf("Error unmarshaling response: %v", err)
|
||||
}
|
||||
data, err := json.MarshalIndent(Response.Result, "", " ")
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = os.WriteFile("classes.json", data, 0o644)
|
||||
err = os.WriteFile("classes.json", data, 0644)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
// log.Println("Updated Classes")//dont need log anymore
|
||||
log.Println("Updated Classes")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,14 +35,14 @@ func Rooms(cookies []*http.Cookie) {
|
|||
g := getRooms{"2023-05-06 15:44:22.215292", "getRooms", map[string]interface{}{}, "2.0"}
|
||||
roomsJson, err := json.Marshal(g)
|
||||
if err != nil {
|
||||
log.Printf("Error marshaling login data: %v", err)
|
||||
log.Fatalf("Error marshaling login data: %v", err)
|
||||
return
|
||||
}
|
||||
rooms := bytes.NewReader(roomsJson)
|
||||
|
||||
prompt, err := http.NewRequest("POST", Url, rooms)
|
||||
if err != nil {
|
||||
log.Printf("Error creatingrequest: %v", err)
|
||||
log.Fatalf("Error creatingrequest: %v", err)
|
||||
return
|
||||
}
|
||||
//log.Println("prompt without extra header or cookie ", prompt)
|
||||
|
|
@ -75,19 +75,16 @@ func Rooms(cookies []*http.Cookie) {
|
|||
var Response RoomsResponse
|
||||
err = json.Unmarshal(response, &Response)
|
||||
if err != nil {
|
||||
log.Printf("Error unmarshaling response: %v", err)
|
||||
return
|
||||
log.Fatalf("Error unmarshaling response: %v", err)
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(Response.Result, "", " ")
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = os.WriteFile("rooms.json", data, 0o644)
|
||||
err = os.WriteFile("rooms.json", data, 0644)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
// log.Println("Updated Rooms")//dont need log anymore
|
||||
log.Println("Updated Rooms")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ func Subjects(cookies []*http.Cookie) {
|
|||
g := getSubjects{"2023-05-06 15:44:22.215292", "getSubjects", map[string]interface{}{}, "2.0"}
|
||||
SubjectsJson, err := json.Marshal(g)
|
||||
if err != nil {
|
||||
log.Printf("Error marshaling login data: %v", err)
|
||||
log.Fatalf("Error marshaling login data: %v", err)
|
||||
return
|
||||
}
|
||||
subjects := bytes.NewReader(SubjectsJson)
|
||||
|
||||
prompt, err := http.NewRequest("POST", Url, subjects)
|
||||
if err != nil {
|
||||
log.Printf("Error creatingrequest: %v", err)
|
||||
log.Fatalf("Error creatingrequest: %v", err)
|
||||
return
|
||||
}
|
||||
//log.Println("prompt without extra header or cookie ", prompt)
|
||||
|
|
@ -72,18 +72,15 @@ func Subjects(cookies []*http.Cookie) {
|
|||
var Response SubjectsResponse
|
||||
err = json.Unmarshal(response, &Response)
|
||||
if err != nil {
|
||||
log.Printf("Error unmarshaling response: %v", err)
|
||||
return
|
||||
log.Fatalf("Error unmarshaling response: %v", err)
|
||||
}
|
||||
data, err := json.MarshalIndent(Response.Result, "", " ")
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = os.WriteFile("subjects.json", data, 0o644)
|
||||
err = os.WriteFile("subjects.json", data, 0644)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
// log.Println("Updated Subjects")//dont need log anymore
|
||||
log.Println("Updated Subjects")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ func Teachers(cookies []*http.Cookie) {
|
|||
g := getTeachers{"2023-05-06 15:44:22.215292", "getTeachers", map[string]interface{}{}, "2.0"}
|
||||
TeachersJson, err := json.Marshal(g)
|
||||
if err != nil {
|
||||
log.Printf("Error marshaling login data: %v", err)
|
||||
log.Fatalf("Error marshaling login data: %v", err)
|
||||
return
|
||||
}
|
||||
teachers := bytes.NewReader(TeachersJson)
|
||||
|
||||
prompt, err := http.NewRequest("POST", Url, teachers)
|
||||
if err != nil {
|
||||
log.Printf("Error creatingrequest: %v", err)
|
||||
log.Fatalf("Error creatingrequest: %v", err)
|
||||
return
|
||||
}
|
||||
//log.Println("prompt without extra header or cookie ", prompt)
|
||||
|
|
@ -72,18 +72,15 @@ func Teachers(cookies []*http.Cookie) {
|
|||
var Response TeachersResponse
|
||||
err = json.Unmarshal(response, &Response)
|
||||
if err != nil {
|
||||
log.Printf("Error unmarshaling response: %v", err)
|
||||
return
|
||||
log.Fatalf("Error unmarshaling response: %v", err)
|
||||
}
|
||||
data, err := json.MarshalIndent(Response.Result, "", " ")
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = os.WriteFile("teachers.json", data, 0o644)
|
||||
err = os.WriteFile("teachers.json", data, 0644)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return
|
||||
log.Fatal(err)
|
||||
}
|
||||
// log.Println("Updated Teachers")//dont need log anymore
|
||||
log.Println("Updated Teachers")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TimetableResponse struct {
|
||||
|
|
@ -99,7 +100,7 @@ func Timetable(cookies []*http.Cookie, userID string) {
|
|||
return
|
||||
}
|
||||
|
||||
today := GetTime().Format("20060102")
|
||||
today := time.Now().Format("20060102")
|
||||
g := getTimetable{"2023-05-06 15:44:22.215292", "getTimetable", params{today, today, loginResult.PersonID, loginResult.PersonType}, "2.0"}
|
||||
timetablesJson, err := json.Marshal(g)
|
||||
if err != nil {
|
||||
|
|
@ -147,12 +148,12 @@ func Timetable(cookies []*http.Cookie, userID string) {
|
|||
if userID != "" {
|
||||
timetableFile = "timetable_" + userID + ".json"
|
||||
}
|
||||
if err := os.WriteFile(timetableFile, data, 0o644); err != nil {
|
||||
if err := os.WriteFile(timetableFile, data, 0644); err != nil {
|
||||
log.Printf("Error writing timetable file: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// log.Printf("Updated timetable for user %s", userID) // dont need log anymore
|
||||
log.Printf("Updated timetable for user %s", userID)
|
||||
setTimetable(userID)
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +172,6 @@ func LoadIDMap(path string) (map[int]string, error) {
|
|||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func LoadTimetable(path string) ([]TimetableEntry, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
|
|
@ -183,13 +183,11 @@ func LoadTimetable(path string) ([]TimetableEntry, error) {
|
|||
}
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func formatTime(t int) string {
|
||||
h := t / 100
|
||||
m := t % 100
|
||||
return fmt.Sprintf("%02d:%02d", h, m)
|
||||
}
|
||||
|
||||
func formatDate(date int) string {
|
||||
s := fmt.Sprintf("%08d", date) // ensures leading zeros
|
||||
year := s[:4]
|
||||
|
|
@ -197,7 +195,6 @@ func formatDate(date int) string {
|
|||
day := s[6:8]
|
||||
return fmt.Sprintf("%s-%s-%s", day, month, year)
|
||||
}
|
||||
|
||||
func setTimetable(userID string) {
|
||||
subjects, _ := LoadIDMap("subjects.json")
|
||||
rooms, _ := LoadIDMap("rooms.json")
|
||||
|
|
@ -245,9 +242,9 @@ func setTimetable(userID string) {
|
|||
if userID != "" {
|
||||
timetableFilledFile = "timetableFilled_" + userID + ".json"
|
||||
}
|
||||
if err := os.WriteFile(timetableFilledFile, data, 0o644); err != nil {
|
||||
if err := os.WriteFile(timetableFilledFile, data, 0644); err != nil {
|
||||
log.Printf("Error writing timetableFilled file: %v", err)
|
||||
return
|
||||
}
|
||||
// log.Printf("Filled timetable for user %s", userID)//log not needed
|
||||
log.Printf("Filled timetable for user %s", userID)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
|
@ -33,6 +32,8 @@ type LoginResponse struct {
|
|||
|
||||
var Url = os.Getenv("URL")
|
||||
|
||||
// var Password = os.Getenv("UNTIS_PASSWORD")
|
||||
// var USERS = os.Getenv("UNTIS_USER")
|
||||
func Main(user, password, userID string) {
|
||||
godotenv.Load("../.env")
|
||||
cookies, err := Auth(user, password, userID)
|
||||
|
|
@ -45,46 +46,26 @@ 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) {
|
||||
godotenv.Load("../.env")
|
||||
cookies, err := Auth(user, password, userID)
|
||||
if err != nil {
|
||||
log.Printf("Authentication failed for user %s: %v", user, err)
|
||||
return
|
||||
}
|
||||
Timetable(cookies, userID)
|
||||
log.Printf("Updated info for user: %s ", user)
|
||||
}
|
||||
|
||||
func Auth(user, password, userID string) ([]*http.Cookie, error) {
|
||||
loginJSON, _ := json.Marshal(Login{
|
||||
"2023-05-06 15:44:22.215292", "authenticate",
|
||||
Params{user, password, "WebUntis Test"},
|
||||
"2.0",
|
||||
})
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
login := bytes.NewReader(loginJSON)
|
||||
if Url == "" {
|
||||
Url = os.Getenv("URL")
|
||||
}
|
||||
|
||||
var LoginOut *http.Response
|
||||
var err error
|
||||
for attempt := 1; attempt <= 3; attempt++ {
|
||||
LoginOut, err = http.Post(Url, "application/json", bytes.NewReader(loginJSON))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
log.Printf("Auth attempt %d/3 failed for %s: %v", attempt, user, err)
|
||||
time.Sleep(time.Duration(attempt*2) * time.Second)
|
||||
}
|
||||
LoginOut, err := http.Post(Url, "application/json", login)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer LoginOut.Body.Close()
|
||||
|
||||
cookies := LoginOut.Cookies()
|
||||
// log.Printf("Login successful for user: %s", user)//log not needed
|
||||
log.Printf("Login successful for user: %s", user)
|
||||
|
||||
response, err := io.ReadAll(LoginOut.Body)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
package Untis
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
var Location *time.Location
|
||||
|
||||
func init() {
|
||||
godotenv.Load("../.env")
|
||||
timezone := os.Getenv("LOCATION_ENV")
|
||||
if timezone == "" {
|
||||
timezone = "UTC"
|
||||
}
|
||||
loc, err := time.LoadLocation(timezone)
|
||||
if err != nil {
|
||||
log.Printf("Failed to load timezone, set as UTC")
|
||||
loc = time.UTC
|
||||
}
|
||||
Location = loc
|
||||
}
|
||||
|
||||
func GetTime() time.Time {
|
||||
return time.Now().In(Location)
|
||||
}
|
||||
|
|
@ -4,4 +4,4 @@ UNTIS_USER=[Default user username]
|
|||
DISCORD_BOT_TOKEN=[Paste Bot token]
|
||||
ENC_KEY=[Generate enc key and paste]
|
||||
URL=[Untis url, create from tutorial in readme]
|
||||
LOCATION_ENV=Europe/Berlin [change to your timezone, needs to be usable by go's time package via time.LoadLocation(LOCATION_ENV)]
|
||||
LOCATION_ENV=Europe/Berlin [change to your timezone, needs to be usable by go's time package via time.LoadLocation()]
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -1,6 +1,6 @@
|
|||
module untislogger
|
||||
|
||||
go 1.27.0
|
||||
go 1.25.2
|
||||
|
||||
require (
|
||||
github.com/bwmarrin/discordgo v0.29.0
|
||||
|
|
|
|||
65
main.go
65
main.go
|
|
@ -4,7 +4,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"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) //Debug info, not needed at the moment
|
||||
log.Printf("DISCORD_WEBHOOK_URL: %q", discordWebhookURL)
|
||||
|
||||
// Check if Discord webhook is configured
|
||||
if discordWebhookURL != "" {
|
||||
|
|
@ -101,15 +101,37 @@ func init() {
|
|||
} else {
|
||||
log.Println("No Discord webhook provided, Discord notifications will be disabled")
|
||||
}
|
||||
locEnv := os.Getenv("LOCATION_ENV")
|
||||
|
||||
var locErr error
|
||||
|
||||
location, locErr = time.LoadLocation(locEnv)
|
||||
|
||||
if locErr != nil {
|
||||
log.Fatalf("Failed to load timezone: %v", locErr)
|
||||
}
|
||||
log.Printf("Timezone set to: %s", location)
|
||||
}
|
||||
|
||||
func getTime() time.Time {
|
||||
return time.Now().In(location)
|
||||
}
|
||||
|
||||
func main() {
|
||||
initUpdate()
|
||||
godotenv.Load(".env")
|
||||
// Untis.Main() //starting API calls function| happens in schedule func
|
||||
// Run()
|
||||
// Starts logging the timetable for each new Lesson and logs changes
|
||||
go BotStart.Start()
|
||||
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...")
|
||||
}
|
||||
|
|
@ -125,12 +147,6 @@ func isScheduledTime(now time.Time) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func initUpdate() {
|
||||
defaultUser := os.Getenv("UNTIS_USER")
|
||||
defaultPassword := os.Getenv("UNTIS_PASSWORD")
|
||||
Untis.Main(defaultUser, defaultPassword, "default")
|
||||
}
|
||||
|
||||
func scheduleTimetableUpdate() {
|
||||
prevData := make(map[string][]byte)
|
||||
|
||||
|
|
@ -141,6 +157,7 @@ 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")
|
||||
|
|
@ -154,8 +171,8 @@ func scheduleTimetableUpdate() {
|
|||
|
||||
// Process each user
|
||||
for _, acc := range accounts {
|
||||
// Fetch the latest timetable and only timetable
|
||||
Untis.Update(acc.Username, acc.DecryptedPassword, acc.UserID)
|
||||
// Fetch the latest timetable
|
||||
Untis.Main(acc.Username, acc.DecryptedPassword, acc.UserID)
|
||||
|
||||
// Check for changes
|
||||
timetableFile := fmt.Sprintf("timetableFilled_%s.json", acc.UserID)
|
||||
|
|
@ -191,15 +208,7 @@ func scheduleTimetableUpdate() {
|
|||
prevTimeslotMap := make(map[string]NamedTimetableEntry)
|
||||
|
||||
// Get current date to filter out new day changes
|
||||
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 := Untis.GetTime()
|
||||
// If before 1am stop and update userdata
|
||||
if now.Hour() < 1 {
|
||||
prevData[acc.UserID] = data
|
||||
continue
|
||||
}
|
||||
today := time.Now().Format("02-01-2006")
|
||||
|
||||
for _, e := range currentEntries {
|
||||
key := lessonKey(e)
|
||||
|
|
@ -298,10 +307,13 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +330,7 @@ func scheduleTimetableUpdate() {
|
|||
|
||||
// Ticker for scheduled lesson notifications
|
||||
startMinuteTicker(func() {
|
||||
now := Untis.GetTime()
|
||||
now := getTime()
|
||||
if isScheduledTime(now) {
|
||||
log.Println("Scheduled time reached, running notifications...")
|
||||
accounts, _ := BotStart.LoadAndDecryptAccounts()
|
||||
|
|
@ -330,11 +342,10 @@ func scheduleTimetableUpdate() {
|
|||
log.Println("Finished running notifications.")
|
||||
}
|
||||
})
|
||||
log.Println("Updated all users")
|
||||
}
|
||||
|
||||
func startMinuteTicker(f func()) {
|
||||
now := Untis.GetTime()
|
||||
now := getTime()
|
||||
next := now.Truncate(time.Minute).Add(time.Minute)
|
||||
time.Sleep(time.Until(next))
|
||||
ticker := time.NewTicker(1 * time.Minute)
|
||||
|
|
@ -363,7 +374,7 @@ func Run(userID string) {
|
|||
roomByStartTime, _ := MapTimeToRoom(timetableFile)
|
||||
subjectByStartTime, _ := MapTimeToSubject(timetableFile)
|
||||
|
||||
now := Untis.GetTime().Format("15:04")
|
||||
now := getTime().Format("15:04")
|
||||
|
||||
nextTime, room, foundRoom := NextRoomForTime(roomByStartTime, now)
|
||||
if !foundRoom {
|
||||
|
|
@ -612,7 +623,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, _ := io.ReadAll(resp.Body)
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
log.Printf("Discord webhook failed with status %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
}
|
||||
|
|
@ -643,7 +654,7 @@ func sendUpdateDiscordWebhookWithDetails(changes []string) {
|
|||
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||
log.Println("Detailed Discord webhook sent successfully")
|
||||
} else {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
log.Printf("Discord webhook failed with status %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue