channels_whatsapp_controller.rb 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class ChannelsWhatsappController < ApplicationController
  3. skip_before_action :verify_csrf_token, only: %i[verify_webhook perform_webhook]
  4. def verify_webhook
  5. configuration = Whatsapp::Webhook::Configuration.new(options: params)
  6. challenge = configuration.verify!
  7. render plain: challenge, status: :ok
  8. rescue Whatsapp::Webhook::Configuration::VerificationError, Whatsapp::Webhook::NoChannelError => e
  9. Rails.logger.error e.message
  10. log_request
  11. raise Exceptions::UnprocessableEntity, e.message
  12. end
  13. def perform_webhook
  14. signature = request.headers['X-Hub-Signature-256'].sub('sha256=', '')
  15. uuid = params[:callback_url_uuid]
  16. json = request.body.read
  17. begin
  18. payload = Whatsapp::Webhook::Payload.new(json:, uuid:, signature:)
  19. payload.process
  20. rescue Whatsapp::Webhook::Payload::ValidationError => e
  21. Rails.logger.error e.message
  22. log_request
  23. raise Exceptions::UnprocessableEntity, e.message
  24. rescue Whatsapp::Webhook::Payload::ProcessableError, Whatsapp::Webhook::NoChannelError => e
  25. # Fail silently, any HTTP status code other than 200 will cause WhatsApp
  26. # to retry the request
  27. Rails.logger.error(e.respond_to?(:reason) && e.reason.present? ? "#{e.message}: #{e.reason}" : e.message)
  28. log_request
  29. end
  30. render json: {}, status: :ok
  31. end
  32. private
  33. def log_request
  34. Rails.logger.error "WhatsApp Webhook: #{request.method} #{request.url}"
  35. Rails.logger.error "WhatsApp Webhook: Headers: #{request.headers.inspect}"
  36. Rails.logger.error "WhatsApp Webhook: Params: #{params.inspect}"
  37. Rails.logger.error "WhatsApp Webhook: Payload: #{request.body.read}"
  38. end
  39. end