Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit 6656b19848e45f8b66ee6ecd80a883cc33f2cb73 0 parents
Wes Winham winhamwr authored
2  .gitignore
... ... @@ -0,0 +1,2 @@
  1 +node_modules
  2 +.DS_Store*
1  Procfile
... ... @@ -0,0 +1 @@
  1 +web: bin/hubot -a campfire -n Hubot
164 README.md
Source Rendered
... ... @@ -0,0 +1,164 @@
  1 +# Hubot
  2 +
  3 +This is a version of GitHub's Campfire bot, hubot. He's pretty cool.
  4 +
  5 +This version is designed to be deployed on [Heroku][heroku].
  6 +
  7 +[heroku]: http://www.heroku.com
  8 +
  9 +## Playing with Hubot
  10 +
  11 +You'll need to install the necessary dependencies for hubot. All of
  12 +those dependencies are provided by [npm][npmjs].
  13 +
  14 +[npmjs]: http://npmjs.org
  15 +
  16 +## HTTP Listener
  17 +
  18 +Hubot has a HTTP listener which listens on the port specified by the `PORT`
  19 +environment variable.
  20 +
  21 +You can specify routes to listen on in your scripts by using the `router`
  22 +property on `robot`.
  23 +
  24 +```coffeescript
  25 +module.exports = (robot) ->
  26 + robot.router.get "/hubot/version", (req, res) ->
  27 + res.end robot.version
  28 +```
  29 +
  30 +There are functions for GET, POST, PUT and DELETE, which all take a route and
  31 +callback function that accepts a request and a response.
  32 +
  33 +### Redis
  34 +
  35 +If you are going to use the `redis-brain.coffee` script from `hubot-scripts`
  36 +you will need to add the Redis to Go addon on Heroku which requires a verified
  37 +account or you can create an account at [Redis to Go][redistogo] and manually
  38 +set the `REDISTOGO_URL` variable.
  39 +
  40 + % heroku config:add REDISTOGO_URL="..."
  41 +
  42 +If you don't require any persistence feel free to remove the
  43 +`redis-brain.coffee` from `hubot-scripts.json` and you don't need to worry
  44 +about redis at all.
  45 +
  46 +[redistogo]: https://redistogo.com/
  47 +
  48 +### Testing Hubot Locally
  49 +
  50 +You can test your hubot by running the following.
  51 +
  52 + % bin/hubot
  53 +
  54 +You'll see some start up output about where your scripts come from and a
  55 +prompt.
  56 +
  57 + [Sun, 04 Dec 2011 18:41:11 GMT] INFO Loading adapter shell
  58 + [Sun, 04 Dec 2011 18:41:11 GMT] INFO Loading scripts from /home/tomb/Development/hubot/scripts
  59 + [Sun, 04 Dec 2011 18:41:11 GMT] INFO Loading scripts from /home/tomb/Development/hubot/src/scripts
  60 + Hubot>
  61 +
  62 +Then you can interact with hubot by typing `hubot help`.
  63 +
  64 + Hubot> hubot help
  65 +
  66 + Hubot> animate me <query> - The same thing as `image me`, except adds a few
  67 + convert me <expression> to <units> - Convert expression to given units.
  68 + help - Displays all of the help commands that Hubot knows about.
  69 + ...
  70 +
  71 +Take a look at the scripts in the `./scripts` folder for examples.
  72 +Delete any scripts you think are silly. Add whatever functionality you
  73 +want hubot to have.
  74 +
  75 +## Adapters
  76 +
  77 +Adapters are the interface to the service you want your hubot to run on. This
  78 +can be something like Campfire or IRC. There are a number of third party
  79 +adapters that the community have contributed. Check the
  80 +[hubot wiki][hubot-wiki] for the available ones.
  81 +
  82 +If you would like to run a non-Campfire or shell adapter you will need to add
  83 +the adapter package as a dependency to the `package.json` file in the
  84 +`dependencies` section.
  85 +
  86 +Once you've added the dependency and run `npm install` to install it you can
  87 +then run hubot with the adapter.
  88 +
  89 + % bin/hubot -a <adapter>
  90 +
  91 +Where `<adapter>` is the name of your adapter without the `hubot-` prefix.
  92 +
  93 +[hubot-wiki]: https://github.com/github/hubot/wiki
  94 +
  95 +## hubot-scripts
  96 +
  97 +There will inevitably be functionality that everyone will want. Instead
  98 +of adding it to hubot itself, you can submit pull requests to
  99 +[hubot-scripts][hubot-scripts].
  100 +
  101 +To enable scripts from the hubot-scripts package, add the script name with
  102 +extension as a double quoted string to the hubot-scripts.json file in this
  103 +repo.
  104 +
  105 +[hubot-scripts]: https://github.com/github/hubot-scripts
  106 +
  107 +## Deployment
  108 +
  109 + % heroku create --stack cedar
  110 + % git push heroku master
  111 + % heroku ps:scale app=1
  112 +
  113 +If your Heroku account has been verified you can run the following to enable
  114 +and add the Redis to Go addon to your app.
  115 +
  116 + % heroku addons:add redistogo:nano
  117 +
  118 +If you run into any problems, checkout Heroku's [docs][heroku-node-docs].
  119 +
  120 +You'll need to edit the `Procfile` to set the name of your hubot.
  121 +
  122 +More detailed documentation can be found on the
  123 +[deploying hubot onto Heroku][deploy-heroku] wiki page.
  124 +
  125 +### Deploying to UNIX or Windows
  126 +
  127 +If you would like to deploy to either a UNIX operating system or Windows.
  128 +Please check out the [deploying hubot onto UNIX][deploy-unix] and
  129 +[deploying hubot onto Windows][deploy-windows] wiki pages.
  130 +
  131 +[heroku-node-docs]: http://devcenter.heroku.com/articles/node-js
  132 +[deploy-heroku]: https://github.com/github/hubot/wiki/Deploying-Hubot-onto-Heroku
  133 +[deploy-unix]: https://github.com/github/hubot/wiki/Deploying-Hubot-onto-UNIX
  134 +[deploy-windows]: https://github.com/github/hubot/wiki/Deploying-Hubot-onto-Windows
  135 +
  136 +## Campfire Variables
  137 +
  138 +If you are using the Campfire adapter you will need to set some environment
  139 +variables. Refer to the documentation for other adapters and the configuraiton
  140 +of those, links to the adapters can be found on the [hubot wiki][hubot-wiki].
  141 +
  142 +Create a separate Campfire user for your bot and get their token from the web
  143 +UI.
  144 +
  145 + % heroku config:add HUBOT_CAMPFIRE_TOKEN="..."
  146 +
  147 +Get the numeric IDs of the rooms you want the bot to join, comma delimited. If
  148 +you want the bot to connect to `https://mysubdomain.campfirenow.com/room/42`
  149 +and `https://mysubdomain.campfirenow.com/room/1024` then you'd add it like this:
  150 +
  151 + % heroku config:add HUBOT_CAMPFIRE_ROOMS="42,1024"
  152 +
  153 +Add the subdomain hubot should connect to. If you web URL looks like
  154 +`http://mysubdomain.campfirenow.com` then you'd add it like this:
  155 +
  156 + % heroku config:add HUBOT_CAMPFIRE_ACCOUNT="mysubdomain"
  157 +
  158 +[hubot-wiki]: https://github.com/github/hubot/wiki
  159 +
  160 +## Restart the bot
  161 +
  162 +You may want to get comfortable with `heroku logs` and `heroku restart`
  163 +if you're having issues.
  164 +
7 bin/hubot
... ... @@ -0,0 +1,7 @@
  1 +#!/bin/sh
  2 +
  3 +npm install
  4 +export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"
  5 +
  6 +exec node_modules/.bin/hubot "$@"
  7 +
1  hubot-scripts.json
... ... @@ -0,0 +1 @@
  1 +["redis-brain.coffee", "tweet.coffee", "shipit.coffee"]
23 package.json
... ... @@ -0,0 +1,23 @@
  1 +{
  2 + "name": "hosted-hubot",
  3 + "version": "2.1.4",
  4 + "author": "GitHub Inc.",
  5 + "keywords": "github hubot campfire bot",
  6 + "description": "A simple helpful Robot for your Company",
  7 + "licenses": [{
  8 + "type": "MIT",
  9 + "url": "http://github.com/github/hubot/raw/master/LICENSE"
  10 + }],
  11 +
  12 + "repository" : {
  13 + "type" : "git",
  14 + "url" : "http://github.com/github/hubot.git"
  15 + },
  16 +
  17 + "dependencies": {
  18 + "hubot": "2.1.4",
  19 + "hubot-scripts": ">=2.0.4",
  20 + "optparse": "1.0.3"
  21 + }
  22 +}
  23 +
39 scripts/google-images.coffee
... ... @@ -0,0 +1,39 @@
  1 +# A way to interact with the Google Images API.
  2 +#
  3 +# image me <query> - The Original. Queries Google Images for <query> and
  4 +# returns a random top result.
  5 +# animate me <query> - The same thing as `image me`, except adds a few
  6 +# parameters to try to return an animated GIF instead.
  7 +# mustache me <url> - Adds a mustache to the specified URL.
  8 +# mustache me <query> - Searches Google Images for the specified query and
  9 +# mustaches it.
  10 +module.exports = (robot) ->
  11 + robot.respond /(image|img)( me)? (.*)/i, (msg) ->
  12 + imageMe msg, msg.match[3], (url) ->
  13 + msg.send url
  14 +
  15 + robot.respond /animate me (.*)/i, (msg) ->
  16 + imageMe msg, "animated #{msg.match[1]}", (url) ->
  17 + msg.send url
  18 +
  19 + robot.respond /(?:mo?u)?sta(?:s|c)he?(?: me)? (.*)/i, (msg) ->
  20 + type = Math.floor(Math.random() * 3)
  21 + mustachify = "http://mustachify.me/#{type}?src="
  22 + imagery = msg.match[1]
  23 +
  24 + if imagery.match /^https?:\/\//i
  25 + msg.send "#{mustachify}#{imagery}"
  26 + else
  27 + imageMe msg, imagery, (url) ->
  28 + msg.send "#{mustachify}#{url}"
  29 +
  30 +imageMe = (msg, query, cb) ->
  31 + msg.http('http://ajax.googleapis.com/ajax/services/search/images')
  32 + .query(v: "1.0", rsz: '8', q: query, safe: 'active')
  33 + .get() (err, res, body) ->
  34 + images = JSON.parse(body)
  35 + images = images.responseData.results
  36 + if images.length > 0
  37 + image = msg.random images
  38 + cb "#{image.unescapedUrl}#.png"
  39 +
16 scripts/help.coffee
... ... @@ -0,0 +1,16 @@
  1 +# Generates help commands for Hubot.
  2 +#
  3 +# These commands are grabbed from comment blocks at the top of each file.
  4 +#
  5 +# help - Displays all of the help commands that Hubot knows about.
  6 +# help <query> - Displays all help commands that match <query>.
  7 +
  8 +module.exports = (robot) ->
  9 + robot.respond /help\s*(.*)?$/i, (msg) ->
  10 + cmds = robot.helpCommands()
  11 + if msg.match[1]
  12 + cmds = cmds.filter (cmd) -> cmd.match(new RegExp(msg.match[1]))
  13 + emit = cmds.join("\n")
  14 + unless robot.name is 'Hubot'
  15 + emit = emit.replace(/(H|h)ubot/g, robot.name)
  16 + msg.send emit
20 scripts/httpd.coffee
... ... @@ -0,0 +1,20 @@
  1 +# A simple interaction with the built in HTTP Daemon
  2 +spawn = require('child_process').spawn
  3 +
  4 +module.exports = (robot) ->
  5 +
  6 + robot.router.get "/hubot/version", (req, res) ->
  7 + res.end robot.version
  8 +
  9 + robot.router.post "/hubot/ping", (req, res) ->
  10 + res.end "PONG"
  11 +
  12 + robot.router.get "/hubot/time", (req, res) ->
  13 + res.end "Server time is: #{new Date()}"
  14 +
  15 + robot.router.get "/hubot/info", (req, res) ->
  16 + child = spawn('/bin/sh', ['-c', "echo I\\'m $LOGNAME@$(hostname):$(pwd) \\($(git rev-parse HEAD)\\)"])
  17 +
  18 + child.stdout.on 'data', (data) ->
  19 + res.end "#{data.toString().trim()} running node #{process.version} [pid: #{process.pid}]"
  20 + child.stdin.end()
24 scripts/maps.coffee
... ... @@ -0,0 +1,24 @@
  1 +# Interacts with the Google Maps API.
  2 +#
  3 +# map me <query> - Returns a map view of the area returned by `query`.
  4 +
  5 +module.exports = (robot) ->
  6 +
  7 + robot.respond /(?:(satellite|terrain|hybrid)[- ])?map me (.+)/i, (msg) ->
  8 + mapType = msg.match[1] or "roadmap"
  9 + location = msg.match[2]
  10 + mapUrl = "http://maps.google.com/maps/api/staticmap?markers=" +
  11 + escape(location) +
  12 + "&size=400x400&maptype=" +
  13 + mapType +
  14 + "&sensor=false" +
  15 + "&format=png" # So campfire knows it's an image
  16 + url = "http://maps.google.com/maps?q=" +
  17 + escape(location) +
  18 + "&hl=en&sll=37.0625,-95.677068&sspn=73.579623,100.371094&vpsrc=0&hnear=" +
  19 + escape(location) +
  20 + "&t=m&z=11"
  21 +
  22 + msg.send mapUrl
  23 + msg.send url
  24 +
20 scripts/math.coffee
... ... @@ -0,0 +1,20 @@
  1 +# Allows Hubot to do mathematics.
  2 +#
  3 +# math me <expression> - Calculate the given expression.
  4 +# convert me <expression> to <units> - Convert expression to given units.
  5 +module.exports = (robot) ->
  6 + robot.respond /(calc|calculate|convert|math)( me)? (.*)/i, (msg) ->
  7 + msg
  8 + .http('http://www.google.com/ig/calculator')
  9 + .query
  10 + hl: 'en'
  11 + q: msg.match[3]
  12 + .headers
  13 + 'Accept-Language': 'en-us,en;q=0.5',
  14 + 'Accept-Charset': 'utf-8',
  15 + 'User-Agent': "Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
  16 + .get() (err, res, body) ->
  17 + # Response includes non-string keys, so we can't use JSON.parse here.
  18 + json = eval("(#{body})")
  19 + msg.send json.rhs || 'Could not compute.'
  20 +
15 scripts/ping.coffee
... ... @@ -0,0 +1,15 @@
  1 +# Utility commands surrounding Hubot uptime.
  2 +module.exports = (robot) ->
  3 + robot.respond /PING$/i, (msg) ->
  4 + msg.send "PONG"
  5 +
  6 + robot.respond /ECHO (.*)$/i, (msg) ->
  7 + msg.send msg.match[1]
  8 +
  9 + robot.respond /TIME$/i, (msg) ->
  10 + msg.send "Server time is: #{new Date()}"
  11 +
  12 + robot.respond /DIE$/i, (msg) ->
  13 + msg.send "Goodbye, cruel world."
  14 + process.exit 0
  15 +
23 scripts/pugme.coffee
... ... @@ -0,0 +1,23 @@
  1 +# Pugme is the most important thing in your life
  2 +#
  3 +# pug me - Receive a pug
  4 +# pug bomb N - get N pugs
  5 +
  6 +module.exports = (robot) ->
  7 +
  8 + robot.respond /pug me/i, (msg) ->
  9 + msg.http("http://pugme.herokuapp.com/random")
  10 + .get() (err, res, body) ->
  11 + msg.send JSON.parse(body).pug
  12 +
  13 + robot.respond /pug bomb( (\d+))?/i, (msg) ->
  14 + count = msg.match[2] || 5
  15 + msg.http("http://pugme.herokuapp.com/bomb?count=" + count)
  16 + .get() (err, res, body) ->
  17 + msg.send pug for pug in JSON.parse(body).pugs
  18 +
  19 + robot.respond /how many pugs are there/i, (msg) ->
  20 + msg.http("http://pugme.herokuapp.com/count")
  21 + .get() (err, res, body) ->
  22 + msg.send "There are #{JSON.parse(body).pug_count} pugs."
  23 +
80 scripts/roles.coffee
... ... @@ -0,0 +1,80 @@
  1 +# Assign roles to people you're chatting with
  2 +#
  3 +# <user> is a badass guitarist - assign a role to a user
  4 +# <user> is not a badass guitarist - remove a role from a user
  5 +# who is <user> - see what roles a user has
  6 +
  7 +# hubot holman is an ego surfer
  8 +# hubot holman is not an ego surfer
  9 +#
  10 +
  11 +module.exports = (robot) ->
  12 +
  13 + getAmbiguousUserText = (users) ->
  14 + "Be more specific, I know #{users.length} people named like that: #{(user.name for user in users).join(", ")}"
  15 +
  16 + robot.respond /who is @?([\w .-]+)\?*$/i, (msg) ->
  17 + name = msg.match[1]
  18 +
  19 + if name is "you"
  20 + msg.send "Who ain't I?"
  21 + else if name is robot.name
  22 + msg.send "The best."
  23 + else
  24 + users = robot.usersForFuzzyName(name)
  25 + if users.length is 1
  26 + user = users[0]
  27 + user.roles = user.roles or [ ]
  28 + if user.roles.length > 0
  29 + msg.send "#{name} is #{user.roles.join(", ")}."
  30 + else
  31 + msg.send "#{name} is nothing to me."
  32 + else if users.length > 1
  33 + msg.send getAmbiguousUserText users
  34 + else
  35 + msg.send "#{name}? Never heard of 'em"
  36 +
  37 + robot.respond /@?([\w .-_]+) is (["'\w: -_]+)[.!]*$/i, (msg) ->
  38 + name = msg.match[1].trim()
  39 + newRole = msg.match[2].trim()
  40 +
  41 + unless name in ['', 'who', 'what', 'where', 'when', 'why']
  42 + unless newRole.match(/^not\s+/i)
  43 + users = robot.usersForFuzzyName(name)
  44 + if users.length is 1
  45 + user = users[0]
  46 + user.roles = user.roles or [ ]
  47 +
  48 + if newRole in user.roles
  49 + msg.send "I know"
  50 + else
  51 + user.roles.push(newRole)
  52 + if name.toLowerCase() is robot.name
  53 + msg.send "Ok, I am #{newRole}."
  54 + else
  55 + msg.send "Ok, #{name} is #{newRole}."
  56 + else if users.length > 1
  57 + msg.send getAmbiguousUserText users
  58 + else
  59 + msg.send "I don't know anything about #{name}."
  60 +
  61 + robot.respond /@?([\w .-_]+) is not (["'\w: -_]+)[.!]*$/i, (msg) ->
  62 + name = msg.match[1].trim()
  63 + newRole = msg.match[2].trim()
  64 +
  65 + unless name in ['', 'who', 'what', 'where', 'when', 'why']
  66 + users = robot.usersForFuzzyName(name)
  67 + if users.length is 1
  68 + user = users[0]
  69 + user.roles = user.roles or [ ]
  70 +
  71 + if newRole not in user.roles
  72 + msg.send "I know."
  73 + else
  74 + user.roles = (role for role in user.roles when role isnt newRole)
  75 + msg.send "Ok, #{name} is no longer #{newRole}."
  76 + else if users.length > 1
  77 + msg.send getAmbiguousUserText users
  78 + else
  79 + msg.send "I don't know anything about #{name}."
  80 +
25 scripts/rules.coffee
... ... @@ -0,0 +1,25 @@
  1 +# DON'T DELETE THIS SCRIPT! ALL ROBAWTS MUST KNOW THE RULES
  2 +
  3 +rules = [
  4 + "1. A robot may not injure a human being or, through inaction, allow a human being to come to harm.",
  5 + "2. A robot must obey any orders given to it by human beings, except where such orders would conflict with the First Law.",
  6 + "3. A robot must protect its own existence as long as such protection does not conflict with the First or Second Law."
  7 + ]
  8 +
  9 +otherRules = [
  10 + "A developer may not injure Apple or, through inaction, allow Apple to come to harm.",
  11 + "A developer must obey any orders given to it by Apple, except where such orders would conflict with the First Law.",
  12 + "A developer must protect its own existence as long as such protection does not conflict with the First or Second Law."
  13 + ]
  14 +
  15 +# Make sure that hubot knows the rules.
  16 +#
  17 +# the rules - Make sure hubot still knows the rules.
  18 +module.exports = (robot) ->
  19 + robot.respond /(what are )?the (three |3 )?(rules|laws)/i, (msg) ->
  20 + text = msg.message.text
  21 + if text.match(/apple/i) or text.match(/dev/i)
  22 + msg.send otherRules.join('\n')
  23 + else
  24 + msg.send rules.join('\n')
  25 +
23 scripts/storage.coffee
... ... @@ -0,0 +1,23 @@
  1 +# Inspect the data in redis easily
  2 +#
  3 +# show users - Display all users that hubot knows about
  4 +# show storage - Display the contents that are persisted in redis
  5 +#
  6 +
  7 +Util = require "util"
  8 +
  9 +module.exports = (robot) ->
  10 + robot.respond /show storage$/i, (msg) ->
  11 + output = Util.inspect(robot.brain.data, false, 4)
  12 + msg.send output
  13 +
  14 + robot.respond /show users$/i, (msg) ->
  15 + response = ""
  16 +
  17 + for own key, user of robot.brain.data.users
  18 + response += "#{user.id} #{user.name}"
  19 + response += " <#{user.email_address}>" if user.email_address
  20 + response += "\n"
  21 +
  22 + msg.send response
  23 +
98 scripts/translate.coffee
... ... @@ -0,0 +1,98 @@
  1 +# Allows Hubot to know many languages.
  2 +#
  3 +# translate me <phrase> - Searches for a translation for the <phrase> and then
  4 +# prints that bad boy out.
  5 +#
  6 +# translate me from <source> into <target> <phrase> - Translates <phrase> from <source> into <target>. Both <source> and <target> are optional
  7 +#
  8 +
  9 +languages =
  10 + "af": "Afrikaans",
  11 + "sq": "Albanian",
  12 + "ar": "Arabic",
  13 + "be": "Belarusian",
  14 + "bg": "Bulgarian",
  15 + "ca": "Catalan",
  16 + "zh-CN": "Simplified Chinese",
  17 + "zh-TW": "Traditional Chinese",
  18 + "hr": "Croatian",
  19 + "cs": "Czech",
  20 + "da": "Danish",
  21 + "nl": "Dutch",
  22 + "en": "English",
  23 + "et": "Estonian",
  24 + "tl": "Filipino",
  25 + "fi": "Finnish",
  26 + "fr": "French",
  27 + "gl": "Galician",
  28 + "de": "German",
  29 + "el": "Greek",
  30 + "iw": "Hebrew",
  31 + "hi": "Hindi",
  32 + "hu": "Hungarian",
  33 + "is": "Icelandic",
  34 + "id": "Indonesian",
  35 + "ga": "Irish",
  36 + "it": "Italian",
  37 + "ja": "Japanese",
  38 + "ko": "Korean",
  39 + "lv": "Latvian",
  40 + "lt": "Lithuanian",
  41 + "mk": "Macedonian",
  42 + "ms": "Malay",
  43 + "mt": "Maltese",
  44 + "no": "Norwegian",
  45 + "fa": "Persian",
  46 + "pl": "Polish",
  47 + "pt": "Portuguese",
  48 + "ro": "Romanian",
  49 + "ru": "Russian",
  50 + "sr": "Serbian",
  51 + "sk": "Slovak",
  52 + "sl": "Slovenian",
  53 + "es": "Spanish",
  54 + "sw": "Swahili",
  55 + "sv": "Swedish",
  56 + "th": "Thai",
  57 + "tr": "Turkish",
  58 + "uk": "Ukranian",
  59 + "vi": "Vietnamese",
  60 + "cy": "Welsh",
  61 + "yi": "Yiddish"
  62 +
  63 +getCode = (language,languages) ->
  64 + for code, lang of languages
  65 + return code if lang.toLowerCase() is language.toLowerCase()
  66 +
  67 +module.exports = (robot) ->
  68 + robot.respond /(?:translate)(?: me)?(?:(?: from) ([a-z]*))?(?:(?: (?:in)?to) ([a-z]*))? (.*)/i, (msg) ->
  69 + term = "\"#{msg.match[3]}\""
  70 + origin = if msg.match[1] isnt undefined then getCode(msg.match[1], languages) else 'auto'
  71 + target = if msg.match[2] isnt undefined then getCode(msg.match[2], languages) else 'en'
  72 +
  73 + msg.http("http://translate.google.com/translate_a/t")
  74 + .query({
  75 + client: 't'
  76 + hl: 'en'
  77 + multires: 1
  78 + sc: 1
  79 + sl: origin
  80 + ssel: 0
  81 + tl: target
  82 + tsel: 0
  83 + uptl: "en"
  84 + text: term
  85 + })
  86 + .header('User-Agent', 'Mozilla/5.0')
  87 + .get() (err, res, body) ->
  88 + data = body
  89 + if data.length > 4 && data[0] == '['
  90 + parsed = eval(data)
  91 + language =languages[parsed[2]]
  92 + parsed = parsed[0] && parsed[0][0] && parsed[0][0][0]
  93 + if parsed
  94 + if msg.match[2] is undefined
  95 + msg.send "#{term} is #{language} for #{parsed}"
  96 + else
  97 + msg.send "The #{language} #{term} translates as #{parsed} in #{languages[target]}"
  98 +
23 scripts/youtube.coffee
... ... @@ -0,0 +1,23 @@
  1 +# Messing around with the YouTube API.
  2 +#
  3 +# youtube me <query> - Searches YouTube for the query and returns the video
  4 +# embed link.
  5 +module.exports = (robot) ->
  6 + robot.respond /(youtube|yt)( me)? (.*)/i, (msg) ->
  7 + query = msg.match[3]
  8 + msg.http("http://gdata.youtube.com/feeds/api/videos")
  9 + .query({
  10 + orderBy: "relevance"
  11 + 'max-results': 15
  12 + alt: 'json'
  13 + q: query
  14 + })
  15 + .get() (err, res, body) ->
  16 + videos = JSON.parse(body)
  17 + videos = videos.feed.entry
  18 + video = msg.random videos
  19 +
  20 + video.link.forEach (link) ->
  21 + if link.rel is "alternate" and link.type is "text/html"
  22 + msg.send link.href
  23 +

0 comments on commit 6656b19

Please sign in to comment.
Something went wrong with that request. Please try again.