defmodule WalletPasses do @moduledoc """ Apple Wallet and Google Wallet pass generation, management, and remote updates. This module provides convenience functions that orchestrate both platforms. For platform-specific control, use `WalletPasses.Apple.Builder`, `WalletPasses.Google.Api`, etc. directly. """ alias WalletPasses.Apple alias WalletPasses.Google alias WalletPasses.PassData alias WalletPasses.Schema @doc """ Generates an Apple .pkpass binary for a pass. Creates or retrieves the Apple pass record, then builds the .pkpass bundle. """ def build_apple_pass(%PassData{} = pass_data, %Apple.Visual{} = visual) do with {:ok, apple_pass} <- Schema.get_or_create_apple_pass(pass_data.serial_number) do Apple.Builder.build_pkpass(pass_data, visual, apple_pass.auth_token) end end @doc """ Generates a "Save to Google Wallet" URL for a pass. Creates or retrieves the Google pass record, creates/updates the object on Google's servers, and returns the save URL. """ def google_save_url(%PassData{} = pass_data, %Google.Visual{} = visual, opts \\ []) do {class_id, save_opts} = Keyword.pop(opts, :class_id) with {:ok, google_pass} <- Schema.get_or_create_google_pass(pass_data.serial_number), {:ok, object_id} <- Google.Api.create_object(pass_data, visual, class_id: class_id) do Schema.update_google_object_id(google_pass, object_id) pass_object = Google.Api.build_pass_object(pass_data, visual, class_id: class_id) Google.SaveUrl.url(pass_object, save_opts) end end @doc "Sends Apple push notifications for a pass to trigger refresh on devices." def notify_apple_devices(serial_number) when is_binary(serial_number) do tokens = Schema.list_push_tokens_for_serial(serial_number) Apple.Push.notify_devices(tokens) end @doc "Updates a Google Wallet pass object on Google's servers." def update_google_pass(%PassData{} = pass_data, %Google.Visual{} = visual, opts \\ []) do case Schema.get_google_pass(pass_data.serial_number) do nil -> {:error, :not_found} google_pass when is_nil(google_pass.object_id) -> {:error, :no_object_id} google_pass -> Google.Api.update_object(pass_data, visual, google_pass.object_id, opts) end end end