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.
- data/lib/active_smsgate/gateway.rb +35 -2
- data/lib/active_smsgate/gateways/amegainform.rb +118 -93
- data/lib/active_smsgate.rb +1 -0
- metadata +17 -3
@@ -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
|
-
[{
|
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
|
-
|
73
|
+
response = self.class.post("#{uri}/sendsms",
|
33
74
|
:query => { :action => "balance"}.merge(auth_options))
|
34
|
-
if
|
35
|
-
xml = Zlib::GzipReader.new( StringIO.new(
|
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
|
-
|
44
|
-
# raise
|
84
|
+
raise
|
45
85
|
end
|
46
|
-
|
47
|
-
|
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
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
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
|
-
{ :
|
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
|
-
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
154
|
-
|
155
|
-
|
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
|
-
#
|
158
|
-
def
|
159
|
-
|
160
|
-
|
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
|
data/lib/active_smsgate.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
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-
|
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: []
|