Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for slack slash commands #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
config/local_env.yml
*.rbc
capybara-*.html
.rspec
/log
/tmp
/db/*.sqlite3
/db/*.sqlite3-journal
/public/system
/coverage/
/spec/tmp
**.orig
rerun.txt
pickle-email-*.html

# TODO Comment out these rules if you are OK with secrets being uploaded to the repo
config/initializers/secret_token.rb
config/secrets.yml

## Environment normalization:
/.bundle
/vendor/bundle

# these should all be checked in to normalize the environment:
# Gemfile.lock, .ruby-version, .ruby-gemset

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc

# if using bower-rails ignore default bower_components path bower.json files
/vendor/assets/bower_components
*.bowerrc
bower.json

# Ignore pow environment settings
.powenv
5 changes: 4 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
source 'https://rubygems.org'
ruby '2.0.0'

gem 'rails', '3.2.13'
gem 'unicorn'
gem 'httparty'
gem 'pg'

gem 'rails_log_stdout'
gem 'rails_12factor'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

Expand Down
17 changes: 12 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ GEM
erubis (2.7.0)
execjs (2.0.2)
hike (1.2.3)
httparty (0.9.0)
multi_json (~> 1.0)
multi_xml
i18n (0.6.1)
journey (1.0.4)
jquery-rails (3.1.0)
Expand All @@ -55,7 +52,6 @@ GEM
treetop (~> 1.4.8)
mime-types (1.25.1)
multi_json (1.9.2)
multi_xml (0.5.1)
pg (0.14.1)
polyglot (0.3.4)
rack (1.4.5)
Expand All @@ -73,6 +69,13 @@ GEM
activesupport (= 3.2.13)
bundler (~> 1.0)
railties (= 3.2.13)
rails_12factor (0.0.3)
rails_serve_static_assets
rails_stdout_logging
rails_log_stdout (0.1.1)
rails (~> 3.2.0)
rails_serve_static_assets (0.0.4)
rails_stdout_logging (0.0.4)
railties (3.2.13)
actionpack (= 3.2.13)
activesupport (= 3.2.13)
Expand Down Expand Up @@ -114,11 +117,15 @@ PLATFORMS

DEPENDENCIES
coffee-rails (~> 3.2.1)
httparty
jquery-rails
pg
rails (= 3.2.13)
rails_12factor
rails_log_stdout
sass-rails (~> 3.2.3)
sqlite3
uglifier (>= 1.0.3)
unicorn

BUNDLED WITH
1.10.6
40 changes: 15 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## slack-map: A slack webhook for the Google Static Maps API
## slack-map: A slack slash command for the Google Static Maps API

slack-map lets you post static Google Maps images into your Slack instance. Request a map with a command like `map London` and an image of that location will be posted into your Slack channel along with a link to open the map in your browser.
slack-map lets you post static Google Maps images into your Slack instance. Request a map with a command like `/map London` and an image of that location will be posted into your Slack channel along with a link to open the map in your browser.

### Examples
### Examples

![Rome](https://slack-files.com/files-pub/T024F5NQC-F028EB7BH-760726/map_rome.png)
![221B Baker Street](https://slack-files.com/files-pub/T024F5NQC-F028EB86D-d3082a/map_sherlock.png)
Expand All @@ -13,39 +13,29 @@ slack-map lets you post static Google Maps images into your Slack instance. Requ

There are a few moving parts to get this integration set up for your Slack team. These steps assume some knowledge of Slack, git, and Heroku, though links to documentation have been provided where possible.

**1. Slack Incoming Webhook**

* Go to https://my.slack.com/services/new
* Add an Incoming Webhook.
* Expand the "Instructions for creating Incoming WebHooks" section.
* Copy the URL under "Sending Messages". It looks something like `http://[teamname].slack.com/services/hooks/incoming-webhook?token=[token]`. You'll need this in the next step.
* Save Settings

**2. Heroku App**
**1. Heroku App**

* Clone this git repo
* Create a file in your local copy of the repo called `config/local_env.yml`
* Paste your Incoming Webhook URL (from the last step) in the following format: `SLACK_WEBHOOK_URL: "https:/[teamname].slack.com/services/hooks/incoming-webhook?token=[token]"`. Save this file.
* Deploy your copy as a new app to Heroku (https://devcenter.heroku.com/articles/git)
* Get your heroku app URL (something like `http://appname.herokuapp.com/`). You'll need this in the next step.
* Set your Heroku config variable for the Incoming Webhook URL (https://devcenter.heroku.com/articles/config-vars): `heroku config:add SLACK_WEBHOOK_URL=https://[teamname].slack.com/services/hooks/incoming-webhook?token=[token]`
* You can test that the var was set correctly by running `heroku config`

_You could also host this Rails app anywhere web-accessible. There's no reason it needs to be on Heroku: it's just a free and easy place to host apps._

**3. Slack Outgoing Webhook**
**2. Slack Slash Command**

* Go to https://my.slack.com/services/new
* Add an Outgoing Webhook with the following settings:
- **Channel:** select a channel, (Any recommended)
- **Trigger Words:** map
- **URL(s):** `http://appname.herokuapp.com/map` (use your heroku app URL from step 2, making sure to add `/map` on to the end)
* Save Integration
* Go to https://slack.com/apps/A0F82E8CA-slash-commands
* Choose your team
* Click "Add Configuration"
* _Command:_ /map
* _URL:_ `http://appname.herokuapp.com/map` (the `/map` is important here. Don't forget it!)
* _Method:_ `POST`
* ... finish customizations to your liking
* Click "Save Integration"

**4. Use slack-map with the following commands and options**
**3. Use slack-map with the following commands and options**

map [location]

Options:

zoom=[0 to 21] # 0 is the whole Earth, 21 is a single building - default is 13 (roughly city-sized)
Expand Down
69 changes: 30 additions & 39 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,69 +1,60 @@
class ApplicationController < ActionController::Base

def static_map

# logger.info "Params: "
# logger.info params

# get params
command = params["text"] # something like "map Rome"
trigger = params["trigger_word"] # something like "map"
# trigger = params["trigger_word"] # something like "map"

# set param defaults
# docs:
# docs:
# https://developers.google.com/maps/documentation/staticmaps/?csw=1#MapTypes
# https://developers.google.com/maps/documentation/staticmaps/?csw=1#Zoomlevels
zoom = 13
maptype = "roadmap"

# regex params
zoom_regex = /zoom=\d+/
maptype_regex = /maptype=[a-z]+/

# match zoom=[0..21], where 0 is the entire Earth and 21 is an individual building
if command.match(zoom_regex)
zoom = command[zoom_regex]
zoom.gsub!("zoom=", "")
command.gsub!(zoom_regex, "")
end

# match maptype=[roadmap, satellite, terrain, hybrid]
# match maptype=[roadmap, satellite, terrain, hybrid]
if command.match(maptype_regex)
maptype = command[maptype_regex]
maptype.gsub!("maptype=", "")
command.gsub!(maptype_regex, "")
end

# strip trigger and assign to location
location = command.gsub!(trigger+" ", "")


# format payload
payload = {
"channel" => "##{params['channel_name']}",
"username" => "mapbot",
"text" => "A map of <https://www.google.com/maps/place/#{CGI.escape(location)}|#{location}> (<https://www.google.com/maps/place/#{CGI.escape(location)}|View on Google Maps>): <http://maps.googleapis.com/maps/api/staticmap?center=#{CGI.escape(location)}&zoom=#{zoom}&size=800x400&sensor=false&maptype=#{maptype}| >",
"icon_emoji" => ":earth_americas:"
location_params = {
center: command,
zoom: zoom,
size: '800x400',
sensor: false,
maptype: maptype
}

payload = {
"text" => "",
"attachments" => [{
"fallback" => "A map of #{command}.",
"title"=> "A map of #{command}",
"title_link"=> "https://www.google.com/maps/place/#{CGI.escape(command)}",
"image_url"=> "http://maps.googleapis.com/maps/api/staticmap?#{location_params.to_param}",
}]
}

post_to_slack(payload)

render :nothing => true

end

# posts a pre-formatted message to your Slack instance
def post_to_slack(payload)

# set your slack incoming webhook URL in local_env.yml (for local testing) and as a Heroku config variable (see README)
# it looks like "https://teamname.slack.com/services/hooks/incoming-webhook?token=[token]"

# post to slack
begin
response = HTTParty.post(ENV["SLACK_WEBHOOK_URL"], :body => { "payload" => payload.to_json })
rescue Timeout::Error => e
logger.info "Unable to post to Slack due to a Timeout"
rescue Exception => e
logger.info "Unable to post to Slack:"
logger.info e.inspect
end
# logger.info payload

render json: payload
end

end

end