Bot start
This commit is contained in:
parent
42ec5bd9b9
commit
b8d9cb5c82
7 changed files with 176 additions and 6 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -5,4 +5,5 @@ subjects.json
|
||||||
teachers.json
|
teachers.json
|
||||||
login.json
|
login.json
|
||||||
timetable.json
|
timetable.json
|
||||||
timetableFilled.json
|
timetableFilled.json
|
||||||
|
accounts.json
|
||||||
|
|
@ -54,7 +54,7 @@ func Main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Auth() ([]*http.Cookie, error) {
|
func Auth() ([]*http.Cookie, error) {
|
||||||
l := Login{"2023-05-06 15:44:22.215292", "authenticate", Params{os.Getenv("UNTIS_USER"), os.Getenv("UNTIS_PASSWORD"), "WebUntis Test"}, "2.0"}
|
l := Login{"2023-05-06 15:44:22.215292", "authenticate", Params{USERS, Password, "WebUntis Test"}, "2.0"}
|
||||||
loginJSON, err := json.Marshal(l)
|
loginJSON, err := json.Marshal(l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error marshaling login data: %v", err)
|
log.Fatalf("Error marshaling login data: %v", err)
|
||||||
|
|
|
||||||
144
Botrun/BotStart.go
Normal file
144
Botrun/BotStart.go
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
package bot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Account structure to save in JSON
|
||||||
|
type Account struct {
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// State management for conversation steps
|
||||||
|
type UserState struct {
|
||||||
|
Step string // "awaiting_username", "awaiting_password"
|
||||||
|
Username string // Temporary storage for username until password is received
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
userStates = make(map[string]*UserState) // userID -> state
|
||||||
|
stateMutex sync.Mutex // protect userStates
|
||||||
|
accountsFile = "accounts.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Save account info to JSON file (appends or updates)
|
||||||
|
func saveAccount(userID, username, password string) error {
|
||||||
|
var accounts []Account
|
||||||
|
|
||||||
|
// Load existing accounts if file exists
|
||||||
|
if data, err := os.ReadFile(accountsFile); err == nil && len(data) > 0 {
|
||||||
|
_ = json.Unmarshal(data, &accounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append new account
|
||||||
|
accounts = append(accounts, Account{
|
||||||
|
UserID: userID,
|
||||||
|
Username: username,
|
||||||
|
Password: password,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Save back to file
|
||||||
|
newData, err := json.MarshalIndent(accounts, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.WriteFile(accountsFile, newData, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Start() {
|
||||||
|
token := os.Getenv("DISCORD_BOT_TOKEN")
|
||||||
|
if token == "" {
|
||||||
|
fmt.Println("DISCORD_BOT_TOKEN environment variable is not set.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dg, err := discordgo.New("Bot " + token)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error creating Discord session,", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dg.AddHandler(messageCreate)
|
||||||
|
err = dg.Open()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error opening connection,", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
|
||||||
|
<-sc
|
||||||
|
|
||||||
|
dg.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||||
|
// Ignore bot's own messages
|
||||||
|
if m.Author.ID == s.State.User.ID {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle "!addaccount" only in guilds (not in DMs)
|
||||||
|
if m.GuildID != "" && m.Content == "!addaccount" {
|
||||||
|
// Delete the command for privacy
|
||||||
|
_ = s.ChannelMessageDelete(m.ChannelID, m.ID)
|
||||||
|
// Create DM channel
|
||||||
|
channel, err := s.UserChannelCreate(m.Author.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error creating DM channel:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.ChannelMessageSend(channel.ID, "Let's add your account. Please provide your username:")
|
||||||
|
|
||||||
|
stateMutex.Lock()
|
||||||
|
userStates[m.Author.ID] = &UserState{Step: "awaiting_username"}
|
||||||
|
stateMutex.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle DMs for the two-step process
|
||||||
|
if m.GuildID == "" {
|
||||||
|
stateMutex.Lock()
|
||||||
|
state, ok := userStates[m.Author.ID]
|
||||||
|
stateMutex.Unlock()
|
||||||
|
if !ok {
|
||||||
|
return // Not in the process
|
||||||
|
}
|
||||||
|
|
||||||
|
switch state.Step {
|
||||||
|
case "awaiting_username":
|
||||||
|
// Store the username and prompt for password
|
||||||
|
stateMutex.Lock()
|
||||||
|
state.Username = m.Content
|
||||||
|
state.Step = "awaiting_password"
|
||||||
|
userStates[m.Author.ID] = state
|
||||||
|
stateMutex.Unlock()
|
||||||
|
s.ChannelMessageSend(m.ChannelID, "Now, please provide your password:")
|
||||||
|
case "awaiting_password":
|
||||||
|
username := state.Username
|
||||||
|
password := m.Content
|
||||||
|
// Save to JSON
|
||||||
|
if err := saveAccount(m.Author.ID, username, password); err != nil {
|
||||||
|
s.ChannelMessageSend(m.ChannelID, "There was an error saving your account. Please try again later.")
|
||||||
|
fmt.Println("Error saving account:", err)
|
||||||
|
} else {
|
||||||
|
s.ChannelMessageSend(m.ChannelID, "Your account has been saved!")
|
||||||
|
}
|
||||||
|
// Cleanup state
|
||||||
|
stateMutex.Lock()
|
||||||
|
delete(userStates, m.Author.ID)
|
||||||
|
stateMutex.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
README.md
11
README.md
|
|
@ -1,5 +1,8 @@
|
||||||
# Discord bot for logging Untis timetable to a Discord Webhook
|
# Discord bot for logging Untis timetable to a Discord Webhook
|
||||||
create .env with Credentials
|
## create .env with Credentials:
|
||||||
UNTIS_PASSWORD
|
- UNTIS_PASSWORD
|
||||||
UNTIS_USER
|
- UNTIS_USER
|
||||||
DISCORD_WEBHOOK_URL
|
- DISCORD_WEBHOOK_URL
|
||||||
|
- DISCORD_BOT_TOKEN
|
||||||
|
|
||||||
|
# This is a project for me, issues will be resolved as i find the motivation to do that, improvements may follow in the future
|
||||||
7
go.mod
7
go.mod
|
|
@ -3,3 +3,10 @@ module untislogger
|
||||||
go 1.24
|
go 1.24
|
||||||
|
|
||||||
require github.com/joho/godotenv v1.5.1
|
require 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
|
||||||
|
)
|
||||||
|
|
|
||||||
12
go.sum
12
go.sum
|
|
@ -1,2 +1,14 @@
|
||||||
|
github.com/bwmarrin/discordgo v0.29.0 h1:FmWeXFaKUwrcL3Cx65c20bTRW+vOb6k8AnaP+EgjDno=
|
||||||
|
github.com/bwmarrin/discordgo v0.29.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
|
||||||
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
||||||
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
|
|
||||||
3
main.go
3
main.go
|
|
@ -14,6 +14,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
Untis "untislogger/Bot"
|
Untis "untislogger/Bot"
|
||||||
|
|
||||||
|
BotStart "untislogger/Botrun"
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -52,6 +54,7 @@ func main() {
|
||||||
//Untis.Main() //starting API calls function| happens in schedule func
|
//Untis.Main() //starting API calls function| happens in schedule func
|
||||||
//Run()
|
//Run()
|
||||||
//Starts logging the timetable for each new Lesson and logs changes
|
//Starts logging the timetable for each new Lesson and logs changes
|
||||||
|
go BotStart.Start()
|
||||||
scheduleTimetableUpdate()
|
scheduleTimetableUpdate()
|
||||||
|
|
||||||
sigChan := make(chan os.Signal, 1)
|
sigChan := make(chan os.Signal, 1)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue