active_smsgate 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,17 +1,39 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  module ActiveSmsgate #:nodoc:
3
3
  module Gateway #:nodoc:
4
+ =begin rdoc
5
+ В каждом шлюзе нужно прописать три метода
6
+ # Выполнение отправки смс завершено
7
+ def complete; end
8
+ alias :complete? :complete
4
9
 
10
+ # Смс досталена
11
+ def success; end
12
+ alias :success? :success
13
+
14
+ # Смс не доставлена
15
+ def failure; end
16
+ alias :failure? :failure
17
+ =end
5
18
  class << self
6
19
  # Список поддерживаемых
7
20
  def support_gateways
8
- [{:class => 'amegainform',:desc => 'www.amegainform.ru' }]
21
+ Dir["#{File.dirname(__FILE__)}/gateways/**/*.rb"].map { |gw|
22
+ gateway = "active_smsgate/gateway/#{File.basename(gw, ".rb")}".classify.constantize
23
+ { :class => File.basename(gw, ".rb"), :alias => gateway::ALIAS,
24
+ :short_desc => gateway::SHORT_DESC, :desc => gateway::DESC} }
25
+ end
26
+
27
+ # получение шлюза по его имени
28
+ def gateway(gw)
29
+ "active_smsgate/gateway/#{gw.to_s}".classify.constantize
9
30
  end
31
+
10
32
  end
11
33
 
12
34
  class Gateway
13
35
  include HTTParty
14
- attr_accessor :login, :password, :use_ssl
36
+ attr_accessor :login, :password, :use_ssl, :errors
15
37
 
16
38
  # Initialize a new gateway.
17
39
  # ==== Параметры
@@ -33,6 +55,17 @@ module ActiveSmsgate #:nodoc:
33
55
  # Использовать резервные сервера
34
56
  def use_of_backup_server?; @use_of_backup_server end
35
57
 
58
+ # Получение uri смс сервиса
59
+ def uri
60
+ self.class.default_options[:base_uri].gsub!(/^https?:\/\//i, '')
61
+ "http#{'s' if use_ssl?}://#{self.class.default_options[:base_uri]}"
62
+ end
63
+
64
+ def valid?
65
+ @errors.blank?
66
+ end
67
+
68
+
36
69
  end
37
70
  end
38
71
  end
@@ -1,22 +1,63 @@
1
1
  # -*- coding: utf-8 -*-
2
-
3
2
  module ActiveSmsgate #:nodoc:
4
- # «Амега Информ» – http://amegainform.ru/
5
- # это сервис массовой рассылки, приема SMS и голосовых сообщений.
6
-
7
3
  module Gateway #:nodoc:
4
+
5
+ =begin rdoc
6
+ «Амега Информ» – http://amegainform.ru/
7
+ это сервис массовой рассылки, приема SMS и голосовых сообщений.
8
+
9
+ # Возвращаемые данные
10
+ # <output>
11
+ # <result sms_group_id="996">
12
+ # <sms id="99991" smstype="SENDSMS" phone="+79999999991" sms_res_count="1"><![CDATA[Привет]]></sms>
13
+ # <sms id="99992" smstype="SENDVOICE" phone="+79999999992" sms_res_count="38"><![CDATA[%PAUSE=1000%%SYNTH=Vika%Привет друг%SAMPLE=#1525%%PAUSE=1000%%SYNTH=Vika%С днём рождения!]]></sms>
14
+ # </result>
15
+ # <output>
16
+
17
+
18
+ # Возвращаемые данные
19
+ # -------------------------------------------------------------------
20
+ # SMS_ID - ID сообщения
21
+ # SMS_GROUP_ID - ID рассылки сообщений
22
+ # SMSTYPE - тип сообщения
23
+ # CREATED - дата и время создания сообщения
24
+ # AUL_USERNAME - Имя пользователя создавшего сообщение
25
+ # AUL_CLIENT_ADR - IP адрес пользователя создавшего сообщение
26
+ # SMS_SENDER - Имя отправителя сообщения
27
+ # SMS_TARGET - Телефон адресата
28
+ # SMS_RES_COUNT - Кол-во единиц ресурсов на данное сообщение
29
+ # SMS_TEXT - Текст сообщения
30
+ # SMSSTC_CODE - Код статуса доставки сообщения
31
+ # -- queued - сообщение в очереди отправки
32
+ # -- wait - передано оператору на отправку
33
+ # -- accepted - сообщение принято оператором, но статус доставки неизвестен
34
+ # -- delivered -сообщение доставлено
35
+ # -- not_delivered - сообщение не доставлено
36
+ # -- failed - ошибка при работе по сообщению
37
+ # SMS_STATUS - Текстовое описание статуса доставки сообщения
38
+ # SMS_CLOSED - [0,1] 0 - сообщения находится в процессинге.
39
+ # 1 = работа по отправке сообщения завершена
40
+ # SMS_SENT - [0,1] 0 - сообщение не отослано. 1 = сообщение отослано успешно
41
+ # SMS_CALL_DURATION - Время,
42
+ # в течение которого было установлено соединение для отправки сообщения.
43
+ # SMS_DTMF_DIGITS - Что пользователь нажимал в сеансе разговора (для SENDVOICE (в разработке))
44
+ # SMS_CLOSE_TIME - Время завершения работы по сообщению.
45
+
46
+
47
+ =end
8
48
  class Amegainform < Gateway
9
49
 
50
+ CLASS_ID = 'amegainform'
51
+ ALIAS = 'www.amegainform.ru'
52
+ SHORT_DESC = 'Шлюз sms рассылок www.amegainform.ru'
53
+ DESC = "Описание шлюза"
54
+
10
55
  headers 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'
11
56
  base_uri 'http://service.amega-inform.ru'
12
57
 
13
58
  # Адреса резервных серверов: service-r1.amegainform.ru и service-r2.amegainform.ru
14
59
 
15
60
  # Создание нового шлюза AmegaInformGateway
16
- # Для работы со шлюзом необходимы логин и пароль
17
- #
18
- # ==== Параметры
19
- #
20
61
  # * <tt>:login</tt> -- REQUIRED
21
62
  # * <tt>:password</tt> -- REQUIRED
22
63
  def initialize(options = {})
@@ -29,10 +70,10 @@ module ActiveSmsgate #:nodoc:
29
70
  # OVERDRAFT [максимальных уход в минус]
30
71
  # PARENT_DEBT [задолженность]
31
72
  def balance
32
- @response = self.class.post("#{uri}/sendsms",
73
+ response = self.class.post("#{uri}/sendsms",
33
74
  :query => { :action => "balance"}.merge(auth_options))
34
- if @response.code == 200
35
- xml = Zlib::GzipReader.new( StringIO.new( @response ) ).read
75
+ if response.code == 200
76
+ xml = Zlib::GzipReader.new( StringIO.new( response ) ).read
36
77
  doc = Nokogiri::XML(xml)
37
78
  {
38
79
  :balance => (doc.at("//balance//AGT_BALANCE").inner_html rescue 0),
@@ -40,14 +81,10 @@ module ActiveSmsgate #:nodoc:
40
81
  :overdraft => (doc.at("//balance//OVERDRAFT").inner_html rescue 0)
41
82
  }
42
83
  else
43
- @response
44
- # raise
84
+ raise
45
85
  end
46
-
47
- # error
48
- # rescue
49
- # nil
50
-
86
+ rescue
87
+ nil
51
88
  end
52
89
 
53
90
  # Отправка сообщения
@@ -59,107 +96,94 @@ module ActiveSmsgate #:nodoc:
59
96
  # * sender - имя отправителя, зарегистрированного в системе service.amegainform.ru.
60
97
  # NULL - используется имя отправителя по умолчанию.
61
98
 
62
-
63
- # Nokogiri::XML::Builder.new do |xml|
64
- # xml.output do
65
- # xml.result(:sms_group_id => 996) do
66
- # xml.sms(:id => '23234',:smstyoe => 'sendsms', :phone => '333', :sms_res_count => '1' ) {
67
- # xml << "\<![CDATA[Привет]]\>"}
68
- # xml.sms(:id => '999',:smstyoe => 'sendsms', :phone => '22', :sms_res_count => '11' ) {
69
- # xml << "\<![CDATA[---------Привет---------]]\>"}
70
- # end
71
- # end
72
- # end
73
-
74
-
75
- # Возвращаемые данные
76
- # <output>
77
- # <result sms_group_id="996">
78
- # <sms id="99991" smstype="SENDSMS" phone="+79999999991" sms_res_count="1"><![CDATA[Привет]]></sms>
79
- # <sms id="99992" smstype="SENDVOICE" phone="+79999999992" sms_res_count="38"><![CDATA[%PAUSE=1000%%SYNTH=Vika%Привет друг%SAMPLE=#1525%%PAUSE=1000%%SYNTH=Vika%С днём рождения!]]></sms>
80
- # </result>
81
- # <output>
82
-
83
- def deliver(options = { :sender => nil})
99
+ # Возвращаемые параметры
100
+ # sms_id - ид в сервисе шлюза
101
+ # sms_count - сколько смс потрачено на отправку сообщения
102
+ # phone - номер куда было отправлено сообщение
103
+ # Если @errors не пустое то возвращает nil
104
+ def deliver_sms(options = { :sender => nil})
84
105
  @options = {
85
- :action => "post_sms",
86
- :message => options[:message],
106
+ :action => "post_sms", :message => options[:message],
87
107
  :target => options[:phones],
88
108
  :sender => options[:sender] }
89
109
 
90
- @response = self.class.post("#{uri}/sendsms", :query => @options.merge(auth_options))
91
- if @response.code == 200
92
- xml = Zlib::GzipReader.new( StringIO.new( @response ) ).read
110
+ response = self.class.post("#{uri}/sendsms", :query => @options.merge(auth_options))
111
+ xml = Zlib::GzipReader.new( StringIO.new( response ) ).read
112
+ if response.code == 200
93
113
  parse(xml)
94
- { :sms => @sms, :messages => @messages, :errors => @errors}
114
+ @sms.map{|x| x.merge({ :sms_group_id => x[:sms_group_id],
115
+ :sms_id => x[:id], :phone => x[:phone], :sms_count => x[:sms_res_count] })}
116
+
95
117
  else
96
118
  raise
97
119
  end
98
120
  rescue
121
+ STDERR.puts " #{$!.inspect} "
122
+ STDERR.puts " #{xml} " if xml
99
123
  nil
100
124
  end
101
125
 
102
126
 
103
-
104
127
  # Получение данных и статусов сообщений
105
128
  # sms_id - ид смс
106
-
107
-
108
- # Возвращаемые данные
109
- # -------------------------------------------------------------------
110
- # SMS_ID - ID сообщения
111
- # SMS_GROUP_ID - ID рассылки сообщений
112
- # SMSTYPE - тип сообщения
113
- # CREATED - дата и время создания сообщения
114
- # AUL_USERNAME - Имя пользователя создавшего сообщение
115
- # AUL_CLIENT_ADR - IP адрес пользователя создавшего сообщение
116
- # SMS_SENDER - Имя отправителя сообщения
117
- # SMS_TARGET - Телефон адресата
118
- # SMS_RES_COUNT - Кол-во единиц ресурсов на данное сообщение
119
- # SMS_TEXT - Текст сообщения
120
- # SMSSTC_CODE - Код статуса доставки сообщения
121
- # -- queued - сообщение в очереди отправки
122
- # -- wait - передано оператору на отправку
123
- # -- accepted - сообщение принято оператором, но статус доставки неизвестен
124
- # -- delivered -сообщение доставлено
125
- # -- not_delivered - сообщение не доставлено
126
- # -- failed - ошибка при работе по сообщению
127
- # SMS_STATUS - Текстовое описание статуса доставки сообщения
128
- # SMS_CLOSED - [0,1] 0 - сообщения находится в процессинге.
129
- # 1 = работа по отправке сообщения завершена
130
- # SMS_SENT - [0,1] 0 - сообщение не отослано. 1 = сообщение отослано успешно
131
- # SMS_CALL_DURATION - Время,
132
- # в течение которого было установлено соединение для отправки сообщения.
133
- # SMS_DTMF_DIGITS - Что пользователь нажимал в сеансе разговора (для SENDVOICE (в разработке))
134
- # SMS_CLOSE_TIME - Время завершения работы по сообщению.
135
-
136
- def reply(sms_id)
137
- @options = { :action => "status", :sendtype => "SENDSMS", :sms_id => sms_id }
138
- @response = self.class.post("#{uri}/sendsms", :query => @options.merge(auth_options))
139
-
140
- if @response.code == 200
141
- xml = Zlib::GzipReader.new( StringIO.new( @response ) ).read
142
- doc = Nokogiri::XML(xml)
129
+ # type - sms - запрашиваем статус по одному сообщению
130
+ # - sms_group - запрашиваем статусы по рассылке
131
+
132
+ # Возвращаем hash
133
+ # где обязательно есть
134
+ # sms_id - ид в сервисе шлюза
135
+ # sms_count - кол-во смс потраченное на отправку сообщения
136
+ # phone - телефон
137
+
138
+ def reply_sms(sms_id, sms_type = :sms)
139
+ raise unless [:sms, :sms_group].include?(sms_type)
140
+
141
+ @options = { :action => "status", :sendtype => "SENDSMS", "#{sms_type}_id" => sms_id }
142
+ response = self.class.post("#{uri}/sendsms", :query => @options.merge(auth_options))
143
+ xml = Zlib::GzipReader.new( StringIO.new( response ) ).read
144
+ if response.code == 200
143
145
  parse(xml)
144
- { :sms => @sms, :messages => @messages, :errors => @errors}
146
+ if sms_type == :sms
147
+ @messages.map{ |msg| msg.merge({ :sms_id => msg[:sms_id],:sms_count => msg[:sms_res_count],
148
+ :phone => msg[:sms_target] }) }.find{ |x| x[:sms_id] == sms_id.to_s }
149
+ else
150
+ @messages.map{ |msg| msg.merge({ :sms_id => msg[:sms_id],
151
+ :sms_count => msg[:sms_res_count], :phone => msg[:sms_target] }) }
152
+ end
145
153
  else
146
154
  raise
147
155
  end
148
156
  rescue
149
- nil
157
+ STDERR.puts " #{$!.inspect} "
158
+ STDERR.puts " #{xml} " if xml
159
+ false
150
160
  end
151
161
 
162
+ # Выполнение отправки смс завершено
163
+ def complete_sms(sms_id)
164
+ @message ||= reply_sms(sms_id)
165
+ true if @message[:sms_closed].to_i == 1
166
+ end
167
+ alias :complete_sms? :complete_sms
152
168
 
153
- private
154
- # Возвращает параметры для авторизации
155
- def auth_options; { :user => @login, :pass => @password } end
169
+ # Смс досталена
170
+ def success_sms(sms_id)
171
+ @message ||= reply_sms(sms_id)
172
+ true if @message[:sms_sent].to_i == 1
173
+ end
174
+ alias :success_sms? :success_sms
156
175
 
157
- # Получение uri смс сервиса
158
- def uri
159
- self.class.default_options[:base_uri].gsub!(/^https?:\/\//i, '')
160
- "http#{'s' if use_ssl?}://#{self.class.default_options[:base_uri]}"
176
+ # Смс не доставлена
177
+ def failure_sms(sms_id)
178
+ @message ||= reply_sms(sms_id)
179
+ true if @message[:sms_sent].to_i != 1
161
180
  end
181
+ alias :failure_sms? :failure_sms
182
+
183
+ private
162
184
 
185
+ # Возвращает параметры для авторизации
186
+ def auth_options; { :user => @login, :pass => @password } end
163
187
 
164
188
  # Разбираем ответ от сервиса amegainform
165
189
  def parse(xml)
@@ -169,6 +193,7 @@ module ActiveSmsgate #:nodoc:
169
193
  @sms = doc.at("//output//result") && doc.at("//output//result").
170
194
  children.search("//sms").map {|x|
171
195
  _x ={}
196
+ doc.at("//output//result").each { |v,l| _x[v.downcase.to_sym] = l }
172
197
  x.each { |v,l| _x[v.downcase.to_sym] = l }
173
198
  _x[:text] = x.inner_html
174
199
  _x
@@ -6,6 +6,7 @@ require 'httparty'
6
6
  require 'nokogiri'
7
7
  require 'digest'
8
8
  require "zlib"
9
+ require 'active_resource'
9
10
 
10
11
  require "active_smsgate/gateway"
11
12
  Dir[File.join(File.dirname(__FILE__), 'active_smsgate','gateways','**','*.rb')].each { |gw| require gw }
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Pechnikov Maxim
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-09 00:00:00 +06:00
17
+ date: 2010-05-13 00:00:00 +06:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -57,6 +57,20 @@ dependencies:
57
57
  version: 0.5.2
58
58
  type: :runtime
59
59
  version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: activeresource
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 2
69
+ - 3
70
+ - 5
71
+ version: 2.3.5
72
+ type: :runtime
73
+ version_requirements: *id004
60
74
  description: Active Smsgate
61
75
  email: parallel588@gmail.com
62
76
  executables: []