Skip to content
This repository was archived by the owner on Jun 8, 2023. It is now read-only.

Commit 4f9a6e4

Browse files
author
Tom Bell
committed
Merge pull request #806 from tybenz/master
Basecamp notifications with walkie
2 parents 3488bef + 9d3c1f0 commit 4f9a6e4

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

src/scripts/walkie.coffee

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Description:
2+
# Stay up-to-date on Basecamp projects
3+
# Powered by http://developer.github.com/v3/repos/hooks/
4+
#
5+
# Dependencies:
6+
# "strftime": "0.5.0"
7+
# "string": "1.2.1"
8+
#
9+
# Configuration:
10+
# HUBOT_WALKIE_USERNAME - Basecamp account username
11+
# HUBOT_WALKIE_PASSWORD - Basecamp account password
12+
# HUBOT_WALKIE_ROOMS - comma-separated list of rooms
13+
#
14+
# Commands:
15+
# hubot walkie on <projectURL> - Start watching events for the project
16+
# hubot walkie off <projectURL> - Stop watching events for the project
17+
#
18+
# Author:
19+
# tybenz
20+
21+
strftime = require 'strftime'
22+
S = require 'string'
23+
24+
module.exports = (robot) ->
25+
26+
if process.env.HUBOT_WALKIE_ROOMS
27+
allRooms = process.env.HUBOT_WALKIE_ROOMS.split(',')
28+
else
29+
allRooms = []
30+
31+
user = process.env.HUBOT_WALKIE_USERNAME
32+
pass = process.env.HUBOT_WALKIE_PASSWORD
33+
if user and pass
34+
auth = 'Basic ' + new Buffer(user + ':' + pass).toString('base64')
35+
format = "%Y-%m-%dT%H:%M:%S%z"
36+
37+
interval = (ms, func) -> setInterval func, ms
38+
39+
# Actual listener
40+
startListening = ->
41+
# Only start listening if our auth is set up. I.E. Configs have been set
42+
if (auth)
43+
interval 10000, ->
44+
listeners = robot.brain.data.walkie
45+
for i, project of listeners
46+
project = JSON.parse project
47+
robot.http("https://basecamp.com/#{project.accountID}/api/v1/projects/#{project.projectID}/events.json?since=#{project.timestamp}")
48+
.headers(Authorization: auth, Accept: 'application/json', 'User-Agent': 'Walkie (http://walkie.tybenz.com)')
49+
.get() (err, res, body) ->
50+
switch res.statusCode
51+
when 200
52+
events = JSON.parse(body)
53+
project.timestamp = strftime format
54+
listeners[i] = JSON.stringify project
55+
for event, i in events
56+
message = "Walkie: [#{project.projectName}] #{event.creator.name} #{event.summary}: #{event.url.replace( /api\/v1\//, '' ).replace(/\.json/g,'')}"
57+
message = S(message).unescapeHTML().s.replace( /(<([^>]+)>)/ig,"" )
58+
robot.messageRoom allRooms, message
59+
else
60+
console.log "Issue with connection to Basecamp#{body}"
61+
else
62+
console.log "Walkie: configs are not set"
63+
64+
# Internal: Initialize our brain
65+
robot.brain.on 'loaded', =>
66+
robot.brain.data.walkie ||= {}
67+
startListening()
68+
69+
# Start listening for events on project
70+
robot.respond /walkie on ([\S]*)/i, (msg) ->
71+
if not(user and pass and allRooms.length > 0)
72+
msg.send "Walkie's config variables are not set"
73+
else
74+
url = msg.match[1]
75+
if /http(s)?\:\/\//.test(url)
76+
accountID = parseInt url.match(/\.com\/([0-9]*)\//)[1]
77+
projectID = parseInt url.match(/projects\/([0-9]*)-/)[1]
78+
msg.http("https://basecamp.com/#{accountID}/api/v1/projects.json")
79+
.headers(Authorization: auth, Accept: 'application/json', 'User-Agent': 'Walkie (http://walkie.tybenz.com)')
80+
.get() (err, res, body) ->
81+
switch res.statusCode
82+
when 200
83+
projects = JSON.parse(body)
84+
target = false
85+
for p, i in projects
86+
if p.id is projectID
87+
target = p
88+
if target
89+
robot.brain.data.walkie["#{accountID}/#{projectID}"] = JSON.stringify { projectName: target.name, accountID: accountID, projectID: projectID, timestamp: strftime(format) }
90+
msg.send "Walkie is scanning on #{target.name}"
91+
else
92+
msg.send "Walkie could not find a project with that ID"
93+
else
94+
msg.send "Walkie was unable to find that frequency. WTF Basecamp?!? #{body}"
95+
else
96+
msg.send "Not a valid URL. Try again"
97+
98+
# Stops listening for events on project
99+
robot.respond /walkie off ([\S]*)/i, (msg) ->
100+
if not(user and pass and allRooms.length > 0)
101+
msg.send("Walkie's config variables are not set")
102+
else
103+
url = msg.match[1]
104+
if /http(s)?\:\/\//.test(url)
105+
accountID = url.match(/\.com\/([0-9]*)\//)[1]
106+
projectID = url.match(/projects\/([0-9]*)-/)[1]
107+
if robot.brain.data.walkie["#{accountID}/#{projectID}"]?
108+
msg.send "Walkie has stopped scanning on #{JSON.parse(robot.brain.data.walkie["#{accountID}/#{projectID}"]).projectName}"
109+
delete robot.brain.data.walkie["#{accountID}/#{projectID}"]
110+
else
111+
msg.send "Walkie was not scanning on that project."
112+
else
113+
msg.send "Not a valid URL. Try again"
114+
115+
# Debugging purposes grab hash stored in brain
116+
robot.respond /walkie fetch ([\S]*)/i, (msg) ->
117+
fetch = msg.match[1]
118+
data = robot.brain.data.walkie[fetch]
119+
if data
120+
msg.send data
121+
else
122+
msg.send "#{fetch} could not be found"
123+
124+
# Stop listening to all projects (clear brain)
125+
robot.respond /walkie clear/i, (msg) ->
126+
for i, item of robot.brain.data.walkie
127+
delete robot.brain.data.walkie[i]
128+
msg.send "Walkie is turning off and will stop scanning on all projects."

0 commit comments

Comments
 (0)