From 82805e4477a5b6141b510fd53b10dda037d13fd8 Mon Sep 17 00:00:00 2001 From: Matthew Rider Date: Thu, 24 Oct 2024 12:41:34 +0200 Subject: [PATCH] Fix create templates job failing on first run (#2061) Fixes #2044 The first time the job is run the three_sixty_dialog_client_waba_account_id is nil so it calls the fetch_client_info method. This method successfully updates the organization, but as it's the last line of the method it saves the return of the update `true` to the local variable that is used in the url to create the templates. This results in an error. Subsequent times it's ran it does not error because it uses the value of the organization's attribute, which is the correct value. --- .rubocop.yml | 6 +- .../three_sixty_dialog_inbound.rb | 4 +- .../three_sixty_dialog_outbound.rb | 13 +- app/jobs/whats_app_adapter/create_api_key.rb | 3 +- .../whats_app_adapter/create_templates.rb | 154 ----------------- .../create_templates_job.rb | 70 ++++++++ .../create_welcome_message_template_job.rb | 54 +----- app/services/application_service.rb | 7 + .../file_fetcher_service.rb | 4 +- .../template_creator_service.rb | 41 +++++ .../template_fetcher_service.rb | 25 +-- .../token_fetcher_service.rb | 4 +- .../three_sixty_dialog_outbound_spec.rb | 13 +- .../create_templates_job_spec.rb | 38 +++++ ...reate_welcome_message_template_job_spec.rb | 17 +- spec/requests/onboarding/whats_app_spec.rb | 13 +- .../file_fetcher_service_spec.rb | 2 +- spec/vcr_setup.rb | 1 - .../three_sixty_dialog_create_template.yml | 108 ++++++++++++ ...e_sixty_dialog_welcome_message_created.yml | 160 +++++------------- 20 files changed, 346 insertions(+), 391 deletions(-) delete mode 100644 app/jobs/whats_app_adapter/create_templates.rb create mode 100644 app/jobs/whats_app_adapter/three_sixty_dialog/create_templates_job.rb create mode 100644 app/services/application_service.rb create mode 100644 app/services/whats_app_adapter/three_sixty_dialog/template_creator_service.rb create mode 100644 spec/jobs/whats_app_adapter/three_sixty_dialog/create_templates_job_spec.rb create mode 100644 vcr_cassettes/three_sixty_dialog_create_template.yml diff --git a/.rubocop.yml b/.rubocop.yml index 456d96524..02858f0d5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -27,4 +27,8 @@ Metrics/PerceivedComplexity: Metrics/AbcSize: Exclude: - - 'db/data/**' \ No newline at end of file + - 'db/data/**' + +Lint/MissingSuper: + Exclude: + - 'app/services/**/*.rb' \ No newline at end of file diff --git a/app/adapters/whats_app_adapter/three_sixty_dialog_inbound.rb b/app/adapters/whats_app_adapter/three_sixty_dialog_inbound.rb index 716a6f7ad..f473aa430 100644 --- a/app/adapters/whats_app_adapter/three_sixty_dialog_inbound.rb +++ b/app/adapters/whats_app_adapter/three_sixty_dialog_inbound.rb @@ -96,10 +96,10 @@ def initialize_file(whats_app_message) content_type = message_file[:mime_type] file_id = message_file[:id] filename = message_file[:filename] || file_id - file_fetcher = WhatsAppAdapter::ThreeSixtyDialog::FileFetcherService.new(organization_id: organization.id, file_id: file_id) + external_file = WhatsAppAdapter::ThreeSixtyDialog::FileFetcherService.call(organization_id: organization.id, file_id: file_id) file.attachment.attach( - io: StringIO.new(file_fetcher.call), + io: StringIO.new(external_file), filename: filename, content_type: content_type, identify: false diff --git a/app/adapters/whats_app_adapter/three_sixty_dialog_outbound.rb b/app/adapters/whats_app_adapter/three_sixty_dialog_outbound.rb index bb490958f..e9fe33760 100644 --- a/app/adapters/whats_app_adapter/three_sixty_dialog_outbound.rb +++ b/app/adapters/whats_app_adapter/three_sixty_dialog_outbound.rb @@ -183,18 +183,7 @@ def welcome_message_payload(recipient, organization) policy: 'deterministic', code: 'de' }, - name: "welcome_message_#{organization.project_name.parameterize.underscore}", - components: [ - { - type: 'body', - parameters: [ - { - type: 'text', - text: organization.project_name - } - ] - } - ] + name: "welcome_message_#{organization.project_name.parameterize.underscore}" } } end diff --git a/app/jobs/whats_app_adapter/create_api_key.rb b/app/jobs/whats_app_adapter/create_api_key.rb index eb2b1b164..9313d4900 100644 --- a/app/jobs/whats_app_adapter/create_api_key.rb +++ b/app/jobs/whats_app_adapter/create_api_key.rb @@ -16,6 +16,7 @@ def perform(organization_id:, channel_id:) url = URI.parse( "#{base_uri}/partners/#{partner_id}/channels/#{channel_id}/api_keys" ) + headers = { Accept: 'application/json', 'Content-Type': 'application/json', @@ -39,7 +40,7 @@ def handle_response(response) Rails.logger.debug api_key organization.update!(three_sixty_dialog_client_api_key: api_key) WhatsAppAdapter::SetWebhookUrl.perform_later(organization_id: organization.id) - WhatsAppAdapter::CreateTemplates.perform_later(organization_id: organization.id, token: token) + WhatsAppAdapter::ThreeSixtyDialog::CreateTemplatesJob.perform_later(organization_id: organization.id) when Net::HTTPClientError, Net::HTTPServerError exception = WhatsAppAdapter::ThreeSixtyDialogError.new(error_code: response.code, message: response.body) ErrorNotifier.report(exception) diff --git a/app/jobs/whats_app_adapter/create_templates.rb b/app/jobs/whats_app_adapter/create_templates.rb deleted file mode 100644 index 854f70c8b..000000000 --- a/app/jobs/whats_app_adapter/create_templates.rb +++ /dev/null @@ -1,154 +0,0 @@ -# frozen_string_literal: true - -require 'net/http' - -module WhatsAppAdapter - class CreateTemplates < ApplicationJob - def perform(organization_id:, token:) - @organization = Organization.find_by(id: organization_id) - return unless organization - - @base_uri = ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693') - @partner_id = ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_ID', nil) - @token = token - @waba_account_id = organization.three_sixty_dialog_client_waba_account_id - @waba_account_id = fetch_client_info if waba_account_id.blank? || organization.three_sixty_dialog_whats_app_template_namespace.blank? - existing_templates = WhatsAppAdapter::ThreeSixtyDialog::TemplateFetcherService.new( - waba_account_id: waba_account_id, - token: token - ).call - templates_to_create_array = whats_app_templates.keys.difference(existing_templates) - templates_to_create = whats_app_templates.select { |key, _value| key.in?(templates_to_create_array) } - templates_to_create.each do |key, value| - @template_name = key - @template_text = value - - create_template - end - end - - attr_reader :organization, :base_uri, :partner_id, :template_name, :template_text, :token, :waba_account_id - - private - - # rubocop:disable Style/FormatStringToken - def whats_app_templates - default_welcome_message = ["*#{File.read(File.join('config', 'locales', 'onboarding', 'success_heading.txt'))}*", - File.read(File.join('config', 'locales', 'onboarding', - 'success_text.txt'))].join("\n\n").gsub('100eyes', '{{1}}') - default_welcome_message_hash = { default_welcome_message: default_welcome_message } - requests_hash = I18n.t('.')[:adapter][:whats_app][:request_template].transform_values do |value| - value.gsub('%{first_name}', '{{1}}').gsub('%{request_title}', '{{2}}') - end - default_welcome_message_hash.merge(requests_hash) - end - # rubocop:enable Style/FormatStringToken - - def create_template - url = URI.parse( - "#{base_uri}/partners/#{partner_id}/waba_accounts/#{waba_account_id}/waba_templates" - ) - headers = set_headers - - request = Net::HTTP::Post.new(url.to_s, headers) - payload = template_name.match?(/welcome_message/) ? welcome_message_template_payload : new_request_template_payload - request.body = payload.to_json - response = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http| - http.request(request) - end - handle_response(response) - end - - def set_headers - { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: "Bearer #{token}" - } - end - - def fetch_client_info - url = URI.parse("#{base_uri}/partners/#{partner_id}/channels") - headers = set_headers - request = Net::HTTP::Get.new(url.to_s, headers) - response = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http| - http.request(request) - end - channels_array = JSON.parse(response.body)['partner_channels'] - client_hash = channels_array.find { |hash| hash['client']['id'] == organization.three_sixty_dialog_client_id } - waba_account = client_hash['waba_account'] - organization.update!(three_sixty_dialog_whats_app_template_namespace: waba_account['namespace'], - three_sixty_dialog_client_waba_account_id: waba_account['id']) - end - - # rubocop:disable Metrics/MethodLength - def new_request_template_payload - { - name: template_name, - category: 'MARKETING', - components: [ - { - type: 'BODY', - text: template_text, - example: { - body_text: [ - [ - 'Jakob', - 'Familie und Freizeit' - ] - ] - } - }, - { - type: 'BUTTONS', - buttons: [ - { - type: 'QUICK_REPLY', - text: 'Antworten' - }, - { - type: 'QUICK_REPLY', - text: 'Mehr Infos' - } - ] - } - ], - language: 'de', - allow_category_change: true - } - end - # rubocop:enable Metrics/MethodLength - - def welcome_message_template_payload - { - name: template_name, - category: 'MARKETING', - components: [ - { - type: 'BODY', - text: template_text, - example: { - body_text: [ - ['100eyes'] - ] - } - } - ], - language: 'de', - allow_category_change: true - } - end - - def handle_response(response) - case response - when Net::HTTPSuccess - Rails.logger.debug 'Great!' - when Net::HTTPClientError, Net::HTTPServerError - return if response.body.match?(/you have provided is already in use. Please choose a different name for your template./) - - exception = WhatsAppAdapter::ThreeSixtyDialogError.new(error_code: response.code, message: response.body) - ErrorNotifier.report(exception) - end - end - end -end diff --git a/app/jobs/whats_app_adapter/three_sixty_dialog/create_templates_job.rb b/app/jobs/whats_app_adapter/three_sixty_dialog/create_templates_job.rb new file mode 100644 index 000000000..e84004062 --- /dev/null +++ b/app/jobs/whats_app_adapter/three_sixty_dialog/create_templates_job.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require 'net/http' + +module WhatsAppAdapter + module ThreeSixtyDialog + class CreateTemplatesJob < ApplicationJob + def perform(organization_id:) + organization = Organization.find(organization_id) + + existing_templates = WhatsAppAdapter::ThreeSixtyDialog::TemplateFetcherService.call(organization_id: organization.id) + + templates_to_create_array = whats_app_templates.keys.difference(existing_templates) + templates_to_create = whats_app_templates.select { |key, _value| key.in?(templates_to_create_array) } + templates_to_create.each do |key, value| + WhatsAppAdapter::ThreeSixtyDialog::TemplateCreatorService.call(organization_id: organization.id, + payload: new_request_template_payload(key, value)) + end + end + + private + + # rubocop:disable Style/FormatStringToken + def whats_app_templates + I18n.t('.')[:adapter][:whats_app][:request_template].transform_values do |value| + value.gsub('%{first_name}', '{{1}}').gsub('%{request_title}', '{{2}}') + end + end + # rubocop:enable Style/FormatStringToken + + # rubocop:disable Metrics/MethodLength + def new_request_template_payload(template_name, template_text) + { + name: template_name, + category: 'MARKETING', + components: [ + { + type: 'BODY', + text: template_text, + example: { + body_text: [ + [ + 'Jakob', + 'Familie und Freizeit' + ] + ] + } + }, + { + type: 'BUTTONS', + buttons: [ + { + type: 'QUICK_REPLY', + text: 'Antworten' + }, + { + type: 'QUICK_REPLY', + text: 'Mehr Infos' + } + ] + } + ], + language: 'de', + allow_category_change: true + } + end + # rubocop:enable Metrics/MethodLength + end + end +end diff --git a/app/jobs/whats_app_adapter/three_sixty_dialog/create_welcome_message_template_job.rb b/app/jobs/whats_app_adapter/three_sixty_dialog/create_welcome_message_template_job.rb index bcba52cce..6aef313c6 100644 --- a/app/jobs/whats_app_adapter/three_sixty_dialog/create_welcome_message_template_job.rb +++ b/app/jobs/whats_app_adapter/three_sixty_dialog/create_welcome_message_template_job.rb @@ -7,23 +7,19 @@ module ThreeSixtyDialog class CreateWelcomeMessageTemplateJob < ApplicationJob def perform(organization_id:) @organization = Organization.find_by(id: organization_id) - @token = WhatsAppAdapter::ThreeSixtyDialog::TokenFetcherService.call - @base_uri = ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693') - @partner_id = ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_ID', nil) - @waba_account_id = organization.three_sixty_dialog_client_waba_account_id - existing_templates = WhatsAppAdapter::ThreeSixtyDialog::TemplateFetcherService.new( - waba_account_id: waba_account_id, - token: token - ).call + @base_uri = ENV.fetch('THREE_SIXTY_DIALOG_WHATS_APP_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693') + existing_templates = WhatsAppAdapter::ThreeSixtyDialog::TemplateFetcherService.call(organization_id: organization.id) + if "welcome_message_#{organization.project_name.parameterize.underscore}".in?(existing_templates) notify_admin_to_update_existing_template else - create_welcome_message_template + WhatsAppAdapter::ThreeSixtyDialog::TemplateCreatorService.call(organization_id: organization.id, + payload: welcome_message_template_payload) end end - attr_reader :organization, :token, :base_uri, :partner_id, :waba_account_id + attr_reader :organization, :base_uri private @@ -31,25 +27,6 @@ def notify_admin_to_update_existing_template User.admin.find_each { |admin| PostmarkAdapter::Outbound.welcome_message_updated!(admin, organization) } end - def create_welcome_message_template - url = URI.parse( - "#{base_uri}/partners/#{partner_id}/waba_accounts/#{waba_account_id}/waba_templates" - ) - headers = { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: "Bearer #{token}" - } - - request = Net::HTTP::Post.new(url.to_s, headers) - payload = welcome_message_template_payload - request.body = payload.to_json - response = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http| - http.request(request) - end - handle_response(response) - end - def welcome_message_template_payload { name: "welcome_message_#{organization.project_name.parameterize.underscore}", @@ -57,30 +34,13 @@ def welcome_message_template_payload components: [ { type: 'BODY', - text: ["*#{organization.onboarding_success_heading}*", organization.onboarding_success_text].join("\n\n").gsub( - organization.project_name.to_s, '{{1}}' - ), - example: { - body_text: [ - ['100eyes'] - ] - } + text: ["*#{organization.onboarding_success_heading}*", organization.onboarding_success_text].join("\n\n") } ], language: 'de', allow_category_change: true } end - - def handle_response(response) - case response - when Net::HTTPSuccess - WhatsAppTemplateCreated.with(organization_id: organization.id).deliver_later(organization.users + User.admin.all) - when Net::HTTPClientError, Net::HTTPServerError - exception = WhatsAppAdapter::ThreeSixtyDialogError.new(error_code: response.code, message: response.body) - ErrorNotifier.report(exception) - end - end end end end diff --git a/app/services/application_service.rb b/app/services/application_service.rb new file mode 100644 index 000000000..48c328eb3 --- /dev/null +++ b/app/services/application_service.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class ApplicationService + def self.call(...) + new(...).call + end +end diff --git a/app/services/whats_app_adapter/three_sixty_dialog/file_fetcher_service.rb b/app/services/whats_app_adapter/three_sixty_dialog/file_fetcher_service.rb index f6c14276f..327fb8412 100644 --- a/app/services/whats_app_adapter/three_sixty_dialog/file_fetcher_service.rb +++ b/app/services/whats_app_adapter/three_sixty_dialog/file_fetcher_service.rb @@ -2,7 +2,7 @@ module WhatsAppAdapter module ThreeSixtyDialog - class FileFetcherService + class FileFetcherService < ApplicationService class FetchError < StandardError; end attr_reader :organization, :base_uri, :headers, :file_id @@ -33,7 +33,7 @@ def call def fetch_streamable_file(media_url) url = URI::HTTPS.build(host: base_uri.hostname, path: base_uri.path + media_url.path, query: media_url.query) - request = Net::HTTP::Get.new(url.to_s, headers) + request = Net::HTTP::Get.new(url, headers) response = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http| http.request(request) end diff --git a/app/services/whats_app_adapter/three_sixty_dialog/template_creator_service.rb b/app/services/whats_app_adapter/three_sixty_dialog/template_creator_service.rb new file mode 100644 index 000000000..f6467c954 --- /dev/null +++ b/app/services/whats_app_adapter/three_sixty_dialog/template_creator_service.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module WhatsAppAdapter + module ThreeSixtyDialog + class TemplateCreatorService < ApplicationService + def initialize(organization_id:, payload:) + @organization = Organization.find(organization_id) + @base_uri = ENV.fetch('THREE_SIXTY_DIALOG_WHATS_APP_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693') + @payload = payload + end + + attr_reader :base_uri, :organization, :payload + + def call + url = URI.parse("#{base_uri}/v1/configs/templates") + headers = { 'D360-API-KEY' => organization.three_sixty_dialog_client_api_key, 'Content-Type' => 'application/json' } + + request = Net::HTTP::Post.new(url, headers) + request.body = payload.to_json + response = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http| + http.request(request) + end + handle_response(response) + end + + private + + def handle_response(response) + case response + when Net::HTTPSuccess + WhatsAppTemplateCreated.with(organization_id: organization.id).deliver_later(organization.users + User.admin.all) + when Net::HTTPClientError, Net::HTTPServerError + return if response.body.match?(/you have provided is already in use. Please choose a different name for your template./) + + exception = WhatsAppAdapter::ThreeSixtyDialogError.new(error_code: response.code, message: response.body) + ErrorNotifier.report(exception) + end + end + end + end +end diff --git a/app/services/whats_app_adapter/three_sixty_dialog/template_fetcher_service.rb b/app/services/whats_app_adapter/three_sixty_dialog/template_fetcher_service.rb index 197eb528a..293740be0 100644 --- a/app/services/whats_app_adapter/three_sixty_dialog/template_fetcher_service.rb +++ b/app/services/whats_app_adapter/three_sixty_dialog/template_fetcher_service.rb @@ -2,26 +2,19 @@ module WhatsAppAdapter module ThreeSixtyDialog - class TemplateFetcherService - def initialize(waba_account_id:, token:) - @base_uri = ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693') - @partner_id = ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_ID', nil) - @waba_account_id = waba_account_id - @token = token + class TemplateFetcherService < ApplicationService + def initialize(organization_id:) + @organization = Organization.find(organization_id) + @base_uri = ENV.fetch('THREE_SIXTY_DIALOG_WHATS_APP_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693') end - attr_reader :base_uri, :partner_id, :waba_account_id, :token + attr_reader :base_uri, :organization def call - url = URI.parse( - "#{base_uri}/partners/#{partner_id}/waba_accounts/#{waba_account_id}/waba_templates" - ) - headers = { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: "Bearer #{token}" - } - request = Net::HTTP::Get.new(url.to_s, headers) + url = URI.parse("#{base_uri}/v1/configs/templates") + headers = { 'D360-API-KEY' => organization.three_sixty_dialog_client_api_key, 'Content-Type' => 'application/json' } + + request = Net::HTTP::Get.new(url, headers) response = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http| http.request(request) end diff --git a/app/services/whats_app_adapter/three_sixty_dialog/token_fetcher_service.rb b/app/services/whats_app_adapter/three_sixty_dialog/token_fetcher_service.rb index 27c60f3ad..6dedc4a6e 100644 --- a/app/services/whats_app_adapter/three_sixty_dialog/token_fetcher_service.rb +++ b/app/services/whats_app_adapter/three_sixty_dialog/token_fetcher_service.rb @@ -2,14 +2,14 @@ module WhatsAppAdapter module ThreeSixtyDialog - class TokenFetcherService + class TokenFetcherService < ApplicationService def self.call base_uri = URI.parse( ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693') ) url = URI::HTTPS.build(host: base_uri.hostname, path: "#{base_uri.path}/token") headers = { 'Content-Type': 'application/json' } - request = Net::HTTP::Post.new(url.to_s, headers) + request = Net::HTTP::Post.new(url, headers) request.body = { username: ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_USERNAME', nil), password: ENV.fetch('THREE_SIXTY_DIALOG_PARTNER_PASSWORD', nil) diff --git a/spec/adapters/whats_app_adapter/three_sixty_dialog_outbound_spec.rb b/spec/adapters/whats_app_adapter/three_sixty_dialog_outbound_spec.rb index 3ba1c4a8a..4d5aa17cc 100644 --- a/spec/adapters/whats_app_adapter/three_sixty_dialog_outbound_spec.rb +++ b/spec/adapters/whats_app_adapter/three_sixty_dialog_outbound_spec.rb @@ -65,18 +65,7 @@ policy: 'deterministic', code: 'de' }, - name: "welcome_message_#{organization.project_name.parameterize.underscore}", - components: [ - { - type: 'body', - parameters: [ - { - type: 'text', - text: organization.project_name - } - ] - } - ] + name: "welcome_message_#{organization.project_name.parameterize.underscore}" } } end diff --git a/spec/jobs/whats_app_adapter/three_sixty_dialog/create_templates_job_spec.rb b/spec/jobs/whats_app_adapter/three_sixty_dialog/create_templates_job_spec.rb new file mode 100644 index 000000000..97be522ca --- /dev/null +++ b/spec/jobs/whats_app_adapter/three_sixty_dialog/create_templates_job_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'webmock/rspec' + +RSpec.describe WhatsAppAdapter::ThreeSixtyDialog::CreateTemplatesJob do + describe '#perform_later(organization_id:)' do + subject { -> { described_class.new.perform(organization_id: organization.id) } } + + let(:organization) { create(:organization, three_sixty_dialog_client_api_key: 'valid_client_api_key') } + let!(:admin) { create_list(:user, 3, admin: true) } + let!(:users_of_an_organization) { create_list(:user, 2, organizations: [organization]) } + let!(:user_of_another_organization) { create_list(:user, 2, organizations: [create(:organization)]) } + + before do + allow(ENV).to receive(:fetch).with( + 'THREE_SIXTY_DIALOG_WHATS_APP_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693' + ).and_return('https://waba-v2.360dialog.io') + allow_any_instance_of(WhatsAppAdapter::ThreeSixtyDialog::CreateTemplatesJob).to receive(:whats_app_templates).and_return( + { 'new_request_morning2' => 'some text' } + ) + end + + describe 'ActivityNotifications', vcr: { cassette_name: :three_sixty_dialog_create_template } do + it 'creates a notification for all admin and users of an organizaiton' do + subject.call + whats_app_template_created_notifications = ActivityNotification.where(type: WhatsAppTemplateCreated.name) + expect(whats_app_template_created_notifications.count).to eq(5) + + recipient_ids = whats_app_template_created_notifications.pluck(:recipient_id).uniq.sort + user_ids = users_of_an_organization.pluck(:id) + admin_ids = admin.pluck(:id) + all_org_user_plus_admin = (user_ids + admin_ids).sort + expect(recipient_ids).to eq(all_org_user_plus_admin) + end + end + end +end diff --git a/spec/jobs/whats_app_adapter/three_sixty_dialog/create_welcome_message_template_job_spec.rb b/spec/jobs/whats_app_adapter/three_sixty_dialog/create_welcome_message_template_job_spec.rb index 60c82987c..bdd2236fa 100644 --- a/spec/jobs/whats_app_adapter/three_sixty_dialog/create_welcome_message_template_job_spec.rb +++ b/spec/jobs/whats_app_adapter/three_sixty_dialog/create_welcome_message_template_job_spec.rb @@ -9,9 +9,9 @@ let!(:organization) do create(:organization, - project_name: 'Test Project Name', + project_name: 'Hundred Eyes', onboarding_success_heading: 'Welcome to Test Project Name', - three_sixty_dialog_client_waba_account_id: 'valid_waba_account_id') + three_sixty_dialog_client_api_key: 'valid_client_api_key') end let!(:admin) { create_list(:user, 3, admin: true) } let!(:users_of_an_organization) { create_list(:user, 2, organizations: [organization]) } @@ -19,17 +19,8 @@ before do allow(ENV).to receive(:fetch).with( - 'THREE_SIXTY_DIALOG_PARTNER_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693' - ).and_return('https://hub.360dialog.io/api/v2') - allow(ENV).to receive(:fetch).with( - 'THREE_SIXTY_DIALOG_PARTNER_USERNAME', nil - ).and_return('valid_partner_username') - allow(ENV).to receive(:fetch).with( - 'THREE_SIXTY_DIALOG_PARTNER_PASSWORD', nil - ).and_return('valid_partner_password') - allow(ENV).to receive(:fetch).with( - 'THREE_SIXTY_DIALOG_PARTNER_ID', nil - ).and_return('valid_partner_id') + 'THREE_SIXTY_DIALOG_WHATS_APP_REST_API_ENDPOINT', 'https://stoplight.io/mocks/360dialog/360dialog-partner-api/24588693' + ).and_return('https://waba-v2.360dialog.io') end describe 'ActivityNotifications', vcr: { cassette_name: :three_sixty_dialog_welcome_message_created } do diff --git a/spec/requests/onboarding/whats_app_spec.rb b/spec/requests/onboarding/whats_app_spec.rb index 23d5bebaa..d025a5eb4 100644 --- a/spec/requests/onboarding/whats_app_spec.rb +++ b/spec/requests/onboarding/whats_app_spec.rb @@ -193,18 +193,7 @@ policy: 'deterministic', code: 'de' }, - name: "welcome_message_#{organization.project_name.parameterize.underscore}", - components: [ - { - type: 'body', - parameters: [ - { - type: 'text', - text: organization.project_name - } - ] - } - ] + name: "welcome_message_#{organization.project_name.parameterize.underscore}" } } end diff --git a/spec/services/whats_app_adapter/three_sixty_dialog/file_fetcher_service_spec.rb b/spec/services/whats_app_adapter/three_sixty_dialog/file_fetcher_service_spec.rb index b224b9fca..abe0ef8bb 100644 --- a/spec/services/whats_app_adapter/three_sixty_dialog/file_fetcher_service_spec.rb +++ b/spec/services/whats_app_adapter/three_sixty_dialog/file_fetcher_service_spec.rb @@ -7,7 +7,7 @@ describe '#call' do subject { -> { described_class.new(organization_id: organization.id, file_id: file_id).call } } - let(:organization) { create(:organization) } + let!(:organization) { create(:organization) } let(:file_id) { 'some_valid_id' } let(:path) { '/whatsapp_business/attachments/' } diff --git a/spec/vcr_setup.rb b/spec/vcr_setup.rb index a2dd469a4..84faa54be 100644 --- a/spec/vcr_setup.rb +++ b/spec/vcr_setup.rb @@ -23,7 +23,6 @@ c.filter_sensitive_data('Bearer ') do |interaction| interaction.request.headers['Authorization'].try(:first) end - c.filter_sensitive_data('THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID') { 'valid_waba_account_id' } c.configure_rspec_metadata! # Capybara.server_host default diff --git a/vcr_cassettes/three_sixty_dialog_create_template.yml b/vcr_cassettes/three_sixty_dialog_create_template.yml new file mode 100644 index 000000000..1ea7bbec3 --- /dev/null +++ b/vcr_cassettes/three_sixty_dialog_create_template.yml @@ -0,0 +1,108 @@ +--- +http_interactions: +- request: + method: get + uri: https://waba-v2.360dialog.io/v1/configs/templates + body: + encoding: US-ASCII + string: '' + headers: + D360-Api-Key: + - D360-API-KEY + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 22 Oct 2024 11:50:11 GMT + Content-Type: + - application/json + Content-Length: + - '3213' + Access-Control-Allow-Origin: + - http://172.16.30.117:3001 + Strict-Transport-Security: + - max-age=15724800; includeSubDomains + Vary: + - Origin + X-Envoy-Upstream-Service-Time: + - '384' + Server: + - istio-envoy + body: + encoding: UTF-8 + string: '{"count":4,"filters":{},"limit":1000,"offset":0,"sort":["id"],"total":4,"waba_templates":[{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"*Welcome + to {{1}}*\n\nUnsere Dialog-Recherche startet bald. Wir melden uns dann bei + Ihnen.\n\nUm unseren Kanal abzubestellen, schreibe \u201eabbestellen\u201c.\n","type":"BODY"}],"created_at":"2024-10-07T08:50:05Z","created_by":{"user_id":"0fIXafU","user_name":"Matt"},"external_id":"1214097339917640","id":"MEuXRnVMAD7ScqqN0VDrWT","language":"de","modified_at":"2024-10-07T08:50:31Z","modified_by":{"user_id":"system","user_name":"system"},"name":"welcome_message_test_project","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie + und Freizeit"]]},"text":"Guten Morgen {{1}}, wir haben eine neue Frage zum + Thema \u201e{{2}}\u201c. Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr + Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2024-10-22T11:41:52Z","created_by":{"user_id":"system","user_name":"System + account"},"external_id":"974244038051108","id":"u2XmEOU54M8b7KHv0nypWT","language":"de","modified_at":"2024-10-22T11:42:25Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_morning1","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"},{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"Vielen + Dank f\u00fcr deine Anmeldung bei {{1}}. Unsere Dialog-Recherche startet bald. + Wir melden uns dann bei dir.","type":"BODY"}],"created_at":"2023-08-11T08:34:22Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"6443353965699593","id":"V7XC4olb3r7aaq416f2eWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"welcome_message","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"},{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"*Welcome + to {{1}}*\n\nUnsere Dialog-Recherche startet bald. Wir melden uns dann bei + Ihnen.\n\nUm unseren Kanal abzubestellen, schreibe \u201eabbestellen\u201c.\n","type":"BODY"}],"created_at":"2024-10-07T09:01:21Z","created_by":{"user_id":"0fIXafU","user_name":"Matt"},"external_id":"1275839723420499","id":"xyJ01IL2o2OZRvICUBDGWT","language":"de","modified_at":"2024-10-07T09:01:33Z","modified_by":{"user_id":"system","user_name":"system"},"name":"welcome_message_test_project_name","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"}]} + + ' + recorded_at: Tue, 22 Oct 2024 11:50:11 GMT +- request: + method: post + uri: https://waba-v2.360dialog.io/v1/configs/templates + body: + encoding: UTF-8 + string: '{"name":"new_request_morning2","category":"MARKETING","components":[{"type":"BODY","text":"Guten + Morgen {{1}}, zum Thema „{{2}}“ haben wir eine neue Frage. Wenn du antworten + möchtest, klicke auf ''Antworten''.","example":{"body_text":[["Jakob","Familie + und Freizeit"]]}},{"type":"BUTTONS","buttons":[{"type":"QUICK_REPLY","text":"Antworten"},{"type":"QUICK_REPLY","text":"Mehr + Infos"}]}],"language":"de","allow_category_change":true}' + headers: + D360-Api-Key: + - D360-API-KEY + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 201 + message: Created + headers: + Date: + - Tue, 22 Oct 2024 11:50:13 GMT + Content-Type: + - application/json + Content-Length: + - '576' + Access-Control-Allow-Origin: + - http://172.16.30.117:3001 + Strict-Transport-Security: + - max-age=15724800; includeSubDomains + Vary: + - Origin + X-Envoy-Upstream-Service-Time: + - '2088' + Server: + - istio-envoy + body: + encoding: UTF-8 + string: '{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie + und Freizeit"]]},"text":"Guten Morgen {{1}}, zum Thema \u201e{{2}}\u201c haben + wir eine neue Frage. Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr + Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"external_id":"1475284523158116","id":"mg83ovEcYk8BJ8PL9FY0WT","language":"de","name":"new_request_morning2","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","rejected_reason":null,"status":"submitted"} + + ' + recorded_at: Tue, 22 Oct 2024 11:50:13 GMT +recorded_with: VCR 6.1.0 diff --git a/vcr_cassettes/three_sixty_dialog_welcome_message_created.yml b/vcr_cassettes/three_sixty_dialog_welcome_message_created.yml index f64ba9627..96c092609 100644 --- a/vcr_cassettes/three_sixty_dialog_welcome_message_created.yml +++ b/vcr_cassettes/three_sixty_dialog_welcome_message_created.yml @@ -1,12 +1,14 @@ --- http_interactions: - request: - method: post - uri: https://hub.360dialog.io/api/v2/token + method: get + uri: https://waba-v2.360dialog.io/v1/configs/templates body: - encoding: UTF-8 - string: '{"username":"THREE_SIXTY_DIALOG_PARTNER_USERNAME","password":"THREE_SIXTY_DIALOG_PARTNER_PASSWORD"}' + encoding: US-ASCII + string: '' headers: + D360-Api-Key: + - D360-API-KEY Content-Type: - application/json Accept-Encoding: @@ -21,159 +23,87 @@ http_interactions: message: OK headers: Date: - - Mon, 07 Oct 2024 09:01:21 GMT + - Wed, 23 Oct 2024 07:33:29 GMT Content-Type: - application/json Content-Length: - - '1235' - Connection: - - keep-alive + - '4080' Access-Control-Allow-Origin: - http://172.16.30.117:3001 - Vary: - - Origin Strict-Transport-Security: - max-age=15724800; includeSubDomains - body: - encoding: UTF-8 - string: '{"access_token":"","expires_in":86400,"refresh_token":"byYbJEwZks37AzgFG540OeW-fItMgGAoXFfw-ba_994VV","token_type":"Bearer"} - - ' - recorded_at: Mon, 07 Oct 2024 09:01:21 GMT -- request: - method: get - uri: https://hub.360dialog.io/api/v2/partners/THREE_SIXTY_DIALOG_PARTNER_ID/waba_accounts/THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID/waba_templates - body: - encoding: US-ASCII - string: '' - headers: - Accept: - - application/json - Content-Type: - - application/json - Authorization: - - Bearer - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - User-Agent: - - Ruby - response: - status: - code: 200 - message: OK - headers: - Date: - - Mon, 07 Oct 2024 09:01:21 GMT - Content-Type: - - application/json - Content-Length: - - '13145' - Connection: - - keep-alive - Access-Control-Allow-Origin: - - http://172.16.30.117:3001 Vary: - Origin - Strict-Transport-Security: - - max-age=15724800; includeSubDomains + X-Envoy-Upstream-Service-Time: + - '78' + Server: + - istio-envoy body: encoding: UTF-8 - string: '{"count":15,"filters":{},"limit":1000,"offset":0,"sort":["id"],"total":15,"waba_templates":[{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Guten Morgen {{1}}, heute haben wir zum Thema \u201e{{2}}\u201c - eine Frage vorbereitet. Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:34:37Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"1949428312134154","id":"6D5ijv87QgDZQtj0ad4mWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_morning_3","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Guten Morgen {{1}}, wir haben eine neue Frage zum - Thema \u201e{{2}}\u201c. Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:34:26Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"820558729663892","id":"BAdzWd15UEtvmCG6CIe7WT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_morning_1","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Hallo {{1}}, heute Abend m\u00f6chte ich gern mehr - zum Thema \u201e{{2}}\u201c erfahren. Wenn du antworten m\u00f6chtest, klicke - auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:35:21Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"1040137623582369","id":"CSpZ6F5sRYrr8BuwgW2PWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_evening_3","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Guten Tag {{1}}, wir haben eine neue Frage zum Thema - \u201e{{2}}\u201c f\u00fcr dich. Wenn du antworten m\u00f6chtest, klicke auf - ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:34:41Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"252644734301298","id":"CvYv8VyCfrSfpbFHvUQdWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_day_1","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Guten Tag {{1}}, ich habe eine neue Frage zu \u201e{{2}}\u201c. - Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:34:49Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"2860193370790221","id":"De9xBrv7mmoYLNBoeNgXWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_day_3","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie + string: '{"count":5,"filters":{},"limit":1000,"offset":0,"sort":["id"],"total":5,"waba_templates":[{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"*Welcome + to {{1}}*\n\nUnsere Dialog-Recherche startet bald. Wir melden uns dann bei + Ihnen.\n\nUm unseren Kanal abzubestellen, schreibe \u201eabbestellen\u201c.\n","type":"BODY"}],"created_at":"2024-10-07T08:50:05Z","created_by":{"user_id":"0fIXafU","user_name":"Matt"},"external_id":"1214097339917640","id":"MEuXRnVMAD7ScqqN0VDrWT","language":"de","modified_at":"2024-10-07T08:50:31Z","modified_by":{"user_id":"system","user_name":"system"},"name":"welcome_message_test_project","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie und Freizeit"]]},"text":"Guten Morgen {{1}}, zum Thema \u201e{{2}}\u201c haben wir eine neue Frage. Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:34:32Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"1016275052721084","id":"gwNeBf6mHzkwdryX1cErWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_morning_2","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Hallo {{1}}, ich wei\u00df, es ist schon sp\u00e4t. - Aber ich m\u00f6chte gern mehr zum Thema \u201e{{2}}\u201c erfahren. Wenn - du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:35:30Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"619159036994241","id":"K5SWWUbrsfa1HyPE38OfWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_night_2","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"*Welcome - to {{1}}*\n\nUnsere Dialog-Recherche startet bald. Wir melden uns dann bei - Ihnen.\n\nUm unseren Kanal abzubestellen, schreibe \u201eabbestellen\u201c.\n","type":"BODY"}],"created_at":"2024-10-07T08:50:05Z","created_by":{"user_id":"0fIXafU","user_name":"Matt"},"external_id":"1214097339917640","id":"MEuXRnVMAD7ScqqN0VDrWT","language":"de","modified_at":"2024-10-07T08:50:31Z","modified_by":{"user_id":"system","user_name":"system"},"name":"welcome_message_test_project","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Hallo {{1}}, ich m\u00f6chte gerne mehr zum Thema - \u201e{{2}}\u201c erfahren. Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:34:45Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"1015388879635601","id":"paNXjwq4WnYKPJERmM90WT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_day_2","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Hallo {{1}}, heute Nacht ist mir etwas zum Thema - \u201e{{2}}\u201c eingefallen. Wenn du antworten m\u00f6chtest, klicke auf - ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:35:25Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"1332407930985100","id":"pav66DM2EOgaVmGGA2NGWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_night_1","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Guten Abend {{1}}, wir haben eine neue Frage zum + Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2024-10-22T11:50:11Z","created_by":{"user_id":"system","user_name":"System + account"},"external_id":"1475284523158116","id":"mg83ovEcYk8BJ8PL9FY0WT","language":"de","modified_at":"2024-10-22T11:50:44Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_morning2","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie + und Freizeit"]]},"text":"Guten Morgen {{1}}, wir haben eine neue Frage zum Thema \u201e{{2}}\u201c. Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:34:53Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"1325500401656814","id":"pDFrXyiyftNYj21ZHpaTWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_evening_1","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"*Vielen - Dank f\u00fcr Ihre Anmeldung bei {{1}}.\n*\n\nUnsere Dialog-Recherche startet - bald. Wir melden uns dann bei Ihnen.\n\nUm unseren Kanal Abzubestellen, schreibe - \u201eabbestellen\u201c.\n","type":"BODY"}],"created_at":"2024-09-16T10:05:24Z","created_by":{"user_id":"0fIXafU","user_name":"Matt"},"external_id":"8196831700408015","id":"QQJzvTfNOec7qpbp91TgWT","language":"de","modified_at":"2024-09-16T10:05:52Z","modified_by":{"user_id":"system","user_name":"system"},"name":"default_welcome_message","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"Vielen + Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2024-10-22T11:41:52Z","created_by":{"user_id":"system","user_name":"System + account"},"external_id":"974244038051108","id":"u2XmEOU54M8b7KHv0nypWT","language":"de","modified_at":"2024-10-22T11:42:25Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_morning1","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"},{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"Vielen Dank f\u00fcr deine Anmeldung bei {{1}}. Unsere Dialog-Recherche startet bald. - Wir melden uns dann bei dir.","type":"BODY"}],"created_at":"2023-08-11T08:34:22Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"6443353965699593","id":"V7XC4olb3r7aaq416f2eWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"welcome_message","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Guten Abend {{1}}, zum Thema \u201e{{2}}\u201c haben - wir eine neue Frage. Wenn du antworten m\u00f6chtest, klicke auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:34:57Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"1261099061091845","id":"wikijRUJB3gXyDsFkxlOWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_evening_2","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"},{"category":"MARKETING","components":[{"example":{"body_text":[["Jakob","Familie - und Freizeit"]]},"text":"Hallo {{1}}, zum Thema \u201e{{2}}\u201c m\u00f6chte - ich heute noch gern mehr erfahren. Wenn du antworten m\u00f6chtest, klicke - auf ''Antworten''.","type":"BODY"},{"buttons":[{"text":"Antworten","type":"QUICK_REPLY"},{"text":"Mehr - Infos","type":"QUICK_REPLY"}],"type":"BUTTONS"}],"created_at":"2023-08-11T08:35:34Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"999005154631078","id":"YjibnEv90XZ2OjWsmuJVWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"new_request_night_3","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"}]} + Wir melden uns dann bei dir.","type":"BODY"}],"created_at":"2023-08-11T08:34:22Z","created_by":{"user_id":"HmpUn8U","user_name":"apiuser"},"external_id":"6443353965699593","id":"V7XC4olb3r7aaq416f2eWT","language":"de","modified_at":"2024-09-12T22:26:51Z","modified_by":{"user_id":"system","user_name":"system"},"name":"welcome_message","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":{"reasons":null,"score":"UNKNOWN"},"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"},{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"*Welcome + to {{1}}*\n\nUnsere Dialog-Recherche startet bald. Wir melden uns dann bei + Ihnen.\n\nUm unseren Kanal abzubestellen, schreibe \u201eabbestellen\u201c.\n","type":"BODY"}],"created_at":"2024-10-07T09:01:21Z","created_by":{"user_id":"0fIXafU","user_name":"Matt"},"external_id":"1275839723420499","id":"xyJ01IL2o2OZRvICUBDGWT","language":"de","modified_at":"2024-10-07T09:01:33Z","modified_by":{"user_id":"system","user_name":"system"},"name":"welcome_message_test_project_name","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"WdBs71PA","quality_score":null,"rejected_reason":"NONE","status":"approved","updated_external":true,"waba_account_id":"uX3BECWA"}]} ' - recorded_at: Mon, 07 Oct 2024 09:01:21 GMT + recorded_at: Wed, 23 Oct 2024 07:33:28 GMT - request: method: post - uri: https://hub.360dialog.io/api/v2/partners/THREE_SIXTY_DIALOG_PARTNER_ID/waba_accounts/THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID/waba_templates + uri: https://waba-v2.360dialog.io/v1/configs/templates body: encoding: UTF-8 - string: '{"name":"welcome_message_test_project_name","category":"MARKETING","components":[{"type":"BODY","text":"*Welcome - to {{1}}*\n\nUnsere Dialog-Recherche startet bald. Wir melden uns dann bei - Ihnen.\n\nUm unseren Kanal abzubestellen, schreibe „abbestellen“.\n","example":{"body_text":[["100eyes"]]}}],"language":"de","allow_category_change":true}' + string: '{"name":"welcome_message_hundred_eyes","category":"MARKETING","components":[{"type":"BODY","text":"*Welcome + to Test Project Name*\n\nUnsere Dialog-Recherche startet bald. Wir melden + uns dann bei Ihnen.\n\nUm unseren Kanal abzubestellen, schreibe „abbestellen“.\n"}],"language":"de","allow_category_change":true}' headers: - Accept: - - application/json + D360-Api-Key: + - D360-API-KEY Content-Type: - application/json - Authorization: - - Bearer Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" User-Agent: - Ruby response: status: code: 201 - message: CREATED + message: Created headers: Date: - - Mon, 07 Oct 2024 09:01:27 GMT + - Wed, 23 Oct 2024 07:33:33 GMT Content-Type: - application/json Content-Length: - - '762' - Connection: - - keep-alive + - '451' Access-Control-Allow-Origin: - http://172.16.30.117:3001 - Vary: - - Origin Strict-Transport-Security: - max-age=15724800; includeSubDomains + Vary: + - Origin + X-Envoy-Upstream-Service-Time: + - '3117' + Server: + - istio-envoy body: encoding: UTF-8 - string: '{"category":"MARKETING","components":[{"example":{"body_text":[["100eyes"]]},"text":"*Welcome - to {{1}}*\n\nUnsere Dialog-Recherche startet bald. Wir melden uns dann bei - Ihnen.\n\nUm unseren Kanal abzubestellen, schreibe \u201eabbestellen\u201c.\n","type":"BODY"}],"created_at":"2024-10-07T09:01:21Z","created_by":{"user_id":"0fIXafU","user_name":"Matt"},"external_id":"1275839723420499","id":"xyJ01IL2o2OZRvICUBDGWT","language":"de","modified_at":"2024-10-07T09:01:27Z","modified_by":{"user_id":"0fIXafU","user_name":"Matt"},"name":"welcome_message_test_project_name","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","partner_id":"THREE_SIXTY_DIALOG_PARTNER_ID","quality_score":null,"rejected_reason":null,"status":"submitted","updated_external":true,"waba_account_id":"THREE_SIXTY_DIALOG_CLIENT_WABA_ACCOUNT_ID"} + string: '{"category":"MARKETING","components":[{"text":"*Welcome to Test Project + Name*\n\nUnsere Dialog-Recherche startet bald. Wir melden uns dann bei Ihnen.\n\nUm + unseren Kanal abzubestellen, schreibe \u201eabbestellen\u201c.\n","type":"BODY"}],"external_id":"8322283881154137","id":"8RNeQaAYgYEnrWvUORy8WT","language":"de","name":"welcome_message_hundred_eyes","namespace":"7380bb95_042f_4bea_a6b2_58f1d0a4be55","rejected_reason":null,"status":"submitted"} ' - recorded_at: Mon, 07 Oct 2024 09:01:27 GMT + recorded_at: Wed, 23 Oct 2024 07:33:32 GMT recorded_with: VCR 6.1.0