You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.2 KiB
133 lines
3.2 KiB
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/bwmarrin/discordgo"
|
|
"log"
|
|
"time"
|
|
)
|
|
|
|
type Task struct {
|
|
ID int64
|
|
Type string
|
|
Content string
|
|
GuildID string
|
|
ChannelID string
|
|
UserID string
|
|
CreationTime time.Time
|
|
TriggerTime time.Time
|
|
}
|
|
|
|
func processTask(task *Task, s *discordgo.Session) {
|
|
query := "SELECT completed, processing from tasks where id = $1"
|
|
res, err := Database.Query(query, task.ID)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
var completed bool
|
|
var processing bool
|
|
res.Next()
|
|
err = res.Scan(&completed, &processing)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
if completed || processing {
|
|
return
|
|
}
|
|
closeQuery := "Update tasks set completed = true where id = $1"
|
|
processQuery := "UPDATE tasks SET processing = true WHERE id = $1"
|
|
defer Database.Exec(closeQuery, task.ID)
|
|
_, err = Database.Exec(processQuery, task.ID)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
log.Println(fmt.Sprintf("Processing task %v", task.ID))
|
|
guild, err := s.Guild(task.GuildID)
|
|
if err != nil {
|
|
log.Print(fmt.Sprintf("Can't find guild with ID %v. Canceling task %v.", task.GuildID, task.ID))
|
|
return
|
|
}
|
|
channel, err := s.Channel(task.ChannelID)
|
|
if err != nil {
|
|
log.Print(fmt.Sprintf("Can't find channel with ID %v. Canceling task %v.", task.ChannelID, task.ID))
|
|
return
|
|
}
|
|
if channel.GuildID != guild.ID {
|
|
log.Print(fmt.Sprintf("The channel %v is not in guild %v. Canceling task %v.", channel.Name, guild.Name, task.ID))
|
|
return
|
|
}
|
|
member, err := s.GuildMember(guild.ID, task.UserID)
|
|
if err != nil {
|
|
log.Print(fmt.Sprintf("Can't find user with ID %v in guild %v. Canceling task %v.", task.UserID, guild.Name, task.ID))
|
|
return
|
|
}
|
|
if task.Type == "Reminder" {
|
|
color := s.State.UserColor(member.User.ID, channel.ID)
|
|
e := discordgo.MessageEmbed{
|
|
Title: "REMINDER",
|
|
Description: task.Content,
|
|
Timestamp: task.CreationTime.Format(time.RFC3339),
|
|
Color: color,
|
|
Footer: &discordgo.MessageEmbedFooter{
|
|
Text: "Created: ",
|
|
},
|
|
}
|
|
msg := discordgo.MessageSend{
|
|
Content: member.Mention(),
|
|
Embed: &e,
|
|
}
|
|
_, err = s.ChannelMessageSendComplex(channel.ID, &msg)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
processQuery = "UPDATE tasks SET processing = false WHERE id = $1"
|
|
_, err = Database.Exec(processQuery, task.ID)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
|
|
}
|
|
|
|
func getTasksToRun() []Task {
|
|
query := "SELECT id, type, content, guild_id, channel_id, user_id, creation_time, trigger_time " +
|
|
"from tasks where completed is false and processing is false and trigger_time < $1"
|
|
res, err := Database.Query(query, time.Now())
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
var tasks []Task
|
|
for res.Next() {
|
|
var t Task
|
|
err = res.Scan(&t.ID, &t.Type, &t.Content, &t.GuildID, &t.ChannelID, &t.UserID, &t.CreationTime, &t.TriggerTime)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
for _, task := range tasks {
|
|
if task.ID == t.ID {
|
|
continue
|
|
}
|
|
}
|
|
tasks = append(tasks, t)
|
|
}
|
|
|
|
return tasks
|
|
}
|
|
|
|
func ProcessTasks(s *discordgo.Session, interval int) {
|
|
for {
|
|
time.Sleep(time.Duration(interval * 1e9))
|
|
|
|
tasks := getTasksToRun()
|
|
|
|
if len(tasks) > 0 {
|
|
for _, t := range tasks {
|
|
go processTask(&t, s)
|
|
}
|
|
}
|
|
}
|
|
}
|