blob: 4e6b0b713aabcbf2fbae7f7bea2cc982e7e0cd30 [file] [log] [blame]
Sergiusz Bazanskia8854882020-01-05 00:34:38 +01001package irc
2
3import (
4 "context"
5 "fmt"
6
7 "github.com/golang/glog"
8)
9
10// Control: send a message to IRC.
Sergiusz Bazanski83e26902020-01-23 14:18:25 +010011func (m *Manager) SendMessage(ctx context.Context, user, text string) error {
Sergiusz Bazanskia8854882020-01-05 00:34:38 +010012 done := make(chan error)
Sergiusz Bazanski83e26902020-01-23 14:18:25 +010013
14 msg := &control{
Sergiusz Bazanskia8854882020-01-05 00:34:38 +010015 message: &controlMessage{
16 from: user,
17 message: text,
18 done: done,
19 },
20 }
Sergiusz Bazanski83e26902020-01-23 14:18:25 +010021
22 select {
23 case <-ctx.Done():
24 return ctx.Err()
25 case m.ctrl <- msg:
26 return <-done
27 }
Sergiusz Bazanskia8854882020-01-05 00:34:38 +010028}
29
30// Control: subscribe to notifiactions.
31func (m *Manager) Subscribe(c chan *Notification) {
32 m.ctrl <- &control{
33 subscribe: &controlSubscribe{
34 c: c,
35 },
36 }
37}
38
39// control message from owner. Only one member can be set.
40type control struct {
41 // message needs to be send to IRC
42 message *controlMessage
43 // a new subscription channel for notifications is presented
44 subscribe *controlSubscribe
45}
46
47// controlMessage is a request to send a message to IRC as a given user
48type controlMessage struct {
49 // user name (native to application)
50 from string
51 // plaintext message
52 message string
53 // channel that will be sent nil or an error when the message has been
54 // succesfully sent or an error occured
55 done chan error
56}
57
58// controlSubscribe is a request to send notifications to a given channel
59type controlSubscribe struct {
60 c chan *Notification
61}
62
63// doctrl processes a given control message.
64func (m *Manager) doctrl(ctx context.Context, c *control) {
65 switch {
66
67 case c.message != nil:
68 // Send a message to IRC.
69
70 // Find a relevant connection, or make one.
71 conn, err := m.getconn(ctx, c.message.from)
72 if err != nil {
73 // Do not attempt to redeliver bans.
74 if err == errBanned {
75 c.message.done <- nil
76 } else {
77 c.message.done <- fmt.Errorf("getting connection: %v", err)
78 }
79 return
80 }
81
82 // Route message to connection.
83 conn.Say(c.message)
84
85 case c.subscribe != nil:
86 // Subscribe to notifications.
87 m.subscribers[c.subscribe.c] = true
88
89 default:
90 glog.Errorf("unhandled control %+v", c)
91 }
92}