Created
December 12, 2014 23:26
-
-
Save mberman84/3e596fe37a0b6eaa42ff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# new api | |
class Api < Grape::API | |
version 'v1' | |
format :json | |
use Rack::Timeout | |
rescue_from Rack::Timeout::RequestTimeoutError do |e| | |
NewRelic::Agent.instance.error_collector.notice_error e, | |
uri: env["api.endpoint"].request.path, | |
referer: env["api.endpoint"].request.referer, | |
request_params: env["api.endpoint"].request.params | |
Airbrake.notify e | |
rack_response({ error: "Request Timed Out" }.to_json, 503) | |
end | |
before do | |
logger.info "received API request with #{printable_params}" | |
authenticate! | |
end | |
after do | |
record_api_history! | |
"Success" | |
end | |
after_validation do | |
logger.info "validated #{api_function} company_id: #{company.id}" | |
end | |
helpers do | |
def ability | |
@ability = ApiAbility.new(company) | |
end | |
def customer | |
nil | |
end | |
def printable_params | |
params.except(:route_info).merge(token: token, client: client) | |
end | |
def saveable_params | |
params.except(:route_info) | |
end | |
def logger | |
Rails.logger | |
end | |
def token | |
headers['Token'] | |
end | |
def publishable_key | |
headers['Publishable_key'] | |
end | |
def client | |
headers['Client'] | |
end | |
def company | |
@company ||= Company.find_by_token(token) | |
end | |
def company_by_publishable_key | |
@company_by_publishable_key ||= Company.find_by_publishable_key(publishable_key) | |
end | |
def authenticate! | |
return error!('Bad Token', 401) unless company | |
return error!('Company inactive', 403) if company.inactive? | |
return error!('Company cancelled', 403) if company.cancelled? | |
return error!('No Active Subscription', 403) unless ability.company_is_paid_up? | |
return error!('Api Disabled For Company', 403) unless ability.can_access_api? | |
logger.info "authorized #{api_function} company_id: #{company.id} with token #{token}" | |
end | |
def record_api_history! | |
api_history = ApiHistory.new | |
api_history.params = saveable_params | |
api_history.api_function = api_function | |
api_history.company = company | |
api_history.customer = customer if customer.try(:persisted?) | |
api_history.client = client | |
api_history.save | |
logger.info "processed API #{api_function} company_id: #{company.id}, customer_id: #{customer.id if customer}" | |
end | |
def api_function | |
'not set' | |
end | |
end | |
# changes from /api_create_message | |
# send token in header 'Token: YOURTOKEN', instead of as a param | |
# do not base 64 encode properties | |
# example: | |
# curl http://localhost:3000/api/v1/customers -X POST \ | |
# -H 'token:3Z9L8xFjeNmXL7Yn-pFJUBoxkVWBbl5o' -H "Content-Type: application/json" \ | |
# -d '{"phone_number": "5555555555", "email": "user@example.com", "first_name": "john", "last_name": "doe", "properties": {"property1": "whateverthismeans"}}' | |
resource :customers do | |
helpers do | |
def customer_phone_number | |
@phone ||= Helper.format_phone_number(params[:phone_number]) | |
end | |
def customer | |
return error!('Malformed Phone Number', 403) if customer_phone_number.nil? | |
@customer ||= company.customers.find_or_initialize_by(customer_phone_number: customer_phone_number) | |
end | |
def api_function | |
'v1/customers POST' | |
end | |
end | |
desc "Add a new customer. Or update the customer if one already exists with that phone number." | |
params do | |
requires :phone_number, type: String, desc: "The customer's phone number (format: 2345678901)" | |
optional :email, type: String, desc: "The customer's email address" | |
optional :first_name, type: String, desc: "The customer's first name" | |
optional :last_name, type: String, desc: "The customer's last name" | |
optional :properties, type: Hash, desc: "Arbitrary properties to record about the customer" | |
end | |
post do | |
return error!('Trial Customer Limit Reached', 403) if company.active_trial? && !TrialChecker.new(company).within_customer_limit? | |
return error!('Forbidden', 403) unless ability.can?(:create, customer) | |
options = { | |
automated_replies: params['automated_replies'], | |
properties: params['properties'], | |
customer_phone_number: customer_phone_number, | |
company_id: company.id | |
} | |
customer.first_name = params['first_name'] if params['first_name'] | |
customer.last_name = params['last_name'] if params['last_name'] | |
customer.email = params['email'] if params['email'] | |
customer.via_api = true | |
if customer.valid? | |
UpdateCustomerWorker.perform_async(customer.attributes, options) | |
status 201 | |
serializer = ApiCustomerSerializer.new(customer) | |
if properties = params['properties'] | |
serializer.properties = properties | |
end | |
serializer | |
else | |
return error!('Customer invalid', 422) | |
end | |
end | |
end | |
resource :phone_numbers do | |
helpers do | |
def authenticate! | |
return error!('Bad Token', 401) unless company_by_publishable_key | |
return error!('Company inactive', 403) if company_by_publishable_key.inactive? | |
return error!('Company cancelled', 403) if company_by_publishable_key.cancelled? | |
return error!('No Active Subscription', 403) unless ability.company_is_paid_up? | |
return error!('Api Disabled For Company', 403) unless ability.can_access_api? | |
logger.info "authorized #{api_function} company_id: #{company_by_publishable_key.id} with publishable_key #{publishable_key}" | |
end | |
end | |
desc "Get an available phone number" | |
get :available do | |
company_by_publishable_key.open_phone_number_digits | |
end | |
end | |
# changes from /api_create_message | |
# send token in header 'Token: YOURTOKEN', instead of as a param | |
# example: | |
# curl http://localhost:3000/api/v1/messages -X POST \ | |
# -H 'token:YOURTOKEN' -H "Content-Type: application/json" \ | |
# -d '{"text": "hi there", "to": "5555555555"}' | |
resource :messages do | |
helpers do | |
def customer_phone_number | |
Helper.format_phone_number(params[:to]) | |
end | |
def message_text | |
params['text'] | |
end | |
def customer | |
return error!('Malformed Phone Number', 403) if customer_phone_number.nil? | |
begin | |
@customer ||= company.customers.find_or_create_by(customer_phone_number: customer_phone_number) | |
rescue ActiveRecord::RecordNotUnique => error | |
# Try again | |
@customer ||= company.customers.find_by(customer_phone_number: customer_phone_number) | |
end | |
end | |
def api_function | |
'v1/messages POST' | |
end | |
end | |
desc "Send a message" | |
params do | |
requires :text, type: String, desc: "The message to be sent" | |
requires :to, type: String, | |
desc: "The recipient's phone number. A customer will be created with this number if not found." | |
end | |
post do | |
return error!('Trial Message Limit Reached', 403) if company.active_trial? && !TrialChecker.new(company).within_message_limit? | |
return error!('Forbidden', 403) unless ability.can?(:create, Message) | |
if customer.subscribed | |
status 202 | |
MessageService.save_and_send_from_api( | |
customer_id: customer.id, | |
full_text: message_text, | |
company_id: company.id, | |
user_id: company.admin.id | |
) | |
{ to: params[:to], text: message_text, status: 'queued' } | |
else | |
status 200 | |
{ to: params[:to], text: message_text, status: 'unsubscribed' } | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment