feat: add meta deletion callback endpoint
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
class Webhooks::FacebookController < ActionController::API
|
||||
class InvalidDigestError < StandardError; end
|
||||
|
||||
def process_deletion
|
||||
signed_request = params['signed_request']
|
||||
payload = parse_fb_signed_request(signed_request)
|
||||
id_to_process = payload['user_id']
|
||||
|
||||
set_processing
|
||||
Webhooks::MetaDeleteJob.perform_later(id_to_process)
|
||||
status_url = "#{app_url_base}/meta/delete-status/#{id_to_process}"
|
||||
|
||||
render json: { status_url: status_url, code: id_to_process }, status: :ok
|
||||
rescue InvalidDigestError
|
||||
render json: { error: 'Invalid signature' }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_processing
|
||||
# we use this key to check if the deletion is completed or not
|
||||
# Once the key is gone, we know the deletion is completed
|
||||
# And we can show as such
|
||||
key = format(::Redis::Alfred::META_DELETE_PROCESSING, id: id_to_process)
|
||||
::Redis::Alfred.set(key, true)
|
||||
end
|
||||
|
||||
def app_url_base
|
||||
ENV.fetch('FRONTEND_URL', nil)
|
||||
end
|
||||
|
||||
def parse_fb_signed_request(signed_request)
|
||||
encoded_signature, payload = signed_request.split('.', 2)
|
||||
|
||||
decoded_signature = Base64.urlsafe_decode64(encoded_signature)
|
||||
decoded_payload = JSON.parse(Base64.urlsafe_decode64(payload))
|
||||
|
||||
expected_signature = OpenSSL::HMAC.digest('sha256', app_secret, payload)
|
||||
|
||||
raise InvalidDigestError if decoded_signature != expected_signature
|
||||
|
||||
decoded_payload
|
||||
end
|
||||
|
||||
def app_secret
|
||||
GlobalConfigService.load('FB_APP_SECRET', '')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
class Webhooks::MetaDeleteJob < ApplicationJob
|
||||
queue_as :low
|
||||
|
||||
attr_reader :id_to_process
|
||||
|
||||
def perform(id_to_process)
|
||||
@id_to_process = id_to_process
|
||||
|
||||
delete_channel_if_present
|
||||
delete_contact_if_present
|
||||
|
||||
unset_processing
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def unset_processing
|
||||
key = format(::Redis::Alfred::META_DELETE_PROCESSING, id: id_to_process)
|
||||
::Redis::Alfred.del(key)
|
||||
end
|
||||
|
||||
def delete_channel_if_present
|
||||
channel = Channel::FacebookPage.find_by(page_id: id_to_process)
|
||||
return unless channel
|
||||
|
||||
inbox = channel.inbox
|
||||
inbox.destroy
|
||||
end
|
||||
|
||||
def remove_contact_if_present
|
||||
contact_inbox = ContactInbox.find_by(source_id: id_to_process)
|
||||
return unless contact_inbox
|
||||
|
||||
contact = contact_inbox.contact
|
||||
contact.update!(
|
||||
name: 'Deleted User',
|
||||
email: nil,
|
||||
phone_number: nil,
|
||||
identifier: nil,
|
||||
additional_attributes: {},
|
||||
custom_attributes: {}
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -448,6 +448,7 @@ Rails.application.routes.draw do
|
||||
post 'webhooks/whatsapp/:phone_number', to: 'webhooks/whatsapp#process_payload'
|
||||
get 'webhooks/instagram', to: 'webhooks/instagram#verify'
|
||||
post 'webhooks/instagram', to: 'webhooks/instagram#events'
|
||||
post 'webhooks/facebook/delete', to: 'webhooks/facebook#process_deletion'
|
||||
|
||||
namespace :twitter do
|
||||
resource :callback, only: [:show]
|
||||
|
||||
@@ -41,4 +41,7 @@ module Redis::RedisKeys
|
||||
IG_MESSAGE_MUTEX = 'IG_MESSAGE_CREATE_LOCK::%<sender_id>s::%<ig_account_id>s'.freeze
|
||||
SLACK_MESSAGE_MUTEX = 'SLACK_MESSAGE_LOCK::%<conversation_id>s::%<reference_id>s'.freeze
|
||||
EMAIL_MESSAGE_MUTEX = 'EMAIL_CHANNEL_LOCK::%<inbox_id>s'.freeze
|
||||
|
||||
## Meta deletion flags
|
||||
META_DELETE_PROCESSING = 'META_DELETE_PROCESSING::%<id>s'.freeze
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user