Current section
29 Versions
Jump to
Current section
29 Versions
Compare versions
8
files changed
+102
additions
-13
deletions
| @@ -2,6 +2,9 @@ | |
| 2 2 | Wechat API wrapper in Elixir. |
| 3 3 | |
| 4 4 | [](https://circleci.com/gh/elixir-wechat/wechat) |
| 5 | + [](https://codebeat.co/projects/github-com-elixir-wechat-wechat-master) |
| 6 | + [](https://hex.pm/packages/wechat) |
| 7 | +  |
| 5 8 | |
| 6 9 | ## Installation |
| 7 10 | ```elixir |
| @@ -17,7 +17,7 @@ | |
| 17 17 | <<"lib/wechat/plugs">>,<<"lib/wechat/plugs/request_validator.ex">>, |
| 18 18 | <<"lib/wechat/plugs/message_parser.ex">>,<<"lib/wechat/base.ex">>, |
| 19 19 | <<"lib/wechat/menu.ex">>,<<"lib/wechat/application.ex">>, |
| 20 | - <<"lib/wechat.ex">>,<<"lib/wechat_bypass">>, |
| 20 | + <<"lib/wechat/helpers">>,<<"lib/wechat.ex">>,<<"lib/wechat_bypass">>, |
| 21 21 | <<"lib/wechat_bypass/assertion.ex">>,<<"lib/wechat_bypass/case.ex">>, |
| 22 22 | <<".formatter.exs">>,<<"mix.exs">>,<<"README.md">>,<<"LICENSE.txt">>]}. |
| 23 23 | {<<"licenses">>,[<<"MIT">>]}. |
| @@ -44,4 +44,4 @@ | |
| 44 44 | {<<"optional">>,true}, |
| 45 45 | {<<"repository">>,<<"hexpm">>}, |
| 46 46 | {<<"requirement">>,<<">= 0.0.0">>}]]}. |
| 47 | - {<<"version">>,<<"0.4.4">>}. |
| 47 | + {<<"version">>,<<"0.4.5">>}. |
| @@ -44,6 +44,42 @@ defmodule Wechat do | |
| 44 44 | def client do |
| 45 45 | Wechat.Client.new(config()) |
| 46 46 | end |
| 47 | + |
| 48 | + def access_token do |
| 49 | + Wechat.Client.access_token(client()) |
| 50 | + end |
| 51 | + |
| 52 | + def encrypt_message(msg) do |
| 53 | + Wechat.Client.encrypt_message(client(), msg) |
| 54 | + end |
| 55 | + |
| 56 | + if Code.ensure_loaded?(Phoenix.Controller) do |
| 57 | + def wechat_config_js(conn, opts \\ []) do |
| 58 | + client = client() |
| 59 | + |
| 60 | + import Phoenix.Controller, only: [current_url: 1] |
| 61 | + page_url = current_url(conn) |
| 62 | + |
| 63 | + debug = Keyword.get(opts, :debug, false) |
| 64 | + js_api_list = opts |> Keyword.get(:api, []) |> Enum.join(",") |
| 65 | + |
| 66 | + %{timestamp: timestamp, noncestr: nonce, signature: signature} = |
| 67 | + Wechat.Client.sign_jsapi(client, page_url) |
| 68 | + |
| 69 | + """ |
| 70 | + <script type="text/javascript"> |
| 71 | + wx.config({ |
| 72 | + debug: #{debug}, |
| 73 | + jsApiList: ['#{js_api_list}'], |
| 74 | + appId: '#{client.appid}', |
| 75 | + timestamp: '#{timestamp}', |
| 76 | + nonceStr: '#{nonce}', |
| 77 | + signature: '#{signature}' |
| 78 | + }); |
| 79 | + </script> |
| 80 | + """ |
| 81 | + end |
| 82 | + end |
| 47 83 | end |
| 48 84 | end |
| 49 85 | end |
| @@ -16,7 +16,7 @@ if Code.ensure_loaded?(Redix) do | |
| 16 16 | def child_spec(arg) do |
| 17 17 | %{ |
| 18 18 | id: __MODULE__, |
| 19 | - start: {__MODULE__, :start_link, [arg]}, |
| 19 | + start: {__MODULE__, :start_link, [arg]} |
| 20 20 | } |
| 21 21 | end |
| @@ -4,6 +4,7 @@ defmodule Wechat.Client do | |
| 4 4 | """ |
| 5 5 | |
| 6 6 | alias Wechat.{AccessToken, Base, Config, Error} |
| 7 | + alias Wechat.Utils.{MessageEncryptor, SignatureVerifier} |
| 7 8 | |
| 8 9 | @endpoint "https://api.weixin.qq.com/" |
| 9 10 | |
| @@ -86,12 +87,57 @@ defmodule Wechat.Client do | |
| 86 87 | end |
| 87 88 | |
| 88 89 | @spec access_token(t) :: binary |
| 89 | - def access_token(%{access_token: access_token}), do: access_token |
| 90 | - |
| 91 | - def access_token(%{appid: appid}) do |
| 90 | + def access_token(%{access_token: nil, appid: appid}) do |
| 92 91 | case Config.adapter().read_token(appid) do |
| 93 92 | {:ok, token} -> token.access_token |
| 94 93 | :error -> "" |
| 95 94 | end |
| 96 95 | end |
| 96 | + |
| 97 | + def access_token(%{access_token: access_token}), do: access_token |
| 98 | + |
| 99 | + @doc """ |
| 100 | + Sign jsapi with url. |
| 101 | + """ |
| 102 | + @spec sign_jsapi(t, :binary) :: map |
| 103 | + def sign_jsapi(client, url) do |
| 104 | + {:ok, %{"ticket" => ticket}} = Wechat.Ticket.get_ticket(client, :jsapi) |
| 105 | + timestamp = Wechat.Util.unix_now() |
| 106 | + nonce = Wechat.Util.nonce() |
| 107 | + |
| 108 | + params = %{jsapi_ticket: ticket, noncestr: nonce, timestamp: timestamp, url: url} |
| 109 | + |
| 110 | + signature = |
| 111 | + params |
| 112 | + |> Enum.map(fn {k, v} -> "#{k}=#{v}" end) |
| 113 | + |> Enum.join("&") |
| 114 | + |> Wechat.Util.sha1() |
| 115 | + |
| 116 | + Map.put(params, :signature, signature) |
| 117 | + end |
| 118 | + |
| 119 | + @doc """ |
| 120 | + Encrypt message with encoding_aes_key. |
| 121 | + """ |
| 122 | + def encrypt_message(client, msg) do |
| 123 | + if client.encoding_aes_key do |
| 124 | + %{appid: appid, token: token, encoding_aes_key: encoding_aes_key} = client |
| 125 | + msg_encrypt = MessageEncryptor.encrypt(msg, appid, encoding_aes_key) |
| 126 | + timestamp = Wechat.Util.unix_now() |
| 127 | + nonce = Wechat.Util.nonce() |
| 128 | + |
| 129 | + msg_signature = SignatureVerifier.sign([token, timestamp, nonce, msg_encrypt]) |
| 130 | + |
| 131 | + reply = %{ |
| 132 | + msg_encrypt: msg_encrypt, |
| 133 | + msg_signature: msg_signature, |
| 134 | + timestamp: timestamp, |
| 135 | + nonce: nonce |
| 136 | + } |
| 137 | + |
| 138 | + {:ok, reply} |
| 139 | + else |
| 140 | + {:error, msg} |
| 141 | + end |
| 142 | + end |
| 97 143 | end |
Loading more files…