Current section

Files

Jump to
aliyun lib sms cli.ex
Raw

lib/sms/cli.ex

require Logger
defmodule Aliyun.SMS.CLI do
@moduledoc """
阿里云SMS库
"""
@sms_endpoint Application.get_env(:aliyun, :sms_endpoint)
@sms_access_key_id Application.get_env(:aliyun, :sms_access_key_id) || Application.get_env(:aliyun, :access_key_id)
@sms_access_key_secret Application.get_env(:aliyun, :sms_access_key_secret) || Application.get_env(:aliyun, :access_key_secret)
@sms_signature_version Application.get_env(:aliyun, :sms_signature_version)
@sms_version Application.get_env(:aliyun, :sms_version)
@sms_region_id Application.get_env(:aliyun, :sms_region_id)
def send(phone_numbers, template_code, template_param, sign_name \\ Application.get_env(:aliyun, :sms_sign_name)) do
arguments = format_arguments(phone_numbers, template_code, template_param, sign_name)
signature = gen_signature(arguments)
body = [{"Signature", signature} | arguments]
case HTTPoison.post(@sms_endpoint, {:form, body}) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
phone_numbers |> String.split(",") |> Enum.each(fn phone -> Logger.info("[#{template_code}##{phone}] => #{Poison.encode!(template_param)}", filter: :sms) end)
{:ok, 200, Poison.decode!(body)}
{:ok, %HTTPoison.Response{status_code: status_code, body: body}} ->
{:ok, status_code, Poison.decode!(body)}
{:error, %HTTPoison.Error{reason: reason}} ->
{:error, reason}
end
end
defp gen_signature(arguments, method \\ "POST") do
args = arguments |> Enum.map(fn {key, val} -> {url_encode(key), url_encode(val)} end) |> Enum.map(fn {key, val} -> "#{key}=#{val}" end) |> Enum.join("&")
string_to_sign = "#{String.upcase(method)}" <> "&" <> url_encode("/") <> "&" <> url_encode(args)
:crypto.hmac(:sha, "#{@sms_access_key_secret}&", string_to_sign) |> Base.encode64
end
defp format_arguments(phone_numbers, template_code, template_param, sign_name) do
%{
"SignatureMethod" => "HMAC-SHA1",
"SignatureNonce" => UUID.uuid1(),
"AccessKeyId" => @sms_access_key_id,
"SignatureVersion" => @sms_signature_version,
"Timestamp" => format_gmt_time(),
"Format" => "JSON",
"Action" => "SendSms",
"Version" => @sms_version,
"RegionId" => @sms_region_id,
"PhoneNumbers" => phone_numbers,
"SignName" => sign_name,
"TemplateParam" => Poison.encode!(template_param),
"TemplateCode" => template_code
} |> Enum.sort_by(fn {key, _} -> key end)
end
defp format_gmt_time do
Timex.format!(Timex.now, "%Y-%m-%dT%H:%M:%SZ", :strftime)
end
defp url_encode(text) do
URI.encode_www_form(text) |> String.replace("%2B", "%20") |> String.replace("%7E", "~")
end
end