Add helpscout API adapter
This commit is contained in:
parent
c1bdb8a4be
commit
6453b53a41
3 changed files with 259 additions and 0 deletions
133
app/lib/helpscout/api.rb
Normal file
133
app/lib/helpscout/api.rb
Normal file
|
@ -0,0 +1,133 @@
|
|||
class Helpscout::API
|
||||
MAILBOXES = 'mailboxes'
|
||||
CONVERSATIONS = 'conversations'
|
||||
TAGS = 'tags'
|
||||
FIELDS = 'fields'
|
||||
OAUTH2_TOKEN = 'oauth2/token'
|
||||
|
||||
def add_tags(conversation_id, tags)
|
||||
call_api(:put, "#{CONVERSATIONS}/#{conversation_id}/#{TAGS}", {
|
||||
tags: tags
|
||||
})
|
||||
end
|
||||
|
||||
def add_custom_fields(conversation_id, dossier_id, browser)
|
||||
body = {
|
||||
'Dossier ID': dossier_id,
|
||||
'Browser': browser
|
||||
}.compact.map do |key, value|
|
||||
{ id: custom_fields[key], value: value }
|
||||
end
|
||||
|
||||
call_api(:put, "#{CONVERSATIONS}/#{conversation_id}/#{FIELDS}", { fields: body })
|
||||
end
|
||||
|
||||
def create_conversation(email, subject, text, file)
|
||||
body = {
|
||||
subject: subject,
|
||||
customer: customer(email),
|
||||
mailboxId: mailbox_id,
|
||||
type: 'email',
|
||||
status: 'active',
|
||||
threads: [
|
||||
{
|
||||
type: 'customer',
|
||||
customer: customer(email),
|
||||
text: text,
|
||||
attachments: attachments(file)
|
||||
}
|
||||
]
|
||||
}.compact
|
||||
|
||||
call_api(:post, CONVERSATIONS, body)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def attachments(file)
|
||||
if file.present?
|
||||
[
|
||||
{
|
||||
fileName: file.original_filename,
|
||||
mimeType: file.content_type,
|
||||
data: Base64.strict_encode64(file.read)
|
||||
}
|
||||
]
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def customer(email)
|
||||
{
|
||||
email: email
|
||||
}
|
||||
end
|
||||
|
||||
def custom_fields
|
||||
@custom_fields ||= get_custom_fields.reduce({}) do |fields, field|
|
||||
fields[field[:name].to_sym] = field[:id]
|
||||
fields
|
||||
end
|
||||
end
|
||||
|
||||
def get_custom_fields
|
||||
parse_response_body(fetch_custom_fields)[:_embedded][:fields]
|
||||
end
|
||||
|
||||
def fetch_custom_fields
|
||||
call_api(:get, "#{MAILBOXES}/#{mailbox_id}/#{FIELDS}")
|
||||
end
|
||||
|
||||
def call_api(method, path, body = nil)
|
||||
url = "#{HELPSCOUT_API_URL}/#{path}"
|
||||
|
||||
case method
|
||||
when :get
|
||||
Typhoeus.get(url, {
|
||||
headers: headers
|
||||
})
|
||||
when :post
|
||||
Typhoeus.post(url, {
|
||||
body: body.to_json,
|
||||
headers: headers
|
||||
})
|
||||
when :put
|
||||
Typhoeus.put(url, {
|
||||
body: body.to_json,
|
||||
headers: headers
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
def parse_response_body(response)
|
||||
JSON.parse(response.body, symbolize_names: true)
|
||||
end
|
||||
|
||||
def mailbox_id
|
||||
Rails.application.secrets.helpscout[:mailbox_id]
|
||||
end
|
||||
|
||||
def headers
|
||||
{
|
||||
'Authorization': "Bearer #{access_token}",
|
||||
'Content-Type': 'application/json; charset=UTF-8'
|
||||
}
|
||||
end
|
||||
|
||||
def access_token
|
||||
@access_token ||= get_access_token
|
||||
end
|
||||
|
||||
def get_access_token
|
||||
parse_response_body(fetch_access_token)[:access_token]
|
||||
end
|
||||
|
||||
def fetch_access_token
|
||||
Typhoeus.post("#{HELPSCOUT_API_URL}/#{OAUTH2_TOKEN}", body: {
|
||||
grant_type: 'client_credentials',
|
||||
client_id: Rails.application.secrets.helpscout[:client_id],
|
||||
client_secret: Rails.application.secrets.helpscout[:client_secret]
|
||||
})
|
||||
end
|
||||
end
|
56
app/lib/helpscout/form_adapter.rb
Normal file
56
app/lib/helpscout/form_adapter.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
class Helpscout::FormAdapter
|
||||
attr_reader :params
|
||||
|
||||
def initialize(params = {}, api = nil)
|
||||
@params = params
|
||||
@api = api || Helpscout::API.new
|
||||
end
|
||||
|
||||
TYPE_INFO = 'info demarche'
|
||||
TYPE_PERDU = 'usager perdu'
|
||||
TYPE_INSTRUCTION = 'info instruction'
|
||||
TYPE_AMELIORATION = 'produit'
|
||||
TYPE_AUTRE = 'autre'
|
||||
|
||||
OPTIONS = [
|
||||
[I18n.t(TYPE_INFO, scope: [:support]), TYPE_INFO],
|
||||
[I18n.t(TYPE_PERDU, scope: [:support]), TYPE_PERDU],
|
||||
[I18n.t(TYPE_INSTRUCTION, scope: [:support]), TYPE_INSTRUCTION],
|
||||
[I18n.t(TYPE_AMELIORATION, scope: [:support]), TYPE_AMELIORATION],
|
||||
[I18n.t(TYPE_AUTRE, scope: [:support]), TYPE_AUTRE]
|
||||
]
|
||||
|
||||
def send_form
|
||||
conversation_id = create_conversation
|
||||
|
||||
if conversation_id.present?
|
||||
add_tags(conversation_id)
|
||||
add_custom_fields(conversation_id)
|
||||
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_tags(conversation_id)
|
||||
@api.add_tags(conversation_id, params[:tags])
|
||||
end
|
||||
|
||||
def add_custom_fields(conversation_id)
|
||||
@api.add_custom_fields(conversation_id, params[:dossier_id], params[:browser])
|
||||
end
|
||||
|
||||
def create_conversation
|
||||
response = @api.create_conversation(
|
||||
params[:email],
|
||||
params[:subject],
|
||||
params[:text],
|
||||
params[:file]
|
||||
)
|
||||
|
||||
response.success? ? response.headers['Resource-ID'] : nil
|
||||
end
|
||||
end
|
70
spec/lib/helpscout/form_adapter_spec.rb
Normal file
70
spec/lib/helpscout/form_adapter_spec.rb
Normal file
|
@ -0,0 +1,70 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Helpscout::FormAdapter do
|
||||
describe '#send_form' do
|
||||
let(:api) { spy(double(:api)) }
|
||||
|
||||
context 'create_conversation' do
|
||||
before do
|
||||
allow(api).to receive(:create_conversation)
|
||||
.and_return(double(success?: false))
|
||||
described_class.new(params, api).send_form
|
||||
end
|
||||
|
||||
let(:params) {
|
||||
{
|
||||
email: email,
|
||||
subject: subject,
|
||||
text: text
|
||||
}
|
||||
}
|
||||
let(:email) { 'paul.chavard@beta.gouv.fr' }
|
||||
let(:subject) { 'Bonjour' }
|
||||
let(:text) { "J'ai un problem" }
|
||||
|
||||
it 'should call method' do
|
||||
expect(api).to have_received(:create_conversation)
|
||||
.with(email, subject, text, nil)
|
||||
end
|
||||
end
|
||||
|
||||
context 'add_tags' do
|
||||
before do
|
||||
allow(api).to receive(:create_conversation)
|
||||
.and_return(
|
||||
double(
|
||||
success?: true,
|
||||
headers: {
|
||||
'Resource-ID' => conversation_id
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
described_class.new(params, api).send_form
|
||||
end
|
||||
|
||||
let(:params) {
|
||||
{
|
||||
email: email,
|
||||
subject: subject,
|
||||
text: text,
|
||||
tags: tags
|
||||
}
|
||||
}
|
||||
let(:email) { 'paul.chavard@beta.gouv.fr' }
|
||||
let(:subject) { 'Bonjour' }
|
||||
let(:text) { "J'ai un problem" }
|
||||
let(:tags) { ['info demarche'] }
|
||||
let(:conversation_id) { '123' }
|
||||
|
||||
it 'should call method' do
|
||||
expect(api).to have_received(:create_conversation)
|
||||
.with(email, subject, text, nil)
|
||||
expect(api).to have_received(:add_tags)
|
||||
.with(conversation_id, tags)
|
||||
expect(api).to have_received(:add_custom_fields)
|
||||
.with(conversation_id, nil, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue