textr 0.0.8
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/.DS_Store +0 -0
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.markdown +44 -0
- data/Rakefile +10 -0
- data/lib/textr.rb +78 -0
- data/lib/textr/extends_textr.rb +14 -0
- data/lib/textr/rake/tasks.rb +27 -0
- data/lib/textr/version.rb +3 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/textr/textr_spec.rb +65 -0
- data/textr.gemspec +25 -0
- data/textr_smtp.yml.tpl +32 -0
- metadata +152 -0
data/.DS_Store
ADDED
Binary file
|
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# textr
|
2
|
+
## Install
|
3
|
+
### RubyGems.org
|
4
|
+
coming soon
|
5
|
+
|
6
|
+
### from source
|
7
|
+
$ git clone http://github.com/forrestgrant/textr
|
8
|
+
$ cd textr
|
9
|
+
$ rake build
|
10
|
+
$ rake install
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
You can use textr with an ActiveRecord model, standalone, or on any object.
|
15
|
+
|
16
|
+
### ActiveRecord
|
17
|
+
|
18
|
+
Just add `extends_textr` to your model.
|
19
|
+
|
20
|
+
class User < ActiveRecord::Base
|
21
|
+
extends_textr
|
22
|
+
end
|
23
|
+
|
24
|
+
You can then send an SMS like this
|
25
|
+
|
26
|
+
User.first.send_notification :carrier => 'att', :body => 'Hello World!'
|
27
|
+
|
28
|
+
Your model must have a `phone` attribute. If you wish to change this to something else (like `number` for example), simply pass it like this `extends_textr :number`
|
29
|
+
|
30
|
+
class User < ActiveRecord::Base
|
31
|
+
extends_textr :number
|
32
|
+
end
|
33
|
+
|
34
|
+
Or you can override the `phone` attribute
|
35
|
+
|
36
|
+
User.first.send_notification :number => '098-765-4321', :carrier => 'att', :body => 'Hello World!'
|
37
|
+
|
38
|
+
### Standalone
|
39
|
+
|
40
|
+
Simply call `Textr.send_sms` and pass the number with the hash.
|
41
|
+
|
42
|
+
$ rails c
|
43
|
+
>> Textr.send_sms :number => '123-456-7890', :body => 'Hello World!', :carrier => 'att'
|
44
|
+
=> #<Mail::Message:12345>
|
data/Rakefile
ADDED
data/lib/textr.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require "textr/version"
|
2
|
+
require "textr/rake/tasks"
|
3
|
+
require 'pony'
|
4
|
+
require 'rails'
|
5
|
+
|
6
|
+
module Textr
|
7
|
+
|
8
|
+
@@config = File.exists?('config/textr_smtp.yml') ? YAML.load(ERB.new(File.read(('config/textr_smtp.yml'))).result)[Rails.env].symbolize_keys : false
|
9
|
+
|
10
|
+
def smtp_options
|
11
|
+
@@config ? { :from => @@config[:from],
|
12
|
+
:via => @@config[:protocol].to_sym,
|
13
|
+
:via_options => {
|
14
|
+
:address => @@config[:address],
|
15
|
+
:port => @@config[:port],
|
16
|
+
:enable_starttls_auto => @@config[:ssl],
|
17
|
+
:user_name => @@config[:username],
|
18
|
+
:password => @@config[:password],
|
19
|
+
:authentication => @@config[:authentication],
|
20
|
+
:domain => @@config[:domain]
|
21
|
+
}
|
22
|
+
} : { }
|
23
|
+
end
|
24
|
+
|
25
|
+
@@carriers = {
|
26
|
+
:att => 'txt.att.net',
|
27
|
+
:boost => 'myboostmobile.com',
|
28
|
+
:tmobile => 'tmomail.net',
|
29
|
+
:sprint => 'messaging.sprintpcs.com',
|
30
|
+
:verizon => 'vtext.com',
|
31
|
+
:virgin => 'vmobl.com'
|
32
|
+
}
|
33
|
+
|
34
|
+
def self.extended(base)
|
35
|
+
unless base.respond_to?(:textr_options)
|
36
|
+
base.class_eval do
|
37
|
+
attr_accessor :phone
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def txtable_address( options={} )
|
43
|
+
"#{options[:number].gsub(/\D/, "")[-10..-1]}@#{@@carriers[options[:carrier].to_sym]}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def txtable_address( options={} )
|
47
|
+
"#{options[:number].gsub(/\D/, "")[-10..-1]}@#{@@carriers[options[:carrier].to_sym]}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def send_sms( options={} )
|
51
|
+
number = options[:number] || self.number_from_options
|
52
|
+
raise "#{self.class.to_s}" if number.blank?
|
53
|
+
raise ':carrier required' if options[:carrier].nil?
|
54
|
+
raise ':body required' if options[:body].nil?
|
55
|
+
|
56
|
+
Pony.mail({
|
57
|
+
:to => txtable_address({:carrier => options[:carrier], :number => number}),
|
58
|
+
:subject => options[:subject],
|
59
|
+
:body => options[:body]
|
60
|
+
}.merge(smtp_options))
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.send_sms( options={} )
|
64
|
+
sms = Object.new
|
65
|
+
sms.extend Textr
|
66
|
+
sms.send_sms(options)
|
67
|
+
end
|
68
|
+
|
69
|
+
def number_from_options
|
70
|
+
if respond_to?(:textr_options)
|
71
|
+
phone = textr_options[:phone_field]
|
72
|
+
end
|
73
|
+
send(phone)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
require File.dirname(__FILE__) + "/textr/extends_textr"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Textr
|
2
|
+
module ExtendsTextr
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
ActiveRecord::Base.class_eval do
|
7
|
+
def self.extends_textr(phone_field = :phone)
|
8
|
+
class_inheritable_reader :textr_options
|
9
|
+
write_inheritable_attribute :textr_options, {
|
10
|
+
:phone_field => phone_field
|
11
|
+
}
|
12
|
+
include Textr
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/tasklib'
|
5
|
+
|
6
|
+
module Textr
|
7
|
+
module Rake
|
8
|
+
|
9
|
+
class TextrTask < ::Rake::TaskLib
|
10
|
+
|
11
|
+
namespace :textr do
|
12
|
+
desc "Generate a textr_smtp.yml file in `config` for use with smtp mail servers"
|
13
|
+
task "config:smtp" do
|
14
|
+
require "ftools"
|
15
|
+
if File.exists? "#{Rails.root.to_s}/config/textr_smtp.yml"
|
16
|
+
puts "\033[31m" + "#{Rails.root.to_s}/config/textr_smtp.yml exists... aborting." + "\033[0m"
|
17
|
+
else
|
18
|
+
status = File.copy(File.dirname(__FILE__) + "/../../../textr_smtp.yml.tpl", "#{Rails.root.to_s}/config/textr_smtp.yml") ? "\033[32m#{'[OK]'}\033[0m" : "\033[31m#{'[FAILED]'}\033[0m"
|
19
|
+
puts "\033[32m" + "Creating `config/textr_smtp.yml`: " + "\033[0m" + status
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'rspec'
|
4
|
+
require 'rails/all'
|
5
|
+
require 'sqlite3'
|
6
|
+
gem 'activerecord', '= 3.0.7'
|
7
|
+
|
8
|
+
ENV["RAILS_ENV"] ||= 'test'
|
9
|
+
Rails.env = 'test'
|
10
|
+
|
11
|
+
require 'textr'
|
12
|
+
|
13
|
+
MY_DB_NAME = "test.db"
|
14
|
+
MY_DB = SQLite3::Database.new(MY_DB_NAME)
|
15
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => MY_DB_NAME)
|
16
|
+
|
17
|
+
class User < ActiveRecord::Base
|
18
|
+
extends_textr
|
19
|
+
end
|
20
|
+
|
21
|
+
class Company < ActiveRecord::Base
|
22
|
+
extends_textr
|
23
|
+
end
|
24
|
+
|
25
|
+
class Person < ActiveRecord::Base
|
26
|
+
extends_textr :number
|
27
|
+
end
|
28
|
+
|
29
|
+
ActiveRecord::Schema.define(:version => 1) do
|
30
|
+
unless User.table_exists?
|
31
|
+
create_table :users do |t|
|
32
|
+
t.string :name
|
33
|
+
t.string :phone
|
34
|
+
end
|
35
|
+
|
36
|
+
User.create({:name => 'foo', :phone => '123-456-7890'})
|
37
|
+
end
|
38
|
+
|
39
|
+
unless Company.table_exists?
|
40
|
+
create_table :companies do |t|
|
41
|
+
t.string :name
|
42
|
+
end
|
43
|
+
|
44
|
+
Company.create({:name => 'bar'})
|
45
|
+
end
|
46
|
+
|
47
|
+
unless Person.table_exists?
|
48
|
+
create_table :people do |t|
|
49
|
+
t.string :name
|
50
|
+
t.string :number
|
51
|
+
end
|
52
|
+
|
53
|
+
Person.create({:name => 'foo', :number => '184-617-3344'})
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
RSpec.configure do |config|
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Textr do
|
4
|
+
|
5
|
+
it "should load textr" do
|
6
|
+
Textr.should_not be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should fail without carrier" do
|
10
|
+
lambda {
|
11
|
+
User.first.send_sms
|
12
|
+
}.should raise_error RuntimeError
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should fail without body" do
|
16
|
+
lambda {
|
17
|
+
User.first.send_sms({:carrier => 'att'})
|
18
|
+
}.should raise_error RuntimeError
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should succeed with all requirements" do
|
22
|
+
user = User.first
|
23
|
+
user.phone.should == '123-456-7890'
|
24
|
+
message = user.send_sms({:carrier => 'att', :body => 'Hello World!'})
|
25
|
+
message.from.should == ['pony@unknown']
|
26
|
+
message.to.should == ['1234567890@txt.att.net']
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow sending without phone column" do
|
30
|
+
company = Company.first
|
31
|
+
company.name.should == 'bar'
|
32
|
+
message = company.send_sms({:carrier => 'att', :body => 'Hello World!', :number => '098-765-4321'})
|
33
|
+
message.to.should == ['0987654321@txt.att.net']
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should create proper sms addresses" do
|
37
|
+
[
|
38
|
+
['att', 'txt.att.net'],
|
39
|
+
['boost', 'myboostmobile.com'],
|
40
|
+
['tmobile', 'tmomail.net'],
|
41
|
+
['sprint', 'messaging.sprintpcs.com'],
|
42
|
+
['verizon', 'vtext.com'],
|
43
|
+
['virgin', 'vmobl.com']
|
44
|
+
].each do |carrier|
|
45
|
+
message = User.first.send_sms({:carrier => carrier[0], :body => 'Hello World!'})
|
46
|
+
message.to.should == ["1234567890@#{carrier[1]}"]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should use number from person table" do
|
51
|
+
person = Person.first
|
52
|
+
person.name.should == 'foo'
|
53
|
+
person.number.should == '184-617-3344'
|
54
|
+
message = person.send_sms({:carrier => 'att', :body => 'Hello Bruins!'})
|
55
|
+
message.to.should == ["1846173344@txt.att.net"]
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should work without model" do
|
59
|
+
lambda {
|
60
|
+
message = Textr.send_sms({:carrier => 'att', :body => 'Hello World!', :number => '098-765-4321'})
|
61
|
+
message.to.should == ['0987654321@txt.att.net']
|
62
|
+
}.should_not raise_error
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/textr.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "textr/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "textr"
|
7
|
+
s.version = Textr::VERSION
|
8
|
+
s.authors = ["Forrest Grant"]
|
9
|
+
s.email = ["forrest@forrestgrant.com"]
|
10
|
+
s.homepage = "https://github.com/forrestgrant/textr"
|
11
|
+
s.summary = %q{Simple gem for sending SMS}
|
12
|
+
s.description = %q{Send SMS either via `phone` column in class, or by calling Textr directly}
|
13
|
+
|
14
|
+
s.rubyforge_project = "textr"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.add_dependency 'pony'
|
21
|
+
s.add_dependency 'rake', '0.8.7'
|
22
|
+
s.add_development_dependency 'rspec-rails'
|
23
|
+
s.add_development_dependency 'sqlite3'
|
24
|
+
s.add_development_dependency 'activerecord', '3.0.7'
|
25
|
+
end
|
data/textr_smtp.yml.tpl
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
development:
|
2
|
+
protocol: smtp
|
3
|
+
from: email@example.com
|
4
|
+
address: smtp.yourserver.com
|
5
|
+
port: 25
|
6
|
+
ssl: true
|
7
|
+
username: user
|
8
|
+
password: password
|
9
|
+
authentication: plain
|
10
|
+
domain: localhost.localdomain
|
11
|
+
|
12
|
+
test:
|
13
|
+
protocol: smtp
|
14
|
+
from: email@example.com
|
15
|
+
address: smtp.yourserver.com
|
16
|
+
port: 25
|
17
|
+
ssl: true
|
18
|
+
username: user
|
19
|
+
password: password
|
20
|
+
authentication: plain
|
21
|
+
domain: localhost.localdomain
|
22
|
+
|
23
|
+
production:
|
24
|
+
protocol: smtp
|
25
|
+
from: email@example.com
|
26
|
+
address: smtp.yourserver.com
|
27
|
+
port: 25
|
28
|
+
ssl: true
|
29
|
+
username: user
|
30
|
+
password: password
|
31
|
+
authentication: plain
|
32
|
+
domain: localhost.localdomain
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: textr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Forrest Grant
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-06-10 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: pony
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rake
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - "="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 49
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 8
|
46
|
+
- 7
|
47
|
+
version: 0.8.7
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rspec-rails
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
type: :development
|
63
|
+
version_requirements: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: sqlite3
|
66
|
+
prerelease: false
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
76
|
+
type: :development
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: activerecord
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - "="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 9
|
87
|
+
segments:
|
88
|
+
- 3
|
89
|
+
- 0
|
90
|
+
- 7
|
91
|
+
version: 3.0.7
|
92
|
+
type: :development
|
93
|
+
version_requirements: *id005
|
94
|
+
description: Send SMS either via `phone` column in class, or by calling Textr directly
|
95
|
+
email:
|
96
|
+
- forrest@forrestgrant.com
|
97
|
+
executables: []
|
98
|
+
|
99
|
+
extensions: []
|
100
|
+
|
101
|
+
extra_rdoc_files: []
|
102
|
+
|
103
|
+
files:
|
104
|
+
- .DS_Store
|
105
|
+
- .gitignore
|
106
|
+
- Gemfile
|
107
|
+
- README.markdown
|
108
|
+
- Rakefile
|
109
|
+
- lib/textr.rb
|
110
|
+
- lib/textr/extends_textr.rb
|
111
|
+
- lib/textr/rake/tasks.rb
|
112
|
+
- lib/textr/version.rb
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
- spec/textr/textr_spec.rb
|
115
|
+
- textr.gemspec
|
116
|
+
- textr_smtp.yml.tpl
|
117
|
+
homepage: https://github.com/forrestgrant/textr
|
118
|
+
licenses: []
|
119
|
+
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
hash: 3
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
version: "0"
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
hash: 3
|
140
|
+
segments:
|
141
|
+
- 0
|
142
|
+
version: "0"
|
143
|
+
requirements: []
|
144
|
+
|
145
|
+
rubyforge_project: textr
|
146
|
+
rubygems_version: 1.8.4
|
147
|
+
signing_key:
|
148
|
+
specification_version: 3
|
149
|
+
summary: Simple gem for sending SMS
|
150
|
+
test_files:
|
151
|
+
- spec/spec_helper.rb
|
152
|
+
- spec/textr/textr_spec.rb
|