/
main.go
121 lines (110 loc) · 2.83 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package main
import (
"database/sql"
"flag"
"fmt"
"math/rand"
"os"
"time"
"github.com/keybase/go-keybase-chat-bot/kbchat"
"github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1"
"github.com/keybase/managed-bots/base"
"github.com/keybase/managed-bots/triviabot/triviabot"
"golang.org/x/sync/errgroup"
)
type BotServer struct {
*base.Server
opts base.Options
kbc *kbchat.API
}
func NewBotServer(opts base.Options) *BotServer {
return &BotServer{
Server: base.NewServer("triviabot", opts.Announcement, opts.AWSOpts, opts.MultiDSN, opts.ReadSelf, kbchat.RunOptions{
KeybaseLocation: opts.KeybaseLocation,
HomeDir: opts.Home,
}),
opts: opts,
}
}
func (s *BotServer) makeAdvertisement() kbchat.Advertisement {
cmds := []chat1.UserBotCommandInput{
{
Name: "trivia begin",
Description: "Begin a new question asking session",
},
{
Name: "trivia end",
Description: "End the current question asking session",
},
{
Name: "trivia top",
Description: "Show the top users for this conversation",
},
{
Name: "trivia reset",
Description: "Reset the scores leaderboard",
},
base.GetFeedbackCommandAdvertisement(s.kbc.GetUsername()),
}
return kbchat.Advertisement{
Alias: "Trivia",
Advertisements: []chat1.AdvertiseCommandAPIParam{
{
Typ: "public",
Commands: cmds,
},
},
}
}
func (s *BotServer) Go() (err error) {
if s.kbc, err = s.Start(s.opts.ErrReportConv); err != nil {
return err
}
sdb, err := sql.Open("mysql", s.opts.DSN)
if err != nil {
s.Errorf("failed to connect to MySQL: %s", err)
return err
}
defer sdb.Close()
db := triviabot.NewDB(sdb)
debugConfig := base.NewChatDebugOutputConfig(s.kbc, s.opts.ErrReportConv)
stats, err := base.NewStatsRegistry(debugConfig, s.opts.StathatEZKey)
if err != nil {
s.Debug("unable to create stats: %v", err)
return err
}
stats = stats.SetPrefix(s.Name())
handler := triviabot.NewHandler(stats, s.kbc, debugConfig, db)
eg := &errgroup.Group{}
s.GoWithRecover(eg, func() error { return s.Listen(handler) })
s.GoWithRecover(eg, func() error { return s.HandleSignals(stats) })
s.GoWithRecover(eg, func() error { return s.AnnounceAndAdvertise(s.makeAdvertisement(), "I live.") })
if err := eg.Wait(); err != nil {
s.Debug("wait error: %s", err)
return err
}
return nil
}
func main() {
rc := mainInner()
os.Exit(rc)
}
func mainInner() int {
rand.Seed(time.Now().Unix())
opts := base.NewOptions()
fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
if err := opts.Parse(fs, os.Args); err != nil {
fmt.Printf("Unable to parse options: %v\n", err)
return 3
}
if len(opts.DSN) == 0 {
fmt.Printf("must specify a database DSN\n")
return 3
}
bs := NewBotServer(*opts)
if err := bs.Go(); err != nil {
fmt.Printf("error running chat loop: %s\n", err)
return 3
}
return 0
}