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…
Add table
Reference in a new issue