Advertisement
Guest User

Untitled

a guest
May 23rd, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.49 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.         "fmt"
  5.         "io/ioutil"
  6.         "log"
  7.         "os"
  8.         "os/signal"
  9.         "regexp"
  10.         "strconv"
  11.         "strings"
  12.         "syscall"
  13.         "time"
  14.  
  15.         "github.com/bwmarrin/discordgo"
  16.         "gopkg.in/go-playground/validator.v9"
  17.         "gopkg.in/yaml.v2"
  18. )
  19.  
  20. const (
  21.         configureFilePath = "/etc/discord-reminder.yml"
  22. )
  23.  
  24. type (
  25.         Configure struct {
  26.                 AllowServersIDs                 []int   `validate:"required" yaml:"allowServerIDs"`
  27.                 AllowRemindsPerServer   int             `validate:"required" yaml:"allowRemindPerServer"`
  28.                 AccessToken                             string  `validate:"required" yaml:"accessToken"`
  29.         }
  30. )
  31.  
  32. func getConfigureObjectByFile() (Configure, error) {
  33.         var c Configure
  34.  
  35.         buf, err := ioutil.ReadFile(configureFilePath)
  36.  
  37.         if err != nil {
  38.                 return c, err
  39.         }
  40.  
  41.         if err := yaml.UnmarshalStrict(buf, &c); err != nil {
  42.                 return c, err
  43.         }
  44.  
  45.         if err := validator.New().Struct(&c); err != nil {
  46.                 return c, err
  47.         }
  48.  
  49.         return c, nil
  50. }
  51.  
  52. func createNotificationFunctionWithParam(
  53.         s *discordgo.Session,
  54.         channelId string,
  55.         userId string,
  56.         memo string,
  57. ) func() {
  58.         log.Print("[Reminder] Notification!")
  59.  
  60.         return func(){
  61.                 s.ChannelMessageSend(
  62.                         channelId,
  63.                         fmt.Sprintf(
  64.                                 "<@%s> %s",
  65.                                 userId,
  66.                                 memo,
  67.                         ),
  68.                 )
  69.         }
  70. }
  71.  
  72. func main() {
  73.         log.SetFlags(log.LstdFlags | log.Lshortfile)
  74.  
  75.         // Configure parsing ...
  76.         log.Print("[SYSTEM] Read configure file...")
  77.  
  78.         c, err := getConfigureObjectByFile()
  79.  
  80.         if err != nil {
  81.                 log.Fatal(err)
  82.         }
  83.  
  84.  
  85.         // Bot initialization
  86.         log.Print("[SYSTEM] Initialization...")
  87.  
  88.         dg, err := discordgo.New("Bot " + c.AccessToken)
  89.  
  90.         if err != nil {
  91.                 log.Fatal("[SYSTEM] ERROR: creating Discord session:", err)
  92.         }
  93.  
  94.         jst, err := time.LoadLocation("Asia/Tokyo")
  95.  
  96.         if err != nil {
  97.                 log.Fatal("[SYSTEM] ERROR: Failed to LoadLocation:", err)
  98.         }
  99.  
  100.         reminderConfigureRegex := regexp.MustCompile(`^!r \d\d? .+$`)
  101.  
  102.         // Handler
  103.         dg.AddHandler(func (
  104.                 s *discordgo.Session,
  105.                 m *discordgo.MessageCreate,
  106.         ) {
  107.                 if m.Author.ID == s.State.User.ID {
  108.                         return
  109.                 }
  110.  
  111.                 if reminderConfigureRegex.Match([]byte(m.Content)) {
  112.                         splittedCommand := strings.Split(m.Content, " ")
  113.  
  114.                         now := time.Now().In(jst)
  115.  
  116.                         memo := strings.Join(splittedCommand[2:], " ")
  117.                         hour, err := strconv.Atoi(splittedCommand[1])
  118.  
  119.                         if err != nil {
  120.                                 return
  121.                         }
  122.  
  123.                         if 24 <= hour {
  124.                                 return
  125.                         }
  126.  
  127.  
  128.                         notificationTime := time.Date(
  129.                                 now.Year(),
  130.                                 now.Month(),
  131.                                 now.Day(),
  132.                                 hour,
  133.                                 0, // min
  134.                                 0, // sec
  135.                                 0, // nsec
  136.                                 jst,
  137.                         )
  138.  
  139.                         // !(now < notification time)
  140.                         if notificationTime.Before(now) {
  141.                                 notificationTime = notificationTime.Add(time.Hour * 24)
  142.                         }
  143.  
  144.                         diff := notificationTime.Sub(now)
  145.  
  146.                         time.AfterFunc(
  147.                                 diff,
  148.                                 createNotificationFunctionWithParam(
  149.                                         s,
  150.                                         m.ChannelID,
  151.                                         m.Author.ID,
  152.                                         memo,
  153.                                 ),
  154.                         )
  155.  
  156.                         s.ChannelMessageSend(
  157.                                 m.ChannelID,
  158.                                 fmt.Sprintf(
  159.                                         "<@%s> Configured reminder after %s.",
  160.                                         m.Author.ID,
  161.                                         diff,
  162.                                 ),
  163.                         )
  164.  
  165.                         log.Print(fmt.Sprintf(
  166.                                 "[Reminder] Configured reminder after %s",
  167.                                 diff,
  168.                         ))
  169.  
  170.                         return
  171.                 }
  172.  
  173.         })
  174.  
  175.         // Bot start
  176.         if err := dg.Open(); err != nil {
  177.                 log.Fatal("[SYSTEM] error open websocket: ", err)
  178.         }
  179.  
  180.         // Wait
  181.         log.Print("[SYSTEM] Bot is now running.  Press ^C to exit.")
  182.  
  183.         sc := make(chan os.Signal, 1)
  184.  
  185.         signal.Notify(
  186.                 sc,
  187.                 syscall.SIGINT,
  188.                 syscall.SIGTERM,
  189.                 os.Interrupt,
  190.                 os.Kill,
  191.         )
  192.  
  193.         <-sc
  194.  
  195.         dg.Close()
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement