active_smsgate 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Pechnikov Maxim
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = active_smsgate
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Pechnikov Maxim. See LICENSE for details.
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+ $:.unshift File.dirname(__FILE__)
3
+
4
+ require 'rubygems'
5
+ require 'httparty'
6
+ require 'nokogiri'
7
+ require 'digest'
8
+ require "zlib"
9
+
10
+ require "active_smsgate/gateway"
11
+ Dir[File.join(File.dirname(__FILE__), 'active_smsgate','gateways','**','*.rb')].each { |gw| require gw }
12
+
13
+ module ActiveSmsgate
14
+ VERSION = "0.0"
15
+ class << self
16
+
17
+ def log message
18
+ puts "lid ---------------"
19
+ # logger.info("[active_smsgate] #{message}") #if logging?
20
+ end
21
+
22
+ def logger #:nodoc:
23
+ # # ActiveRecord::Base.logger
24
+ # FILE = "sms_send.log"
25
+ # $logger = Logger.new(FILE,3,5000000)
26
+ end
27
+
28
+ def logging? #:nodoc:
29
+ true #options[:log]
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ module ActiveSmsgate #:nodoc:
3
+ module Gateway #:nodoc:
4
+
5
+ class << self
6
+ # Список поддерживаемых
7
+ def support_gateways
8
+ [{:class => 'amegainform',:desc => 'www.amegainform.ru' }]
9
+ end
10
+ end
11
+
12
+ class Gateway
13
+ include HTTParty
14
+ attr_accessor :login, :password, :use_ssl
15
+
16
+ # Initialize a new gateway.
17
+ # ==== Параметры
18
+ #
19
+ # * <tt>:login</tt> -- REQUIRED
20
+ # * <tt>:password</tt> -- REQUIRED
21
+ # * <tt>:ssl</tt> -- использовать https (OPTIONAL)
22
+ # * <tt>:backup_server</tt> -- использовать адреса резервных серверов (OPTIONAL)
23
+ def initialize(options = {})
24
+ raise "Be sure to login and password" if options[:login].blank? || options[:password].blank?
25
+ @login, @password = options[:login], options[:password]
26
+ @use_ssl = options[:ssl] || false
27
+ @use_of_backup_server = options[:backup_server] || false
28
+ end
29
+
30
+ # Использовать https или http
31
+ def use_ssl?; @use_ssl end
32
+
33
+ # Использовать резервные сервера
34
+ def use_of_backup_server?; @use_of_backup_server end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,194 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module ActiveSmsgate #:nodoc:
4
+ # «Амега Информ» – http://amegainform.ru/
5
+ # это сервис массовой рассылки, приема SMS и голосовых сообщений.
6
+
7
+ module Gateway #:nodoc:
8
+ class Amegainform < Gateway
9
+
10
+ headers 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'
11
+ base_uri 'http://service.amega-inform.ru'
12
+
13
+ # Адреса резервных серверов: service-r1.amegainform.ru и service-r2.amegainform.ru
14
+
15
+ # Создание нового шлюза AmegaInformGateway
16
+ # Для работы со шлюзом необходимы логин и пароль
17
+ #
18
+ # ==== Параметры
19
+ #
20
+ # * <tt>:login</tt> -- REQUIRED
21
+ # * <tt>:password</tt> -- REQUIRED
22
+ def initialize(options = {})
23
+ @options = options
24
+ super
25
+ end
26
+
27
+ # Получение текущего баланса
28
+ # BALANCE [текущее состояние счёта]
29
+ # OVERDRAFT [максимальных уход в минус]
30
+ # PARENT_DEBT [задолженность]
31
+ def balance
32
+ @response = self.class.post("#{uri}/sendsms",
33
+ :query => { :action => "balance"}.merge(auth_options))
34
+ if @response.code == 200
35
+ xml = Zlib::GzipReader.new( StringIO.new( @response ) ).read
36
+ doc = Nokogiri::XML(xml)
37
+ {
38
+ :balance => (doc.at("//balance//AGT_BALANCE").inner_html rescue 0),
39
+ :debt => (doc.at("//balance//PARENT_DEBT").inner_html rescue 0),
40
+ :overdraft => (doc.at("//balance//OVERDRAFT").inner_html rescue 0)
41
+ }
42
+ else
43
+ @response
44
+ # raise
45
+ end
46
+
47
+ # error
48
+ # rescue
49
+ # nil
50
+
51
+ end
52
+
53
+ # Отправка сообщения
54
+
55
+ # Параметры
56
+
57
+ # * message - сообщение
58
+ # * phones - номера телефонов. Список через запятую. (Н-р: "+70010001212, 80009990000")
59
+ # * sender - имя отправителя, зарегистрированного в системе service.amegainform.ru.
60
+ # NULL - используется имя отправителя по умолчанию.
61
+
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})
84
+ @options = {
85
+ :action => "post_sms",
86
+ :message => options[:message],
87
+ :target => options[:phones],
88
+ :sender => options[:sender] }
89
+
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
93
+ parse(xml)
94
+ { :sms => @sms, :messages => @messages, :errors => @errors}
95
+ else
96
+ raise
97
+ end
98
+ rescue
99
+ nil
100
+ end
101
+
102
+
103
+
104
+ # Получение данных и статусов сообщений
105
+ # 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)
143
+ parse(xml)
144
+ { :sms => @sms, :messages => @messages, :errors => @errors}
145
+ else
146
+ raise
147
+ end
148
+ rescue
149
+ nil
150
+ end
151
+
152
+
153
+ private
154
+ # Возвращает параметры для авторизации
155
+ def auth_options; { :user => @login, :pass => @password } end
156
+
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]}"
161
+ end
162
+
163
+
164
+ # Разбираем ответ от сервиса amegainform
165
+ def parse(xml)
166
+ doc = Nokogiri::XML(xml)
167
+ @sms, @messages, @errors = nil, nil, nil
168
+ # Ответ от отправка смс
169
+ @sms = doc.at("//output//result") && doc.at("//output//result").
170
+ children.search("//sms").map {|x|
171
+ _x ={}
172
+ x.each { |v,l| _x[v.downcase.to_sym] = l }
173
+ _x[:text] = x.inner_html
174
+ _x
175
+ }
176
+
177
+ # Сообщения о доставках смс
178
+ @messages = doc.at("//output//MESSAGES") && doc.at("//output//MESSAGES").
179
+ children.search("//MESSAGE").map { |x|
180
+ _x = { }
181
+ x.each { |v,l| _x[v.downcase.to_sym] = l }
182
+ x.children.each {|n| _x[n.name.downcase.to_sym] = n.inner_html unless n.blank? }
183
+ _x
184
+ }
185
+
186
+ # Сообщения об ошибках
187
+ @errors = doc.at("//output//errors") && doc.at("//output//errors").
188
+ children.search("//error").map {|x| x.inner_html }
189
+
190
+ { :sms => @sms, :messages => @messages, :errors => @errors}
191
+ end
192
+ end
193
+ end
194
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'active_smsgate'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestActiveSmsgate < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_smsgate
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Pechnikov Maxim
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-09 00:00:00 +06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: thoughtbot-shoulda
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: nokogiri
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 1
41
+ - 4
42
+ - 1
43
+ version: 1.4.1
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: httparty
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ - 5
56
+ - 2
57
+ version: 0.5.2
58
+ type: :runtime
59
+ version_requirements: *id003
60
+ description: Active Smsgate
61
+ email: parallel588@gmail.com
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files:
67
+ - LICENSE
68
+ - README.rdoc
69
+ files:
70
+ - lib/active_smsgate.rb
71
+ - lib/active_smsgate/gateway.rb
72
+ - lib/active_smsgate/gateways/amegainform.rb
73
+ - LICENSE
74
+ - README.rdoc
75
+ has_rdoc: true
76
+ homepage: http://github.com/pronix/active_smsgate
77
+ licenses: []
78
+
79
+ post_install_message:
80
+ rdoc_options:
81
+ - --charset=UTF-8
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.6
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Active Smsgate
105
+ test_files:
106
+ - test/helper.rb
107
+ - test/test_active_smsgate.rb