defmodule Wechat do @moduledoc """ Module for `use`d in your own module. For example, defmodule MyApp.Wechat do use Wechat, otp_app: :my_app // or use Wechat, appid: "", secret: "" end In config.exs, config :wechat, MyApp.Wechat, appid: "app_id", secret: "app_secret" Then: 1. You can invoke APIs by `MyApp.Wechat.users` 2. You have plugs in hand such as `MyApp.Wechat.Plug.MessageParser` """ alias Wechat.{API, Client} @default_hosts [ api_host: "https://api.weixin.qq.com/cgi-bin", sns_host: "https://api.weixin.qq.com/sns", mp_host: "https://mp.weixin.qq.com/cgi-bin" ] @doc """ Application config for Wechat. `@default_hosts` can be tested to simplify test. """ def config do opts = Application.get_env(:wechat, Wechat, []) Keyword.merge(@default_hosts, opts) end @doc """ Adapter to save tokens such as access_token and jsapi_ticket. Default: Wechat.Adapter.Agent """ def adapter do config()[:adapter] || Wechat.Adapter.Agent end defmacro __using__(opts) do quote bind_quoted: [opts: opts] do @otp_app opts[:otp_app] def client do if @otp_app do Client.new(Application.get_env(@otp_app, __MODULE__, [])) else Client.new(unquote(opts)) end end if Code.ensure_loaded?(Plug) do [__MODULE__, :Plug, :MessageParser] |> Module.concat() |> Module.create( quote do use Wechat.Plug.MessageParser, unquote(__MODULE__) end, Macro.Env.location(__ENV__) ) [__MODULE__, :Plug, :RequestValidator] |> Module.concat() |> Module.create( quote do use Wechat.Plug.RequestValidator, unquote(__MODULE__) end, Macro.Env.location(__ENV__) ) end # Base functionality API def access_token, do: API.access_token(client()) def jsapi_ticket, do: API.jsapi_ticket(client()) def clear_quota, do: API.clear_quota(client()) def callbackip, do: API.callbackip(client()) def jscode2session(js_code), do: API.jscode2session(js_code, client()) # User API def users(next_openid \\ ""), do: API.users(next_openid, client()) def user(openid, lang \\ ""), do: API.user(openid, lang, client()) def user_update_remark(openid, remark), do: API.user_update_remark(openid, remark, client()) # Temporary Media API def upload_image(file), do: API.upload_image(file, client()) def upload_voice(file), do: API.upload_voice(file, client()) def upload_video(file), do: API.upload_video(file, client()) def upload_thumb(file), do: API.upload_thumb(file, client()) def upload_media(type, file), do: API.upload_media(type, file, client()) def download_media(media_id), do: API.download_media(media_id, client()) # Custom Message API def send_text(openid, content), do: API.send_text(openid, content, client()) def send_bulk_news(openid, articles), do: API.send_bulk_news(openid, articles, client()) def send_image(openid, media_id), do: API.send_image(openid, media_id, client()) def send_voice(openid, media_id), do: API.send_voice(openid, media_id, client()) def send_mpnews(openid, media_id), do: API.send_mpnews(openid, media_id, client()) def send_wxcard(openid, card_id), do: API.send_wxcard(openid, card_id, client()) def send_music(openid, opts), do: API.send_music(openid, opts, client()) def send_video(openid, opts), do: API.send_video(openid, opts, client()) def send_link(openid, opts), do: API.send_link(openid, opts, client()) def send_mini_program_page(openid, opts), do: API.send_mini_program_page(openid, opts, client()) # Template Message API def send_template_message(openid, template_id, data, opts \\ []), do: API.send_template_message(openid, template_id, data, opts, client()) # Menu API def get_menu, do: API.get_menu(client()) def get_self_menu, do: API.get_self_menu(client()) def delete_menu, do: API.delete_menu(client()) def create_menu(menu), do: API.create_menu(menu, client()) def create_conditional_menu(menu), do: API.create_conditional_menu(menu, client()) def delete_conditional_menu(menu_id), do: API.delete_conditional_menu(menu_id, client()) def try_match_menu(user_id), do: API.try_match_menu(user_id, client()) # Streaming API def users_stream, do: API.users_stream(client()) defoverridable client: 0 end end end