Commit f6f90316 by lra

阿里大鱼短信发送优化和语音验证码 语音通知添加

parent c2aa3091
......@@ -30,49 +30,103 @@ class SmsSender
SOURCES = %w(taobao zucp)
attr_accessor :source, :template_code
attr_accessor :source, :source_config, :template_code, :attrs
def initialize(options = {})
options[:source] = redis.get('sms:source') || SOURCES.first if options[:source].blank?
return unless options[:source].in?(SOURCES)
def initialize(opts = {})
self.attrs = HashWithIndifferentAccess.new(opts)
if load_config.present? && load_config[options[:source]].present?
options = load_config[options[:source]].merge(options)
end
options = HashWithIndifferentAccess.new(options)
assign_source
extend_attrs
return unless attrs[:source]
if options[:source].eql? 'zucp'
send("#{attrs[:source].to_s}_init")
@source = "Sms/#{attrs[:source]}".camelize.constantize.new(attrs)
end
if options[:template_code].present?
templates = backend(I18n.locale => {'sms_zucp_templates' => load_config[:zucp][:templates]})
I18n.backend = I18n::Backend::Chain.new(templates)
def assign_source
return if attrs[:source]
options.merge!(content: I18n.t("sms_zucp_templates.#{options[:template_code].to_s.gsub('.', '_')}", options[:content_params]))
attrs[:source] = redis.get('sms:source') || SOURCES.first
return unless attrs[:source].in?(SOURCES)
end
elsif options[:source].eql? 'taobao'
def extend_attrs
return unless load_config.present?
self.source_config = load_config[attrs[:source]]
return unless source_config.present?
if options[:template_code].present?
options.merge!(sms_template_code: load_config[:taobao][:templates][options[:template_code].to_s.gsub('.', '_')])
options.merge!(sms_param: options[:content_params])
self.attrs = source_config.merge(attrs)
end
def zucp_init
return unless attrs[:template_code].present?
return unless source_config.present?
templates = backend(I18n.locale => {
'sms_zucp_templates' => source_config[:templates]
})
I18n.backend = I18n::Backend::Chain.new(templates)
zucp_template_code = "sms_zucp_templates.#{attrs[:template_code].to_s.gsub('.', '_')}"
attrs.merge!(content: I18n.t(zucp_template_code, attrs[:content_params]))
end
@source = "Sms/#{options[:source]}".camelize.constantize.new(options)
def taobao_init
return unless attrs[:template_code].present?
return unless source_config.present?
template_code = attrs[:template_code].to_s.gsub('.', '_')
taobao_template_code = source_config[:templates][template_code] rescue nil
attrs.merge!({
template_code: taobao_template_code,
param: attrs[:content_params]
})
end
def singleSend(number)
return unless @source
return unless number.present?
@source.singleSend(number)
numbers = number_regroup(number)
return unless numbers.present?
@source.single_send(numbers)
end
def batchSend(numbers)
return unless @source
_numbers = numbers.is_a?(String) ? numbers.split(',') : (numbers.is_a?(Array) ? numbers : [])
_numbers = _numbers.compact.uniq
@source.batchSend(_numbers)
numbers = number_regroup(numbers)
return unless numbers.present?
@source.batch_send(numbers)
end
# 语音验证码
def text_to_voice_verify(number)
return unless @source
numbers = number_regroup(number)
return unless numbers.present?
@source.tts_num_singlecall(numbers, 'verify')
end
# 语音通知
def text_to_voice_notify(number)
return unless @source
numbers = number_regroup(number)
return unless numbers.present?
@source.tts_num_singlecall(numbers, 'notify')
end
def number_regroup(number)
return number.split(',') if number.is_a?(String)
return number if number.is_a?(Array)
[]
end
protected
......@@ -90,7 +144,8 @@ if defined? ::Rails
module Rails
class Railtie < ::Rails::Railtie
rake_tasks do
load "tasks/sms.rake"
# import "/Users/lihui/workplace/demo/rails/gems/sms/lib/tasks/sms.rake"
load 'tasks/sms.rake'
end
end
end
......
......@@ -5,62 +5,91 @@ require 'net/http'
module Sms
class Taobao
attr_accessor :app_secret, :app_key, :sms_free_sign_name, :sms_template_code, :sms_param
attr_accessor :app_secret, :app_key,
:sms_free_sign_name, :called_show_verify_nums, :called_show_notify_nums,
:template_code, :param,
:custom_params, :request_params
def initialize(options = {})
self.app_secret = options[:app_secret]
self.app_key = options[:app_key]
self.sms_free_sign_name = options[:sms_free_sign_name]
self.sms_template_code = options[:sms_template_code]
self.sms_param = options[:sms_param] || {}
options.each{|k, v|
next unless respond_to?(k)
self.send("#{k.to_s}=", v)
}
end
def singleSend(number)
send(number.split)
def single_send(number)
sms_num_send(number.split)
end
def batchSend(numbers)
send(numbers)
def batch_send(numbers)
sms_num_send(numbers)
end
def defaultParams(numbers)
def public_params
{
method: 'alibaba.aliqin.fc.sms.num.send',
app_key: self.app_key,
timestamp: Time.now.strftime("%Y-%m-%d %H:%M:%S"),
format: 'json',
v: 2.0,
sign_method: 'md5',
sms_type: 'normal',
sms_free_sign_name: self.sms_free_sign_name,
rec_num: numbers.join(','),
sms_param: self.sms_param.to_json,
sms_template_code: self.sms_template_code
}
end
def generate_sign(params)
str = params.to_a.map{|m| m.map(&:to_s).join }.sort.join
def extend_params
params = public_params.merge(self.custom_params)
self.request_params = params.merge(sign: generate_sign(params))
end
def generate_sign(opts = {})
str = opts.to_a.map{|m| m.map(&:to_s).join }.sort.join
Digest::MD5.hexdigest("#{app_secret.to_s}#{str}#{app_secret.to_s}").upcase
end
def send(numbers)
params = defaultParams(numbers)
params = params.merge(sign: generate_sign(params))
data = request_api(params)
data = JSON.parse(data.body)
puts "data ************* #{data}"
if data['alibaba_aliqin_fc_sms_num_send_response']['result']['success']
data
else
false
def sms_num_send(numbers)
self.custom_params = {
method: 'alibaba.aliqin.fc.sms.num.send',
rec_num: numbers.join(','),
sms_param: param.to_json,
sms_template_code: template_code,
sms_type: 'normal',
sms_free_sign_name: self.sms_free_sign_name
}
post
end
rescue => e
false
def tts_num_singlecall(numbers, type = 'notify')
called_show_nums = send("called_show_#{type}_nums")
size = called_show_nums.size
self.custom_params = {
method: 'alibaba.aliqin.fc.tts.num.singlecall',
called_num: numbers.join(','),
called_show_num: called_show_nums[rand(1..size)],
tts_param: param.to_json,
tts_code: template_code
}
post
end
def request_api(params)
Net::HTTP.post_form(URI.parse('http://gw.api.taobao.com/router/rest'), params)
def post
res = Net::HTTP.post_form(URI.parse('http://gw.api.taobao.com/router/rest'), extend_params)
puts "#{request_params[:method]} request params: #{request_params.inspect}"
data = res.body
data = JSON.parse(data) if data.is_a? String
puts "#{request_params[:method]} request result: #{data.inspect}"
result = HashWithIndifferentAccess.new data
keys = result.keys
return if 'error_response'.in?(keys)
key = "#{request_params[:method].gsub(/\./, '_')}_response"
return unless key.in?(keys) && keys.size == 1
result[key][:err_code].to_i.zero?
end
end
......
module Sms
VERSION = "0.1.0"
VERSION = "0.1.1"
end
......@@ -39,7 +39,7 @@ module Sms
end
# 批量发送 numbers是个数组
def batchSend(numbers)
def batch_send(numbers)
params = defaultParams(numbers)
data = send(params)
puts "data ************* #{data}"
......@@ -55,7 +55,7 @@ module Sms
end
# 单次发送(用户名,密码,接收方号码,内容)
def singleSend(number)
def single_send(number)
params = defaultParams(number.split)
data = send(params)
# VcoolineLog::SmsApi.add("sms api singleSend data: #{data}")
......
namespace :sms do
desc 'create default sms config file'
task :create_default_config_file do
unless File.exist?("#{::Rails.root}/config/sms.yml")
FileUtils.cp(File.expand_path("../../templates/sms.yml", __FILE__), "#{::Rails.root}/config/sms.yml")
......
......@@ -12,6 +12,12 @@ defaults: &defaults
app_secret: xxxx
app_key: xxxx
sms_free_sign_name: xxxx
called_show_verify_nums:
- xxx1
- xxx2
called_show_notify_nums:
- xxx1
- xxx2
templates:
devise_supplier_applies_otp_code_confirm: xxxx
devise_passwords_otp_code_confirm: xxxx
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment