defmodule WeChat.Storage.Hub do @moduledoc """ The storage adapter specification for WeChat common application. Since we need to temporarily storage some key data(e.g. `access_token`) for invoking WeChat APIs, this module is used for customizing the persistence when use `elixir_wechat` in the centralization nodes(hereinafter "hub") side of WeChat common application. Notice: the scenario as a hub, we need to implement the completed functions to maintain the persistence. ## Writing custom storage adapter #### Example for WeChat Official Account Platform application defmodule MyAppStorageHub do @behaviour WeChat.Storage.Hub @impl true def fetch_secret_key(appid, args) do secret_key = "Get secret_key by appid from your persistence..." secret_key end @impl true def fetch_access_token(appid, args) do access_token = "Get access_token by appid from your persistence..." {:ok, %WeChat.Token{access_token: access_token}} end @impl true def fetch_ticket(appid, type, args) do ticket = "Get ticket by appid from your persistence..." {:ok, ticket} end @impl true def refresh_access_token(appid, access_token, args) do access_token = "Refresh access_token by appid from your persistence..." {:ok, %WeChat.Token{access_token: access_token}} end @impl true def save_access_token(appid, access_token, args) do # Save access_token by appid to your persistence end @impl true def save_ticket(appid, ticket, type, args) do # Save ticket by appid to your persistence end end #### Use `MyAppStorageHub` Global configure `MyAppStorageHub` defmodule Client do use WeChat, adapter_storage: {MyAppStorageHub, args} end defmodule Client do use WeChat, adapter_storage: MyAppStorageHub end Dynamically set `MyAppStorageHub` when call `WeChat.request/2` WeChat.request(:post, url: ..., adapter_storage: {MyAppStorageHub, args}, ...) WeChat.request(:post, url: ..., adapter_storage: MyAppStorageHub, ...) Notice: The above `args` will be returned back into each implement of callback function, if not input it, `args` will be as an empty list in callback. """ @doc """ Fetch secret_key of WeChat common application. """ @callback fetch_secret_key(appid :: String.t(), args :: term()) :: {:ok, String.t()} | nil @doc """ Fetch access_token of WeChat common application. """ @callback fetch_access_token(appid :: String.t(), args :: term()) :: {:ok, %WeChat.Token{}} | {:error, %WeChat.Error{}} @doc """ Save access_token of WeChat common application. """ @callback save_access_token(appid :: String.t(), access_token :: String.t(), args :: term()) :: {:ok, %WeChat.Token{}} @doc """ Refresh access_token of WeChat common application. """ @callback refresh_access_token(appid :: String.t(), access_token :: String.t(), args :: term()) :: {:ok, %WeChat.Token{}} | {:error, %WeChat.Error{}} @doc """ Save ticket of WeChat common application, the option of `type` parameter is "wx_card" or "jsapi"(refer WeChat Official document). """ @callback save_ticket( appid :: String.t(), ticket :: String.t(), type :: String.t(), args :: term() ) :: {:ok, %WeChat.Ticket{}} @doc """ Fetch ticket of WeChat common application, the option of `type` parameter is "wx_card" or "jsapi"(refer WeChat Official document). """ @callback fetch_ticket(appid :: String.t(), type :: String.t(), args :: term()) :: {:ok, %WeChat.Ticket{}} | {:error, %WeChat.Error{}} end defmodule WeChat.Storage.ComponentHub do @moduledoc """ The storage adapter specification for WeChat component application. Since we need to temporarily storage some key data(e.g. `access_token`/`component_access_token`) for invoking WeChat APIs, this module is used for customizing the persistence when use `elixir_wechat` in the centralization nodes(hereinafter "hub") side of WeChat component application. Notice: the scenario as a hub, we need to implement the completed functions to maintain the persistence. ## Writing custom storage adapter #### Example for WeChat 3rd-party Platform application defmodule MyComponentAppStorageHub do @behaviour WeChat.Storage.ComponentHub @impl true def fetch_access_token(appid, authorizer_appid, args) do access_token = "Get authorizer's access_token for WeChat component application from your persistence..." {:ok, %WeChat.Token{access_token: access_token}} end @impl true def fetch_component_access_token(appid, args) do access_token = "Get component access_token for WeChat component application from your persistence..." {:ok, %WeChat.Token{access_token: access_token}} end @impl true def fetch_component_verify_ticket(appid, args) do component_verify_ticket = "Get component_verify_ticket for WeChat component application from your persistence..." {:ok, component_verify_ticket} end @impl true def fetch_secret_key(appid, args) do secret_key = "Get component application secret_key from your persistence..." secret_key end @impl true def fetch_ticket(appid, authorizer_appid, type, args) do ticket = "Get authorizer account's ticket for WeChat component application from your persistence..." {:ok, ticket} end @impl true def refresh_access_token(appid, authorizer_appid, access_token, args) do access_token = "Refresh authorizer's access_token for WeChat component application from your persistence..." {:ok, %WeChat.Token{access_token: access_token}} end @impl true def refresh_component_access_token(appid, component_access_token, args) do access_token = "Refresh access_token of WeChat component application..." {:ok, %WeChat.Token{access_token: access_token}} end @impl true def save_access_token(appid, authorizer_appid, access_token, refresh_token, args) do # Save authorizer's access_token and its refresh_token to your persistence end @impl true def save_component_access_token(appid, component_access_token, args) do # Save access_token of WeChat component application end @impl true def save_component_verify_ticket(appid, component_verify_ticket, args) do # Save component_verify_ticket to your persistence end @impl true def save_ticket(appid, authorizer_appid, ticket, type, args) do # Save authorizer account's ticket to your persistence end end #### Use `MyComponentAppStorageHub` Global configure `MyComponentAppStorageHub` defmodule Client do use WeChat, adapter_storage: {MyComponentAppStorageHub, args} end defmodule Client do use WeChat, adapter_storage: MyComponentAppStorageHub end Dynamically set `MyComponentAppStorageHub` when call `WeChat.request/2` WeChat.request(:post, url: ..., adapter_storage: {MyComponentAppStorageHub, args}, ...) WeChat.request(:post, url: ..., adapter_storage: MyComponentAppStorageHub, ...) Notice: The above `args` will be returned back into each implement of callback function, if not input it, `args` will be as an empty list in callback. """ @doc """ Get secret_key of WeChat component application. """ @callback fetch_secret_key(appid :: String.t(), args :: term()) :: {:ok, String.t()} | nil @doc """ Get authorizer's access_token for WeChat component application. """ @callback fetch_access_token( appid :: String.t(), authorizer_appid :: String.t(), args :: term() ) :: {:ok, %WeChat.Token{}} | {:error, %WeChat.Error{}} @doc """ Save authorizer's access_token for WeChat component application. """ @callback save_access_token( appid :: String.t(), authorizer_appid :: String.t(), access_token :: String.t(), refresh_token :: String.t(), args :: term() ) :: term() @doc """ Refresh authorizer's access_token for WeChat component application. """ @callback refresh_access_token( appid :: String.t(), authorizer_appid :: String.t(), access_token :: String.t(), args :: term() ) :: {:ok, %WeChat.Token{}} | {:error, %WeChat.Error{}} @doc """ Get access_token of WeChat component application. """ @callback fetch_component_access_token(appid :: String.t(), args :: term()) :: {:ok, %WeChat.Token{}} @doc """ Save access_token of WeChat component application. """ @callback save_component_access_token( appid :: String.t(), component_access_token :: String.t(), args :: term() ) :: {:ok, %WeChat.Token{}} @doc """ Refresh access_token of WeChat component application. """ @callback refresh_component_access_token( appid :: String.t(), component_access_token :: String.t(), args :: term() ) :: {:ok, %WeChat.Token{}} | {:error, %WeChat.Error{}} @doc """ Fetch component_verify_ticket of WeChat component application. """ @callback fetch_component_verify_ticket(appid :: String.t(), args :: term()) :: {:ok, String.t()} | {:error, %WeChat.Error{}} @doc """ Save component_verify_ticket of WeChat component application. """ @callback save_component_verify_ticket( appid :: String.t(), component_verify_ticket :: String.t(), args :: term() ) :: term() @doc """ Save authorizer account's ticket in WeChat component application. """ @callback save_ticket( appid :: String.t(), authorizer_appid :: String.t(), ticket :: String.t(), type :: String.t(), args :: term() ) :: {:ok, %WeChat.Ticket{}} @doc """ Fetch authorizer account's ticket in WeChat component application. """ @callback fetch_ticket( appid :: String.t(), authorizer_appid :: String.t(), type :: String.t(), args :: term() ) :: {:ok, %WeChat.Ticket{}} | {:error, %WeChat.Error{}} end