-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbottom.go
114 lines (97 loc) · 2.34 KB
/
bottom.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
package bottom
import (
"crypto/tls"
"net/url"
"strconv"
"github.com/lrstanley/girc"
)
var (
defaultAutoAcceptInvites = true
)
// Bottom is the transport logic for an IRC Bot
//
// It handles things like routing messages and error handling
type Bottom struct {
Middlewares *Middlewares
Client *girc.Client
ErrorFunc func(Context, error)
// The following are extra tunables which are not
// passed in via args, partially for backwards
// compatability reasons, but part because the defaults
// are sane enough- setting them is not compulsary
AutoAcceptInvites bool
// nick is the name this bot is using
// it's useful for testing whether messages
// come from a channel, or directly
nick string
}
// New accepts some connection parameters, initialises an IRC client,
// and sets up an empty Middlewares list, and a default ErrorFunc
//
// It will error for malformed server addresses. The form it expects is:
// [irc|ircs]://hostname:port
//
// So:
// 1. `irc://irc.example.com:6667`
// 2. `ircs://irc.example.com:6697`
//
// Are valid, whereas
//
// 1. `irc.example.com`
//
// Is not.
func New(user, password, server string, verifyTLS bool) (b Bottom, err error) {
u, err := url.Parse(server)
if err != nil {
return
}
port, err := strconv.Atoi(u.Port())
if err != nil {
return
}
config := girc.Config{
Server: u.Hostname(),
Port: port,
Nick: user,
User: user,
Name: user,
SASL: &girc.SASLPlain{
User: user,
Pass: password,
},
SSL: u.Scheme == "ircs",
TLSConfig: &tls.Config{
InsecureSkipVerify: !verifyTLS,
},
AllowFlood: true,
}
b.Client = girc.New(config)
b.Middlewares = NewMiddlewares()
b.ErrorFunc = b.defaultErrorFunc
b.AutoAcceptInvites = defaultAutoAcceptInvites
b.nick = user
b.Client.Handlers.Add(girc.PRIVMSG, b.privmsg)
b.Client.Handlers.Add(girc.INVITE, func(c *girc.Client, e girc.Event) {
if b.AutoAcceptInvites {
c.Cmd.Join(e.Last())
}
})
return
}
func (b Bottom) privmsg(_ *girc.Client, e girc.Event) {
var err error
ctx := make(Context)
ctx["sender"] = e.Source.Name
ctx["recipient"] = b.nick
ctx["message"] = e.Last()
for _, m := range *b.Middlewares {
err = m.Do(ctx, e)
if err != nil {
b.ErrorFunc(ctx, err)
return
}
}
}
func (b Bottom) defaultErrorFunc(ctx Context, err error) {
b.Client.Cmd.Message(ctx["sender"].(string), err.Error())
}