Skip to content

Commit

Permalink
Custom reactjis (#35)
Browse files Browse the repository at this point in the history
* implement custom reactjis for upvotes/downvotes

* update README

fixes #34
  • Loading branch information
kamaln7 authored Oct 11, 2017
1 parent d5b732e commit 9add3c5
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 39 deletions.
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ karmabot is a Slack bot that listens for and performs karma operations (aka upvo
- `<user>++ for <message>`; or
- `<user>++ <message>`
- query a user's current points: `<user>==`
- upvote/downvote a user by adding reactjis to their message
- [motivate.im](http://motivate.im/) support:
- `?m <user>`
- `!m <user>`
Expand Down Expand Up @@ -61,18 +62,20 @@ karmabot is a Slack bot that listens for and performs karma operations (aka upvo
3. run `karmabot`. the following options are supported:


| option | required? | description | default |
| ----------------------- | --------- | ---------------------------------------- | -------------- |
| `-token string` | **yes** | slack RTM token | |
| `-debug=bool` | no | set debug mode | `false` |
| `-db string` | no | path to sqlite database | `./db.sqlite3` |
| `-leaderboardlimit int` | no | the default amount of users to list in the leaderboard | `10` |
| `-maxpoints int` | no | the maximum amount of points that users can give/take at once | `6` |
| `-motivate=bool` | no | toggle [motivate.im](http://motivate.im/) support | `true` |
| `-blacklist string` | no | **may be passed multiple times** blacklist `string` i.e. ignore karma commands for `string` | `[]` |
| `-reactji bool` | no | use reactji (👍 and 👎) as reaction events | `true` |
| `-alias string` | no | **may be passed multiple times** alias different users to one user. syntax: `-alias main++alias1++alias2++...++aliasN` | |
| `-selfkarma bool` | yes | allow users to add/remove karma to themselves | `true` |
| option | required? | description | default |
| --------------------------- | --------- | ---------------------------------------- | -------------------------------- |
| `-token string` | **yes** | slack RTM token | |
| `-debug=bool` | no | set debug mode | `false` |
| `-db string` | no | path to sqlite database | `./db.sqlite3` |
| `-leaderboardlimit int` | no | the default amount of users to list in the leaderboard | `10` |
| `-maxpoints int` | no | the maximum amount of points that users can give/take at once | `6` |
| `-motivate=bool` | no | toggle [motivate.im](http://motivate.im/) support | `true` |
| `-blacklist string` | no | **may be passed multiple times** blacklist `string` i.e. ignore karma commands for `string` | `[]` |
| `-reactji bool` | no | use reactji (👍 and 👎) as reaction events | `true` |
| `-reactjis.upvote string` | no | **may be passed multiple times** a list of reactjis to use for upvotes. for emojis with aliases, use the first name that is shown in the emoji popup | `+1`, `thumbsup`, `thumbsup_all` |
| `-reactjis.downvote string` | no | **may be passed multiple times** a list of reactjis to use for downvotes. for emojis with aliases, use the first name that is shown in the emoji popup | `-1`, `thumbsdown` |
| `-alias string` | no | **may be passed multiple times** alias different users to one user. syntax: `-alias main++alias1++alias2++...++aliasN` | |
| `-selfkarma bool` | yes | allow users to add/remove karma to themselves | `true` |

In addition, see the table below for the options related to the web UI.

Expand Down
21 changes: 20 additions & 1 deletion cmd/karmabot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ var (
motivate = flag.Bool("motivate", true, "toggle motivate.im support")
blacklist = make(karmabot.StringList, 0)
reactji = flag.Bool("reactji", true, "use reactji as karma operations")
upvotereactji = make(karmabot.StringList, 0)
downvotereactji = make(karmabot.StringList, 0)
aliases = make(karmabot.StringList, 0)
selfkarma = flag.Bool("selfkarma", true, "allow users to add/remove karma to themselves")
)
Expand All @@ -37,16 +39,33 @@ func main() {

ll := log.KV("version", karmabot.Version)

// reactji defaults
upvotereactji.Set("+1")
upvotereactji.Set("thumbsup")
upvotereactji.Set("thumbsup_all")
downvotereactji.Set("-1")
downvotereactji.Set("thumbsdown")

// cli flags

flag.Var(&blacklist, "blacklist", "blacklist users from having karma operations applied on them")
flag.Var(&aliases, "alias", "alias different users to one user")
flag.Var(&upvotereactji, "reactji.upvote", "a list of reactjis to use for upvotes")
flag.Var(&downvotereactji, "reactji.downvote", "a list of reactjis to use for downvotes")

flag.Parse()

// startup

ll.Info("starting karmabot")

// reactjis
reactjiConfig := &karmabot.ReactjiConfig{
Enabled: *reactji,
Upvote: upvotereactji,
Downvote: downvotereactji,
}

// format aliases
aliasMap := make(karmabot.UserAliases, 0)
for k := range aliases {
Expand Down Expand Up @@ -117,7 +136,7 @@ func main() {
Log: ll,
DB: db,
UserBlacklist: blacklist,
Reactji: *reactji,
Reactji: reactjiConfig,
Motivate: *motivate,
Aliases: aliasMap,
SelfKarma: *selfkarma,
Expand Down
47 changes: 26 additions & 21 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,23 @@ func (s SlackChatService) IncomingEventsChan() chan slack.RTMEvent {
// UserAliases is a map of alias -> main username
type UserAliases map[string]string

// ReactjiConfig contains the configuration for reactji-based votes
type ReactjiConfig struct {
Enabled bool
Upvote, Downvote StringList
}

// Config contains all the necessary configs for karmabot.
type Config struct {
Slack ChatService
Debug, Motivate, Reactji, SelfKarma bool
MaxPoints, LeaderboardLimit int
Log *log.Log
UI ui.Provider
DB Database
UserBlacklist StringList
Aliases UserAliases
Slack ChatService
Debug, Motivate, SelfKarma bool
MaxPoints, LeaderboardLimit int
Log *log.Log
UI ui.Provider
DB Database
UserBlacklist StringList
Aliases UserAliases
Reactji *ReactjiConfig
}

// A Bot is an instance of karmabot.
Expand Down Expand Up @@ -164,48 +171,46 @@ func (b *Bot) handleError(err error, channel, thread string) bool {
}

func (b *Bot) handleReactionAddedEvent(ev *slack.ReactionAddedEvent) {
if !b.Config.Reactji {
if !b.Config.Reactji.Enabled {
return
}

var (
points int
reason string
)
switch ev.Reaction {
case "+1":
switch {
case b.Config.Reactji.Upvote.Contains(ev.Reaction):
points = +1
reason = "adding a :thumbsup: reactji"
case "-1":
case b.Config.Reactji.Downvote.Contains(ev.Reaction):
points = -1
reason = "adding a :thumbsdown: reactji"
default:
return
}

reason = fmt.Sprintf("adding a :%s: reactji", ev.Reaction)
b.handleReactionEvent(ev.User, ev.ItemUser, reason, points)
}

func (b *Bot) handleReactionRemovedEvent(ev *slack.ReactionRemovedEvent) {
if !b.Config.Reactji {
if !b.Config.Reactji.Enabled {
return
}

var (
points int
reason string
)
switch ev.Reaction {
case "+1":
switch {
case b.Config.Reactji.Upvote.Contains(ev.Reaction):
points = -1
reason = "removing a :thumbsup: reactji"
case "-1":
points = 1
reason = "removing a :thumbsdown: reactji"
case b.Config.Reactji.Downvote.Contains(ev.Reaction):
points = +1
default:
return
}

reason = fmt.Sprintf("removing a :%s: reactji", ev.Reaction)
b.handleReactionEvent(ev.User, ev.ItemUser, reason, points)
}

Expand Down
20 changes: 15 additions & 5 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func TestHandleReactionEvent(t *testing.T) {
ItemUser: "onehundred_points",
Reaction: "+1",
},
ExpectMessage: "onehundred_points == 101 (+1 for adding a :thumbsup: reactji)",
ExpectMessage: "onehundred_points == 101 (+1 for adding a :+1: reactji)",
ShouldHavePoints: 101,
},
{
Expand All @@ -99,7 +99,7 @@ func TestHandleReactionEvent(t *testing.T) {
ItemUser: "onehundred_points",
Reaction: "-1",
},
ExpectMessage: "onehundred_points == 99 (-1 for adding a :thumbsdown: reactji)",
ExpectMessage: "onehundred_points == 99 (-1 for adding a :-1: reactji)",
ShouldHavePoints: 99,
},
{
Expand Down Expand Up @@ -132,7 +132,7 @@ func TestHandleReactionEvent(t *testing.T) {
ItemUser: "onehundred_points",
Reaction: "+1",
},
ExpectMessage: "onehundred_points == 99 (-1 for removing a :thumbsup: reactji)",
ExpectMessage: "onehundred_points == 99 (-1 for removing a :+1: reactji)",
ShouldHavePoints: 99,
},
{
Expand All @@ -143,7 +143,7 @@ func TestHandleReactionEvent(t *testing.T) {
ItemUser: "onehundred_points",
Reaction: "-1",
},
ExpectMessage: "onehundred_points == 101 (+1 for removing a :thumbsdown: reactji)",
ExpectMessage: "onehundred_points == 101 (+1 for removing a :-1: reactji)",
ShouldHavePoints: 101,
},
{
Expand All @@ -159,7 +159,17 @@ func TestHandleReactionEvent(t *testing.T) {
}

for _, tc := range tt {
b, cs, db := newBot(&Config{Reactji: !tc.ReacjiDisabled})
upvote, downvote := make(StringList, 1), make(StringList, 1)
upvote.Set("+1")
downvote.Set("-1")

b, cs, db := newBot(&Config{
Reactji: &ReactjiConfig{
Enabled: !tc.ReacjiDisabled,
Upvote: upvote,
Downvote: downvote,
},
})

if tc.ReactionAddedEvent != nil {
b.handleReactionAddedEvent(tc.ReactionAddedEvent)
Expand Down
7 changes: 7 additions & 0 deletions stringlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,10 @@ func (sl *StringList) Set(value string) error {
(*sl)[value] = struct{}{}
return nil
}

// Contains checks if the list contains a certain item
func (sl *StringList) Contains(value string) bool {
_, ok := (*sl)[value]

return ok
}

0 comments on commit 9add3c5

Please sign in to comment.