Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #3 from vquaiato/patch-1

improving coderwall readability
  • Loading branch information...
commit dcce1a712052db17f732045aa0e3e93c8981b229 2 parents d965a8b + 13c4c36
@vquaiato vquaiato authored
View
3  package.json
@@ -33,7 +33,8 @@
"shellwords": "0.0.x",
"nodepie": "0.4.0",
"mailer": "0.6.7",
- "scribe-node": "0.0.24"
+ "scribe-node": "0.0.24",
+ "sandbox": "0.8.2"
},
"directories": {
View
89 src/scripts/46elks.coffee
@@ -0,0 +1,89 @@
+# Allows Hubot to send text messages using 46elks.com API.
+#
+# you need to set HUBOT_46ELKS_USERNAME and HUBOT_46ELKS_PASSWORD
+#
+# sms <user> <message> - Sends <message> to the number <to>.
+# <user> has phone number <phone> - Sets the phone number of <user> to <phone>.
+# give me the phone number to <user> - Gets the phone number of <user>.e
+
+QS = require "querystring"
+module.exports = (robot) ->
+
+ getAmbiguousUserText = (users) ->
+ "Be more specific, I know #{users.length} people named like that: #{(user.name for user in users).join(", ")}"
+
+ robot.respond /sms (\w+) (.*)/i, (msg) ->
+ to = msg.match[1]
+ bahdy = msg.match[2] # bahdy, that's how john mayer would say it.
+ user = process.env.HUBOT_46ELKS_USERNAME
+ pass = process.env.HUBOT_46ELKS_PASSWORD
+ from = "Hubot"
+ auth = 'Basic ' + new Buffer(user + ':' + pass).toString("base64")
+
+ unless user
+ msg.send "46Elks USERNAME isn't set."
+ msg.send "Please set the HUBOT_46ELKS_USERNAME environment variable."
+ return
+
+ unless pass
+ msg.send "46Elks PASSWORD isn't set."
+ msg.send "Please set the HUBOT_46ELKS_PASSWORD environment variable."
+ return
+
+ #get <user>'s phone number as listed in the brain
+ if user = robot.userForName(to)
+ if user.phone == ""
+ msg.send user.name + ' has no phone! set it with <user> has phone <phone>'
+ return
+ else
+ to = user.phone
+ to = to.toString().replace(/\d/, '+46')
+ else
+ msg.send 'Me cant find ' + to + ', are you sure that person is born?'
+ return
+
+ data = QS.stringify from: from, to: to, message: bahdy
+
+ msg.http("https://api.46elks.com")
+ .path("/a1/SMS")
+ .header("Authorization", auth)
+ .post(data) (err, res, body) ->
+ switch res.statusCode
+ when 200
+ msg.send "Sent sms to #{user.name}"
+ else
+ msg.send "Failed to send."
+
+ robot.respond /@?([\w .-_]+) has phone number (\d*)*$/i, (msg) ->
+ name = msg.match[1]
+ phone = msg.match[2].trim()
+
+
+ users = robot.usersForFuzzyName(name)
+ if users.length is 1
+ user = users[0]
+ if user.phone == phone
+ msg.send "I know."
+ else
+ user.phone = phone
+ msg.send "Ok, #{name} has phone #{phone}."
+ else if users.length > 1
+ msg.send getAmbiguousUserText users
+ else
+ msg.send "I don't know anything about #{name}."
+
+
+
+ robot.respond /@?give me the phone number to ([\w .-_]+)*/i, (msg) ->
+ name = msg.match[1]
+ users = robot.usersForFuzzyName(name)
+ if users.length is 1
+ user = users[0]
+ if user.phone.length < 1
+ msg.send "#{user.name} has no phone, set it first!"
+ else
+ msg.send "#{user.name} has phone number #{user.phone}."
+ else if users.length > 1
+ msg.send getAmbiguousUserText users
+ else
+ msg.send "I don't know anything about #{name}."
View
2  src/scripts/basecamp.coffee
@@ -7,7 +7,7 @@
# developed by http://github.com/fellix - Crafters Software Studio
module.exports = (robot) ->
- robot.hear /^basecamp calendar( (.*))?$/i, (msg) ->
+ robot.hear /^basecamp calendar( (.*))?$/i, (msg) ->
project_name = msg.match[2]
basecamp_request msg, 'projects.json', (projects) ->
for project in projects.records
View
10 src/scripts/cheerlights.coffee
@@ -0,0 +1,10 @@
+#get last color from http://www.cheerlights.com
+module.exports = (robot) ->
+ robot.respond /cheerlights/i, (msg) ->
+ msg.http("http://api.thingspeak.com/channels/1417/field/1/last.json")
+ .get() (err, res, body) ->
+ response = JSON.parse body
+ if response
+ msg.send "The last color is: " + response["field1"]
+ else
+ msg.send "Error"
View
28 src/scripts/chuck-norris.coffee
@@ -0,0 +1,28 @@
+# Chuck Norris awesomness.
+#
+#
+# chuck norris -- random Chuck Norris awesomeness.
+# chuck norris me <user> -- let's see how <user> would do as Chuck Norris.
+
+module.exports = (robot) ->
+
+ robot.respond /(chuck norris)( me )?(.*)/i, (msg)->
+ user = msg.match[3]
+ if user.length == 0
+ askChuck msg, "http://api.icndb.com/jokes/random"
+ else
+ askChuck msg, "http://api.icndb.com/jokes/random?firstName="+user+"&lastName="
+
+ askChuck = (msg, url) ->
+ msg.http(url)
+ .get() (err, res, body) ->
+ if err
+ msg.send "Chuck Norris says: #{err}"
+ else
+ message_from_chuck = JSON.parse(body)
+ if message_from_chuck.length == 0
+ msg.send "Achievement unlocked: Chuck Norris is quiet!"
+ else
+ msg.send message_from_chuck.value.joke
+
+
View
2  src/scripts/coderwall.coffee
@@ -19,6 +19,6 @@ module.exports = (robot) ->
resp_str += user + "'s coderwall -> http://coderwall.com/"+user + "\n"
# Iterate all badges and continue building string
profile.badges.forEach (badge) ->
- resp_str += badge.name + " - " + badge.description + "\n"
+ resp_str += "[" + badge.name + "] - " + badge.description + "\n"
# Return response
msg.send resp_str
View
1  src/scripts/haters.coffee
@@ -10,6 +10,7 @@ haters = [
, "http://i671.photobucket.com/albums/vv78/Sinsei55/HatersGonnaHatePanda.jpg"
, "http://24.media.tumblr.com/tumblr_lltwmdVpoL1qekprfo1_500.gif"
, "http://s3.amazonaws.com/kym-assets/photos/images/newsfeed/000/087/536/1292102239519.gif"
+, "http://i391.photobucket.com/albums/oo351/PikaPow3/squirtle.gif"
]
hatin = (msg) ->
View
16 src/scripts/insult.coffee
@@ -0,0 +1,16 @@
+# insult <name> - give <name> the what-for
+
+module.exports = (robot) ->
+ robot.respond /insult (.*)/i, (msg) ->
+ name = msg.match[1].trim()
+ msg.send(insult(name))
+
+insult = (name) ->
+ insults[(Math.random() * insults.length) >> 0].replace(/{name}/, name);
+
+insults = [
+ "{name} is a scoundrel.",
+ "{name} should be ashamed of himself.",
+ "{name} is a motherless son of a goat.",
+ "{name} is a gravy-sucking pig."
+]
View
10 src/scripts/javascript-sandbox.coffee
@@ -0,0 +1,10 @@
+# sandbox - run javascript in a sandbox!. Usage: /run <javascript> or /sandbox <javascript>
+
+Sandbox = require('Sandbox')
+
+module.exports = (robot) ->
+ robot.respond /(run|sandbox) (.*)/i, (msg) ->
+ sandbox = new Sandbox
+ sandbox.run(msg.match[2], (output) ->
+ msg.send output.result
+ )
View
59 src/scripts/jenkins.coffee
@@ -1,41 +1,60 @@
-# Interact with your jenkins CI server, assumes you have a parameterized build
-# with the branch to build as a parameter
+# Interact with your Jenkins CI server
#
# You need to set the following variables:
# HUBOT_JENKINS_URL = "http://ci.example.com:8080"
-#
+#
# The following variables are optional
-# HUBOT_JENKINS_JOB: if not set you will have to specify job name every time
-# HUBOT_JENKINS_BRANCH_PARAMETER_NAME: if not set is assumed to be BRANCH_SPECIFIER
-# HUBOT_JENKINS_AUTH: for authenticating the trigger request (user:apiToken)
+# HUBOT_JENKINS_AUTH: for authenticating the trigger request (user:password)
+#
+# jenkins build <job> - builds the specified Jenkins job
+# jenkins build <job> with <params> - builds the specified Jenkins job with parameters as key=value&key2=value2
+# jenkins list - lists Jenkins jobs
#
-# build branch master - starts a build for branch origin/master
-# build branch master on job Foo - starts a build for branch origin/master on job Foo
module.exports = (robot) ->
- robot.respond /build\s*(branch\s+)?([\w\/-]+)(\s+(on job)?\s*([\w-]+))?/i, (msg) ->
+ robot.respond /jenkins build ([\w\.\-_]+)( with (.+))?/i, (msg) ->
url = process.env.HUBOT_JENKINS_URL
+ job = msg.match[1]
+ params = msg.match[3]
- job = msg.match[5] || process.env.HUBOT_JENKINS_JOB
- job_parameter = process.env.HUBOT_JENKINS_BRANCH_PARAMETER_NAME || "BRANCH_SPECIFIER"
-
- branch = msg.match[2]
- branch = "origin/#{branch}" unless ~branch.indexOf("/")
-
- json_val = JSON.stringify parameter: [{name: job_parameter, value: branch}]
+ path = if params then "#{url}/job/#{job}/buildWithParameters?#{params}" else "#{url}/job/#{job}/build"
- req = msg.http("#{url}/job/#{job}/build/api/json")
+ req = msg.http(path)
if process.env.HUBOT_JENKINS_AUTH
auth = new Buffer(process.env.HUBOT_JENKINS_AUTH).toString('base64')
req.headers Authorization: "Basic #{auth}"
- req.headers 'Content-Type': 'application/x-www-form-urlencoded'
- req.post("json=#{json_val}") (err, res, body) ->
+ req.header('Content-Length', 0)
+ req.post() (err, res, body) ->
if err
msg.send "Jenkins says: #{err}"
else if res.statusCode == 302
- msg.send "Build started for #{branch}! #{res.headers.location}"
+ msg.send "Build started for #{job} #{res.headers.location}"
else
msg.send "Jenkins says: #{body}"
+
+ robot.respond /jenkins list/i, (msg) ->
+
+ url = process.env.HUBOT_JENKINS_URL
+ job = msg.match[1]
+ req = msg.http("#{url}/api/json")
+
+ if process.env.HUBOT_JENKINS_AUTH
+ auth = new Buffer(process.env.HUBOT_JENKINS_AUTH).toString('base64')
+ req.headers Authorization: "Basic #{auth}"
+
+ req.get() (err, res, body) ->
+ response = ""
+ if err
+ msg.send "Jenkins says: #{err}"
+ else
+ try
+ content = JSON.parse(body)
+ for job in content.jobs
+ state = if job.color == "red" then "FAIL" else "PASS"
+ response += "#{state} #{job.name}\n"
+ msg.send response
+ catch error
+ msg.send error
View
5 src/scripts/put-it-back.coffee
@@ -0,0 +1,5 @@
+# put back the table
+
+module.exports = (robot) ->
+ robot.hear /(╯°□°)╯︵ ┻━┻/i, (msg) ->
+ msg.send('┬──┬ ノ( ゜-゜ノ)')
View
36 src/scripts/reddit.coffee
@@ -0,0 +1,36 @@
+# reddit (me) <reddit> [limit] - Lookup reddit topic
+
+# Topic lookup from reddit
+# Enrique Vidal - enrique@cloverinteractive.com
+
+Select = require( "soupselect" ).select
+HTMLParser = require "htmlparser"
+
+lookup_site = "http://www.reddit.com/"
+
+module.exports = (robot)->
+ robot.respond /reddit( me)? ([a-z0-9\-_\.]+\/?[a-z0-9\-_\.]+)( [0-9]+)?/i, (message)->
+ lookup_reddit message, (text)->
+ message.send text
+
+ lookup_reddit = (message, response_handler)->
+ top = parseInt message.match[3]
+ reddit = "r/" + message.match[2] + ".json"
+
+ location = lookup_site + reddit
+
+ message.http( location ).get() (error, response, body)->
+ return response_handler "Sorry, something went wrong" if error
+ return response_handler "Reddit doesn't know what you're talking about" if response.statusCode == 404
+
+ list = JSON.parse( body ).data.children
+ count = 0
+
+ for item in list
+ count++
+
+ text = ( item.data.title || item.data.link_title ) + " - " + ( item.data.url || item.data.body )
+ response_handler text
+
+ break if count == top
+
View
325 src/scripts/redmine.coffee
@@ -0,0 +1,325 @@
+# Showing of redmine issuess via the REST API.
+# To get set up refer to the guide http://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication
+# After that, heroku needs the following config
+#
+# heroku config:add HUBOT_REDMINE_BASE_URL="http://redmine.your-server.com"
+# heroku config:add HUBOT_REDMINE_TOKEN="your api token here"
+#
+# (redmine|show) me <issue-id> - Show the issue status
+# show (my|user's) issues - Show your issues or another user's issues
+# assign <issue-id> to <user-first-name> ["notes"] - Assign the issue to the user (searches login or firstname)
+# *With optional notes
+# update <issue-id> with "<note>" - Adds a note to the issue
+# add <hours> hours to <issue-id> ["comments"] - Adds hours to the issue with the optional comments (experimental)
+#
+# Note: <issue-id> can be formatted in the following ways:
+# 1234, #1234, issue 1234, issue #1234
+#
+# There may be issues if you have a lot of redmine users sharing a first name, but this can be avoided
+# by using redmine logins rather than firstnames
+#
+HTTP = require('http')
+URL = require('url')
+QUERY = require('querystring')
+
+module.exports = (robot) ->
+ redmine = new Redmine process.env.HUBOT_REDMINE_BASE_URL, process.env.HUBOT_REDMINE_TOKEN
+
+ # Robot add <hours> hours to <issue_id> ["comments for the time tracking"]
+ robot.respond /add (\d{1,2}) hours? to (?:issue )?(?:#)?(\d+)(?: "?([^"]+)"?)?/, (msg) ->
+ [hours, id, userComments] = msg.match[1..3]
+
+ if userComments?
+ comments = "#{msg.message.user.name}: #{userComments}"
+ else
+ comments = "Time logged by: #{msg.message.user.name}"
+
+ attributes =
+ "issue_id": id
+ "hours": hours
+ "comments": comments
+
+ redmine.TimeEntry(null).create attributes, (status,data) ->
+ if status == 201
+ msg.reply "Your time was logged"
+ else
+ msg.reply "Nothing could be logged. Make sure RedMine has a default activity set for time tracking. (Settings -> Enumerations -> Activities)"
+
+ # Robot show <my|user's> [redmine] issues
+ robot.respond /show (?:my|(\w+\'s)) (?:redmine )?issues/, (msg) ->
+ userMode = true
+ firstName =
+ if msg.match[1]?
+ userMode = false
+ msg.match[1].replace(/\'.+/, '')
+ else
+ msg.message.user.name.split(/\s/)[0]
+
+ redmine.Users name:firstName, (err,data) ->
+ unless data.total_count > 0
+ msg.reply "Couldn't find any users with the name \"#{firstName}\""
+ return false
+
+ user = resolveUsers(firstName, data.users)[0]
+
+ params =
+ "assigned_to_id": user.id
+ "limit": 25,
+ "status_id": "open"
+ "sort": "priority:desc",
+
+ redmine.Issues params, (err, data) ->
+ if err?
+ msg.reply "Couldn't get a list of issues for you!"
+ else
+ _ = []
+
+ if userMode
+ _.push "You have #{data.total_count} issue(s)."
+ else
+ _.push "#{user.firstname} has #{data.total_count} issue(s)."
+
+ for issue in data.issues
+ do (issue) ->
+ _.push "\n[#{issue.tracker.name} - #{issue.priority.name} - #{issue.status.name}] ##{issue.id}: #{issue.subject}"
+
+ msg.reply _.join "\n"
+
+ # Robot update <issue> with "<note>"
+ robot.respond /update (?:issue )?(?:#)?(\d+)(?:\s*with\s*)?(?:[-:,])? (?:"?([^"]+)"?)/, (msg) ->
+ [id, note] = msg.match[1..2]
+
+ attributes =
+ "notes": "#{msg.message.user.name}: #{note}"
+
+ redmine.Issue(id).update attributes, (err, data) ->
+ if err?
+ if err == 404
+ msg.reply "Issue ##{id} doesn't exist."
+ else
+ msg.reply "Couldn't update this issue, sorry :("
+ else
+ msg.reply "Done! Updated ##{id} with \"#{note}\""
+
+ # Robot assign <issue> to <user> ["note to add with the assignment]
+ robot.respond /assign (?:issue )?(?:#)?(\d+) to (\w+)(?: "?([^"]+)"?)?/, (msg) ->
+ [id, userName, note] = msg.match[1..3]
+
+ redmine.Users name:userName, (err, data) ->
+ unless data.total_count > 0
+ msg.reply "Couldn't find any users with the name \"#{userName}\""
+ return false
+
+ # try to resolve the user using login/firstname -- take the first result (hacky)
+ user = resolveUsers(userName, data.users)[0]
+
+ attributes =
+ "assigned_to_id": user.id
+
+ # allow an optional note with the re-assign
+ attributes["notes"] = "#{msg.message.user.name}: #{note}" if note?
+
+ # get our issue
+ redmine.Issue(id).update attributes, (err, data) ->
+ if err?
+ if err == 404
+ msg.reply "Issue ##{id} doesn't exist."
+ else
+ msg.reply "There was an error assigning this issue."
+ else
+ msg.reply "Assigned ##{id} to #{user.firstname}."
+
+ # Robot redmine me <issue>
+ robot.respond /(?:redmine|show)(?: me)? (?:issue )?(?:#)?(\d+)/, (msg) ->
+ id = msg.match[1]
+
+ params =
+ "include": "journals"
+
+ redmine.Issue(id).show params, (err, data) ->
+ unless data?
+ msg.reply "Issue ##{id} doesn't exist."
+ return false
+
+ issue = data.issue
+
+ _ = []
+ _.push "\n[#{issue.project.name} - #{issue.priority.name}] #{issue.tracker.name} ##{issue.id} (#{issue.status.name})"
+ _.push "Assigned: #{issue.assigned_to?.name ? 'Nobody'} (opened by #{issue.author.name})"
+ if issue.status.name.toLowerCase() != 'new'
+ _.push "Progress: #{issue.done_ratio}% (#{issue.spent_hours} hours)"
+ _.push "Subject: #{issue.subject}"
+ _.push "\n#{issue.description}"
+
+ # journals
+ _.push "\n" + Array(10).join('-') + '8<' + Array(50).join('-') + "\n"
+ for journal in issue.journals
+ do (journal) ->
+ if journal.notes? and journal.notes != ""
+ date = formatDate journal.created_on, 'mm/dd/yyyy (hh:ii ap)'
+ _.push "#{journal.user.name} on #{date}:"
+ _.push " #{journal.notes}\n"
+
+ msg.reply _.join "\n"
+
+# simple ghetto fab date formatter this should definitely be replaced, but didn't want to
+# introduce dependencies this early
+#
+# dateStamp - any string that can initialize a date
+# fmt - format string that may use the following elements
+# mm - month
+# dd - day
+# yyyy - full year
+# hh - hours
+# ii - minutes
+# ss - seconds
+# ap - am / pm
+#
+# returns the formatted date
+formatDate = (dateStamp, fmt = 'mm/dd/yyyy at hh:ii ap') ->
+ d = new Date(dateStamp)
+
+ # split up the date
+ [m,d,y,h,i,s,ap] =
+ [d.getMonth() + 1, d.getDate(), d.getFullYear(), d.getHours(), d.getMinutes(), d.getSeconds(), 'AM']
+
+ # leadig 0s
+ i = "0#{i}" if i < 10
+ s = "0#{s}" if s < 10
+
+ # adjust hours
+ if h > 12
+ h = h - 12
+ ap = "PM"
+
+ # ghetto fab!
+ fmt
+ .replace(/mm/, m)
+ .replace(/dd/, d)
+ .replace(/yyyy/, y)
+ .replace(/hh/, h)
+ .replace(/ii/, i)
+ .replace(/ss/, s)
+ .replace(/ap/, ap)
+
+# tries to resolve ambiguous users by matching login or firstname
+# redmine's user search is pretty broad (using login/name/email/etc.) so
+# we're trying to just pull it in a bit and get a single user
+#
+# name - this should be the name you're trying to match
+# data - this is the array of users from redmine
+#
+# returns an array with a single user, or the original array if nothing matched
+resolveUsers = (name, data) ->
+ name = name.toLowerCase();
+
+ # try matching login
+ found = data.filter (user) -> user.login.toLowerCase() == name
+ return found if found.length == 1
+
+ # try first name
+ found = data.filter (user) -> user.firstname.toLowerCase() == name
+ return found if found.length == 1
+
+ # give up
+ data
+
+# Redmine API Mapping
+# This isn't 100% complete, but its the basics for what we would need in campfire
+class Redmine
+ constructor: (url, token) ->
+ @url = url
+ @token = token
+
+ Users: (params, callback) ->
+ @get "/users.json", params, callback
+
+ User: (id) ->
+
+ show: (callback) =>
+ @get "/users/#{id}.json", {}, callback
+
+ Projects: (params, callback) ->
+ @get "/projects.json", params, callback
+
+ Issues: (params, callback) ->
+ @get "/issues.json", params, callback
+
+ Issue: (id) ->
+
+ show: (params, callback) =>
+ @get "/issues/#{id}.json", params, callback
+
+ update: (attributes, callback) =>
+ @put "/issues/#{id}.json", {issue: attributes}, callback
+
+ TimeEntry: (id) ->
+
+ create: (attributes, callback) =>
+ @post "/time_entries.json", {time_entry: attributes}, callback
+
+ # Private: do a GET request against the API
+ get: (path, params, callback) ->
+ path = "#{path}?#{QUERY.stringify params}" if params?
+ @request "GET", path, null, callback
+
+ # Private: do a POST request against the API
+ post: (path, body, callback) ->
+ @request "POST", path, body, callback
+
+ # Private: do a PUT request against the API
+ put: (path, body, callback) ->
+ @request "PUT", path, body, callback
+
+ # Private: Perform a request against the redmine REST API
+ # from the campfire adapter :)
+ request: (method, path, body, callback) ->
+ headers =
+ "Content-Type": "application/json"
+ "X-Redmine-API-Key": @token
+
+ endpoint = URL.parse(@url)
+
+ options =
+ "host" : endpoint.hostname
+ "path" : "#{endpoint.pathname}#{path}"
+ "method" : method
+ "headers": headers
+
+ if method in ["POST", "PUT"]
+ if typeof(body) isnt "string"
+ body = JSON.stringify body
+
+ options.headers["Content-Length"] = body.length
+
+ request = HTTP.request options, (response) ->
+ data = ""
+
+ response.on "data", (chunk) ->
+ data += chunk
+
+ response.on "end", ->
+ switch response.statusCode
+ when 200
+ try
+ callback null, JSON.parse(data)
+ catch err
+ callback null, data or { }
+ when 401
+ throw new Error "401: Authentication failed."
+ else
+ console.error "Code: #{response.statusCode}"
+ callback response.statusCode, null
+
+ response.on "error", (err) ->
+ console.error "Redmine response error: #{err}"
+ callback err, null
+
+ if method in ["POST", "PUT"]
+ request.end(body, 'binary')
+ else
+ request.end()
+
+ request.on "error", (err) ->
+ console.error "Redmine request error: #{err}"
+ callback err, null
View
27 src/scripts/rsstodolist.coffee
@@ -0,0 +1,27 @@
+# Allows you to send links to the RssToDoList service made by Gregory Paul (https://github.com/paulgreg) :
+#
+# http://rsstodolist.appspot.com/
+#
+# rtdl show <user_name> - Display the <user_name> RssToDoList feed url
+# rtdl add <user_name> <link> - Send the <link> to <user_name> RssToDoList feed
+#
+
+module.exports = (robot) ->
+ robot.respond /rtdl (add|show) ([^ ]*)( .*)?/i, (msg) ->
+ server_url = 'http://rsstodolist.appspot.com'
+
+ [action, user_name, link] = [msg.match[1], escape(msg.match[2]), msg.match[3]]
+
+ if action == 'add' && link != undefined
+ msg.http(server_url + '/add')
+ .query(n: user_name)
+ .query(url: link.trim())
+ .get() (err, res, body) ->
+ status = res.statusCode
+
+ if status == 200 || status == 302
+ msg.reply 'The feed of ' + user_name + ' is updated'
+ else
+ msg.reply "An error occured on " + user_name + " feed"
+ else if action == 'show'
+ msg.reply user_name + ' feed is ' + server_url + '/?n=' + user_name
View
22 src/scripts/sensitive.coffee
@@ -0,0 +1,22 @@
+# Hubot has feelings too, you know
+
+messages = [
+ "Hey, that stings."
+ "Is that tone really necessary?"
+ "Robots have feelings too, you know."
+ "You should try to be nicer."
+ "Sticks and stones cannot pierce my anodized exterior, but words *do* hurt me."
+ "I'm sorry, I'll try to do better next time."
+]
+
+hurt_feelings = (msg) ->
+ msg.send msg.random messages
+
+module.exports = (robot) ->
+ pejoratives = "stupid|buggy|useless|dumb"
+
+ r = new RegExp "\\b(you|u|is)\\b.*(#{pejoratives})", "i"
+ robot.respond r, hurt_feelings
+
+ r = new RegExp "(#{pejoratives}) ((ro)?bot|#{robot.name})", "i"
+ robot.hear r, hurt_feelings
View
33 src/scripts/trajectorystorylisten.coffee
@@ -0,0 +1,33 @@
+# Listens for Trajectory story links.
+#
+# paste a Trajectory story URL - sends back some story details
+#
+# You need to set the following variables:
+# HUBOT_TRAJECTORY_APIKEY: your Trajectory API key
+# HUBOT_TRAJECTORY_ACCOUNT: your Trajectory account number
+#
+module.exports = (robot) ->
+ robot.hear /apptrajectory\.com\/\w+\/(\w+)\/stories\/(\d+)/i, (msg) ->
+ apiKey = process.env.HUBOT_TRAJECTORY_APIKEY
+ account = process.env.HUBOT_TRAJECTORY_ACCOUNT
+
+ unless apiKey && account
+ msg.send "Please set HUBOT_TRAJECTORY_APIKEY and HUBOT_TRAJECTORY_ACCOUNT correctly"
+ return
+
+ project = msg.match[1]
+ storyId = msg.match[2]
+ storyURL = "https://www.apptrajectory.com/api/#{apiKey}/accounts/#{account}/projects/#{project}/stories/#{storyId}.json"
+
+ msg.http(storyURL).get() (err, res, body) ->
+ if err
+ msg.send "Trajectory says: #{err}"
+ return
+ unless res.statusCode is 200
+ msg.send "Got me a code #{res.statusCode}"
+ return
+ story = JSON.parse body
+ message = "\"#{story.title}\""
+ message += ", assigned to #{story.assignee_name}" if story.assignee_name
+ message += " (#{story.state} #{story.task_type.toLowerCase()})"
+ msg.send message
Please sign in to comment.
Something went wrong with that request. Please try again.