ScuttleBot

scuttlebot / pkg / sessionrelay / channelstate.go
Blame History Raw 102 lines
1
package sessionrelay
2
3
import (
4
"fmt"
5
"os"
6
"path/filepath"
7
"strings"
8
)
9
10
type BrokerCommand struct {
11
Name string
12
Channel string
13
}
14
15
func ParseEnvChannels(primary, raw string) []string {
16
if strings.TrimSpace(raw) == "" {
17
return normalizeChannels(primary, nil)
18
}
19
20
parts := strings.Split(raw, ",")
21
return normalizeChannels(primary, parts)
22
}
23
24
func ChannelSlugs(channels []string) []string {
25
out := make([]string, 0, len(channels))
26
for _, channel := range channels {
27
if slug := channelSlug(channel); slug != "" {
28
out = append(out, slug)
29
}
30
}
31
return out
32
}
33
34
func FormatChannels(channels []string) string {
35
if len(channels) == 0 {
36
return "(none)"
37
}
38
return strings.Join(normalizeChannels("", channels), ", ")
39
}
40
41
func WriteChannelStateFile(path, control string, channels []string) error {
42
if path == "" {
43
return nil
44
}
45
control = channelSlug(control)
46
channels = normalizeChannels(control, channels)
47
if len(channels) == 0 {
48
return fmt.Errorf("sessionrelay: channel state requires at least one channel")
49
}
50
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
51
return err
52
}
53
54
data := strings.Join([]string{
55
"SCUTTLEBOT_CHANNEL=" + control,
56
"SCUTTLEBOT_CHANNELS=" + strings.Join(ChannelSlugs(channels), ","),
57
"",
58
}, "\n")
59
60
tmp := path + ".tmp"
61
if err := os.WriteFile(tmp, []byte(data), 0o600); err != nil {
62
return err
63
}
64
return os.Rename(tmp, path)
65
}
66
67
func RemoveChannelStateFile(path string) error {
68
if path == "" {
69
return nil
70
}
71
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
72
return err
73
}
74
return nil
75
}
76
77
func ParseBrokerCommand(text string) (BrokerCommand, bool) {
78
fields := strings.Fields(strings.TrimSpace(text))
79
if len(fields) == 0 {
80
return BrokerCommand{}, false
81
}
82
83
switch strings.ToLower(fields[0]) {
84
case "/join":
85
cmd := BrokerCommand{Name: "join"}
86
if len(fields) > 1 {
87
cmd.Channel = normalizeChannel(fields[1])
88
}
89
return cmd, true
90
case "/part":
91
cmd := BrokerCommand{Name: "part"}
92
if len(fields) > 1 {
93
cmd.Channel = normalizeChannel(fields[1])
94
}
95
return cmd, true
96
case "/channels":
97
return BrokerCommand{Name: "channels"}, true
98
default:
99
return BrokerCommand{}, false
100
}
101
}
102

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button