blythedunham-sms_on_rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/Manifest +101 -0
- data/README +163 -0
- data/README.rdoc +211 -0
- data/Rakefile +76 -0
- data/app/controllers/admin/sms_on_rails/base_controller.rb +11 -0
- data/app/controllers/admin/sms_on_rails/drafts_controller.rb +75 -0
- data/app/controllers/admin/sms_on_rails/outbounds_controller.rb +117 -0
- data/app/controllers/admin/sms_on_rails/phone_carriers_controller.rb +85 -0
- data/app/controllers/admin/sms_on_rails/phone_numbers_controller.rb +101 -0
- data/app/controllers/sms_on_rails/creation_support.rb +99 -0
- data/app/controllers/sms_on_rails_controller.rb +14 -0
- data/app/helpers/admin/sms_on_rails/drafts_helper.rb +2 -0
- data/app/helpers/admin/sms_on_rails/phone_carriers_helper.rb +2 -0
- data/app/helpers/sms_on_rails/phone_numbers_helper.rb +9 -0
- data/app/helpers/sms_on_rails/sms_helper.rb +44 -0
- data/app/models/sms_on_rails/draft.rb +9 -0
- data/app/models/sms_on_rails/outbound.rb +17 -0
- data/app/models/sms_on_rails/phone_carrier.rb +14 -0
- data/app/models/sms_on_rails/phone_number.rb +8 -0
- data/app/views/admin/sms_on_rails/base/index.html.erb +5 -0
- data/app/views/admin/sms_on_rails/drafts/_show.html.erb +34 -0
- data/app/views/admin/sms_on_rails/drafts/edit.html.erb +36 -0
- data/app/views/admin/sms_on_rails/drafts/index.html.erb +32 -0
- data/app/views/admin/sms_on_rails/drafts/new.html.erb +34 -0
- data/app/views/admin/sms_on_rails/drafts/send_sms.html.erb +3 -0
- data/app/views/admin/sms_on_rails/drafts/show.html.erb +4 -0
- data/app/views/admin/sms_on_rails/outbounds/edit.html.erb +68 -0
- data/app/views/admin/sms_on_rails/outbounds/index.html.erb +37 -0
- data/app/views/admin/sms_on_rails/outbounds/new.html.erb +54 -0
- data/app/views/admin/sms_on_rails/outbounds/show.html.erb +69 -0
- data/app/views/admin/sms_on_rails/phone_carriers/edit.html.erb +24 -0
- data/app/views/admin/sms_on_rails/phone_carriers/index.html.erb +24 -0
- data/app/views/admin/sms_on_rails/phone_carriers/new.html.erb +22 -0
- data/app/views/admin/sms_on_rails/phone_carriers/show.html.erb +24 -0
- data/app/views/admin/sms_on_rails/phone_numbers/edit.html.erb +33 -0
- data/app/views/admin/sms_on_rails/phone_numbers/index.html.erb +28 -0
- data/app/views/admin/sms_on_rails/phone_numbers/new.html.erb +31 -0
- data/app/views/admin/sms_on_rails/phone_numbers/show.html.erb +32 -0
- data/app/views/layouts/sms_on_rails/basic.html.erb +26 -0
- data/app/views/sms_on_rails/_phone_carrier_form_item.html.erb +6 -0
- data/app/views/sms_on_rails/_send_sms.html.erb +33 -0
- data/app/views/sms_on_rails/index.html.erb +8 -0
- data/app/views/sms_on_rails/send_sms.html.erb +3 -0
- data/app/views/sms_on_rails/show.html.erb +29 -0
- data/config/routes.rb +19 -0
- data/db/data/fixtures/sms_phone_carriers.yml +110 -0
- data/db/migrate/sms_on_rails_carrier_tables.rb +9 -0
- data/db/migrate/sms_on_rails_model_tables.rb +48 -0
- data/db/migrate/sms_on_rails_phone_number_tables.rb +11 -0
- data/db/seed_data.rb +16 -0
- data/generators/sms_on_rails/USAGE +31 -0
- data/generators/sms_on_rails/commands/inserts.rb +63 -0
- data/generators/sms_on_rails/commands/timestamps.rb +33 -0
- data/generators/sms_on_rails/runners/add_all_models.rb +6 -0
- data/generators/sms_on_rails/runners/dependencies.rb +1 -0
- data/generators/sms_on_rails/runners/remove_all_models.rb +5 -0
- data/generators/sms_on_rails/runners/sms_on_rails_routes.rb +14 -0
- data/generators/sms_on_rails/sms_on_rails_generator.rb +255 -0
- data/generators/sms_on_rails/templates/configuration/clickatell.rb +6 -0
- data/generators/sms_on_rails/templates/configuration/email_gateway.rb +7 -0
- data/generators/sms_on_rails/templates/migrate/schema_migration.rb +15 -0
- data/generators/sms_on_rails/templates/migrate/sms_on_rails_update_phone_numbers.rb +40 -0
- data/generators/sms_on_rails/templates/phone_number_collision.rb +2 -0
- data/init.rb +3 -0
- data/install.rb +1 -0
- data/lib/sms_on_rails.rb +8 -0
- data/lib/sms_on_rails/activerecord_extensions/acts_as_deliverable.rb +92 -0
- data/lib/sms_on_rails/activerecord_extensions/acts_as_substitutable.rb +80 -0
- data/lib/sms_on_rails/activerecord_extensions/has_a_sms_service_provider.rb +101 -0
- data/lib/sms_on_rails/activerecord_extensions/lockable_record.rb +186 -0
- data/lib/sms_on_rails/all_models.rb +3 -0
- data/lib/sms_on_rails/model_support/draft.rb +178 -0
- data/lib/sms_on_rails/model_support/outbound.rb +136 -0
- data/lib/sms_on_rails/model_support/phone_carrier.rb +77 -0
- data/lib/sms_on_rails/model_support/phone_number.rb +248 -0
- data/lib/sms_on_rails/model_support/phone_number_associations.rb +13 -0
- data/lib/sms_on_rails/schema_helper.rb +51 -0
- data/lib/sms_on_rails/service_providers/base.rb +222 -0
- data/lib/sms_on_rails/service_providers/clickatell.rb +52 -0
- data/lib/sms_on_rails/service_providers/dummy.rb +19 -0
- data/lib/sms_on_rails/service_providers/email_gateway.rb +68 -0
- data/lib/sms_on_rails/service_providers/email_gateway_support/errors.rb +20 -0
- data/lib/sms_on_rails/service_providers/email_gateway_support/sms_mailer.rb +21 -0
- data/lib/sms_on_rails/service_providers/email_gateway_support/sms_mailer/sms_through_gateway.erb +6 -0
- data/lib/sms_on_rails/util/sms_error.rb +12 -0
- data/lib/smsonrails.rb +1 -0
- data/public/images/sms_on_rails/railsYoDawg.jpg +0 -0
- data/public/stylesheets/sms_on_rails.css +137 -0
- data/sms_on_rails.gemspec +32 -0
- data/tasks/sms_on_rails_tasks.rake +67 -0
- data/test/active_record_extensions/delivery_and_locking_test.rb +84 -0
- data/test/models/draft_test.rb +72 -0
- data/test/models/outbound_test.rb +89 -0
- data/test/models/phone_number_test.rb +131 -0
- data/test/run.rb +18 -0
- data/test/service_providers/abstract_test_support.rb +104 -0
- data/test/service_providers/clickatell_test.rb +39 -0
- data/test/service_providers/email_gateway_test.rb +30 -0
- data/test/test_helper.rb +24 -0
- data/uninstall.rb +1 -0
- metadata +187 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
module SmsOnRails
|
2
|
+
module ModelSupport
|
3
|
+
module PhoneNumberAssociations
|
4
|
+
def self.included(base)
|
5
|
+
base.send :has_many, :outbounds, :class_name => 'SmsOnRails::Outbound',
|
6
|
+
:foreign_key => 'sms_phone_number_id', :dependent => :delete_all
|
7
|
+
base.send :belongs_to, :carrier, :class_name => 'SmsOnRails::PhoneCarrier',
|
8
|
+
:foreign_key => :carrier_id
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module SmsOnRails
|
2
|
+
class SchemaHelper
|
3
|
+
class << self
|
4
|
+
def create(*files)
|
5
|
+
each_file(*files) {|file, options| file_to_string(file, options) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def drop(*files)
|
9
|
+
each_file(*files) {|file, options| drop_tables(file, options)}
|
10
|
+
end
|
11
|
+
|
12
|
+
def each_file(*files, &block)
|
13
|
+
options = parse_options(files)
|
14
|
+
files.inject('') {|str, f| str << yield(f, options); str }
|
15
|
+
end
|
16
|
+
|
17
|
+
def schema(command, *files)
|
18
|
+
str = "ActiveRecord::Schema.define do\n"
|
19
|
+
str << self.send(command, *files)
|
20
|
+
str << "\nend"
|
21
|
+
str
|
22
|
+
end
|
23
|
+
|
24
|
+
def file_to_string(file, options={})
|
25
|
+
File.read(File.join(File.dirname(__FILE__), "../../db/migrate/#{file}.rb"))
|
26
|
+
end
|
27
|
+
|
28
|
+
def drop_tables(file, options={})
|
29
|
+
str = "\n"
|
30
|
+
data = file_to_string(file)
|
31
|
+
data.scan(/create_table\s+[":]([^\W]*)/) do
|
32
|
+
table_name = $1.dup
|
33
|
+
str << safe_code(str, options) { |code| code << " drop_table :#{table_name}\n" }
|
34
|
+
end
|
35
|
+
str
|
36
|
+
end
|
37
|
+
|
38
|
+
def safe_code(str, options, &block)
|
39
|
+
str = ''
|
40
|
+
str << " begin\n " if options[:safe]
|
41
|
+
yield str
|
42
|
+
str << " rescue Exception => e\n end\n" if options[:safe]
|
43
|
+
str
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_options(files)
|
47
|
+
options = files.last.is_a?(Hash) ? files.pop : {}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# This is the base class for service providers from which all others inherit
|
2
|
+
# All service providers are singletons and can be accessed by their instance
|
3
|
+
#
|
4
|
+
# To send a message without validation
|
5
|
+
# SmsOnRails::ServiceProviders::<Provider>.instance.send_message '12065551234', 'my message', options
|
6
|
+
#
|
7
|
+
# To send a message with validation use send_to_phone_number with a string or SmsOnRails::PhoneNumber instance
|
8
|
+
# SmsOnRails::ServiceProviders<Provider>.instance.send_to_phone_number(number, message, options)
|
9
|
+
#
|
10
|
+
# To send an sms(with validation)
|
11
|
+
# SmsOnRails::ServiceProviders<Provider>.instance.send_sms(sms, options)
|
12
|
+
# However, it is preferred to use the locking mechanism to prevent double messages from being sent
|
13
|
+
# sms.deliver!
|
14
|
+
#
|
15
|
+
module SmsOnRails
|
16
|
+
module ServiceProviders
|
17
|
+
class Base
|
18
|
+
include Singleton
|
19
|
+
|
20
|
+
#the configuration options for the service provider
|
21
|
+
class_inheritable_hash :config
|
22
|
+
self.config ||= {}
|
23
|
+
|
24
|
+
#special deliver options specific to the service provider
|
25
|
+
class_inheritable_accessor :delivery_options
|
26
|
+
self.delivery_options ||= {}
|
27
|
+
|
28
|
+
#the default service provider
|
29
|
+
cattr_accessor :default_service_provider
|
30
|
+
|
31
|
+
#a unique id by which each service provider is identified
|
32
|
+
class_inheritable_accessor :provider_id, :instance_writer => false
|
33
|
+
|
34
|
+
#the logger -> ActiveRecord::Base.logger
|
35
|
+
cattr_accessor :logger
|
36
|
+
@@logger ||= ActiveRecord::Base.logger
|
37
|
+
|
38
|
+
|
39
|
+
def requires_carrier?; false; end
|
40
|
+
|
41
|
+
# Deliver all the sms messages marked with this as its sms service provider
|
42
|
+
def deliver
|
43
|
+
Outbound.deliver(delivery_options.merge(:conditions => ['sms_service_provider_id = ?', self.provider_id]))
|
44
|
+
end
|
45
|
+
|
46
|
+
[:config, :name, :provider_id, :logger, :human_name].each{|method| class_eval "def #{method}; self.class.#{method}; end"}
|
47
|
+
|
48
|
+
|
49
|
+
# Sends a message to a phone number directly to the provider.
|
50
|
+
# No validations are performed
|
51
|
+
# * +phone_number+ the exact string text to send
|
52
|
+
# * +message+ - the string message to send
|
53
|
+
# * +options+ - additional options to be used by the provider
|
54
|
+
#
|
55
|
+
def send_message(phone_number, message, options={})
|
56
|
+
raise SmsOnRails::SmsError.new("Override send_message in subclass #{self.class}")
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# Sends a message to a phone number active record object or string
|
61
|
+
# and performs validation on the phone_number
|
62
|
+
#
|
63
|
+
# * +phone_number+ can be either a phone number active record obj or a string text. Strings are converted to phone_number objects
|
64
|
+
# * +message+ - the message to send
|
65
|
+
# * +options+ - additional options to be used by the provider
|
66
|
+
#
|
67
|
+
# ===Options
|
68
|
+
# <tt>:skip_validation</tt> - skips validation and sends the message directly to the
|
69
|
+
# provider
|
70
|
+
def send_to_phone(phone_obj, message, options={})
|
71
|
+
|
72
|
+
if options[:skip_validation]
|
73
|
+
phone_text = phone_obj.is_a?(ActiveRecord::Base) ? format_phone_number(phone_number) : phone_obj
|
74
|
+
return send_message(phone_text, message, options)
|
75
|
+
end
|
76
|
+
|
77
|
+
phone_number = phone_obj.is_a?(ActiveRecord::Base) ? phone_obj :
|
78
|
+
find_or_create_phone_number(phone_obj, options)
|
79
|
+
|
80
|
+
assert_message_options!(phone_number, message, options)
|
81
|
+
send_message(format_phone_number(phone_number), message, options)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Send an Sms with validation
|
85
|
+
# +sms+ is an sms active record object that responds to phone_number and full_message
|
86
|
+
#
|
87
|
+
# Refer to send_to_phone for more infomation on validation
|
88
|
+
def send_sms(sms, options={})
|
89
|
+
send_to_phone(sms.phone_number, sms.actual_message, options)
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
#can override in subclass if different finder should be used
|
95
|
+
def find_or_create_phone_number(phone_text, options={})
|
96
|
+
phone = phone_klass.find_and_create_by_number(phone_text)
|
97
|
+
phone.assign_carrier(options[:carrier]) if options[:carrier]
|
98
|
+
phone
|
99
|
+
end
|
100
|
+
|
101
|
+
#override this if the expected format differs in subclass
|
102
|
+
def format_phone_number(phone_number)
|
103
|
+
phone_number.digits
|
104
|
+
end
|
105
|
+
|
106
|
+
# Raise an exception if the white list is being used (only sends to people on this list)
|
107
|
+
# and this phone number is not on the list
|
108
|
+
def check_white_list!(phone_number)
|
109
|
+
if self.class.config[:white_list] && !phone_number.white_list?
|
110
|
+
raise SmsOnRails::SmsError.new("Phone number #{phone_number.human_display} is not in white list")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Raise an exception if this phone_number is marked as do not send
|
115
|
+
def check_do_not_send!(phone_number)
|
116
|
+
if phone_number.do_not_send?
|
117
|
+
raise SmsOnRails::SmsError.new("Phone number #{phone_number.human_display} do not send is set:#{phone_number.do_not_send}")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Raise exception if invalid data is entered
|
122
|
+
def assert_message_options!(phone_number, message, options)
|
123
|
+
raise SmsOnRails::SmsError.new("Invalid or undefined phone number: #{phone_number.human_display}") unless phone_number && phone_number.valid?
|
124
|
+
raise SmsOnRails::SmsError.new("No message specified") unless message
|
125
|
+
raise SmsOnRails::SmsError.new("Message is too long. #{message}") if message.length > self.class.max_characters
|
126
|
+
check_white_list!(phone_number)
|
127
|
+
check_do_not_send!(phone_number)
|
128
|
+
end
|
129
|
+
|
130
|
+
# return the appropriate exception class
|
131
|
+
# Return a fatal error if the block returns true and a non fatal if the
|
132
|
+
# block returns false
|
133
|
+
def sms_error_class(&block)#:nodoc
|
134
|
+
if yield
|
135
|
+
SmsOnRails::FatalSmsError
|
136
|
+
else
|
137
|
+
SmsOnRails::SmsError
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# The class used for phone numbers
|
142
|
+
# can be overwritten and specified in environment.rb
|
143
|
+
def phone_klass
|
144
|
+
config[:phone_klass]||SmsOnRails::PhoneNumber
|
145
|
+
end
|
146
|
+
|
147
|
+
class << self
|
148
|
+
|
149
|
+
def set_default_service_provider(provider)
|
150
|
+
return if $gems_rake_task
|
151
|
+
provider_instance = get_service_provider(provider)
|
152
|
+
raise SmsOnRails::FatalSmsError.new("Cannot set default provider to #{provider}. Check that support for #{provider} exists.") unless provider_instance
|
153
|
+
self.default_service_provider = provider_instance
|
154
|
+
end
|
155
|
+
|
156
|
+
def max_characters
|
157
|
+
self.config[:max_characters]||140
|
158
|
+
end
|
159
|
+
|
160
|
+
# Name of service provider (downcase no spaces)
|
161
|
+
def name
|
162
|
+
@name ||= self.to_s.demodulize.underscore
|
163
|
+
end
|
164
|
+
|
165
|
+
# Human name of provider
|
166
|
+
def human_name
|
167
|
+
@human_name ||= self.to_s.demodulize.titleize
|
168
|
+
end
|
169
|
+
|
170
|
+
# Hash map of provider_id to the provider
|
171
|
+
def provider_map
|
172
|
+
@provider_map ||= provider_list.inject({}) do |map, klass|
|
173
|
+
map[klass.provider_id] = klass unless klass.nil?
|
174
|
+
map
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
#List of all providers available
|
179
|
+
def provider_list
|
180
|
+
@provider_list ||= subclasses.inject([]) do |list, klass_name|
|
181
|
+
klass = klass_name.constantize
|
182
|
+
begin
|
183
|
+
list << klass.instance
|
184
|
+
rescue LoadError => exc
|
185
|
+
logger.error "#{klass} load error: #{exc}"
|
186
|
+
end
|
187
|
+
list
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# Locate the service provider by provider id
|
192
|
+
# Example: SmsOnRails::ServiceProviders::Base.provider_by_id 1
|
193
|
+
def provider_by_id(provider_id)
|
194
|
+
provider_map[provider_id.to_i] if provider_id.to_i > 0
|
195
|
+
end
|
196
|
+
|
197
|
+
# Locate the service provider by name or symbol
|
198
|
+
# Example: SmsOnRails::ServiceProviders::Base.provider_by_name :dummy
|
199
|
+
def provider_by_name(provider_name)
|
200
|
+
key = provider_name.to_s.downcase
|
201
|
+
provider_list.detect{|p| key == p.name || provider_name == p.human_name}
|
202
|
+
end
|
203
|
+
|
204
|
+
# Locate the service provider object by provider_id, string, symbol, or ServiceProvider object
|
205
|
+
# Defaults to the default service provider
|
206
|
+
# SmsOnRails::ServiceProviders::Base.get_service_provider :dummy
|
207
|
+
# SmsOnRails::ServiceProviders::Base.get_service_provider 1
|
208
|
+
# SmsOnRails::ServiceProviders::Base.get_service_provider SmsOnRails::ServiceProviders::Dummy
|
209
|
+
def get_service_provider(provider)
|
210
|
+
case provider.class.to_s
|
211
|
+
when 'Fixnum' then provider_by_id(provider)
|
212
|
+
when 'String' then (provider.to_i > 0 ? provider_by_id(provider) : provider_by_name(provider))
|
213
|
+
when 'Symbol' then provider_by_name(provider)
|
214
|
+
when 'NilClass' then nil
|
215
|
+
else
|
216
|
+
provider
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module SmsOnRails
|
2
|
+
module ServiceProviders
|
3
|
+
class Clickatell < Base
|
4
|
+
self.provider_id = 1
|
5
|
+
|
6
|
+
FATAL_ERROR_CODES = %w(105 114) unless defined?(FATAL_ERROR_CODES)
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
begin
|
10
|
+
require 'clickatell'
|
11
|
+
rescue LoadError => exc
|
12
|
+
raise LoadError.new(exc.to_s + " Please make sure the clickatell gem is installed.")
|
13
|
+
end
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def ping
|
18
|
+
result = invoke_clickatell{ api.ping(nil) }
|
19
|
+
result.is_a?(Net::HTTPOK)
|
20
|
+
end
|
21
|
+
|
22
|
+
def authenticate
|
23
|
+
invoke_clickatell{ api }
|
24
|
+
end
|
25
|
+
|
26
|
+
#Send a message without validation
|
27
|
+
# * phone_number - phone number string digits
|
28
|
+
# * message - the message text
|
29
|
+
# * options - anything else
|
30
|
+
def send_message(phone_number, message, options={})
|
31
|
+
unique_id = invoke_clickatell{ api.send_message(phone_number, message) }
|
32
|
+
{:unique_id => unique_id}
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
#Get the api key
|
38
|
+
def api#:nodoc:
|
39
|
+
@@api ||= ::Clickatell::API.authenticate(config[:api_id], config[:user_name], config[:password])
|
40
|
+
end
|
41
|
+
|
42
|
+
# wrap this method around all clickatell calls
|
43
|
+
# if anything other than a 105 is thrown, reraise FatalSmsError
|
44
|
+
def invoke_clickatell(&block)#:nodoc
|
45
|
+
yield
|
46
|
+
|
47
|
+
rescue ::Clickatell::API::Error => cae
|
48
|
+
raise sms_error_class{ !(FATAL_ERROR_CODES.include?(cae.code)) }.new("Clickatell Error:#{cae.code}:#{cae.message}", cae.code)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SmsOnRails
|
2
|
+
module ServiceProviders
|
3
|
+
class Dummy < Base
|
4
|
+
|
5
|
+
self.provider_id = 2
|
6
|
+
|
7
|
+
def ping
|
8
|
+
true
|
9
|
+
end
|
10
|
+
|
11
|
+
def send_message(phone_number, message, options={})
|
12
|
+
response = {:unique_id => "#{$$}:#{Time.now.strftime('%Y%m%d%H%M%SZ')}.#{rand(1000)}"}
|
13
|
+
response
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
SmsOnRails::ServiceProviders::Base.default_service_provider ||= SmsOnRails::ServiceProviders::Dummy.instance
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#Require all the email gateway support files
|
2
|
+
Dir.glob(File.dirname(__FILE__) + '/email_gateway_support/*.rb').each {|f| require f }
|
3
|
+
|
4
|
+
module SmsOnRails
|
5
|
+
module ServiceProviders
|
6
|
+
class EmailGateway < Base
|
7
|
+
self.provider_id = 3
|
8
|
+
|
9
|
+
def ping; true; end
|
10
|
+
|
11
|
+
def mailer_klass; self.class.mailer_klass; end
|
12
|
+
|
13
|
+
def requires_carrier?; true; end
|
14
|
+
|
15
|
+
# Email Gateway Send message
|
16
|
+
#
|
17
|
+
# send_message('2065551234@txt.att.net', 'My message')
|
18
|
+
# send_message('12065551234', 'my message', :carrier => 'Verizon')
|
19
|
+
# send_message(['12065551234', '4125556667'], 'my message', :carrier => 'Verizon')
|
20
|
+
#
|
21
|
+
# === Params
|
22
|
+
# * +phone_number+ - can be one of the following
|
23
|
+
# sms_email_address. Example: '2065551234@txt.att.net'
|
24
|
+
# array of sms_email_addresses: ['2065551234@txt.att.net', '2065552234@txt.att.net']
|
25
|
+
# * +message+ - the text message to send
|
26
|
+
#
|
27
|
+
# ===Options
|
28
|
+
# * <tt>:sender</tt> - email address of the sender overrides default
|
29
|
+
# * <tt>:bcc</tt> - email_address or array of email_addresses to blind carbon copy
|
30
|
+
def send_message(phone_text, message, options={})
|
31
|
+
mailer_klass.deliver_sms_through_gateway(phone_text, message, self.class.config.merge(options))
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
#the formate for email is the sms email address
|
38
|
+
def format_phone_number(phone_number)
|
39
|
+
phone_number.sms_email_address
|
40
|
+
end
|
41
|
+
|
42
|
+
# additional check to make sure the sms_email_address is valid
|
43
|
+
def assert_message_options!(phone_number, message, options)
|
44
|
+
super(phone_number, message, options)
|
45
|
+
unless phone_number.carrier || phone_number.sms_email_address
|
46
|
+
raise EmailGatewayInvalidSms.phone_error(phone_number)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# override to append the carrier if specified as part of the phone number
|
51
|
+
# or as a separate option
|
52
|
+
def find_or_create_phone_number(phone_text, options={})
|
53
|
+
phone = phone_klass.find_by_sms_email_address(phone_text)
|
54
|
+
phone ||= super(phone_text, options)
|
55
|
+
phone.assign_carrier(options[:carrier]) if options[:carrier]
|
56
|
+
phone
|
57
|
+
end
|
58
|
+
|
59
|
+
class << self
|
60
|
+
# The mailer class to use that can be specified in the config options for :mailer_klass
|
61
|
+
def mailer_klass#:nodoc:
|
62
|
+
@mailer_klass ||= config[:mailer_klass]||SmsOnRails::ServiceProviders::EmailGatewaySupport::SmsMailer
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SmsOnRails
|
2
|
+
module ServiceProviders
|
3
|
+
class EmailGatewayInvalidSms < SmsOnRails::SmsError
|
4
|
+
def self.phone_error(phone_number)
|
5
|
+
new(self.phone_message(phone_number))
|
6
|
+
end
|
7
|
+
def self.phone_message(phone_number)
|
8
|
+
msg = "Invalid phone number #{phone_number.human_display if phone_number}. "
|
9
|
+
msg << "Please specify the digits and the option :carrier, "
|
10
|
+
msg << "or specify the full email address like 2065551234@txt.att.net"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class EmailGatewayInvalidCarrier < EmailGatewayInvalidSms
|
15
|
+
def self.phone_message(phone_number)
|
16
|
+
msg = "The carrier for #{phone_number.human_display if phone_number} is invalid."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|