defmodule MessengerBot.Webhook.Callback do @moduledoc """ MessengerBot webhook for all callbacks """ alias MessengerBot.Model.{Entry, Sender, Recipient, AccountLinking, Delivery, Message, Optin, Postback, Read, Referral} alias MessengerBot.Payload.Process, as: ProcessPayload alias MessengerBot.Payload.Webhook, as: WebhookPayload @decoder %WebhookPayload{entry: [%Entry{}]} @spec process(String.t) :: {:ok, String.t} def process(payload) do EventBus.notify({:mb_webhook_received, payload}) webhook_payload = Poison.decode!(payload, as: @decoder, keys: :atoms) Enum.each(webhook_payload.entry, fn(entry) -> process_entry(entry) end) {:ok, "ok"} end defp process_entry(%Entry{} = entry) do Enum.each(entry.messaging, fn(messaging) -> process_messaging(entry.id, entry.time, messaging) end) end defp process_messaging(page_id, time, messaging) do {topic, data} = fetch_topic_and_data(messaging) payload = %ProcessPayload{page_id: page_id, data: data, time: time, sender: struct(Sender, messaging.sender || %{}), recipient: struct(Recipient, messaging.recipient || %{})} EventBus.notify({topic, payload}) end defp fetch_topic_and_data(%{delivery: delivery}) when not is_nil(delivery) do {:mb_delivery_received, struct(Delivery, delivery)} end defp fetch_topic_and_data(%{read: read}) when not is_nil(read) do {:mb_read_received, struct(Read, read)} end defp fetch_topic_and_data(%{message: %{is_echo: true}} = messaging) do {:mb_message_echo_received, struct(Message, messaging.message)} end defp fetch_topic_and_data(%{message: %{attachments: attachments}} = messaging) when not is_nil(attachments) do {:mb_message_attachments_received, struct(Message, messaging.message)} end defp fetch_topic_and_data(%{message: %{quick_reply: quick_reply}} = messaging) when not is_nil(quick_reply) do {:mb_message_quick_reply_received, struct(Message, messaging.message)} end defp fetch_topic_and_data(%{message: message}) when not is_nil(message) do {:mb_message_received, struct(Message, message)} end defp fetch_topic_and_data(%{optin: optin}) when not is_nil(optin) do {:mb_optin_received, struct(Optin, optin)} end defp fetch_topic_and_data(%{postback: postback}) when not is_nil(postback) do {:mb_postback_received, struct(Postback, postback)} end defp fetch_topic_and_data(%{referral: referral}) when not is_nil(referral) do {:mb_referral_received, struct(Referral, referral)} end defp fetch_topic_and_data(%{payment: payment}) when not is_nil(payment) do {:mb_payment_received, payment} end defp fetch_topic_and_data(%{checkout_update: checkout_update}) when not is_nil(checkout_update) do {:mb_checkout_update_received, checkout_update} end defp fetch_topic_and_data(%{pre_checkout: pre_checkout}) when not is_nil(pre_checkout) do {:mb_pre_checkout_received, pre_checkout} end defp fetch_topic_and_data(%{account_linking: account_linking}) when not is_nil(account_linking) do {:mb_account_linking_received, struct(AccountLinking, account_linking)} end defp fetch_topic_and_data(%{policy_enforcement: policy_enforcement}) when not is_nil(policy_enforcement) do {:mb_policy_enforcement_received, policy_enforcement} end defp fetch_topic_and_data(%{app_roles: app_roles}) when not is_nil(app_roles) do {:mb_app_roles_received, app_roles} end defp fetch_topic_and_data(%{standby: standby}) when not is_nil(standby) do {:mb_standby_received, standby} end defp fetch_topic_and_data(%{pass_thread_control: pass_thread_control}) when not is_nil(pass_thread_control) do {:mb_pass_thread_control_received, pass_thread_control} end defp fetch_topic_and_data(%{take_thread_control: take_thread_control}) when not is_nil(take_thread_control) do {:mb_take_thread_control_received, take_thread_control} end defp fetch_topic_and_data(data) do {:mb_na_received, data} end end