Service API for Pearl, Downtown Grand Rapids Inc.'s website. Mantle provides a standardized interface for Pearl to access data from various endpoints providing event, business, and location information.
This repo follows the git-flow workflow using the default naming conventions. If you don't have gitflow installed you can get it here.
git flow init --defaults
Dependencies: postgresql 9.6.x
, ruby 2.1.4
To install Postgres, brew install [email protected]
. Follow any post-install instructions from homebrew.
To install Ruby, I suggest using rbenv via homebrew. Install it with brew install rbenv
. Then install the latest version of Ruby with rbenv install 2.1.4
. Confirm you're on the correct version of ruby (as specified by .ruby-version
) with rbenv version
. Finally, install Bundler with gem install bundler
.
Within the project's directory, start with this:
bundle install
cp .env.example .env
Update .env
with appropriate service tokens. Be sure to set MANTLE_USER
and MANTLE_PASS
. You'll need those credentials to access the API.
Setup a local database Heroku recommends running Postgres locally to ensure parity between environments.
Start postgresql in the foreground
pg_ctl -D /usr/local/var/[email protected] start
Check the latest postgresql production status
heroku pg:info
Import the latest production database into postgres via heroku pg:pull
heroku pg:pull HEROKU_POSTGRESQL_MAROON_URL dgri-mantle --app dgri-mantle
To run the Procfile-based app locally:
gem install foreman
foreman start
Alternatively, with heroku local: heroku local
- start postgresql if desired
postgres -D /usr/local/var/postgres
(assumes postgresql installed through homebrew) - rspec
bundle exec rspec
Pearl should assume that every location will be pulling from one service per content section (business attributes, events, photos, etc.).
This should allow an administrator of Pearl to determine which source provides the best information per location. For example, Facebook may provide the most accurate business information for Founders, while Foursquare provides the best data for Bartertown.
Mantle provides a standard interface to data per content section provided by a variety of outside services.
Mantle uses Basic Auth. Simply set MANTLE_USER
and MANTLE_PASS
to what you want and keep it a secret.
Location API returns a standardized JSON object of business information pulled from one of several difference services. The request must specify what service to pull from in the path. Currently, the services avaiable are Facebook and Foursquare, identified as facebook
and foursquare
, respectively.
Location API requests are construced as such: GET /location/:service/:service_id
. The service_id
is the UUID of the location provided by the particular service. Thus, the service_id
will vary depending on what service's data being requested.
An attribute will return nil
if the service does not provide the attribute, or if the attribute is not available for the requested location.
attribute | Foursquare | format | |
---|---|---|---|
address | ✅ | ✅ | |
latitude | ✅ | ✅ | |
longitude | ✅ | ✅ | |
phone | ✅ | ✅ | string "(xxx) xxx-xxxx" |
source_link | ✅ | ✅ | |
website | ✅ | ✅ | string "http://www.example.com" |
hours | ✅ | ✅ | array "Mon": ["9:00am-5:00pm", "7:00pm-11:00pm"] |
price_range | ✅ | ✅ | |
delivery | ✅ | ✅ | boolean |
outdoor | ✅ | ✅ | boolean |
cash_only | ✅ | ✅ | boolean |
kids | ✅ | ❌ | boolean |
takeout | ✅ | ✅ | boolean |
reserve | ✅ | ✅ | boolean |
tags | ✅ | ✅ | array |
cover_photo | ✅ | ❌ | |
primary_photo | ✅ | ❌ |
All services return the same flat JSON object of business information.
{ "location":
{
"address":"6 Jefferson Ave SE",
"latitude":42.962910271139,
"longitude":-85.664197952905,
"phone":"(616) 233-3219",
"source_link":"https://www.facebook.com/pages/Bartertown-Diner/175495679140580",
"website":"http://www.bartertowngr.com",
"hours": {
"Mon": ["11:00am-2:00am"],
"Tue": ["11:00am-2:00am"],
"Wed": ["11:00am-2:00am"],
"Thu": ["11:00am-2:00am"],
"Fri": ["11:00am-2:00am"],
"Sat": ["11:00am-2:00am"],
"Sun": ["12:00pm-0:00am"]
},
"price_range":"$ (0-10)",
"tags":["Breakfast & Brunch Restaurant","Vegetarian & Vegan Restaurant","Sandwich Shop","Breakfast","Coffee","Dinner","Lunch"],
"delivery":false,
"kids":false,
"outdoor":true,
"reserve":false,
"takeout":true,
"cash_only":false,
"cover_photo":"https://fbcdn-sphotos-f-a.akamaihd.net/cover_photo.jpg",
"primary_photo":"https://fbcdn-sphotos-f-a.akamaihd.net/photo_location.jpg"
}
}
GET /location/facebook/:id
id
is the UUID of the location's Facebook page. It can be either the unique numerical UUID like 175495679140580
or the custom UUID like foundersbrewing
.
GET /location/foursquare/:id
id
is the UUID of the location's Foursqure venue. It is an alphanumeric UUID similar to 4b12c269f964a5208b8d23e3
.
The Events API returns an arry of upcoming events for a given location. The location's ID is the ID from the outside service, similar to the Location API.
The returned external_id
is the event's UUID identified by the outside service. This attribute should be used to pair and update existing event records within Pearl.
attribute | GRNow | ExperienceGR | format | |
---|---|---|---|---|
event_name | ✅ | ✅ | ✅ | |
start_time | ✅ | ✅ | ✅ | timestamp midnight EDT if all day |
end_time | ✅ | ✅ | ✅ | timestamp optional |
external_id | ✅ | ✅ | ✅ | |
event_url | ❌ | ✅ | ✅ |
{
"events":[
{
"event_name":"REVEREND HORTON HEAT + Nekromantix + Whiskey Shivers @The Pyramid Scheme 6/10",
"start_time":1431057600,
"end_time":null,
"external_id":"1418539731769421",
"event_url":"http://www.grnow.com/some_event_path"
}
]
}
GET /events/facebook/:id
GET /events/grnow/:id
GET /events/experiencegr/:id
Note: the ExperienceGR endpoint accepts a venue's Listing ID
. Some venues have multiple Listing ID
s in ExperienceGR's database, with unique events per ID. Mantle will try to match the given venue with it's other IDs using a shared Account ID
. Not all Listing ID
s currently have an Account ID
returned by ExperienceGR's Listing endpoint, so not all events are guaranteed to be returned.
attribute | Foursquare | format | |
---|---|---|---|
photo_url | ✅ | ✅ | |
external_id | ✅ | ❌ | |
external_url | ✅ | ✅ |
{
"photos":[
{
"photo_url":"http://scontent-a.cdninstagram.com/hphotos-xaf1/t51.2885-15/e15/10963903_1383589831954534_537918980_n.jpg",
"external_id":"920420860022976241_917430474",
"external_url":"http://instagram.com/p/zF_eVFh27x/"
}
]
}
GET /photos/instagram/:id
Returns 5 most recent photos for a given Instagram user.
GET /photos/foursquare/:id
Returns 5 most highly rated photos for the given Foursquare venue.