smart_sms 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,7 +7,11 @@ module SmartSms
7
7
 
8
8
  source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
9
9
 
10
- desc 'Generates (but does not run) a migration to add a message table.'
10
+ desc <<-EOF
11
+ Generates (but does not run) a migration to add a messages table.
12
+ You need to set `store_sms_in_local` to `true` in your config file
13
+ before running this command
14
+ EOF
11
15
 
12
16
  def create_migration_file
13
17
  add_smart_sms_migration('create_smart_sms_messages') if SmartSMS.config.store_sms_in_local
@@ -18,10 +22,11 @@ module SmartSms
18
22
  end
19
23
 
20
24
  protected
25
+
21
26
  def add_smart_sms_migration(template)
22
27
  migration_dir = File.expand_path('db/migrate')
23
28
 
24
- if !self.class.migration_exists?(migration_dir, template)
29
+ unless self.class.migration_exists?(migration_dir, template)
25
30
  migration_template "#{template}.rb", "db/migrate/#{template}.rb"
26
31
  end
27
32
  end
@@ -12,4 +12,4 @@ SmartSMS.configure do |config|
12
12
  # config.default_interval = 1.day
13
13
  # config.store_sms_in_local = false
14
14
  # config.verification_code_algorithm = :simple
15
- end
15
+ end
data/lib/smart_sms.rb CHANGED
@@ -6,7 +6,7 @@ require 'smart_sms/helpers/verification_code'
6
6
  require 'smart_sms/message_service'
7
7
  require 'smart_sms/account'
8
8
 
9
- if !defined? ActiveRecord
9
+ unless defined? ActiveRecord
10
10
  begin
11
11
  require 'active_record'
12
12
  rescue LoadError; end
@@ -32,4 +32,4 @@ require 'smart_sms/has_sms_verification'
32
32
 
33
33
  ActiveSupport.on_load(:active_record) do
34
34
  include SmartSMS::HasSmsVerification
35
- end
35
+ end
@@ -1,8 +1,10 @@
1
- #encoding: utf-8
1
+ # encoding: utf-8
2
2
 
3
3
  module SmartSMS
4
+ # Module that handle user information
5
+ #
4
6
  module Account
5
- extend self
7
+ module_function
6
8
 
7
9
  # 获取用户信息
8
10
  def info
@@ -13,8 +15,8 @@ module SmartSMS
13
15
  # emergency_contact: 紧急联系人
14
16
  # emergency_mobile: 紧急联系人手机号
15
17
  # alarm_balance: 短信余额提醒阈值。一天只提示一次
16
- def set options = {}
18
+ def set(options = {})
17
19
  Request.post 'user/set.json', options
18
20
  end
19
21
  end
20
- end
22
+ end
@@ -1,9 +1,8 @@
1
- #encoding: utf-8
1
+ # encoding: utf-8
2
2
  require 'active_support/configurable'
3
3
  require 'active_support/core_ext'
4
4
 
5
5
  module SmartSMS
6
-
7
6
  # Configures global settings for SmartSMS
8
7
  # SmartSMS.configure do |config|
9
8
  # config.api_key = 'd63124354422b046081a44466'
@@ -17,6 +16,8 @@ module SmartSMS
17
16
  @config
18
17
  end
19
18
 
19
+ # Configuration class
20
+ #
20
21
  class Configuration #:nodoc:
21
22
  include ActiveSupport::Configurable
22
23
  config_accessor :api_key # 授权 API KEY
@@ -45,4 +46,4 @@ module SmartSMS
45
46
  config.store_sms_in_local = false
46
47
  config.verification_code_algorithm = :simple
47
48
  end
48
- end
49
+ end
@@ -2,23 +2,25 @@
2
2
  require File.expand_path(File.join(File.dirname(__FILE__), 'model/message'))
3
3
 
4
4
  module SmartSMS
5
+ # Module that will be hooked into ActiveRecord to provide magic methods
6
+ #
5
7
  module HasSmsVerification
6
-
7
8
  def self.included(base)
8
9
  base.send :extend, ClassMethods
9
10
  end
10
11
 
12
+ # Class methods that will be extended
11
13
  module ClassMethods
12
14
 
13
15
  # 在您的Model里面声明这个方法, 以添加SMS短信验证功能
14
16
  # moible_column: mobile 绑定的字段, 用于发送短信
15
- # verification_column: 验证绑定的字段, 用于判断是否以验证
17
+ # verification_column: 验证绑定的字段, 用于判断是否已验证
16
18
  #
17
19
  # Options:
18
20
  # :class_name 自定义的Message类名称. 默认是 `::SmartSMS::Message`
19
21
  # :messages 自定义的Message关联名称. 默认是 `:versions`.
20
22
  #
21
- def has_sms_verification moible_column = :phone, verification_column = :verified_at, options = {}
23
+ def has_sms_verification(moible_column = :phone, verification_column = :verified_at, options = {})
22
24
  send :include, InstanceMethods
23
25
 
24
26
  # 用于判断是否已经验证的字段, Datetime 类型, 例如 :verified_at
@@ -40,33 +42,34 @@ module SmartSMS
40
42
  self.message_class_name = options[:class_name] || '::SmartSMS::Message'
41
43
 
42
44
  if ::ActiveRecord::VERSION::MAJOR >= 4 # Rails 4 里面, 在 `has_many` 声明中定义order lambda的语法
43
- has_many self.messages_association_name,
44
- lambda { order("send_time ASC") },
45
- :class_name => self.message_class_name, :as => :smsable
45
+ has_many messages_association_name,
46
+ -> { order('send_time ASC') },
47
+ class_name: message_class_name,
48
+ as: :smsable
46
49
  else
47
- has_many self.messages_association_name,
48
- :class_name => self.message_class_name,
49
- :as => :smsable,
50
- :order => "send_time ASC"
50
+ has_many messages_association_name,
51
+ class_name: message_class_name,
52
+ as: :smsable,
53
+ order: 'send_time ASC'
51
54
  end
52
55
 
53
56
  end
54
57
  end
55
58
 
59
+ # Instance methods
56
60
  module InstanceMethods
57
-
58
61
  # 非安全verify!方法, 验证成功后会存储成功的结果到数据表中
59
- def verify! code
62
+ def verify!(code)
60
63
  result = verify code
61
64
  if result
62
- self.send("#{self.class.sms_verification_column}=", Time.now)
63
- self.save(validate: false)
65
+ send("#{self.class.sms_verification_column}=", Time.now)
66
+ save(validate: false)
64
67
  end
65
68
  end
66
69
 
67
70
  # 安全verify方法, 用于校验短信验证码是否正确, 返回: true 或 false
68
71
  #
69
- def verify code
72
+ def verify(code)
70
73
  sms = latest_message
71
74
  return false if sms.blank?
72
75
  if SmartSMS.config.store_sms_in_local
@@ -90,16 +93,16 @@ module SmartSMS
90
93
  #
91
94
  def latest_message
92
95
  end_time = Time.now
93
- start_time = end_time - SmartSMS.config.expires_in # the verification code will be expired within 1 hour
96
+ start_time = end_time - SmartSMS.config.expires_in
94
97
  if SmartSMS.config.store_sms_in_local
95
- self.send(self.class.messages_association_name)
96
- .where("send_time >= ? and send_time <= ?", start_time, end_time)
97
- .last
98
+ send(self.class.messages_association_name)
99
+ .where('send_time >= ? and send_time <= ?', start_time, end_time)
100
+ .last
98
101
  else
99
102
  result = SmartSMS.find(
100
103
  start_time: start_time,
101
104
  end_time: end_time,
102
- mobile: self.send(self.class.sms_mobile_column),
105
+ mobile: send(self.class.sms_mobile_column),
103
106
  page_size: 1
104
107
  )
105
108
  result['sms'].first
@@ -108,27 +111,29 @@ module SmartSMS
108
111
 
109
112
  # 发送短信至手机
110
113
  #
111
- def deliver text = SmartSMS::VerificationCode.random
112
- result = SmartSMS.deliver self.send(self.class.sms_mobile_column), text
114
+ def deliver(text = SmartSMS::VerificationCode.random)
115
+ result = SmartSMS.deliver send(self.class.sms_mobile_column), text
113
116
  if result['code'] == 0
114
117
  sms = SmartSMS.find_by_sid(result['result']['sid'])['sms']
115
- if SmartSMS.config.store_sms_in_local
116
- message = self.send(self.messages_association_name).build sms
117
- message.code = text
118
- message.save
119
- else
120
- sms
121
- end
118
+ save_or_return_message sms, text
122
119
  else
123
- self.errors.add :deliver, result
120
+ errors.add :deliver, result
124
121
  false
125
122
  end
126
123
  end
127
124
 
128
- def deliver_fake_sms text = SmartSMS::VerificationCode.random
129
- sms = SmartSMS::FakeSMS.build_fake_sms self.send(self.class.sms_mobile_column), text, SmartSMS.config.company
125
+ def deliver_fake_sms(text = SmartSMS::VerificationCode.random)
126
+ mobile = send(self.class.sms_mobile_column)
127
+ company = SmartSMS.config.company
128
+ sms = SmartSMS::FakeSMS.build_fake_sms mobile, text, company
129
+ save_or_return_message sms, text
130
+ end
131
+
132
+ private
133
+
134
+ def save_or_return_message(sms, text)
130
135
  if SmartSMS.config.store_sms_in_local
131
- message = self.send(self.messages_association_name).build sms
136
+ message = send(self.class.messages_association_name).build sms
132
137
  message.code = text
133
138
  message.save
134
139
  else
@@ -138,4 +143,4 @@ module SmartSMS
138
143
  end
139
144
  end
140
145
  end
141
- end
146
+ end
@@ -1,22 +1,23 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module SmartSMS
4
+ # This will generate fake sms
5
+ #
4
6
  module FakeSMS
5
- extend self
7
+ module_function
6
8
 
7
- def build_fake_sms mobile, code, company
9
+ def build_fake_sms(mobile, code, company)
8
10
  {
9
- "sid" => SecureRandom.uuid,
10
- "mobile" => mobile,
11
- "send_time" => Time.zone.now,
12
- "text" => "您的验证码是#{code}。如非本人操作,请忽略本短信【#{company}】",
13
- "send_status" => "SUCCESS",
14
- "report_status" => "UNKNOWN",
15
- "fee" => 1,
16
- "user_receive_time" => nil,
17
- "error_msg" => nil
11
+ 'sid' => SecureRandom.uuid,
12
+ 'mobile' => mobile,
13
+ 'send_time' => Time.zone.now,
14
+ 'text' => "您的验证码是#{code}。如非本人操作,请忽略本短信【#{company}】",
15
+ 'send_status' => 'SUCCESS',
16
+ 'report_status' => 'UNKNOWN',
17
+ 'fee' => 1,
18
+ 'user_receive_time' => nil,
19
+ 'error_msg' => nil
18
20
  }
19
21
  end
20
-
21
22
  end
22
- end
23
+ end
@@ -1,32 +1,40 @@
1
1
  require 'securerandom'
2
2
 
3
3
  module SmartSMS
4
+ # This module provides some methods to generate random verification code
5
+ # Algorithm:
6
+ # short: Generate short code with 4 numbers
7
+ # simple: Generate simple code with 6 numbers
8
+ # middle: Generate middle complex code of 6 charactors with mixed numbers and letters
9
+ # complex: Generate complex code of 8 charactors with mixed numbers, letters or special charactors
4
10
  module VerificationCode
5
- extend self
11
+ module_function
6
12
 
7
- REGISTERED_ALGORITHMS = [:simple, :middle, :complex]
13
+ REGISTERED_ALGORITHMS = [:short, :simple, :middle, :complex]
8
14
 
9
- def random algorithm = ''
15
+ def random(algorithm = '')
10
16
  algorithm = SmartSMS.config.verification_code_algorithm if algorithm.blank?
11
17
  if REGISTERED_ALGORITHMS.include? algorithm
12
18
  SmartSMS::VerificationCode.send algorithm
13
19
  else
14
- raise NoMethodError
20
+ fail NoMethodError
15
21
  end
16
22
  end
17
23
 
18
- private
24
+ def short
25
+ SecureRandom.random_number.to_s.slice(-4..-1)
26
+ end
19
27
 
20
28
  def simple
21
29
  SecureRandom.random_number.to_s.slice(-6..-1)
22
30
  end
23
31
 
24
32
  def middle
25
- SecureRandom.base64.gsub!(/[^0-9a-zA-Z]/,'').slice(1..6).downcase
33
+ SecureRandom.base64.gsub!(/[^0-9a-zA-Z]/, '').slice(1..6).downcase
26
34
  end
27
35
 
28
36
  def complex
29
37
  SecureRandom.base64.slice(1..8).downcase
30
38
  end
31
39
  end
32
- end
40
+ end
@@ -1,13 +1,13 @@
1
1
  module SmartSMS
2
+ # Message service: methods that are used to manage messages
2
3
  module MessageService
3
-
4
4
  def self.included(base)
5
5
  base.send :extend, ClassMethods
6
6
  end
7
7
 
8
+ # Class methods
8
9
  module ClassMethods
9
-
10
- DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
10
+ DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
11
11
 
12
12
  # 发送短信到手机, 默认使用模板发送, 提供通用接口支持
13
13
  # phone: 需要接受短信的手机号码
@@ -16,7 +16,7 @@ module SmartSMS
16
16
  # Options:
17
17
  # :method 如若要使用通用短信接口, 需要 :method => :general
18
18
  # :tpl_id 选择发送短信的模板, 默认是2
19
- def deliver phone, content, options = {}
19
+ def deliver(phone, content, options = {})
20
20
  if options[:method] == :general
21
21
  Request.post 'sms/send.json', mobile: phone, text: content, extend: options[:extend]
22
22
  else
@@ -29,20 +29,20 @@ module SmartSMS
29
29
 
30
30
  # 根据sid来查询短信记录
31
31
  #
32
- def find_by_sid sid
32
+ def find_by_sid(sid)
33
33
  Request.post 'sms/get.json', sid: sid
34
34
  end
35
35
 
36
36
  # 参见 `find_messages` 方法
37
- def find options = {}
37
+ def find(options = {})
38
38
  find_messages 'sms/get.json', options
39
39
  end
40
40
 
41
- def get_black_word text = ''
41
+ def get_black_word(text = '')
42
42
  Request.post 'sms/get_black_word.json', text: text
43
43
  end
44
44
 
45
- def get_reply options = {}
45
+ def get_reply(options = {})
46
46
  find_messages 'sms/get_reply.json', options
47
47
  end
48
48
 
@@ -55,7 +55,7 @@ module SmartSMS
55
55
  # page_size: 每页个数,最大100个
56
56
  # mobile: 接收短信的手机号
57
57
  #
58
- def find_messages api, options = {}
58
+ def find_messages(api, options = {})
59
59
  options[:end_time] = Time.now if options[:end_time].blank?
60
60
  options[:start_time] = options[:end_time] - SmartSMS.config.default_interval if options[:start_time].blank?
61
61
  options[:end_time] = parse_time(options[:end_time])
@@ -65,21 +65,23 @@ module SmartSMS
65
65
  Request.post api, options
66
66
  end
67
67
 
68
- def parse_time time = ''
68
+ def parse_time(time = '')
69
69
  if time.present? && time.is_a?(Time)
70
70
  time.strftime DATETIME_FORMAT
71
+ elsif time.is_a? String
72
+ time
71
73
  else
72
74
  ''
73
75
  end
74
76
  end
75
77
 
76
- def parse_content options = {}
78
+ def parse_content(options = {})
77
79
  options[:code] ||= ''
78
80
  options[:company] ||= SmartSMS.config.company
79
81
  SmartSMS.config.template_value.map do |key|
80
- "##{key.to_s}#=#{options[key]}"
82
+ "##{key}#=#{options[key]}"
81
83
  end.join('&')
82
84
  end
83
85
  end
84
86
  end
85
- end
87
+ end
@@ -1,4 +1,6 @@
1
1
  module SmartSMS
2
+ # Message model to store sms messages
3
+ #
2
4
  class Message < ::ActiveRecord::Base
3
5
  self.table_name = 'smart_sms_messages'
4
6
  belongs_to :smsable, polymorphic: true
@@ -3,17 +3,16 @@ require 'net/http'
3
3
  require 'active_support/json'
4
4
 
5
5
  module SmartSMS
6
+ # Module that manage requests
6
7
  module Request
7
- extend self
8
-
9
- def post api, options = {}
8
+ def post(api, options = {})
10
9
  options[:apikey] = SmartSMS.config.api_key
11
10
  uri = URI.join(base_url, api)
12
11
  res = Net::HTTP.post_form(uri, options)
13
12
  result res.body
14
13
  end
15
14
 
16
- def get api, options = {}
15
+ def get(api, options = {})
17
16
  options[:apikey] = SmartSMS.config.api_key
18
17
  uri = URI.join(base_url, api)
19
18
  result Net::HTTP.get(uri, options)
@@ -21,20 +20,22 @@ module SmartSMS
21
20
 
22
21
  private
23
22
 
24
- def result body
23
+ def result(body)
25
24
  begin
26
25
  ActiveSupport::JSON.decode body
27
26
  rescue => e
28
27
  {
29
28
  code: 502,
30
- msg: "内容解析错误",
29
+ msg: '内容解析错误',
31
30
  detail: e.to_s
32
31
  }
33
32
  end
34
33
  end
35
34
 
36
35
  def base_url
37
- "http://yunpian.com/#{SmartSMS.config.api_version.to_s}/"
36
+ "http://yunpian.com/#{SmartSMS.config.api_version}/"
38
37
  end
38
+
39
+ module_function :post, :get, :result, :base_url
39
40
  end
40
- end
41
+ end