UNPKG

jarvis-bot

Version:

A JARVIS for your team - your most powerful bot and loyal butler.

214 lines (183 loc) 7.1 kB
# Description: # time-me and darksky combined, with memory of users' locations. # Modified from parkr (time-me), and kyleslattery, awaxa (darksky) # # Dependencies: # node-geocoder # # Configuration: # HUBOT_TIMEZONEDB_API_KEY # HUBOT_DARK_SKY_API_KEY # HUBOT_DARK_SKY_DEFAULT_LOCATION # HUBOT_DARK_SKY_SEPARATOR (optional - defaults to "\n") # # Notes: # If HUBOT_DARK_SKY_DEFAULT_LOCATION is blank, weather commands without a location will be ignored # # Commands: # hubot <user> is | <I'm> in <location> - Set where user is # hubot where am I | is <user> - Tells where user is # hubot time me | [at] [user] - Time at where user is # hubot weather - Get the weather for HUBOT_DARK_SKY_DEFAULT_LOCATION # hubot weather me | [at] <location|user> - Weather at where user is # # Author: # kengz userId = require(__dirname+'/helper.coffee').userId geocoder = require('node-geocoder').getGeocoder('google', 'http', {}) timezonedbKey = process.env["HUBOT_TIMEZONEDB_API_KEY"] unless timezonedbKey? console.log "Whoops, can't use /time me, as HUBOT_TIMEZONEDB_API_KEY isn't set." monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] dayNames = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ] now = -> Math.round(new Date().getTime() / 1000) locationForUser = (robot, userName, msg) -> robot.brain.data.locations[userId(robot, userName, msg)] setLatitudeAndLongitudeOnUser = (robot, user, msg, lat, lon) -> id = userId(robot, user, msg) robot.brain.data.locations[id] ?= {} robot.brain.data.locations[id]["lat"] = lat robot.brain.data.locations[id]["lon"] = lon setLocationForUser = (robot, user, msg, location, cb) -> name = userId(robot, user, msg) robot.brain.data.locations[name] ?= {} robot.brain.data.locations[name]["stringLocation"] = location geocodeNewLocation robot, user, msg, location, cb geocodeNewLocation = (robot, user, msg, location, cb) -> geocoder.geocode location, (err, res) -> if err console.log err cb("There was an error: #{err}") else setLatitudeAndLongitudeOnUser(robot, user, msg, res[0].latitude, res[0].longitude) cb("Ok, updated #{userId(robot, user, msg)}'s location to '#{location}'") relativeToNoon = (hours) -> if hours - 12 > -1 "PM" else "AM" formattedUnixTime = (timestamp) -> date = new Date(parseInt(timestamp) * 1000) console.log date "#{dayNames[date.getUTCDay()]}, #{monthNames[date.getUTCMonth()]} #{date.getUTCDate()} at #{date.getUTCHours()}:#{date.getUTCMinutes()} #{relativeToNoon(date.getUTCHours())}." timeAtLatitudeAndLongitude = (robot, location, cb) -> robot.http("http://api.timezonedb.com/").query key: timezonedbKey, lat: location.lat, lng: location.lon, time: now(), format: "json" .get() (err, res, body) -> if err or JSON.parse(body).status != "OK" cb "Sorry, I can't fetch time from unrecognized geolocation :(" else info = JSON.parse body cb "```It's currently #{formattedUnixTime info.timestamp} in #{location.stringLocation}.```" module.exports = (robot) -> robot.brain.data.locations ?= {} robot.respond /time( at)? ?(.+)?/i, (msg) -> user = userId(robot, msg.match[2], msg) location = if user? and robot.brain.data.locations[user]? then robot.brain.data.locations[user].stringLocation else msg.match[2] if location? geocoder.geocode location, (err, res) -> if err msg.send "Sorry, I don't know where #{location} is" else codedlocation = {} codedlocation['stringLocation'] = location codedlocation['lat'] = res[0].latitude codedlocation['lon'] = res[0].longitude timeAtLatitudeAndLongitude robot, codedlocation, (message) -> msg.send message else msg.send "Sorry, I don't know where #{user} is so I can't tell what time zone he or she is in. :(" robot.respond /((?:(?!is).)*) is (in|at) (.*)/i, (msg) -> user = userId(robot, msg.match[1], msg) if user? location = msg.match[3] setLocationForUser robot, user, msg, location, (message) -> msg.send message robot.respond /I\'*\’*m (in|at) (.*)/i, (msg) -> user = msg.message.user.name location = msg.match[2] setLocationForUser robot, user, msg, location, (message) -> msg.send message robot.respond /I am (in|at) (.*)/i, (msg) -> user = msg.message.user.name location = msg.match[2] setLocationForUser robot, user, msg, location, (message) -> msg.send message robot.respond /where is (.+)/i, (msg) -> user = userId(robot, msg.match[1], msg) if user? location = locationForUser(robot, user, msg) if location? msg.send "#{user} is in #{location.stringLocation}." else msg.send "Sorry, no idea where #{user} is." robot.respond /where am I/i, (msg) -> user = msg.message.user.name location = locationForUser(robot, user, msg) if location? msg.send "#{user} is in #{location.stringLocation}." else msg.send "Sorry, no idea where #{user} is." # This part henceforth is Darksky: uses either location or username robot.respond /weather( at)? ?(.+)?/i, (msg) -> user = userId(robot, msg.match[2], msg) location = if user? and robot.brain.data.locations[user]? then robot.brain.data.locations[user].stringLocation else msg.match[2] options = separator: process.env.HUBOT_DARK_SKY_SEPARATOR unless options.separator options.separator = "\n" googleurl = "http://maps.googleapis.com/maps/api/geocode/json" q = sensor: false, address: location msg.http(googleurl) .query(q) .get() (err, res, body) -> result = JSON.parse(body) if result.results.length > 0 lat = result.results[0].geometry.location.lat lng = result.results[0].geometry.location.lng darkSkyMe msg, lat,lng , options.separator, (darkSkyText) -> response = "```Weather for #{result.results[0].formatted_address}#{options.separator}#{darkSkyText}```" .replace /-?(\d+\.?\d*)°C/g, (match) -> centigrade = match.replace /°C/, '' match = Math.round(centigrade*10)/10 + '°C/' + Math.round(centigrade * (9/5) + parseInt(32, 10)) + '°F' msg.send response else msg.send "Couldn't find #{location}" darkSkyMe = (msg, lat, lng, separator, cb) -> url = "https://api.forecast.io/forecast/#{process.env.HUBOT_DARK_SKY_API_KEY}/#{lat},#{lng}/?units=si" msg.http(url) .get() (err, res, body) -> result = JSON.parse(body) if result.error cb "#{result.error}" return response = "Currently: #{result.currently.summary} #{result.currently.temperature}°C" response += "#{separator}Today: #{result.hourly.summary}" response += "#{separator}Coming week: #{result.daily.summary}" cb response