ExLine.EventRouter behaviour (ExLine v0.1.0)

Copy Markdown View Source

A DSL for routing parsed LINE webhook events (ExLine.Webhook structs) to handlers.

Routes are declared with macros and matched against the event struct plus an event_assigns map you control. Parse the raw payload with ExLine.Webhook.parse/1 first, then route each event.

Example

defmodule MyApp.LineRouter do
  use ExLine.EventRouter

  # Routes can also match on the assigns set by before_action/2 (e.g. the
  # loaded current_user) — declare the more specific route first.
  text "menu", %{current_user: %{role: :admin}}, MyApp.AdminHandler, :menu
  text "menu", MyApp.MenuHandler, :menu

  message :image, MyApp.MediaHandler, :on_image   # any image message
  postback "buy", MyApp.ShopHandler, :buy
  follow MyApp.OnboardHandler, :welcome
  unfollow MyApp.OnboardHandler, :goodbye
  default MyApp.FallbackHandler, :unknown         # REQUIRED: also catches Event.Unknown

  # Preprocess every event before it is matched: load the current user from
  # the event's source and stash the messaging client for handlers to use.
  @impl true
  def before_action(event, assigns) do
    user =
      case event.source do
        %ExLine.Webhook.Source{user_id: id} when is_binary(id) ->
          MyApp.Accounts.get_by_line_id(id)

        _ ->
          nil
      end

    {event, assigns |> Map.put(:current_user, user) |> Map.put(:client, MyApp.client())}
  end
end

# In your webhook controller (after ExLine.Webhook.Signature has verified it):
params["events"] |> ExLine.Webhook.parse() |> Enum.each(&MyApp.LineRouter.call/1)

Because LINE adds event types without notice (and unknown types become ExLine.Webhook.Event.Unknown), always declare a default/2 route so unmatched events never raise.

Ref: https://developers.line.biz/en/reference/messaging-api/#webhook-event-objects

Summary

Callbacks

Invoked before an event is matched; preprocess the event and assigns here.

Invoked just before the handler is called; lets you tweak the dispatch.

Functions

Routes a module-channel activated event.

Routes a module-channel deactivated event.

Catch-all route for any unmatched event (also catches UnknownEvent).

Routes any message event of the given content kind (:text | :image | :video | :audio | :file | :location | :sticker).

Routes a PNP (LINE notification message) delivery-completion event.

Routes a postback event whose data equals data.

Routes a text message event whose text equals text.

Callbacks

before_action(event, event_assigns)

(optional)
@callback before_action(event :: struct(), event_assigns :: map()) ::
  {event :: struct(), event_assigns :: map()}

Invoked before an event is matched; preprocess the event and assigns here.

before_handler_call(handler, action, event, event_assigns)

@callback before_handler_call(
  handler :: atom(),
  action :: atom(),
  event :: struct(),
  event_assigns :: map()
) :: {atom(), atom(), struct(), map()}

Invoked just before the handler is called; lets you tweak the dispatch.

Functions

account_link(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes an account-link event.

activated(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a module-channel activated event.

beacon(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a beacon event.

bot_resumed(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a bot-resumed event.

bot_suspended(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a bot-suspended event.

deactivated(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a module-channel deactivated event.

default(handler, action)

(macro)

Catch-all route for any unmatched event (also catches UnknownEvent).

follow(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a follow event.

join(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a join event.

leave(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a leave event.

member_joined(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a member-joined event.

member_left(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a member-left event.

membership(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a membership event.

message(kind, assign_match \\ quote do %{} end, handler, action)

(macro)

Routes any message event of the given content kind (:text | :image | :video | :audio | :file | :location | :sticker).

module(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a module-channel event.

pnp_delivery_completion(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a PNP (LINE notification message) delivery-completion event.

postback(data, assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a postback event whose data equals data.

text(text, assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a text message event whose text equals text.

unfollow(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes an unfollow event.

unsend(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes an unsend event.

video_play_complete(assign_match \\ quote do %{} end, handler, action)

(macro)

Routes a video-play-complete event.