Skip to content

Instantly share code, notes, and snippets.

@eskfung
Last active July 13, 2022 06:44
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eskfung/587a810d925d30064a35 to your computer and use it in GitHub Desktop.
Save eskfung/587a810d925d30064a35 to your computer and use it in GitHub Desktop.
KISSmetrics' use of Help Scout's dynamic apps. http://developer.helpscout.net/custom-apps/
require 'json'
require 'base64'
require 'hmac-sha1'
require 'httparty'
require 'models/user'
require 'app_config'
class HelpScout
def initialize(auth_options={:basic_auth => {:username => AppConfig.default.helpscout["api_key"],
:password => "X"}})
@auth_options = auth_options
end
# Takes the conversation object that Help Scout posts and returns the User with the given email
# http://developer.helpscout.net/objects/conversation/
# http://developer.helpscout.net/custom-apps/
#
# @param body [String] a JSON message containing conversation data
# @return [User] the User corresponding to the email address found, if any
def parse_message_for_user(body)
content = JSON.parse(body)
if content['customer'] && content['customer']['email']
customer_email = content['customer']['email']
end
User[:login => customer_email]
end
# Compares X-HelpScout-Signature against the signature generated from the secret key and request body
# http://developer.helpscout.net/webhooks/
#
# @param body [String] a JSON message containing conversation data
# @param header_signature [String] the computed X-HelpScout-Signature header
# @return [Boolean] whether the signatures match
def valid_signature?(body, header_signature)
generate_body_signature(body) == header_signature.strip
end
private
def generate_body_signature(body)
hmac = HMAC::SHA1.new( AppConfig.default.helpscout["webhook_secret"] )
hmac.update(body)
signature = Base64.encode64(hmac.digest).strip
end
def build_helpscout_convo_request(number)
HTTParty.get("https://api.helpscout.net/v1/conversations/#{number}.json", @auth_options)
end
end
require 'models/helpscout'
post '/admin.helpscout.dynamic' do
body = request.body.read
helpscout = HelpScout.new
if helpscout.valid_signature?(body, env['HTTP_X_HELPSCOUT_SIGNATURE'])
if @user = helpscout.parse_message_for_user(body)
response = {:html => erubis(:'admin/support_issues/_helpscout_sidebar.html', :layout => false)}
else
response = {:html => "Can't find this user."}
end
status(200)
body(response.to_json)
else
response = {:html => "Signature not verified."}
status(403)
body(response.to_json)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment