action_smser 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ActionSmser
2
2
 
3
- Simple way to use SMS (Short Message Service) in the same way as ActionMailer (ActionSmser == ActionMailer).
3
+ ActionSmser == SMS && ActionMailer. Simple way to use SMS (Short Message Service) in the same way as ActionMailer.
4
4
  Includes also delivery reports and easy way to add custom gateways. See examples below.
5
5
 
6
6
  [<img src="https://secure.travis-ci.org/holli/action_smser.png" />](http://travis-ci.org/holli/action_smser)
@@ -16,7 +16,7 @@ Gemfile ->
16
16
  gem 'action_smser'
17
17
 
18
18
  # To use delivery reports
19
- bundle exec rake railties:install:migrations FROM=ActionSmser
19
+ bundle exec rake railties:install:migrations
20
20
  rake db:migrate
21
21
  ```
22
22
 
@@ -68,6 +68,37 @@ Optional delivery methods can be used by creating classes under "ActionSmser::De
68
68
  them as downcase infos. See example of :simple_http at
69
69
  https://github.com/holli/action_smser/blob/master/lib/action_smser/delivery_methods/simple_http.rb
70
70
 
71
+ Simplest case is to use simple_http and override path
72
+
73
+ ```
74
+ # Example of changing simple_http delivery path. Options are the same options that were presented above.
75
+
76
+ module ActionSmser::DeliveryMethods
77
+ class SimpleHttp
78
+ def self.deliver_path(sms, options)
79
+ "/my_gateways_api/send?user=#{options[:username]}&password=#{options[:password]}&ValidityPeriod=24:00&sender=#{sms.from_encoded}&SMSText=#{sms.body_encoded_escaped}&GSM=#{sms.to_encoded}"
80
+ end
81
+ end
82
+ end
83
+
84
+ ```
85
+
86
+ **Nexmo** (http://nexmo.com/) is supported also.
87
+
88
+ ```
89
+ ActionSmser.delivery_options[:delivery_method] = :nexmo
90
+ ActionSmser.delivery_options[:nexmo] = {
91
+ :username => 'key', :password => "password"
92
+ }
93
+
94
+ # set callback url to nexmo http://localhost:3000/action_smser/delivery_reports/gateway_commit/nexmo
95
+ ActionSmser.delivery_options[:gateway_commit]['nexmo'] = ActionSmser::DeliveryMethods::Nexmo
96
+
97
+ ```
98
+
99
+ If you add other common gateways to this framework, plz generate tests and send us a patch.
100
+
101
+
71
102
  ## Delivery reports
72
103
 
73
104
  Gem handles collecting and analysing of delivery reports. This enables you to make sure that your gateway works.
@@ -110,23 +141,24 @@ class ActionSmserConfigExample
110
141
  end
111
142
  end
112
143
 
113
-
114
144
  # This is simple proc that is used in a before filter, if it returns true it allows access to
115
145
  # http://localhost.inv:3000/action_smser/delivery_reports/ with infos about delivery reports
116
146
  ActionSmser.delivery_options[:admin_access] = ActionSmserConfigExample
117
147
 
118
- # This gives ActionSmser way to parse infos from pushed to gateway
119
- # Params is all params gotten in the request
120
- test_gateway = lambda
121
-
122
148
  # Parser is used with urls like
123
149
  # /action_smser/delivery_reports/gateway_commit/test_gateway
124
150
  # where 'test_gateway' is the part that is used for locating right parser.
125
- ActionSmser.delivery_options[:gateway_commit] = {'test_gateway' => test_gateway}
126
-
151
+ ActionSmser.delivery_options[:gateway_commit]['test_gateway'] = ActionSmserConfigExample
127
152
 
128
153
  ```
129
154
 
155
+ DeliveryReports can be searched by "dr = ::ActionSmser::DeliveryReport.where(xxx).first".
156
+ Some helpers in delivery_reports include
157
+
158
+ - dr.to_sms => creates new sms message from deliveryreport.
159
+ - dr.resent(:gateway) => creates new sms and sends it through given gateway.
160
+
161
+
130
162
  ## Other options
131
163
 
132
164
  Observers can be used by implementing "delivery_observer" in your sms class
@@ -138,12 +170,32 @@ class TestSms < ActionSmser::Base
138
170
  sms(:to => to, :from => from, :body => str)
139
171
  end
140
172
 
173
+ def before_delivery()
174
+ puts "Called just before delivery"
175
+ end
176
+
141
177
  def after_delivery(response_from_delivery_method)
142
178
  puts "Done with delivery"
143
179
  end
144
180
  end
145
181
  ```
146
182
 
183
+ Gateway committed status updates can also have observers
184
+
185
+ ```
186
+ in /config/initializers/active_smser.rb
187
+
188
+ class ActionSmserConfigGatewayObserver
189
+ def self.after_gateway_commit(delivery_reports)
190
+ puts delivery_reports.inspect
191
+ end
192
+ end
193
+
194
+ ActionSmser.gateway_commit_observer_add(ActionSmserConfigGatewayObserver)
195
+
196
+ ```
197
+
198
+
147
199
  ## Testing
148
200
 
149
201
  Default delivery method is "test_array". It saves delivered sms to ActionSmser::DeliveryMethods::TestArray.deliveries to help test your own software.
@@ -11,10 +11,11 @@ module ActionSmser
11
11
 
12
12
  ActionSmser::Logger.info("Gateway_commit found parser for gateway: #{params['gateway']}")
13
13
 
14
- dr_array = ActionSmser.delivery_options[:gateway_commit][params['gateway']].send(:process_delivery_report, params)
14
+ dr_var_array = ActionSmser.delivery_options[:gateway_commit][params['gateway']].send(:process_delivery_report, params)
15
+ dr_array = []
15
16
 
16
- if !dr_array.blank?
17
- dr_array.each do |dr_update|
17
+ if !dr_var_array.blank?
18
+ dr_var_array.each do |dr_update|
18
19
  msg_id = dr_update["msg_id"]
19
20
  dr = ActionSmser::DeliveryReport.where(:msg_id => msg_id).first
20
21
 
@@ -23,9 +24,9 @@ module ActionSmser
23
24
  dr.send("#{key}=", value) if dr.attribute_names.include?(key.to_s)
24
25
  end
25
26
 
26
-
27
27
  if dr.save
28
28
  updated_count += 1
29
+ dr_array << dr
29
30
  ActionSmser::Logger.info("Gateway_commit updated item with id: #{msg_id}, params: #{dr_update.inspect}")
30
31
  else
31
32
  ActionSmser::Logger.info("Gateway_commit problem updating item with id: #{msg_id}, params: #{dr_update.inspect}")
@@ -35,6 +36,16 @@ module ActionSmser
35
36
  end
36
37
  end
37
38
  end
39
+
40
+ begin
41
+ ActionSmser.delivery_options[:gateway_commit_observers].each do |observer|
42
+ observer.after_gateway_commit(dr_array)
43
+ end
44
+ rescue Exception => e
45
+ ActionSmser::Logger.error("Problem with gateway_commit_observers: #{e}")
46
+ end
47
+
48
+
38
49
  end
39
50
 
40
51
  if updated_count > 0
@@ -44,12 +55,18 @@ module ActionSmser
44
55
  end
45
56
  end
46
57
 
58
+
47
59
  before_filter :admin_access_only, :except => :gateway_commit
48
60
 
49
61
  def index
50
62
 
51
63
  end
52
64
 
65
+ def list
66
+
67
+ end
68
+
69
+
53
70
  def admin_access_only
54
71
  if !ActionSmser.delivery_options[:admin_access].blank? && ActionSmser.delivery_options[:admin_access].send(:admin_access, self)
55
72
  return true
@@ -1,15 +1,20 @@
1
1
  module ActionSmser
2
2
  class DeliveryReport < ActiveRecord::Base
3
3
 
4
+ has_many :re_deliveries, :class_name => self.to_s, :foreign_key => :re_delivery_of_delivery_report_id
5
+ puts self
6
+ belongs_to :re_delivery_of, :class_name => self.to_s, :foreign_key => :re_delivery_of_delivery_report_id
7
+
4
8
  def self.build_from_sms(sms, to, msg_id)
5
9
  @delivery_report = self.new
6
10
 
7
- [:from, :body, :sms_type].each do |var|
11
+ [:from, :body, :sms_type, :re_delivery_of_delivery_report_id].each do |var|
8
12
  @delivery_report.send("#{var}=", sms.send(var))
9
13
  end
10
14
  @delivery_report.to = to
11
15
  @delivery_report.msg_id = msg_id
12
16
  @delivery_report.status = "LOCAL_SENT"
17
+ @delivery_report.gateway = sms.delivery_options[:delivery_method].to_s
13
18
  @delivery_report
14
19
  end
15
20
 
@@ -22,8 +27,36 @@ module ActionSmser
22
27
  def status=(stat, skip_log = false)
23
28
  self[:status] = stat
24
29
  self.status_updated_at = Time.now
30
+ add_log("#{Time.now.to_s(:db)}: #{stat}") unless skip_log
31
+ end
32
+
33
+ def add_log(str)
25
34
  self.log = "" if self.log.nil?
26
- self.log += "#{Time.now.to_s(:db)}: #{stat}\n" if !skip_log
35
+ self.log += "#{str}\n"
36
+ end
37
+
38
+ # Copy this delivery_report information to a new sms object
39
+ def to_sms
40
+ sms_new = ActionSmser::Base.new()
41
+ [:sms_type, :to, :from, :body, :sms_type].each do |var|
42
+ sms_new.send("#{var}=", self.send(var))
43
+ end
44
+ sms_new
45
+ end
46
+
47
+ def re_deliver(gateway = :default)
48
+ ActionSmser::Logger.info("Re_delivering: #{self.inspect}")
49
+ self.update_attribute(:re_delivered, true)
50
+
51
+ sms_new = self.to_sms
52
+ sms_new.sms_type = "#{sms_new.sms_type}.re_delivery"
53
+ sms_new.re_delivery_of_delivery_report_id = self.id
54
+
55
+ unless gateway == :default
56
+ sms_new.delivery_options[:delivery_method] = gateway
57
+ end
58
+
59
+ [sms_new, sms_new.deliver]
27
60
  end
28
61
 
29
62
  end
@@ -14,28 +14,53 @@ time_span = case params['time_span'].to_s.downcase
14
14
  else
15
15
  1.week.ago..10.minutes.ago
16
16
  end
17
+
18
+ ar_timespan = ActionSmser::DeliveryReport.where(:created_at => time_span)
19
+
20
+ ar_gateway = ar_timespan
21
+ ar_gateway = ar_gateway.where(:gateway => params[:gateway]) if (params[:gateway] && params[:gateway].to_s != 'all')
22
+
17
23
  %>
18
24
 
19
25
 
20
- <h1>Delivery Reports Summary for <%= params['time_span'] %></h1>
26
+ <h1>Delivery Reports Summary for <%= params['time_span'] %> <%= "for #{params[:gateway]}" unless params[:gateway].blank? %></h1>
21
27
 
22
28
  <p>
23
29
  Show summary:
24
- <%= link_to 'Last 24 hours', delivery_reports_path(:time_span => 'Last 24 Hours') %>,
25
- <%= link_to '24 hours before that', delivery_reports_path(:time_span => 'Previous 24 Hours') %>,
26
- <%= link_to 'Last week', delivery_reports_path(:time_span => 'Last Week') %>,
27
- <%= link_to 'Week before that', delivery_reports_path(:time_span => 'Previous Week') %> or
28
- <%= link_to 'Last month', delivery_reports_path(:time_span => 'Last Month') %>.
30
+ <%= link_to 'Last 24 hours', delivery_reports_path(:time_span => 'Last 24 Hours', :gateway => params[:gateway]) %>,
31
+ <%= link_to '24 hours before that', delivery_reports_path(:time_span => 'Previous 24 Hours', :gateway => params[:gateway]) %>,
32
+ <%= link_to 'Last week', delivery_reports_path(:time_span => 'Last Week', :gateway => params[:gateway]) %>,
33
+ <%= link_to 'Week before that', delivery_reports_path(:time_span => 'Previous Week', :gateway => params[:gateway]) %> or
34
+ <%= link_to 'Last month', delivery_reports_path(:time_span => 'Last Month', :gateway => params[:gateway]) %>.
29
35
  </p>
30
36
 
31
- <h2>Delivered Within (hour:min:sec)</h2>
37
+ <h2>Select gateway</h2>
32
38
 
33
- <%
34
- ar = ActionSmser::DeliveryReport.where(:created_at => time_span)
35
- ar_delivered = ar.where(:status => 'delivered')
36
- total = ar.count
37
- total_delivered = ar_delivered.count
38
- %>
39
+ <ul>
40
+ <li>
41
+ <strong>
42
+ <%= link_to('all', delivery_reports_path(:time_span => params[:time_span]) ) %>
43
+ </strong>
44
+ &nbsp;&nbsp;
45
+ (you can select only gateways that have messages in this period)
46
+ </li>
47
+ <%
48
+ total = ar_timespan.count
49
+ grouped_by_status = ar_timespan.group(:gateway).count.each do |key, val| %>
50
+ <li>
51
+ <strong>
52
+ <%= link_to(key, delivery_reports_path(:time_span => params[:time_span], :gateway => key) ) %>
53
+ </strong>
54
+ &nbsp;&nbsp;
55
+ <%= val %> sms
56
+ &nbsp;&nbsp;
57
+ (<strong><%= number_to_percentage(100.0 * val / total, :precision => 2) %></strong>)
58
+ </li>
59
+ <% end %>
60
+ </ul>
61
+
62
+
63
+ <h2>Delivered Within (hour:min:sec)</h2>
39
64
 
40
65
  <% if ActiveRecord::Base.connection.adapter_name.downcase.to_s.include?("mysql") %>
41
66
 
@@ -47,6 +72,10 @@ Show summary:
47
72
  <th>% of delivered sms</th>
48
73
  </tr>
49
74
 
75
+ <% ar_delivered = ar_gateway.where(:status => 'delivered')
76
+ total = ar_gateway.count
77
+ total_delivered = ar_delivered.count
78
+ %>
50
79
  <% ["00:00:30", "00:01:00", "00:02:00", "00:10:00", "00:30:00", "00:90:00", "24:00:00", "48:00:00"].each do |time| %>
51
80
  <% dev_count = ar_delivered.where('TIMEDIFF(status_updated_at, created_at) < ?', time).count %>
52
81
  <tr>
@@ -66,9 +95,8 @@ Show summary:
66
95
  <h2>DeliveryReport Statuses</h2>
67
96
  <ul>
68
97
  <%
69
- quest = ActionSmser::DeliveryReport.where(:created_at => time_span)
70
- total = quest.count
71
- grouped_by_status = quest.group(:status).count.each do |key, val| %>
98
+ total = ar_gateway.count
99
+ grouped_by_status = ar_gateway.group(:status).count.each do |key, val| %>
72
100
 
73
101
  <li>
74
102
  <strong><%= key %></strong>:
@@ -91,9 +119,8 @@ Show summary:
91
119
  </tr>
92
120
 
93
121
  <%
94
- quest = ActionSmser::DeliveryReport.where(:created_at => time_span)
95
- total = quest.count
96
- grouped_by_status = quest.group(:sms_type).count.each do |key, val| %>
122
+ total = ar_gateway.count
123
+ grouped_by_status = ar_gateway.group(:sms_type).count.each do |key, val| %>
97
124
  <tr>
98
125
  <td><strong><%= key %></strong></td>
99
126
  <td><%= val %></td>
@@ -105,46 +132,3 @@ Show summary:
105
132
  </table>
106
133
 
107
134
 
108
- <hr>
109
-
110
- <% items_within_page = 20 %>
111
- <h1 id="delivery_reports_list"><%= items_within_page %> delivery_reports ordered by created_at</h1>
112
-
113
- <%
114
- offset = params[:offset].to_i
115
- offset = 0 if offset < -0
116
- %>
117
-
118
- <p>
119
- <strong>List offset: <%= offset %>.</strong>
120
- Add
121
- <%= link_to("- #{items_within_page}", delivery_reports_path(:offset => offset-items_within_page, :anchor => 'delivery_reports_list')) unless offset == 0 %>
122
- <%= link_to "+ #{items_within_page}", delivery_reports_path(:offset => offset+items_within_page, :anchor => 'delivery_reports_list') %>
123
- to offset
124
- </p>
125
-
126
- <table style="margin-top: 20px;">
127
- <tr>
128
- <th>Created_at</th>
129
- <th>Msg id</th>
130
- <th>Status</th>
131
- <th>Status updated at</th>
132
- <th>Recipient</th>
133
- <th>Sender</th>
134
- <th>Text body</th>
135
- </tr>
136
-
137
- <% ActionSmser::DeliveryReport.order('created_at DESC').offset(offset).first(items_within_page).each do |delivery_report| %>
138
- <tr>
139
- <td style="white-space: nowrap;"><%= delivery_report.created_at %></td>
140
- <td><%= delivery_report.msg_id %></td>
141
- <td><%= delivery_report.status %></td>
142
- <td style="white-space: nowrap;"><%= delivery_report.status_updated_at %></td>
143
- <td><%= delivery_report.to %></td>
144
- <td><%= delivery_report.from %></td>
145
- <td><%= delivery_report.body %></td>
146
- </tr>
147
- <% end %>
148
- </table>
149
-
150
-
@@ -0,0 +1,52 @@
1
+
2
+ <% items_within_page = 20 %>
3
+ <h1 id="delivery_reports_list"><%= items_within_page %> delivery_reports ordered by created_at</h1>
4
+
5
+ <%
6
+ offset = params[:offset].to_i
7
+ offset = 0 if offset < -0
8
+ %>
9
+
10
+ <p>
11
+ <strong>List offset: <%= offset %>.</strong>
12
+ Add
13
+ <%= link_to("- #{items_within_page}", list_delivery_reports_path(:offset => offset-items_within_page)) unless offset == 0 %>
14
+ <%= link_to "+ #{items_within_page}", list_delivery_reports_path(:offset => offset+items_within_page) %>
15
+ to offset
16
+ </p>
17
+
18
+ <table style="margin-top: 20px; font-size: 10px;">
19
+ <tr>
20
+ <th>Id</th>
21
+ <th>Created_at</th>
22
+ <th>Msg id</th>
23
+ <th>Gateway</th>
24
+ <th>Status</th>
25
+ <th>Status updated at</th>
26
+ <th>Recipient</th>
27
+ <th>Sender</th>
28
+ <th>Sms Type</th>
29
+ <th>Re Delivered</th>
30
+ <th>Re Delivery Of</th>
31
+ <th>&nbsp;O</th>
32
+ </tr>
33
+
34
+ <% ActionSmser::DeliveryReport.order('created_at DESC').offset(offset).first(items_within_page).each do |delivery_report| %>
35
+ <tr>
36
+ <td style="white-space: nowrap;"><%= delivery_report.id %></td>
37
+ <td style="white-space: nowrap;"><%= delivery_report.created_at %></td>
38
+ <td><%= delivery_report.msg_id %></td>
39
+ <td><%= delivery_report.gateway %></td>
40
+ <td><%= delivery_report.status %></td>
41
+ <td style="white-space: nowrap;"><%= delivery_report.status_updated_at %></td>
42
+ <td><%= delivery_report.to %></td>
43
+ <td><%= delivery_report.from %></td>
44
+ <td><%= delivery_report.sms_type %></td>
45
+ <td><%= delivery_report.re_delivered? %></td>
46
+ <td><%= delivery_report.re_delivery_of.msg_id unless delivery_report.re_delivery_of.blank? %></td>
47
+ <td title="<%= delivery_report.body %>">&nbsp;O</td>
48
+ </tr>
49
+ <% end %>
50
+ </table>
51
+
52
+
@@ -14,7 +14,7 @@
14
14
  }
15
15
  th, td {
16
16
  border: 1px solid gray;
17
- padding: 1px 10px 1px 3px;
17
+ padding: 1px 8px 1px 3px;
18
18
  }
19
19
 
20
20
  h1 { margin-top: 40px; }
@@ -29,6 +29,9 @@
29
29
 
30
30
  }
31
31
  hr { margin-top: 20px; margin-bottom: 10px; }
32
+
33
+ .menu { margin-top: 30px; }
34
+ .menu a { margin-right: 20px; font-size: 16px; }
32
35
 
33
36
  </STYLE>
34
37
 
@@ -37,7 +40,9 @@
37
40
 
38
41
  <h1>ActionSmser infos</h1>
39
42
 
40
- Back to <%= link_to 'Main application', '/' %>
43
+ <div class="menu">
44
+ <%= link_to 'Main application', '/' %> <%= link_to 'Summary of SMS', delivery_reports_path -%> <%= link_to 'List All SMS', list_delivery_reports_path %>
45
+ </div>
41
46
 
42
47
  <hr>
43
48