diff --git a/app/controllers/concerns/meta_token_verify_concern.rb b/app/controllers/concerns/meta_token_verify_concern.rb new file mode 100644 index 000000000..b3f920644 --- /dev/null +++ b/app/controllers/concerns/meta_token_verify_concern.rb @@ -0,0 +1,20 @@ +# services from Meta (Prev: Facebook) needs a token verification step for webhook subscriptions, +# This concern handles the token verification step. + +module MetaTokenVerifyConcern + def verify + service = is_a?(Webhooks::WhatsappController) ? 'whatsapp' : 'instagram' + if valid_token?(params['hub.verify_token']) + Rails.logger.info("#{service.capitalize} webhook verified") + render json: params['hub.challenge'] + else + render status: :unauthorized, json: { error: 'Error; wrong verify token' } + end + end + + private + + def valid_token?(_token) + raise 'Overwrite this method your controller' + end +end diff --git a/app/controllers/webhooks/instagram_controller.rb b/app/controllers/webhooks/instagram_controller.rb index e6fe93566..b658915ed 100644 --- a/app/controllers/webhooks/instagram_controller.rb +++ b/app/controllers/webhooks/instagram_controller.rb @@ -1,15 +1,5 @@ -class Webhooks::InstagramController < ApplicationController - skip_before_action :authenticate_user!, raise: false - skip_before_action :set_current_user - - def verify - if valid_instagram_token?(params['hub.verify_token']) - Rails.logger.info('Instagram webhook verified') - render json: params['hub.challenge'] - else - render json: { error: 'Error; wrong verify token', status: 403 } - end - end +class Webhooks::InstagramController < ActionController::API + include MetaTokenVerifyConcern def events Rails.logger.info('Instagram webhook received events') @@ -24,7 +14,7 @@ class Webhooks::InstagramController < ApplicationController private - def valid_instagram_token?(token) + def valid_token?(token) token == GlobalConfigService.load('IG_VERIFY_TOKEN', '') end end diff --git a/app/controllers/webhooks/whatsapp_controller.rb b/app/controllers/webhooks/whatsapp_controller.rb index 7560da1e4..8f408d2b0 100644 --- a/app/controllers/webhooks/whatsapp_controller.rb +++ b/app/controllers/webhooks/whatsapp_controller.rb @@ -1,6 +1,16 @@ class Webhooks::WhatsappController < ActionController::API + include MetaTokenVerifyConcern + def process_payload Webhooks::WhatsappEventsJob.perform_later(params.to_unsafe_hash) head :ok end + + private + + def valid_token?(token) + channel = Channel::Whatsapp.find_by(phone_number: params[:phone_number]) + whatsapp_webhook_verify_token = channel.provider_config['webhook_verify_token'] if channel.present? + token == whatsapp_webhook_verify_token if whatsapp_webhook_verify_token.present? + end end diff --git a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json index ed811a6e9..e6ed1e397 100644 --- a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json @@ -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":{ diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/FinishSetup.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/FinishSetup.vue index e4fda7269..6d0a0a597 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/FinishSetup.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/FinishSetup.vue @@ -19,6 +19,13 @@ :script="currentInbox.callback_webhook_url" /> +
+ +
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue index dadce2d3b..d43e3feda 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue @@ -8,6 +8,9 @@