feat: Implement multi-user timetable tracking and notifications #1

Merged
Jannover5000r merged 3 commits from feature/multi-user-support into main 2025-10-10 23:00:28 +02:00
3 changed files with 83 additions and 4 deletions
Showing only changes of commit 2c0c1b289b - Show all commits

3
.gitignore vendored
View file

@ -6,4 +6,5 @@ teachers.json
login.json
timetable*.json
timetableFilled*.json
accounts.json
accounts.json
login*.json

View file

@ -305,6 +305,56 @@ func SendDM(userID, message string) {
}
}
// Delete account and associated files for a given userID
func deleteAccount(userID string) error {
var accounts []Account
// Load existing accounts
data, err := os.ReadFile(accountsFile)
if err != nil {
if os.IsNotExist(err) {
return nil // No accounts file means nothing to delete
}
return err
}
if len(data) > 0 {
if err := json.Unmarshal(data, &accounts); err != nil {
return err
}
}
// Filter out the account with matching userID
newAccounts := accounts[:0]
found := false
for _, acc := range accounts {
if acc.UserID != userID {
newAccounts = append(newAccounts, acc)
} else {
found = true
}
}
if !found {
return errors.New("account not found")
}
// Save remaining accounts back to file
newData, err := json.MarshalIndent(newAccounts, "", " ")
if err != nil {
return err
}
if err := os.WriteFile(accountsFile, newData, 0644); err != nil {
return err
}
// Delete associated timetable files
os.Remove(getTimetableFile(userID))
os.Remove(getTimetableFilledFile(userID))
return nil
}
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
// Ignore bot's own messages
if m.Author.ID == s.State.User.ID {
@ -329,6 +379,29 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
return
}
// Handle "!deleteaccount" and "!removeaccount" commands
if m.GuildID != "" && (m.Content == "!deleteaccount" || m.Content == "!removeaccount") {
// Delete the command message for privacy
_ = s.ChannelMessageDelete(m.ChannelID, m.ID)
err := deleteAccount(m.Author.ID)
if err != nil {
// Create DM channel to notify of error
channel, err := s.UserChannelCreate(m.Author.ID)
if err == nil {
s.ChannelMessageSend(channel.ID, "Failed to delete your account: "+err.Error())
}
return
}
// Notify success via DM
channel, err := s.UserChannelCreate(m.Author.ID)
if err == nil {
s.ChannelMessageSend(channel.ID, "Your account has been successfully deleted.")
}
return
}
// Handle DMs for the two-step process
if m.GuildID == "" {
stateMutex.Lock()

View file

@ -11,8 +11,13 @@
# Installation
### This bot is self hosted and will run correctly when doing "go run . " in the root folder of the project. Before usage add the .env file with the Credentials as mentioned above. When you run the Programm for the first time, all important files will be created automatically and the bot is ready to go. The user added via the fields UNTIS_USER and UNTIS_PASSWORD in the .env will be the one where the Webhook is sourced from and the other users will be send a DM after adding their account with the command.
# This is a discord application intended for self hosting. You will need to add an application in the disord developer website for this bot mainly with the read messages and write messages privelege as well as send privat messages for the account handling. If you give it administrator permissions you dont have to worry further but this could present you with a security risk if my github account gets compromised and a malicious update to the script gets pushed which you than use since the bot got access to your whole server.
## In case your school is using a different timing for the Lessons than mine, you can change the times where you will be notified with the next room and Lesson for the day in **Line 71 in the main.go** file.
# I am neither a representative of Untis Untis Baden-Württemberg GmbH nor a Developer in their team. This project is based on their API and is not affiliated with them.
### This bot is self hosted and will run correctly when doing "go run . " in the root folder of the project. **Before usage add the .env file with the Credentials as mentioned above.** When you run the Programm for the first time, all important files will be created automatically and the bot is ready to go. The user added via the fields UNTIS_USER and UNTIS_PASSWORD in the .env will be the one where the Webhook is sourced from and the other users will be send a DM after adding their account with the command.
### For multi user support: using the command **!addaccount** in the discord server the bot is used in, it will than dm you with the sign up process prompting you to enter your untis Username and password (no email neededd). The Username is stored as plain text and the password is hashed on the device hosting the bot, so currently it is **not secure** since the host will have access to the hashed password and the hash used! Deleting an account is done by using **!removeaccount** which will delete the account, created with you discord account.
## In case your school is using a different timing for the Lessons than mine, you can change the times where you will be notified with the next room and Lesson for the day in **Line 71 in the main.go** file. The bot may not send you a message if there is no lesson after the specified time so that you can leave empty lessons as is for the days.
# I am neither a representative of Untis, Untis Baden-Württemberg GmbH nor a Developer in their team. This project is based on their API and my code and is not affiliated with them.