pigeon_fu 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog +2 -0
- data/MIT-LICENSE +23 -0
- data/README.markdown +35 -0
- data/Rakefile +29 -0
- data/bin/pigeonfu.rb +17 -0
- data/examples/send_sms.rb +11 -0
- data/lib/pigeon_fu.rb +19 -0
- data/lib/pigeon_fu/authenticate.rb +78 -0
- data/lib/pigeon_fu/base.rb +34 -0
- data/lib/pigeon_fu/call.rb +14 -0
- data/lib/pigeon_fu/command_line.rb +5 -0
- data/lib/pigeon_fu/exceptions.rb +36 -0
- data/lib/pigeon_fu/fax.rb +14 -0
- data/lib/pigeon_fu/ivr.rb +14 -0
- data/lib/pigeon_fu/rest.rb +99 -0
- data/lib/pigeon_fu/sms.rb +69 -0
- data/lib/pigeon_fu/utils.rb +5 -0
- data/lib/pigeon_fu/version.rb +3 -0
- metadata +79 -0
data/Changelog
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2010 Why404.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
data/README.markdown
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
### About PigeonFu
|
2
|
+
|
3
|
+
PigeonFu is a Ruby gem for building voice and SMS applications. It allows your web application to easily make and receive phone calls and SMS text messages using the ChinaTelecom Open API. You can send E-FAX by using PigeonFu or build hosted IVR, WebCall and SMS applications easily and quickly.
|
4
|
+
|
5
|
+
|
6
|
+
### Installation
|
7
|
+
|
8
|
+
$ gem install pigeon_fu
|
9
|
+
|
10
|
+
|
11
|
+
### Usage
|
12
|
+
|
13
|
+
First, you need to register for an authorized app-account on the ChinaTelecom open platform(http://www.189works.com/).
|
14
|
+
|
15
|
+
Then allow me writen an example show you how to send a phone text message to some body.
|
16
|
+
|
17
|
+
require 'pigeon_fu'
|
18
|
+
|
19
|
+
ENV["PIGEON_ACCOUNT_SID"] = '1000XXXX' # YOUR_APP_KEY
|
20
|
+
ENV["PIGEON_ACCOUNT_TOKEN"] = '76e9bde81f1e4e51ac8d86517e4bXXXX' # YOUR_APP_SECRET_KEY
|
21
|
+
|
22
|
+
PigeonFu.send_sms :to => '1318698XXXX',
|
23
|
+
:say => 'Just testing to send a sms from my program what I am writting now!'
|
24
|
+
|
25
|
+
See the examples/ folder for more examples.
|
26
|
+
|
27
|
+
|
28
|
+
### TODO
|
29
|
+
|
30
|
+
I am working on it currently, more features will be added in later versions, and it will support both Ruby on Rails 3.0 and Sinatra ASAP.
|
31
|
+
|
32
|
+
|
33
|
+
### Copyright
|
34
|
+
|
35
|
+
Copyright (c) 2010 why404(why404#gmail), released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require File.dirname(__FILE__) + '/lib/pigeon_fu/version'
|
4
|
+
|
5
|
+
PKG_FILES = FileList[
|
6
|
+
'[a-zA-Z-]*',
|
7
|
+
'lib/**/*',
|
8
|
+
'examples/*',
|
9
|
+
'bin/*'
|
10
|
+
]
|
11
|
+
|
12
|
+
spec = Gem::Specification.new do |s|
|
13
|
+
s.name = "pigeon_fu"
|
14
|
+
s.version = PigeonFu::VERSION
|
15
|
+
s.author = "why404"
|
16
|
+
s.email = "why404@gmail.com"
|
17
|
+
s.homepage = "http://rubygems.org/gems/pigeon_fu"
|
18
|
+
s.platform = Gem::Platform::RUBY
|
19
|
+
s.summary = "SDK written in Ruby for the ChinaTelecom Open Platform."
|
20
|
+
s.description = "PigeonFu is a Ruby gem (also can be as a Rails plugin, it'll support Rails 3.0.0 or above ASAP) as an unofficial Ruby SDK for the ChinaTelecom Open Platform(http://open.189works.com/)."
|
21
|
+
s.files = PKG_FILES.to_a
|
22
|
+
s.require_path = "lib"
|
23
|
+
s.has_rdoc = false
|
24
|
+
s.extra_rdoc_files = ["README.markdown"]
|
25
|
+
end
|
26
|
+
|
27
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
28
|
+
pkg.gem_spec = spec
|
29
|
+
end
|
data/bin/pigeonfu.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
#TODO
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: pigeonfu [path] \n(should be the applition root path)\n e.g \"pigeonfu . \"."
|
9
|
+
|
10
|
+
begin
|
11
|
+
opts.parse!(ARGV)
|
12
|
+
rescue OptionParser::ParseError => e
|
13
|
+
warn e.message
|
14
|
+
puts opts
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
|
4
|
+
|
5
|
+
require 'pigeon_fu'
|
6
|
+
|
7
|
+
ENV["PIGEON_ACCOUNT_SID"] = '1000XXXX' # YOUR_APP_KEY
|
8
|
+
ENV["PIGEON_ACCOUNT_TOKEN"] = '76e9bde81f1e4e51ac8d86517e4bXXXX' # YOUR_APP_SECRET_KEY
|
9
|
+
|
10
|
+
PigeonFu.send_sms :to => '13186988528',
|
11
|
+
:say => 'Just testing to send a sms from my program what I am writting now!'
|
data/lib/pigeon_fu.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'time'
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
require 'cgi'
|
6
|
+
require 'digest/sha1'
|
7
|
+
require 'base64'
|
8
|
+
require 'logger'
|
9
|
+
require 'pigeon_fu/base'
|
10
|
+
require 'pigeon_fu/utils'
|
11
|
+
require 'pigeon_fu/rest'
|
12
|
+
require 'pigeon_fu/exceptions'
|
13
|
+
require 'pigeon_fu/authenticate'
|
14
|
+
require 'pigeon_fu/sms'
|
15
|
+
require 'pigeon_fu/call'
|
16
|
+
require 'pigeon_fu/ivr'
|
17
|
+
require 'pigeon_fu/fax'
|
18
|
+
require 'pigeon_fu/version.rb'
|
19
|
+
#require 'pigeon_fu/command_line.rb'
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module PigeonFu
|
2
|
+
class Authenticate
|
3
|
+
|
4
|
+
def self.start(options={})
|
5
|
+
new(options).run
|
6
|
+
end
|
7
|
+
|
8
|
+
# 调用相关API之前需要获得电信开放平台的认证授权
|
9
|
+
def initialize(with_interface_code)
|
10
|
+
raise RuntimeError, "constant PIGEON_ACCOUNT_SID sould be defined" unless defined?(ENV["PIGEON_ACCOUNT_SID"])
|
11
|
+
raise RuntimeError, "constant PIGEON_ACCOUNT_TOKEN sould be defined" unless defined?(ENV["PIGEON_ACCOUNT_TOKEN"])
|
12
|
+
@result = Hash.new
|
13
|
+
@options = Hash.new
|
14
|
+
@options[:account_sid] = ENV["PIGEON_ACCOUNT_SID"] # 开发者的用户ID
|
15
|
+
@options[:account_token] = ENV["PIGEON_ACCOUNT_TOKEN"] # 开发者访问电信API的密钥
|
16
|
+
@options[:api_id] ||= with_interface_code # API功能接口的编号(电信为每种API定义了一个数字编号,比如发短信的接口ID为10000033)
|
17
|
+
@options[:url] ||= PigeonFu::AUTH_INTERFACE_URL
|
18
|
+
@options[:timestamp] = (Time.now.to_f * 1000).to_i
|
19
|
+
@options[:session_id] = session_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
parse_result(make_request)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def session_id
|
29
|
+
PigeonFu::Rest.get(PigeonFu::SESS_INTERFACE_URL)
|
30
|
+
end
|
31
|
+
|
32
|
+
# 生成当前用于发起认证请求的签名(signature)
|
33
|
+
# 格式:Base64(SHA1(TimeStamp + "$" + APID + "$" + APUserAccount + "$" + FunID + "$" + APKEY))
|
34
|
+
def generate_signature
|
35
|
+
string_for_token = [@options[:session_id],
|
36
|
+
@options[:account_sid],
|
37
|
+
@options[:account_nick],
|
38
|
+
@options[:api_id],
|
39
|
+
@options[:account_token]
|
40
|
+
].join("$")
|
41
|
+
CGI.escape(Base64.encode64(Digest::SHA1.digest(string_for_token)).chomp!)
|
42
|
+
end
|
43
|
+
|
44
|
+
# 构造发起认证请求需要的查询字符串
|
45
|
+
# 格式:TimeStamp + "$" + APID + "$" + APUserAccount + "$" + FunID + "$" + UrlEncode(Authenticator)
|
46
|
+
def generate_query_string
|
47
|
+
[@options[:session_id], @options[:account_sid], @options[:account_nick],\
|
48
|
+
@options[:api_id], generate_signature].join("$")
|
49
|
+
end
|
50
|
+
|
51
|
+
# 发起认证请求
|
52
|
+
def make_request
|
53
|
+
PigeonFu::Rest.get(@options[:url], {'AuthRequest' => generate_query_string})
|
54
|
+
end
|
55
|
+
|
56
|
+
# 解析认证过后的返回结果
|
57
|
+
# 返回数据格式:Result + "$" + TransactionID + "$" + Token+ "$" + ErrorDescription+ "$" + TimeStamp
|
58
|
+
def parse_result(data)
|
59
|
+
if data.include?("$")
|
60
|
+
@result[:number], @result[:transaction_id], @result[:token],\
|
61
|
+
@result[:error_description], @result[:timestamp] = data.split("$")
|
62
|
+
end
|
63
|
+
# 返回认证后的通行证
|
64
|
+
authorized_token
|
65
|
+
end
|
66
|
+
|
67
|
+
# 是否认证通过?
|
68
|
+
def authenticated?
|
69
|
+
@result[:number].to_i == 0 ? true : false
|
70
|
+
end
|
71
|
+
|
72
|
+
# 根据认证结果取得行使指定API功能的凭证
|
73
|
+
def authorized_token
|
74
|
+
authenticated? ? @result[:token] : (raise Unauthorized, @result)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module PigeonFu
|
2
|
+
|
3
|
+
SESS_INTERFACE_URL = 'http://open.189works.com/InterfaceForAP/GetSessionID.aspx'
|
4
|
+
AUTH_INTERFACE_URL = 'http://open.189works.com/InterfaceForAP/Authv1.1.aspx'
|
5
|
+
|
6
|
+
SMS_INTERFACE_CODE = 10000033
|
7
|
+
SMS_INTERFACE_URL = 'http://ims.open.ctfactory.com/ims/ghsendim.php'
|
8
|
+
|
9
|
+
CALL_INTERFACE_CODE = 10000034
|
10
|
+
CALL_INTERFACE_URL = ''
|
11
|
+
|
12
|
+
IVR_INTERFACE_CODE = 10000108
|
13
|
+
IVR_INTERFACE_URL = ''
|
14
|
+
|
15
|
+
FAX_INTERFACE_CODE = 0
|
16
|
+
FAX_INTERFACE_URL = ''
|
17
|
+
|
18
|
+
PHONE_NUMBER_REGEX = /^\d{8,13}$/ # The overwhelming majority phone numbers in China should be supported.
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def send_sms(options={})
|
22
|
+
PigeonFu::Sms.send_message(options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
module Base
|
28
|
+
# In fact it will as a class-methods module mix-in class object. For example see PigeonFu::Sms::ClassMethods
|
29
|
+
module InstanceMethods
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module PigeonFu #:nodoc:
|
2
|
+
|
3
|
+
class Exception < RuntimeError #:nodoc:
|
4
|
+
def message(default=nil)
|
5
|
+
self.class::ErrorMessage
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Unauthorized < Exception #:nodoc:
|
10
|
+
ErrorMessage = 'Unauthorized'
|
11
|
+
|
12
|
+
def initialize(response)
|
13
|
+
@error_code = response[:number]
|
14
|
+
@error_desc = response[:error_description]
|
15
|
+
end
|
16
|
+
|
17
|
+
def message
|
18
|
+
"Error code #{@error_code}, #{@error_desc}."
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
message
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class SendSMSFailed < Exception #:nodoc:
|
27
|
+
ErrorMessage = 'Message was send failed!'
|
28
|
+
|
29
|
+
attr_accessor :message
|
30
|
+
|
31
|
+
def initialize(response_code)
|
32
|
+
@message = "Message was send failed! Error: #{response_code}."
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module PigeonFu
|
2
|
+
module Rest
|
3
|
+
class << self
|
4
|
+
def get(url, hashed_vars = {})
|
5
|
+
res = request(url, 'GET', hashed_vars)
|
6
|
+
process_result(res, url)
|
7
|
+
end
|
8
|
+
|
9
|
+
def post(url, hashed_vars)
|
10
|
+
res = request(url, 'POST', hashed_vars)
|
11
|
+
process_result(res, url)
|
12
|
+
end
|
13
|
+
|
14
|
+
def put(url, hashed_vars)
|
15
|
+
res = request(url, 'PUT', hashed_vars)
|
16
|
+
process_result(res, url)
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(url, hashed_vars)
|
20
|
+
res = request(url, 'DELETE', hashed_vars)
|
21
|
+
process_result(res, url)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def request(url, method=nil, params = {})
|
27
|
+
if !url || url.length < 1
|
28
|
+
raise ArgumentError, 'Invalid url parameter'
|
29
|
+
end
|
30
|
+
if method && !['GET', 'POST', 'DELETE', 'PUT'].include?(method)
|
31
|
+
raise NotImplementedError, 'HTTP %s not implemented' % method
|
32
|
+
end
|
33
|
+
|
34
|
+
if method && method == 'GET'
|
35
|
+
url = build_get_uri(url, params)
|
36
|
+
end
|
37
|
+
|
38
|
+
uri = URI.parse(url)
|
39
|
+
|
40
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
41
|
+
|
42
|
+
if method && method == 'GET'
|
43
|
+
req = Net::HTTP::Get.new(uri.request_uri)
|
44
|
+
elsif method && method == 'DELETE'
|
45
|
+
req = Net::HTTP::Delete.new(uri.request_uri)
|
46
|
+
elsif method && method == 'PUT'
|
47
|
+
req = Net::HTTP::Put.new(uri.request_uri)
|
48
|
+
req.set_form_data(params)
|
49
|
+
else
|
50
|
+
req = Net::HTTP::Post.new(uri.request_uri)
|
51
|
+
req.set_form_data(params)
|
52
|
+
end
|
53
|
+
|
54
|
+
http.request(req)
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_get_uri(uri, params)
|
58
|
+
if params && params.length > 0
|
59
|
+
if uri.include?('?')
|
60
|
+
if uri[-1, 1] != '&'
|
61
|
+
uri += '&'
|
62
|
+
end
|
63
|
+
uri += urlencode(params)
|
64
|
+
else
|
65
|
+
uri += '?' + urlencode(params)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
uri
|
69
|
+
end
|
70
|
+
|
71
|
+
def urlencode(params)
|
72
|
+
params.to_a.collect! { |k, v| "#{k.to_s}=#{v.to_s}" }.join("&")
|
73
|
+
end
|
74
|
+
|
75
|
+
def process_result(res, raw_url)
|
76
|
+
if res.code =~ /\A2\d{2}\z/
|
77
|
+
res.body
|
78
|
+
elsif %w(301 302 303).include? res.code
|
79
|
+
url = res.header['Location']
|
80
|
+
if url !~ /^http/
|
81
|
+
uri = URI.parse(raw_url)
|
82
|
+
uri.path = "/#{url}".squeeze('/')
|
83
|
+
url = uri.to_s
|
84
|
+
end
|
85
|
+
raise RuntimeError, "Redirect #{url}"
|
86
|
+
elsif res.code == "304"
|
87
|
+
raise RuntimeError, "NotModified #{res}"
|
88
|
+
elsif res.code == "401"
|
89
|
+
raise RuntimeError, "Unauthorized #{res}"
|
90
|
+
elsif res.code == "404"
|
91
|
+
raise RuntimeError, "Resource not found #{res}"
|
92
|
+
else
|
93
|
+
raise RuntimeError, "Maybe request timed out #{res}. HTTP status code #{res.code}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module PigeonFu
|
2
|
+
class Sms
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
# include PigeonFu::Base::InstanceMethods
|
6
|
+
|
7
|
+
def send_message(options={})
|
8
|
+
raise ArgumentError, "You must pass the :to argument to specify the receiver." unless options[:to]
|
9
|
+
raise ArgumentError, "You must pass the :say argument to specify the short message." unless options[:say]
|
10
|
+
@sms = PigeonFu::Sms.new
|
11
|
+
@sms.auth = PigeonFu::Authenticate.new(PigeonFu::SMS_INTERFACE_CODE)
|
12
|
+
@sms.content = encoded_message_from(options[:say])
|
13
|
+
@sms.receivers = fetch_receivers_from(options[:to])
|
14
|
+
@sms.sender = fetch_sender_from(options[:from])
|
15
|
+
@sms.send_phone_text_message
|
16
|
+
end
|
17
|
+
|
18
|
+
def send_message_to_me(text_content)
|
19
|
+
send_message :to => default_contact, :say => text_content, :from => default_ims
|
20
|
+
end
|
21
|
+
|
22
|
+
def encoded_message_from(content)
|
23
|
+
Base64.encode64(content.strip).gsub('+', '%2B').gsub('&','%26').gsub("\n","") # CGI.escape
|
24
|
+
end
|
25
|
+
|
26
|
+
def fetch_receivers_from(given_receivers)
|
27
|
+
receiver_phone_numbers = []
|
28
|
+
if given_receivers.is_a?(String)
|
29
|
+
receivers = given_receivers.include?(',') ? given_receivers.split(',') : [given_receivers]
|
30
|
+
end
|
31
|
+
receivers.each do |receiver|
|
32
|
+
if receiver.is_a_phone_number?
|
33
|
+
receiver_phone_numbers << receiver
|
34
|
+
else
|
35
|
+
raise ArgumentError, "#{receiver} haven't or isn't a valid phone number"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
receiver_phone_numbers
|
39
|
+
end
|
40
|
+
|
41
|
+
def fetch_sender_from(given_sender = nil)
|
42
|
+
unless given_sender.nil?
|
43
|
+
raise ArgumentError, "#{sender} is not a valid phone number." unless sender.is_a_phone_number?
|
44
|
+
end
|
45
|
+
given_sender
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module InstanceMethods
|
50
|
+
attr_writer :auth, :content, :receivers, :sender
|
51
|
+
|
52
|
+
def send_phone_text_message
|
53
|
+
@receivers.each { |receiver| send_message_to(receiver) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def send_message_to(receiver)
|
57
|
+
auth_token = @auth.run
|
58
|
+
request_vars = {'SendMsgRequest' => [auth_token, receiver, @content, @sender].join("$")}
|
59
|
+
response = PigeonFu::Rest.get(PigeonFu::SMS_INTERFACE_URL, request_vars)
|
60
|
+
response_code = response.split("=")[1]
|
61
|
+
raise SendSMSFailed, response_code unless response_code.to_i == 200
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
extend self::ClassMethods
|
66
|
+
include self::InstanceMethods
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pigeon_fu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- why404
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-10 00:00:00 +08:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: PigeonFu is a Ruby gem (also can be as a Rails plugin, it'll support Rails 3.0.0 or above ASAP) as an unofficial Ruby SDK for the ChinaTelecom Open Platform(http://open.189works.com/).
|
22
|
+
email: why404@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README.markdown
|
29
|
+
files:
|
30
|
+
- Changelog
|
31
|
+
- MIT-LICENSE
|
32
|
+
- README.markdown
|
33
|
+
- Rakefile
|
34
|
+
- lib/pigeon_fu/authenticate.rb
|
35
|
+
- lib/pigeon_fu/version.rb
|
36
|
+
- lib/pigeon_fu/call.rb
|
37
|
+
- lib/pigeon_fu/rest.rb
|
38
|
+
- lib/pigeon_fu/ivr.rb
|
39
|
+
- lib/pigeon_fu/base.rb
|
40
|
+
- lib/pigeon_fu/exceptions.rb
|
41
|
+
- lib/pigeon_fu/fax.rb
|
42
|
+
- lib/pigeon_fu/sms.rb
|
43
|
+
- lib/pigeon_fu/command_line.rb
|
44
|
+
- lib/pigeon_fu/utils.rb
|
45
|
+
- lib/pigeon_fu.rb
|
46
|
+
- examples/send_sms.rb
|
47
|
+
- bin/pigeonfu.rb
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: http://rubygems.org/gems/pigeon_fu
|
50
|
+
licenses: []
|
51
|
+
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
requirements: []
|
72
|
+
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.3.6
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: SDK written in Ruby for the ChinaTelecom Open Platform.
|
78
|
+
test_files: []
|
79
|
+
|