Skip to content

Instantly share code, notes, and snippets.

@leeyisoft
Last active July 14, 2020 10:02
Show Gist options
  • Save leeyisoft/a6f8c16fee8623437b72fc6378a396ca to your computer and use it in GitHub Desktop.
Save leeyisoft/a6f8c16fee8623437b72fc6378a396ca to your computer and use it in GitHub Desktop.
阿里云短信服务短信发送API(SendSms) Erlang版本
-module (dt_util).
%%%
% datetime 工具箱
%%%
-export ([milliseconds/0]).
-export ([utc_date/1]).
%% 得到现在在制时间毫秒
milliseconds() ->
{MegaSecs, Secs, MicroSecs} = os:timestamp(),
1000000000 * MegaSecs + Secs * 1000 + MicroSecs div 1000.
utc_date("Y-m-d\TH:i:s\Z") ->
TS = {_, _, _Micro} = os:timestamp(),
{{Year, Month, Day}, {Hour, Minute, Second}} =
calendar:now_to_universal_time(TS),
% Mstr = element(Month,{"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}),
Dt = io_lib:format("~4.10.0B-~2.10.0B-~2.10.0BT~2.10.0B:~2.10.0B:~2.10.0BZ",
[Year,Month,Day,Hour,Minute,Second]),
list_to_binary(Dt) .
-module (hash_util).
-export ([hmac_sha1/2]).
hmac_sha1(Str, Key) ->
DataHash = crypto:hmac(sha, Key, Str),
base64:encode_to_string(binary_to_list(DataHash)).
-module (request).
%%%
%% link https://ninenines.eu/docs/en/gun/2.0/guide/http/
%%
%% request:post("localhost", 9800, "/im/v2", [http], D2)
%%%
-export ([get/4]).
-export ([post/5]).
-include("chat.hrl").
get(Host, Port, Path, Protocols) ->
{ok, ConnPid} = open(Host, Port, Protocols),
StreamRef = gun:get(ConnPid, Path, [{"content-type", "application/json"}]),
{ok, Resp} = gun:await_body(ConnPid, StreamRef),
gun:close(ConnPid),
?LOG(Resp),
jsx:decode(Resp).
post(Host, Port, Path, Protocols, Data) ->
{ok, ConnPid} = open(Host, Port, Protocols),
?LOG(Data),
Body = jsx:encode(Data),
% ?LOG(Body),
Body2 = binary_to_list(Body),
% ?LOG(Body2),
StreamRef = gun:post(ConnPid, Path, [
{<<"content-length">>, integer_to_binary(length(Body2))}
, {<<"content-type">>, "application/json"}
], Body2),
{ok, Resp} = gun:await_body(ConnPid, StreamRef),
gun:close(ConnPid),
?LOG(Resp),
jsx:decode(Resp).
%% Internal.
open(Host, Port, Protocols) ->
application:ensure_all_started(gun),
gun:open(Host, Port, #{
connect_timeout => timer:seconds(15),
retry => 10,
protocols => Protocols
}).
https://helpcdn.aliyun.com/document_detail/56189.html?spm=a2c4g.11186623.6.665.535d31445MqOB8
, {sms, [
{switch, <<"on">>}
, {default_code, <<"">>}
, {platform, <<"aliyun">>}
, {<<"aliyun">>, [
{sign_name, <<"xxxxx"/utf8>>}
, {template_code, <<"">>}
, {key_id, <<"">>}
, {key_secret, <<"">>}
, {region_id, <<"cn-shenzhen">>}
]}
]}
上面是配置
erlang代码:
aliyun_send(Mobile, _Type, PtConf, Code) ->
% ?LOG([Mobile, Type]),
KeyId = proplists:get_value(key_id, PtConf),
KeySecret = proplists:get_value(key_secret, PtConf),
RegionId = proplists:get_value(region_id, PtConf),
SignName = proplists:get_value(sign_name, PtConf),
TemplateCode = proplists:get_value(template_code, PtConf),
Nonce = dt_util:milliseconds(),
UtcDatetime = dt_util:utc_date("Y-m-d\TH:i:s\Z"),
TemplateParam = jsx:encode([
{<<"code">>, Code}
]),
% ?LOG(Data),
Data = [
{<<"SignatureMethod">>, <<"HMAC-SHA1">>}
, {<<"SignatureNonce">>, list_to_binary(integer_to_list(Nonce))}
, {<<"SignatureVersion">>, <<"1.0">>}
, {<<"AccessKeyId">>, KeyId}
, {<<"RegionId">>, RegionId}
, {<<"Action">>, <<"SendSms">>}
, {<<"Version">>, <<"2017-05-25">>}
, {<<"Timestamp">>, cow_qs:urlencode(UtcDatetime)}
, {<<"Format">>, <<"JSON">>}
, {<<"PhoneNumbers">>, Mobile}
, {<<"SignName">>, cow_qs:urlencode(SignName)}
, {<<"TemplateCode">>, cow_qs:urlencode(TemplateCode)}
, {<<"TemplateParam">>, cow_qs:urlencode(TemplateParam)}
],
% ?LOG(Data),
Data2 = [binary_to_list(<<"&", Key/binary,"=", Val/binary>>) || {Key, Val} <- lists:keysort(1, Data)],
Data3 = [binary_to_list(cow_qs:urlencode(list_to_binary(KV))) || KV <- Data2],
Tail = lists:concat(Data3),
StrToSign = "GET&%2F&" ++ lists:sublist(Tail, 4, length(Tail)),
Sign = hash_util:hmac_sha1(StrToSign, binary_to_list(<<KeySecret/binary, "&">>)),
Sign2 = ali_r(Sign),
% ?LOG([Sign2, Sign, StrToSign]),
Path1 = <<"/?Signature=", Sign2/binary>>,
Path2 = lists:concat([binary_to_list(Path1) | Data2]),
Resp = request:get("dysmsapi.aliyuncs.com", 80, Path2, [http]),
RespCode = proplists:get_value(<<"Code">>, Resp),
case RespCode of
<<"OK">> ->
{ok, []};
Msg ->
{error, Msg}
end.
ali_r(Str) when is_list(Str) ->
ali_r(list_to_binary(Str));
ali_r(Str) ->
Str2 = binary:replace(Str, <<"+">>, <<"%2B">>, [global]),
Str3 = binary:replace(Str2, <<"*">>, <<"%2A">>, [global]),
binary:replace(Str3, <<"%7E">>, <<"~">>, [global]).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment