feat: Support for Whatsapp Cloud API (#4938)

Ability to configure Whatsapp Cloud API Inboxes

fixes: #4712
This commit is contained in:
Sojan Jose
2022-07-06 21:45:03 +02:00
committed by GitHub
parent 4375a7646e
commit a6c609f43d
27 changed files with 999 additions and 229 deletions

View File

@@ -197,6 +197,7 @@
"PROVIDERS": {
"LABEL": "API Provider",
"TWILIO": "Twilio",
"WHATSAPP_CLOUD": "WhatsApp Cloud",
"360_DIALOG": "360Dialog"
},
"INBOX_NAME": {
@@ -209,12 +210,31 @@
"PLACEHOLDER": "Please enter the phone number from which message will be sent.",
"ERROR": "Please enter a valid value. Phone number should start with `+` sign."
},
"PHONE_NUMBER_ID": {
"LABEL": "Phone number ID",
"PLACEHOLDER": "Please enter the Phone number ID obtained from Facebook developer dashboard.",
"ERROR": "Please enter a valid value."
},
"BUSINESS_ACCOUNT_ID": {
"LABEL": "Business Account ID",
"PLACEHOLDER": "Please enter the Business Account ID obtained from Facebook developer dashboard.",
"ERROR": "Please enter a valid value."
},
"WEBHOOK_VERIFY_TOKEN": {
"LABEL": "Webhook Verify Token",
"PLACEHOLDER": "Enter a verify token which you want to configure for facebook webhooks.",
"ERROR": "Please enter a valid value."
},
"API_KEY": {
"LABEL": "API key",
"SUBTITLE": "Configure the WhatsApp API key.",
"PLACEHOLDER": "API key",
"ERROR": "Please enter a valid value."
},
"API_CALLBACK": {
"TITLE": "Callback URL",
"SUBTITLE": "You have to configure the webhook URL in facebook developer portal with the URL mentioned here."
},
"SUBMIT_BUTTON": "Create WhatsApp Channel",
"API": {
"ERROR_MESSAGE": "We were not able to save the WhatsApp channel"
@@ -424,7 +444,7 @@
"FORWARD_EMAIL_SUB_TEXT": "Start forwarding your emails to the following email address.",
"ALLOW_MESSAGES_AFTER_RESOLVED": "Allow messages after conversation resolved",
"ALLOW_MESSAGES_AFTER_RESOLVED_SUB_TEXT": "Allow the end-users to send messages even after the conversation is resolved.",
"WHATSAPP_SECTION_SUBHEADER": "This API Key is used in the integration with the 360Dialog WhatsApp channel.",
"WHATSAPP_SECTION_SUBHEADER": "This API Key is used for the integration with the WhatsApp APIs.",
"WHATSAPP_SECTION_TITLE": "API Key"
},
"AUTO_ASSIGNMENT":{

View File

@@ -19,6 +19,13 @@
:script="currentInbox.callback_webhook_url"
/>
</div>
<div class="medium-6 small-offset-3">
<woot-code
v-if="isAWhatsappWhatsappCloudInbox"
lang="html"
:script="currentInbox.callback_webhook_url"
/>
</div>
<div class="medium-6 small-offset-3">
<woot-code
v-if="isALineInbox"
@@ -92,6 +99,12 @@ export default {
isASmsInbox() {
return this.currentInbox.channel_type === 'Channel::Sms';
},
isAWhatsappWhatsappCloudInbox() {
return (
this.currentInbox.channel_type === 'Channel::Whatsapp' &&
this.currentInbox.provider === 'whatsapp_cloud'
);
},
message() {
if (this.isATwilioInbox) {
return `${this.$t('INBOX_MGMT.FINISH.MESSAGE')}. ${this.$t(
@@ -111,6 +124,12 @@ export default {
)}`;
}
if (this.isAWhatsappWhatsappCloudInbox) {
return `${this.$t('INBOX_MGMT.FINISH.MESSAGE')}. ${this.$t(
'INBOX_MGMT.ADD.WHATSAPP.API_CALLBACK.SUBTITLE'
)}`;
}
if (this.isAEmailInbox) {
return this.$t('INBOX_MGMT.ADD.EMAIL_CHANNEL.FINISH_MESSAGE');
}

View File

@@ -0,0 +1,186 @@
<template>
<form class="row" @submit.prevent="createChannel()">
<div class="medium-8 columns">
<label :class="{ error: $v.inboxName.$error }">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.INBOX_NAME.LABEL') }}
<input
v-model.trim="inboxName"
type="text"
:placeholder="$t('INBOX_MGMT.ADD.WHATSAPP.INBOX_NAME.PLACEHOLDER')"
@blur="$v.inboxName.$touch"
/>
<span v-if="$v.inboxName.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.INBOX_NAME.ERROR') }}
</span>
</label>
</div>
<div class="medium-8 columns">
<label :class="{ error: $v.phoneNumber.$error }">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.PHONE_NUMBER.LABEL') }}
<input
v-model.trim="phoneNumber"
type="text"
:placeholder="$t('INBOX_MGMT.ADD.WHATSAPP.PHONE_NUMBER.PLACEHOLDER')"
@blur="$v.phoneNumber.$touch"
/>
<span v-if="$v.phoneNumber.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.PHONE_NUMBER.ERROR') }}
</span>
</label>
</div>
<div class="medium-8 columns">
<label :class="{ error: $v.phoneNumberId.$error }">
<span>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.PHONE_NUMBER_ID.LABEL') }}
</span>
<input
v-model.trim="phoneNumberId"
type="text"
:placeholder="
$t('INBOX_MGMT.ADD.WHATSAPP.PHONE_NUMBER_ID.PLACEHOLDER')
"
@blur="$v.phoneNumberId.$touch"
/>
<span v-if="$v.phoneNumberId.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.PHONE_NUMBER_ID.ERROR') }}
</span>
</label>
</div>
<div class="medium-8 columns">
<label :class="{ error: $v.businessAccountId.$error }">
<span>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.BUSINESS_ACCOUNT_ID.LABEL') }}
</span>
<input
v-model.trim="businessAccountId"
type="text"
:placeholder="
$t('INBOX_MGMT.ADD.WHATSAPP.BUSINESS_ACCOUNT_ID.PLACEHOLDER')
"
@blur="$v.businessAccountId.$touch"
/>
<span v-if="$v.businessAccountId.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.BUSINESS_ACCOUNT_ID.ERROR') }}
</span>
</label>
</div>
<div class="medium-8 columns">
<label :class="{ error: $v.apiKey.$error }">
<span>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.API_KEY.LABEL') }}
</span>
<input
v-model.trim="apiKey"
type="text"
:placeholder="$t('INBOX_MGMT.ADD.WHATSAPP.API_KEY.PLACEHOLDER')"
@blur="$v.apiKey.$touch"
/>
<span v-if="$v.apiKey.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.API_KEY.ERROR') }}
</span>
</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"
:button-text="$t('INBOX_MGMT.ADD.WHATSAPP.SUBMIT_BUTTON')"
/>
</div>
</form>
</template>
<script>
import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
import { required } from 'vuelidate/lib/validators';
import router from '../../../../index';
const shouldStartWithPlusSign = (value = '') => value.startsWith('+');
export default {
mixins: [alertMixin],
data() {
return {
inboxName: '',
phoneNumber: '',
apiKey: '',
phoneNumberId: '',
businessAccountId: '',
webhookVerifyToken: '',
};
},
computed: {
...mapGetters({ uiFlags: 'inboxes/getUIFlags' }),
},
validations: {
inboxName: { required },
phoneNumber: { required, shouldStartWithPlusSign },
apiKey: { required },
phoneNumberId: { required },
businessAccountId: { required },
webhookVerifyToken: { required },
},
methods: {
async createChannel() {
this.$v.$touch();
if (this.$v.$invalid) {
return;
}
try {
const whatsappChannel = await this.$store.dispatch(
'inboxes/createChannel',
{
name: this.inboxName,
channel: {
type: 'whatsapp',
phone_number: this.phoneNumber,
provider: 'whatsapp_cloud',
provider_config: {
api_key: this.apiKey,
phone_number_id: this.phoneNumberId,
business_account_id: this.businessAccountId,
webhook_verify_token: this.webhookVerifyToken,
},
},
}
);
router.replace({
name: 'settings_inboxes_add_agents',
params: {
page: 'new',
inbox_id: whatsappChannel.id,
},
});
} catch (error) {
this.showAlert(this.$t('INBOX_MGMT.ADD.WHATSAPP.API.ERROR_MESSAGE'));
}
},
},
};
</script>

View File

@@ -8,6 +8,9 @@
<label>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.PROVIDERS.LABEL') }}
<select v-model="provider">
<option value="whatsapp_cloud">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.PROVIDERS.WHATSAPP_CLOUD') }}
</option>
<option value="twilio">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.PROVIDERS.TWILIO') }}
</option>
@@ -19,7 +22,8 @@
</div>
<twilio v-if="provider === 'twilio'" type="whatsapp" />
<three-sixty-dialog-whatsapp v-else />
<three-sixty-dialog-whatsapp v-else-if="provider === '360dialog'" />
<cloud-whatsapp v-else />
</div>
</template>
@@ -27,16 +31,18 @@
import PageHeader from '../../SettingsSubPageHeader';
import Twilio from './Twilio';
import ThreeSixtyDialogWhatsapp from './360DialogWhatsapp';
import CloudWhatsapp from './CloudWhatsapp';
export default {
components: {
PageHeader,
Twilio,
ThreeSixtyDialogWhatsapp,
CloudWhatsapp,
},
data() {
return {
provider: 'twilio',
provider: 'whatsapp_cloud',
};
},
};