Permalink
Fetching contributors…
Cannot retrieve contributors at this time
131 lines (119 sloc) 4.87 KB
# Description:
# A way to interact with the Google Images API.
#
# Configuration
# HUBOT_GOOGLE_CSE_KEY - Your Google developer API key
# HUBOT_GOOGLE_CSE_ID - The ID of your Custom Search Engine
# HUBOT_MUSTACHIFY_URL - Optional. Allow you to use your own mustachify instance.
# HUBOT_GOOGLE_IMAGES_HEAR - Optional. If set, bot will respond to any line that begins with "image me" or "animate me" without needing to address the bot directly
# HUBOT_GOOGLE_SAFE_SEARCH - Optional. Search safety level.
# HUBOT_GOOGLE_IMAGES_FALLBACK - The URL to use when API fails. `{q}` will be replaced with the query string.
#
# Commands:
# hubot image me <query> - The Original. Queries Google Images for <query> and returns a random top result.
# hubot animate me <query> - The same thing as `image me`, except adds a few parameters to try to return an animated GIF instead.
# hubot mustache me <url|query> - Adds a mustache to the specified URL or query result.
module.exports = (robot) ->
robot.respond /(image|img)( me)? (.+)/i, (msg) ->
imageMe msg, msg.match[3], (url) ->
msg.send url
robot.respond /animate( me)? (.+)/i, (msg) ->
imageMe msg, msg.match[2], true, (url) ->
msg.send url
# pro feature, not added to docs since you can't conditionally document commands
if process.env.HUBOT_GOOGLE_IMAGES_HEAR?
robot.hear /^(image|img) me (.+)/i, (msg) ->
imageMe msg, msg.match[2], (url) ->
msg.send url
robot.hear /^animate me (.+)/i, (msg) ->
imageMe msg, msg.match[1], true, (url) ->
msg.send url
robot.respond /(?:mo?u)?sta(?:s|c)h(?:e|ify)?(?: me)? (.+)/i, (msg) ->
if not process.env.HUBOT_MUSTACHIFY_URL?
msg.send "Sorry, the Mustachify server is not configured."
, "http://i.imgur.com/BXbGJ1N.png"
return
mustacheBaseUrl =
process.env.HUBOT_MUSTACHIFY_URL?.replace(/\/$/, '')
mustachify = "#{mustacheBaseUrl}/rand?src="
imagery = msg.match[1]
if imagery.match /^https?:\/\//i
encodedUrl = encodeURIComponent imagery
msg.send "#{mustachify}#{encodedUrl}"
else
imageMe msg, imagery, false, true, (url) ->
encodedUrl = encodeURIComponent url
msg.send "#{mustachify}#{encodedUrl}"
imageMe = (msg, query, animated, faces, cb) ->
cb = animated if typeof animated == 'function'
cb = faces if typeof faces == 'function'
googleCseId = process.env.HUBOT_GOOGLE_CSE_ID
if googleCseId
# Using Google Custom Search API
googleApiKey = process.env.HUBOT_GOOGLE_CSE_KEY
if !googleApiKey
msg.robot.logger.error "Missing environment variable HUBOT_GOOGLE_CSE_KEY"
msg.send "Missing server environment variable HUBOT_GOOGLE_CSE_KEY."
return
q =
q: query,
searchType:'image',
safe: process.env.HUBOT_GOOGLE_SAFE_SEARCH || 'high',
fields:'items(link)',
cx: googleCseId,
key: googleApiKey
if animated is true
q.fileType = 'gif'
q.hq = 'animated'
q.tbs = 'itp:animated'
if faces is true
q.imgType = 'face'
url = 'https://www.googleapis.com/customsearch/v1'
msg.http(url)
.query(q)
.get() (err, res, body) ->
if err
if res.statusCode is 403
msg.send "Daily image quota exceeded, using alternate source."
deprecatedImage(msg, query, animated, faces, cb)
else
msg.send "Encountered an error :( #{err}"
return
if res.statusCode isnt 200
msg.send "Bad HTTP response :( #{res.statusCode}"
return
response = JSON.parse(body)
if response?.items
image = msg.random response.items
cb ensureResult(image.link, animated)
else
msg.send "Oops. I had trouble searching '#{query}'. Try later."
((error) ->
msg.robot.logger.error error.message
msg.robot.logger
.error "(see #{error.extendedHelp})" if error.extendedHelp
) error for error in response.error.errors if response.error?.errors
else
msg.send "Google Image Search API is no longer available. " +
"Please [setup up Custom Search Engine API](https://github.com/hubot-scripts/hubot-google-images#cse-setup-details)."
deprecatedImage(msg, query, animated, faces, cb)
deprecatedImage = (msg, query, animated, faces, cb) ->
# Show a fallback image
imgUrl = process.env.HUBOT_GOOGLE_IMAGES_FALLBACK ||
'http://i.imgur.com/CzFTOkI.png'
imgUrl = imgUrl.replace(/\{q\}/, encodeURIComponent(query))
cb ensureResult(imgUrl, animated)
# Forces giphy result to use animated version
ensureResult = (url, animated) ->
if animated is true
ensureImageExtension url.replace(
/(giphy\.com\/.*)\/.+_s.gif$/,
'$1/giphy.gif')
else
ensureImageExtension url
# Forces the URL look like an image URL by adding `#.png`
ensureImageExtension = (url) ->
if /(png|jpe?g|gif)$/i.test(url)
url
else
"#{url}#.png"