这篇文章讲什么?

如何在 Ruby on Rails 里实现用 阿里云发短信

这篇文章对谁有用?

Ruby on Rails 程序员

有什么用?

节省开发时间

外观

外观其实没啥可说的,注册登录页面大家都见过,
但文章开头还是贴一个图,这样直观一些

先问前提:为什么选"阿里云"而不是其他服务商?

我2018年5月时,调查对比过短信服务商,链接在此

结论:各家价格差异不大,都是4分钱左右。

既然这样,那就选一个大的服务商来用。
当时在做的那个项目,我有决策权,所以选了阿里云,后续使用没什么问题。

这次2020年2月再做,是因为上级说要用阿里云来发短信,
据说之前用 AWS 不稳定还是咋回事。那个部分我没有参与,所以不清楚。

这次再做短信发送我已经全部忘记了,
原本想翻一下自己的博客,看看之前是怎么做的,然后发现我根本没写。所以这次补一下。

正文开始

我们使用 gem 'aliyun-sms' 这个 Gem
把它填入 Gemfile 然后 bundle install 即可

这个 gem 的Github 地址在这里

注意,这个 gem 不是阿里云官方的

另外,虽然阿里云文档没有写 "Ruby SDK"

https://help.aliyun.com/document_detail/101874.html?spm=a2c4g.11186623.6.650.5d5856e0qAOkF8

但实际上是有 Ruby SDK 的

在 OpenAPI Explorer 里

https://api.aliyun.com/new?spm=5176.12207334.0.0.5de01cbeViD6sg#/?product=Dysmsapi&api=SendSms&params=%7B%22RegionId%22%3A%22cn-hangzhou%22%2C%22PhoneNumbers%22%3A%22%22%2C%22SignName%22%3A%22%22%2C%22TemplateCode%22%3A%22%22%7D&tab=DEMO&lang=JAVA

进入 OpenAPI Explorer 的地方是 :

aliyunsdkcore gem 的 Github 长这样:

https://github.com/aliyun/openapi-core-ruby-sdk

所以,用以下 2 个 gem 都可以

  • gem 'aliyun-sms'(非官方)
  • gem 'aliyunsdkcore'(官方)

但因为我代码已经写好了,用的是 gem 'aliyun-sms',所以下文都是基于这个 gem

第二步:配置 aliyun-sms

新建一个文件叫 config/initializers/aliyun-sms.rb
填入如下内容:

这些其实文档里都有写:

后文会提供可复制粘贴的代码

https://github.com/VICTOR-LUO-F/aliyun-sms/blob/master/README.zh-CN.md

我做一下补充,可以看到上图里,需要我们填的是

  • ACCESS_KEY_SECRET
  • ACCESS_KEY_ID
  • SIGN_NAME

ACCESS_KEY_SECRET 和 ACCESS_KEY_ID 的来源是

点击右上角,创建 AccessKey

SIGN_NAME 的来源是

其实文档也有写:

https://help.aliyun.com/document_detail/101414.html?spm=a2c4g.11186623.2.13.2f3e3e2cvmgFL6

最终成品类似这样:

Aliyun::Sms.configure do |config|
  config.access_key_secret = 'BE0xxxfyKB1qiI8vZVmtvFDLoKgxxx'
  config.access_key_id = 'LTAI4xxxtZ1P1pm1nKRcvxxx'
  config.action = 'SendSms'                       # default value
  config.format = 'XML'                           # http return format, value is 'JSON' or 'XML'
  config.region_id = 'cn-hangzhou'                # default value
  config.sign_name = '奇绩创坛' # 短信签名,在阿里云申请开通短信服务时获取。
  config.signature_method = 'HMAC-SHA1'           # default value
  config.signature_version = '1.0'                # default value
  config.version = '2017-05-25'                   # default value
end

第三步:发送短信

比如这样(可复制粘贴自己测试)

phone = '135xxxx1111'
template_code = "SMS_182825750"
token = rand(100000..999999)
template_param = {"code" => token.to_s}.to_json
Aliyun::Sms.send(phone, template_code, template_param)

如何发送国际短信(2020-2-27 更新)

阿里云分成国内和国际两种渠道

第一步:首先确保你有"国际/港澳台套餐包",没有就买

这个在阿里云官网买就行了

https://common-buy.aliyun.com/?spm=5176.8195934.1299677.4.759d30c9MMbDHp&commodityCode=newdysmsbag_int&aly_as=hIlaHt8F#/buy

第二步:确保有"国际/港澳台消息"的短信模板

没有就填写并且等待审核通过

第三步:测试

我们用 OpenAPI Explorer 来测

这里这个手机号是 +1 650391xxxx
+1 是美国手机号。

注意只需要写成 1650391xxxx 就行。阿里云不需要+号,不需要空格,不需要00

https://help.aliyun.com/document_detail/101414.html?spm=a2c4g.11186623.6.624.2d7e5f30WqvKFX
https://help.aliyun.com/document_detail/109098.html?spm=a2c4g.11186623.6.710.4af556e0n5v7C6

结论,如果发短信到国外号码

+1 650391xxxx 写成 1650391xxxx 传给阿里云即可。

额外注意:为了发到国外,必须用国外的 Template Code

用国内的 "模板CODE",会被当做国内号码
用国际的 "模板CODE",会被当做国际号码