chore: Generate webhook-verify-token automatically (#5593)

- Autogenerate webhook verification token in the WhatsAppCloud channel.

Co-authored-by: Sojan <sojan@pepalo.com>
This commit is contained in:
Pranav Raj S
2022-10-12 11:32:31 +11:00
committed by GitHub
parent 5f4b6f2ce4
commit 38776906ab
8 changed files with 58 additions and 36 deletions

View File

@@ -239,7 +239,9 @@
},
"API_CALLBACK": {
"TITLE": "Callback URL",
"SUBTITLE": "You have to configure the webhook URL in facebook developer portal with the URL mentioned here."
"SUBTITLE": "You have to configure the webhook URL and the verification token in the Facebook Developer portal with the values shown below.",
"WEBHOOK_URL": "Webhook URL",
"WEBHOOK_VERIFICATION_TOKEN": "Webhook Verification Token"
},
"SUBMIT_BUTTON": "Create WhatsApp Channel",
"API": {
@@ -357,7 +359,7 @@
},
"FINISH": {
"TITLE": "Your Inbox is ready!",
"MESSAGE": "You can now engage with your customers through your new Channel. Happy supporting ",
"MESSAGE": "You can now engage with your customers through your new Channel. Happy supporting",
"BUTTON_TEXT": "Take me there",
"MORE_SETTINGS": "More settings",
"WEBSITE_SUCCESS": "You have successfully finished creating a website channel. Copy the code shown below and paste it on your website. Next time a customer use the live chat, the conversation will automatically appear on your inbox."

View File

@@ -20,11 +20,26 @@
/>
</div>
<div class="medium-6 small-offset-3">
<p class="config--label">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.API_CALLBACK.WEBHOOK_URL') }}
</p>
<woot-code
v-if="isAWhatsappWhatsappCloudInbox"
v-if="isWhatsAppCloudInbox"
lang="html"
:script="currentInbox.callback_webhook_url"
/>
<p class="config--label">
{{
$t(
'INBOX_MGMT.ADD.WHATSAPP.API_CALLBACK.WEBHOOK_VERIFICATION_TOKEN'
)
}}
</p>
<woot-code
v-if="isWhatsAppCloudInbox"
lang="html"
:script="currentInbox.provider_config.webhook_verify_token"
/>
</div>
<div class="medium-6 small-offset-3">
<woot-code
@@ -99,7 +114,7 @@ export default {
isASmsInbox() {
return this.currentInbox.channel_type === 'Channel::Sms';
},
isAWhatsappWhatsappCloudInbox() {
isWhatsAppCloudInbox() {
return (
this.currentInbox.channel_type === 'Channel::Whatsapp' &&
this.currentInbox.provider === 'whatsapp_cloud'
@@ -124,7 +139,7 @@ export default {
)}`;
}
if (this.isAWhatsappWhatsappCloudInbox) {
if (this.isWhatsAppCloudInbox) {
return `${this.$t('INBOX_MGMT.FINISH.MESSAGE')}. ${this.$t(
'INBOX_MGMT.ADD.WHATSAPP.API_CALLBACK.SUBTITLE'
)}`;
@@ -159,4 +174,10 @@ export default {
.settings-button {
margin-right: var(--space-small);
}
.config--label {
color: var(--b-600);
font-weight: var(--font-weight-medium);
margin-top: var(--space-large);
}
</style>

View File

@@ -85,25 +85,6 @@
</label>
</div>
<div class="medium-8 columns">
<label :class="{ error: $v.webhookVerifyToken.$error }">
<span>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.WEBHOOK_VERIFY_TOKEN.LABEL') }}
</span>
<input
v-model.trim="webhookVerifyToken"
type="text"
:placeholder="
$t('INBOX_MGMT.ADD.WHATSAPP.WEBHOOK_VERIFY_TOKEN.PLACEHOLDER')
"
@blur="$v.webhookVerifyToken.$touch"
/>
<span v-if="$v.webhookVerifyToken.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.WEBHOOK_VERIFY_TOKEN.ERROR') }}
</span>
</label>
</div>
<div class="medium-12 columns">
<woot-submit-button
:loading="uiFlags.isCreating"
@@ -130,7 +111,6 @@ export default {
apiKey: '',
phoneNumberId: '',
businessAccountId: '',
webhookVerifyToken: '',
};
},
computed: {
@@ -142,7 +122,6 @@ export default {
apiKey: { required },
phoneNumberId: { required },
businessAccountId: { required },
webhookVerifyToken: { required },
},
methods: {
async createChannel() {
@@ -164,7 +143,6 @@ export default {
api_key: this.apiKey,
phone_number_id: this.phoneNumberId,
business_account_id: this.businessAccountId,
webhook_verify_token: this.webhookVerifyToken,
},
},
}

View File

@@ -25,11 +25,12 @@ class Channel::Whatsapp < ApplicationRecord
# default at the moment is 360dialog lets change later.
PROVIDERS = %w[default whatsapp_cloud].freeze
before_validation :ensure_webhook_verify_token
validates :provider, inclusion: { in: PROVIDERS }
validates :phone_number, presence: true, uniqueness: true
validate :validate_provider_config
after_create :sync_templates
def name
@@ -56,6 +57,10 @@ class Channel::Whatsapp < ApplicationRecord
private
def ensure_webhook_verify_token
provider_config['webhook_verify_token'] ||= SecureRandom.hex(16) if provider == 'whatsapp_cloud'
end
def validate_provider_config
errors.add(:provider_config, 'Invalid Credentials') unless provider_service.validate_provider_config?
end

View File

@@ -7,7 +7,7 @@ module RegexHelper
UNICODE_CHARACTER_NUMBER_HYPHEN_UNDERSCORE = Regexp.new('\A[\p{L}\p{N}]+[\p{L}\p{N}_-]+\Z')
MENTION_REGEX = Regexp.new('\[(@[\w_. ]+)\]\(mention://(?:user|team)/\d+/(.*?)+\)')
TWILIO_CHANNEL_SMS_REGEX = Regexp.new('^\+\d{1,14}\z')
TWILIO_CHANNEL_WHATSAPP_REGEX = Regexp.new('^whatsapp:\+\d{1,14}\z')
TWILIO_CHANNEL_SMS_REGEX = Regexp.new('^\+\d{1,15}\z')
TWILIO_CHANNEL_WHATSAPP_REGEX = Regexp.new('^whatsapp:\+\d{1,15}\z')
WHATSAPP_CHANNEL_REGEX = Regexp.new('^\d{1,14}\z')
end

View File

@@ -44,8 +44,8 @@ FactoryBot.define do
channel_whatsapp.define_singleton_method(:sync_templates) { return } unless options.sync_templates
channel_whatsapp.define_singleton_method(:validate_provider_config) { return } unless options.validate_provider_config
if channel_whatsapp.provider == 'whatsapp_cloud'
channel_whatsapp.provider_config = { 'api_key' => 'test_key', 'phone_number_id' => '123456789', 'business_account_id' => '123456789',
'webhook_verify_token': 'test_token' }
channel_whatsapp.provider_config = channel_whatsapp.provider_config.merge({ 'api_key' => 'test_key', 'phone_number_id' => '123456789',
'business_account_id' => '123456789' })
end
end

View File

@@ -20,4 +20,20 @@ RSpec.describe Channel::Whatsapp do
expect(channel.save).to be(true)
end
end
describe 'webhook_verify_token' do
it 'generates webhook_verify_token if not present' do
channel = create(:channel_whatsapp, provider_config: { webhook_verify_token: nil }, provider: 'whatsapp_cloud', account: create(:account),
validate_provider_config: false, sync_templates: false)
expect(channel.provider_config['webhook_verify_token']).not_to be_nil
end
it 'does not generate webhook_verify_token if present' do
channel = create(:channel_whatsapp, provider: 'whatsapp_cloud', provider_config: { webhook_verify_token: '123' }, account: create(:account),
validate_provider_config: false, sync_templates: false)
expect(channel.provider_config['webhook_verify_token']).to eq '123'
end
end
end

View File

@@ -66,11 +66,11 @@ RSpec.describe ContactInbox do
expect(valid_source_id.valid?).to be(true)
expect(ci_character_in_source_id.valid?).to be(false)
expect(ci_character_in_source_id.errors.full_messages).to eq(
['Source invalid source id for twilio sms inbox. valid Regex (?-mix:^\\+\\d{1,14}\\z)']
['Source invalid source id for twilio sms inbox. valid Regex (?-mix:^\\+\\d{1,15}\\z)']
)
expect(ci_without_plus_in_source_id.valid?).to be(false)
expect(ci_without_plus_in_source_id.errors.full_messages).to eq(
['Source invalid source id for twilio sms inbox. valid Regex (?-mix:^\\+\\d{1,14}\\z)']
['Source invalid source id for twilio sms inbox. valid Regex (?-mix:^\\+\\d{1,15}\\z)']
)
end
@@ -83,11 +83,11 @@ RSpec.describe ContactInbox do
expect(valid_source_id.valid?).to be(true)
expect(ci_character_in_source_id.valid?).to be(false)
expect(ci_character_in_source_id.errors.full_messages).to eq(
['Source invalid source id for twilio whatsapp inbox. valid Regex (?-mix:^whatsapp:\\+\\d{1,14}\\z)']
['Source invalid source id for twilio whatsapp inbox. valid Regex (?-mix:^whatsapp:\\+\\d{1,15}\\z)']
)
expect(ci_without_plus_in_source_id.valid?).to be(false)
expect(ci_without_plus_in_source_id.errors.full_messages).to eq(
['Source invalid source id for twilio whatsapp inbox. valid Regex (?-mix:^whatsapp:\\+\\d{1,14}\\z)']
['Source invalid source id for twilio whatsapp inbox. valid Regex (?-mix:^whatsapp:\\+\\d{1,15}\\z)']
)
end
end