Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic groups #7

Merged
merged 4 commits into from
Nov 3, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ That is:

**Note**: *When set in a shell environment, you may want to put `''` around your alias definition so that any `;` don't try to break the command.*

### Dynamic Configuration
Group Alias supports dynamically defining groups using the [hubot-auth][auth] package. All "roles" that are created by `hubot-auth` will be treated able to be expanded into @mention messages. To do this, simple set:

HUBOUT_GROUP_ALIAS='DYNAMIC'

and make sure `hubot-auth` is installed.

##### Notes
* The only supported modes are dynamic or pre-defined. There is currently not "hybrid" mode.
* Currently dynamic mode is _not_ case sensitive because `hubot-auth` roles act the same way.
* You should probably set `HUBOUT_GROUP_ALIAS_NAME_PROP` because otherwise, `hubot-auth` simply returns full user names.

[auth]: https://github.com/hubot-scripts/hubot-auth

## Autocomplete Abilities
By default, most chat apps don't support autocomplete for bots. :(

Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "hubot-group-alias",
"description": "Hubot page for user @mention aliases",
"version": "1.7.0",
"version": "2.0.0",
"author": "Michael Ball <[email protected]>",
"license": "MIT",
"keywords": [
Expand All @@ -20,6 +20,10 @@
"bugs": {
"url": "https://github.com/cycomachead/hubot-group-alias/issues"
},
"peerDependencies": {
"hubot": "2.x.x",
"hubot-auth": "latest"
},
"dependencies": {
"coffee-script": "~1.6",
"underscore": "^1.8.2"
Expand Down
116 changes: 83 additions & 33 deletions src/alias.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,94 @@

_ = require 'underscore'

module.exports = (robot) ->
config = process.env.HUBOT_GROUP_ALIAS
user_prop = process.env.HUBOT_GROUP_ALIAS_NAME_PROP || ''
useDynamicGroups = config == 'DYNAMIC'
groupCache = {}

config = process.env.HUBOT_GROUP_ALIAS
buildGroupObject = () ->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty parameter list is forbidden

if !_.isEqual(groupCache, {})
return groupCache
# Create a 1D list of group assignments
staticGroups = config.split(';')
# Create 2D list of [alias, users]
staticGroups = _.map(staticGroups, (val, item, array) -> val.split('='))
# expand "user1,user2" to "@user1 @user2"
staticGroups = _.map(staticGroups, (val, item, array) -> [val[0],
'@' + val[1].replace(/,/g, ' @')])
# Convert 2D list to native object
groupCache = _.object(staticGroups)
return groupCache

if !config
robot.logger.warning "Configuration HUBOT_GROUP_ALIAS is not defined."
return
getGroups = (text) ->
if useDynamicGroups
groupMap = {}
regex = /[:(]+(\w+)[:)]+|@(\w+)/gi
matches = regex.exec(text)
while matches != null
# If matched, 1 group will always be `undefined`
group = matches[1] || matches[2]
users = robot.auth.usersWithRole(group)
if !_.isEqual(users, [])
groupMap[group] = users
matches = regex.exec(text)
for own group, members of groupMap
list = _.map(members, userFromName)
list = _.map(list, mentionName)
groupMap[group] = listToMentions(list)
return groupMap
else
return buildGroupObject()

groups = config.split(';')
userFromName = (name) ->
allUsers = robot.brain.data.users
for own id, user of allUsers
if user.name == name
return user
return {}

# Create 2D list of [alias, users]
groups = _.map(groups, (val, item, array) -> val.split('='))
# expand "user1,user2" to "@user1 @user2"
groups = _.map(groups, (val, item, array) -> [val[0],
'@' + val[1].split(',').join(' @')])
mentionName = (user) ->
# mention_name is for Hipchat
return user[user_prop] || user.mention_name || user.name

# Convert 2D list to native object
groups = _.object(groups)

user_prop = process.env.HUBOT_GROUP_ALIAS_NAME_PROP

# Replace aliases with @mentions in the message
expand = (message, user) ->
filterName = user.mention_name || user[user_prop]
for own alias, members of groups
# Filter inviduals from their own messages.
if filterName
members = members.replace('@' + filterName, '')
reg = new RegExp('[:(]+' + alias + '[:)]+|@' + alias, 'i')
message = message.replace(reg, members)
return message

# Compile RegEx to match only the aliases
# Note this matches (alias) :alias: and @alias
aliases = _.keys(groups).join('|')
listToMentions = (list) ->
return '@' + list.join(' @')

# Replace aliases with @mentions in the message
expand = (message, groups, user) ->
filterName = mentionName(user)
for own alias, members of groups
# Filter inviduals from their own messages.
if filterName
members = members.replace('@' + filterName, '').replace(/\s+/g, ' ')
reg = new RegExp('[:(]+' + alias + '[:)]+|@' + alias, 'i')
message = message.replace(reg, members)
return message

buildRegExp = () ->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty parameter list is forbidden

if useDynamicGroups
aliases = '\\w+'
else
# Compile RegEx to match only the aliases
# Note this matches (alias) :alias: and @alias
aliases = _.keys(buildGroupObject()).join('|')
# The last group is a set of stop conditions (word boundaries or end of line)
atRE = '(?:@(' + aliases + ')(?:\\b[^.]|$))'
emojiRE = '(?:[(:])(' + aliases + ')(?:[:)])'
regex = new RegExp(atRE + '|' + emojiRE, 'i')
robot.hear regex, (msg) ->
msg.send expand(msg.message.text, msg.message.user)

return new RegExp(atRE + '|' + emojiRE, 'i')

module.exports = (robot) ->
if !config
robot.logger.warning "Configuration HUBOT_GROUP_ALIAS is not defined."
return

if useDynamicGroups && !robot.auth
robot.logger.warning "Using dynamic groups requires hubot-auth to be loaded"
return

regex = buildRegExp()
robot.hear regex, (resp) ->
groups = getGroups(resp.message.text)
if !_.isEqual(groups, {})
resp.send expand(resp.message.text, groups, resp.message.user)