-
Notifications
You must be signed in to change notification settings - Fork 4
/
soulshack.go
118 lines (102 loc) · 3.33 KB
/
soulshack.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
package main
// ____ _ ____ _ _
// / ___| ___ _ _ | | / ___| | |__ __ _ ___ | | __
// \___ \ / _ \ | | | | | | \___ \ | '_ \ / _` | / __| | |/ /
// ___) | | (_) | | |_| | | | ___) | | | | | | (_| | | (__ | <
// |____/ \___/ \__,_| |_| |____/ |_| |_| \__,_| \___| |_|\_\
// . . . because real people are overrated
import (
"context"
"crypto/tls"
"fmt"
"log"
"strings"
"time"
"github.com/common-nighthawk/go-figure"
"github.com/spf13/cobra"
"github.com/lrstanley/girc"
)
var root = &cobra.Command{
Use: "soulshack --channel <channel> [--nick <nickname>] [--server <server>] [--port <port>] [--tls] [--apikey <key>]",
Example: "soulshack --nick chatbot --server irc.freenode.net --port 6697 --channel '#soulshack' --tls --apikey ****************",
Run: runBot,
Version: "0.7 - http://github.com/pkdindustries/soulshack",
}
func main() {
fmt.Printf("%s\n", getBanner())
initializeConfig()
if err := root.Execute(); err != nil {
log.Fatal(err)
}
}
func getBanner() string {
return fmt.Sprintf("%s\n%s",
figure.NewColorFigure("SoulShack", "", "green", true).ColorString(),
figure.NewColorFigure(" . . . because real people are overrated", "term", "green", true).ColorString())
}
func runBot(r *cobra.Command, _ []string) {
config := NewConfiguration()
sys := NewSystem(config)
irc := girc.New(girc.Config{
Server: config.Server.Server,
Port: config.Server.Port,
Nick: config.Server.Nick,
User: "soulshack",
Name: "soulshack",
SSL: config.Server.SSL,
TLSConfig: &tls.Config{InsecureSkipVerify: config.Server.TLSInsecure},
})
if config.Server.SASLNick != "" && config.Server.SASLPass != "" {
irc.Config.SASL = &girc.SASLPlain{
User: config.Server.SASLNick,
Pass: config.Server.SASLPass,
}
}
irc.Handlers.AddBg(girc.CONNECTED, func(irc *girc.Client, e girc.Event) {
log.Println("joining channel:", config.Server.Channel)
irc.Cmd.Join(config.Server.Channel)
})
irc.Handlers.AddBg(girc.JOIN, func(irc *girc.Client, e girc.Event) {
if e.Source.Name == config.Server.Nick {
ctx, cancel := NewChatContext(context.Background(), config, sys, irc, &e)
defer cancel()
greeting(ctx)
}
})
irc.Handlers.AddBg(girc.PRIVMSG, func(irc *girc.Client, e girc.Event) {
ctx, cancel := NewChatContext(context.Background(), config, sys, irc, &e)
defer cancel()
if ctx.Valid() {
log.Println(">>", strings.Join(e.Params[1:], " "))
switch ctx.GetCommand() {
case "/set":
slashSet(ctx)
case "/get":
slashGet(ctx)
case "/leave":
slashLeave(ctx)
case "/help":
fallthrough
case "/?":
ctx.Reply("Supported commands: /set, /get, /leave, /help, /version")
case "/version":
ctx.Reply(r.Version)
default:
completionResponse(ctx)
}
}
})
// Reconnect loop with a maximum retry limit
maxRetries := 5
for retries := 0; retries < maxRetries; retries++ {
log.Printf("connecting to server:%s, port:%d, tls:%t, sasl:%t, api:%s", irc.Config.Server, irc.Config.Port, irc.Config.SSL, irc.Config.SASL != nil, config.API.URL)
if err := irc.Connect(); err != nil {
log.Println("connection error:", err)
log.Println("reconnecting in 5 seconds...")
time.Sleep(5 * time.Second)
continue
}
return
}
log.Println("maximum retry limit reached, exiting...")
}