class Helpscout::API MAILBOXES = 'mailboxes' CONVERSATIONS = 'conversations' TAGS = 'tags' FIELDS = 'fields' CUSTOMERS = 'customers' PHONES = 'phones' OAUTH2_TOKEN = 'oauth2/token' def ready? required_secrets = [ Rails.application.secrets.helpscout[:mailbox_id], Rails.application.secrets.helpscout[:client_id], Rails.application.secrets.helpscout[:client_secret] ] required_secrets.all?(&:present?) end 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 def add_phone_number(email, phone) query = URI.encode("(email:#{email})") response = call_api(:get, "#{CUSTOMERS}?mailbox=#{mailbox_id}&query=#{query}") if response.success? body = parse_response_body(response) if body[:page][:totalElements] > 0 customer_id = body[:_embedded][:customers].first[:id] call_api(:post, "#{CUSTOMERS}/#{customer_id}/#{PHONES}", { type: "work", value: phone }) end end end def conversations_report(year, month) Rails.logger.info("[HelpScout API] Retrieving conversations report for #{month}-#{year}…") params = { start: Time.utc(year, month).iso8601, end: Time.utc(year, month).next_month.iso8601 } response = call_api(:get, 'reports/conversations?' + params.to_query) if !response.success? raise StandardError, "Error while fetching conversation report: #{response.response_code} '#{response.body}'" end parse_response_body(response) 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