Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 44f7145

Browse files
authored
Merge pull request #65 from keybase/david/bot-announce
Add feature for bot to announce itself at startup
2 parents 38f5a25 + 6bbc7eb commit 44f7145

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed

docs/env.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,26 @@ export CHAT_CHANNEL="team.prod#ssh-provision"
8686
export CHAT_CHANNEL="team.ssh_bot#general"
8787
```
8888

89+
### Announcement
90+
91+
The `ANNOUNCEMENT` environment variable contains a string that will be announced in all of the configured teams when
92+
the bot is started. This is useful if you would like the bot to announce the fact it has started and granted access in
93+
a given team. The `ANNOUNCEMENT` environment variable supports a number of templating variables that will be instantiated
94+
based off of the current config. These are:
95+
96+
* `{USERNAME}` will be replaced with the username of the bot
97+
* `{CURRENT_TEAM}` will be replaced with the team that the message is being sent in
98+
* `{TEAMS}` will be replaced with the comma separated list of teams that the bot is running in
99+
100+
Examples:
101+
102+
```bash
103+
export ANNOUNCEMENT="SSH CA bot starting up..."
104+
export ANNOUNCEMENT="Hello! I'm {USERNAME} and I'm an SSH bot! See github.com/keybase/bot-sshca for information on using Keybase for SSH."
105+
export ANNOUNCEMENT="Hello! I'm {USERNAME} and I'm an SSH bot! I'm currently listening in {TEAMS}."
106+
export ANNOUNCEMENT="Hello! I'm {USERNAME} and I'm an SSH bot! Being in {CURRENT_TEAM} will grant you SSH access to certain servers. Reach out to @dworken for more information."
107+
```
108+
89109
## Developer Options
90110

91111
These environment variables are mainly useful for dev work. For security reasons, it is recommended always to run a

src/keybaseca/bot/bot.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,18 @@ func GetUsername(conf config.Config) (string, error) {
3636
return username, nil
3737
}
3838

39-
// Start the keybaseca bot in an infinite loop. Does not return unless it encounters an error.
39+
// Start the keybaseca bot in an infinite loop. Does not return unless it encounters an unrecoverable error.
4040
func StartBot(conf config.Config) error {
4141
kbc, err := GetKBChat(conf)
4242
if err != nil {
4343
return fmt.Errorf("error starting Keybase chat: %v", err)
4444
}
4545

46+
err = sendAnnouncementMessage(conf, kbc)
47+
if err != nil {
48+
return fmt.Errorf("failed to start bot due to error while sending announcement: %v", err)
49+
}
50+
4651
sub, err := kbc.ListenForNewTextMessages()
4752
if err != nil {
4853
return fmt.Errorf("error subscribing to messages: %v", err)
@@ -144,3 +149,44 @@ func isConfiguredTeam(conf config.Config, teamName string, channelName string) b
144149
}
145150
return false
146151
}
152+
153+
type AnnouncementTemplateValues struct {
154+
Username string
155+
CurrentTeam string
156+
Teams []string
157+
}
158+
159+
func buildAnnouncement(template string, values AnnouncementTemplateValues) string {
160+
replacements := map[string]string{
161+
"{USERNAME}": values.Username,
162+
"{CURRENT_TEAM}": values.CurrentTeam,
163+
"{TEAMS}": strings.Join(values.Teams, ", "),
164+
}
165+
166+
templatedMessage := template
167+
for templateStr, templateVal := range replacements {
168+
templatedMessage = strings.Replace(templatedMessage, templateStr, templateVal, -1)
169+
}
170+
171+
return templatedMessage
172+
}
173+
174+
func sendAnnouncementMessage(conf config.Config, kbc *kbchat.API) error {
175+
if conf.GetAnnouncement() == "" {
176+
// No announcement to send
177+
return nil
178+
}
179+
for _, team := range conf.GetTeams() {
180+
announcement := buildAnnouncement(conf.GetAnnouncement(),
181+
AnnouncementTemplateValues{Username: kbc.GetUsername(),
182+
CurrentTeam: team,
183+
Teams: conf.GetTeams()})
184+
185+
var channel *string
186+
_, err := kbc.SendMessageByTeamName(team, announcement, channel)
187+
if err != nil {
188+
return err
189+
}
190+
}
191+
return nil
192+
}

src/keybaseca/bot/bot_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package bot
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestBuildAnnouncement(t *testing.T) {
10+
values := AnnouncementTemplateValues{Username: "my_username", CurrentTeam: "my_cur_team", Teams: []string{"my_team1", "my_team2"}}
11+
12+
require.Equal(t, "",
13+
buildAnnouncement("", values))
14+
require.Equal(t, "no templates",
15+
buildAnnouncement("no templates", values))
16+
require.Equal(t, "repeated my_username my_username my_username",
17+
buildAnnouncement("repeated {USERNAME} {USERNAME} {USERNAME}", values))
18+
require.Equal(t, "all my_username my_cur_team my_team1, my_team2",
19+
buildAnnouncement("all {USERNAME} {CURRENT_TEAM} {TEAMS}", values))
20+
require.Equal(t, "bogus {FOO}",
21+
buildAnnouncement("bogus {FOO}", values))
22+
require.Equal(t, "double-is-not-escape {my_username}",
23+
buildAnnouncement("double-is-not-escape {{USERNAME}}", values))
24+
}

src/keybaseca/config/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Config interface {
2727
GetChannelName() string
2828
GetLogLocation() string
2929
GetStrictLogging() bool
30+
GetAnnouncement() string
3031
DebugString() string
3132
}
3233

@@ -250,6 +251,11 @@ func (ef *EnvConfig) GetChannelName() string {
250251
return channel
251252
}
252253

254+
// Get the announcement string used when the bot is started up. May be empty.
255+
func (ef *EnvConfig) GetAnnouncement() string {
256+
return os.Getenv("ANNOUNCEMENT")
257+
}
258+
253259
// Dump this EnvConfig to a string for debugging purposes
254260
func (ef *EnvConfig) DebugString() string {
255261
return fmt.Sprintf("CAKeyLocation='%s'; KeybaseHomeDir='%s'; KeybasePaperKey='%s'; KeybaseUsername='%s'; "+

tests/envFiles/test_env_1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export KEYBASE_PAPERKEY="$BOT_PAPERKEY"
77
export KEYBASE_USERNAME="$BOT_USERNAME"
88
export CHAT_CHANNEL="$SUBTEAM.ssh#ssh-provision"
99
export CA_KEY_LOCATION="/shared/keybase-ca-key"
10+
export ANNOUNCEMENT='Hello my name is {USERNAME}. This is {CURRENT_TEAM} and the configured teams are {TEAMS}'

0 commit comments

Comments
 (0)