baidu-push 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9f9c16baf080244732e2b621132b4746fef3b20d
4
+ data.tar.gz: cbf1e368461b0a98459b9dc1ca51a46a38e70dd8
5
+ SHA512:
6
+ metadata.gz: a28a7891bb1e7c6ead906baa78dfea43aa64bb51a24e86e6862797fb1c9ea28b8ac05f0d0f75f711b735fd656bb97efacd5bf05bedea4cc95a8b9b0adf311ea8
7
+ data.tar.gz: 99da21a5a7ba97aa76c8cce68a54c9eefb7e67d930f8f9e3cb17cae4ca18a2084a98fa61617fa1d6bfdfbdadb500aafcaba78faf2dce5ff2200d1eb31a03bd81
@@ -0,0 +1,18 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+
16
+ .ruby-gemset
17
+ .ruby-version
18
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in baidu-push-client.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 scorix
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # Baidu::Push::Client
2
+
3
+ A simple REST client for [baidu push](http://developer.baidu.com/wiki/index.php?title=docs/cplat/push/api/list)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'baidu-push', github: 'scorix/baidu-push'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ ## Usage
18
+
19
+ ```ruby
20
+ # build a baidu message
21
+ msg = Baidu::Push::Message.new msg_keys: "#{Time.now.to_i}_test", user_id: 'userid'
22
+ msg.messages = {title: 'test', description: 'test', custom_content: {}}
23
+
24
+ # new a client instance
25
+ client = Baidu::Push::Client.setup api_key: 'YOUR_API_KEY', secret_key: 'YOUR_SECRET_KEY'
26
+ client.push_msg(msg)
27
+ ```
28
+
29
+ Or, you can also push the message with an async way
30
+
31
+ ```ruby
32
+ # build a baidu message
33
+ msg = Baidu::Push::Message.new msg_keys: "#{Time.now.to_i}_test", user_id: 'userid'
34
+ msg.messages = {title: 'test', description: 'test', custom_content: {}}
35
+
36
+ # new a client instance
37
+ client = Baidu::Push::AsyncClient.setup api_key: 'YOUR_API_KEY', secret_key: 'YOUR_SECRET_KEY'
38
+ client.async.push_msg(msg)
39
+ ```
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it ( https://github.com/scorix/baidu-push/fork )
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'baidu/push/version'
5
+ require 'baidu/push'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'baidu-push'
9
+ spec.version = Baidu::Push::VERSION
10
+ spec.authors = ['scorix']
11
+ spec.email = ['scorix@gmail.com']
12
+ spec.summary = %q{Baidu push client}
13
+ spec.description = %q{}
14
+ spec.homepage = ''
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency 'faraday'
23
+ spec.add_dependency 'celluloid'
24
+ spec.add_dependency 'virtus'
25
+
26
+ spec.add_development_dependency 'bundler'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rspec'
29
+ end
@@ -0,0 +1,11 @@
1
+ require 'json'
2
+
3
+ module Baidu
4
+ module Push
5
+ require 'baidu/push/api'
6
+ require 'baidu/push/client'
7
+ require 'baidu/push/async_client'
8
+ require 'baidu/push/configuration'
9
+ require 'baidu/push/message'
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ require 'faraday'
2
+
3
+ module Baidu
4
+ module Push
5
+ class API
6
+ attr_reader :connection
7
+
8
+ def initialize(options = {})
9
+ @connection = Faraday.new(url: default_domain) do |faraday|
10
+ faraday.request :multipart
11
+ faraday.request :url_encoded
12
+ faraday.response :logger, options[:logger] if options[:logger]
13
+ faraday.adapter Faraday.default_adapter
14
+ end
15
+ end
16
+
17
+ def base_path
18
+ '/rest/2.0/channel'
19
+ end
20
+
21
+ def default_domain
22
+ 'https://channel.api.duapp.com'
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ require 'celluloid'
2
+
3
+ module Baidu
4
+ module Push
5
+ class AsyncClient < Client
6
+ include Celluloid
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ module Baidu
2
+ module Push
3
+
4
+ class Client
5
+ attr_accessor :config, :logger
6
+
7
+ def self.setup(options = {api_key: nil, secret_key: nil})
8
+ raise 'api_key can not be nil.' unless options[:api_key]
9
+ raise 'secret_key can not be nil.' unless options[:secret_key]
10
+ md5 = Digest::MD5.hexdigest([options[:api_key], options[:secret_key]].join)
11
+ instance_variable_get("@client_#{md5}") ||
12
+ instance_variable_set("@client_#{md5}", begin
13
+ config = Configuration.new
14
+ config.api_key = options[:api_key]
15
+ config.secret_key = options[:secret_key]
16
+ client = self.new
17
+ client.config = config
18
+ client.logger = options[:logger]
19
+ client
20
+ end)
21
+ end
22
+
23
+ def rest_api
24
+ @api ||= API.new(logger: logger)
25
+ end
26
+
27
+ def push_msg(message)
28
+ raise 'invalid baidu push message' unless message.is_a?(Baidu::Push::Message)
29
+ attr = message.non_nil_attributes
30
+ attr.merge!(apikey: config.api_key, method: __method__)
31
+ rest_api.connection.post do |req|
32
+ req.url "#{rest_api.base_path}/channel"
33
+ req.params = attr.merge(sign: get_sign('POST', "#{rest_api.default_domain}#{rest_api.base_path}/channel", attr))
34
+ end
35
+ end
36
+
37
+ private
38
+ def get_sign(http_method, url, params)
39
+ es = [http_method.to_s.upcase, url, params.sort.map { |x| "#{x[0]}=#{x[1]}" }, config.secret_key]
40
+ Digest::MD5.hexdigest(CGI.escape(es.flatten.join))
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,7 @@
1
+ module Baidu
2
+ module Push
3
+ class Configuration
4
+ attr_accessor :api_key, :secret_key
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+ require 'virtus'
3
+
4
+ module Baidu
5
+ module Push
6
+ class Message
7
+
8
+ include Virtus.model
9
+
10
+ # required
11
+ # 方法名
12
+ attribute :method, String
13
+
14
+ # required
15
+ # 访问令牌,明文AK,可从此值获得App的信息,配合sign中的sk做合法性身份认证。
16
+ attribute :apikey, String
17
+
18
+ # required, but don't set here
19
+ # 调用参数签名值,与apikey成对出现。
20
+ # 详细用法,请参考:[签名计算算法](http://developer.baidu.com/wiki/index.php?title=docs/cplat/push/api#.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95)
21
+ # attribute :sign, String
22
+
23
+ # required
24
+ # 推送类型,取值范围为:1~3
25
+ # 1:单个人,必须指定user_id 和 channel_id (指定用户的指定设备)或者user_id(指定用户的所有设备)
26
+ # 2:一群人,必须指定 tag
27
+ # 3:所有人,无需指定tag、user_id、channel_id
28
+ attribute :push_type, Integer, default: ->(_, _) { 1 }
29
+
30
+ # required
31
+ # 用户发起请求时的unix时间戳。本次请求签名的有效时间为该时间戳+10分钟。
32
+ attribute :timestamp, Integer, default: ->(_, _) { Time.now.to_i }
33
+
34
+ # required
35
+ # 指定消息内容,单个消息为单独字符串。如果有二进制的消息内容,请先做 BASE64 的编码。
36
+ # 当message_type为1 (通知类型),请按以下格式指定消息内容。
37
+ # 通知消息格式及默认值:
38
+ #
39
+ # {
40
+ # //android必选,ios可选
41
+ # "title" : "hello" ,
42
+ # “description: "hello world"
43
+ #
44
+ # //android特有字段,可选
45
+ # "notification_builder_id": 0,
46
+ # "notification_basic_style": 7,
47
+ # "open_type":0,
48
+ # "net_support" : 1,
49
+ # "user_confirm": 0,
50
+ # "url": "http://developer.baidu.com",
51
+ # "pkg_content":"",
52
+ # "pkg_name" : "com.baidu.bccsclient",
53
+ # "pkg_version":"0.1",
54
+ #
55
+ # //android自定义字段
56
+ # "custom_content": {
57
+ # "key1":"value1",
58
+ # "key2":"value2"
59
+ # },
60
+ #
61
+ # //ios特有字段,可选
62
+ # "aps": {
63
+ # "alert":"Message From Baidu Push",
64
+ # "sound":"",
65
+ # "badge":0
66
+ # },
67
+ #
68
+ # //ios的自定义字段
69
+ # "key1":"value1",
70
+ # "key2":"value2"
71
+ # }
72
+ # 注意:
73
+ #
74
+ # 当description与alert同时存在时,ios推送以alert内容作为通知内容
75
+ # 当custom_content与 ios的自定义字段"key" :"value"同时存在时,ios推送的自定义字段内容会将以上两个内容合并,但推送内容整体长度不能大于256B,否则有被截断的风险。
76
+ # 此格式兼容Android和ios原生通知格式的推送。
77
+ # 如果通过Server SDK推送成功,Android端却收不到通知,解决方案请参考该:问题
78
+ attribute :messages, String
79
+
80
+ # required
81
+ # 消息标识。
82
+ # 指定消息标识,必须和messages一一对应。相同消息标识的消息会自动覆盖。特别提醒:该功能只支持android、browser、pc三种设备类型。
83
+ attribute :msg_keys, String
84
+
85
+ # optional
86
+ # 用户标识,在Android里,channel_id + userid指定某一个特定client。不超过256字节,如果存在此字段,则只推送给此用户。
87
+ attribute :user_id, String
88
+
89
+ # optional
90
+ # 通道标识
91
+ attribute :channel_id, Integer
92
+
93
+ # optional
94
+ # 标签名称,不超过128字节
95
+ attribute :tag, String
96
+
97
+ # optional
98
+ # 设备类型,取值范围为:1~5
99
+ # 云推送支持多种设备,各种设备的类型编号如下:
100
+ # 1:浏览器设备;
101
+ # 2:PC设备;
102
+ # 3:Android设备;(default)
103
+ # 4:iOS设备;
104
+ # 5:Windows Phone设备;
105
+ attribute :device_type, Integer, default: ->(_, _) { 3 }
106
+
107
+ # optional
108
+ # 消息类型
109
+ # 0:消息(透传给应用的消息体)(default)
110
+ # 1:通知(对应设备上的消息通知)
111
+ attribute :message_type, Integer, default: ->(_, _) { 0 }
112
+
113
+ # optional
114
+ # 指定消息的过期时间,默认为 86400 秒。必须和messages一一对应。
115
+ attribute :message_expires, Integer, default: ->(_, _) { 86400 }
116
+
117
+ # optional
118
+ # 部署状态。指定应用当前的部署状态,可取值:
119
+ # 1:开发状态 (default for the gem)
120
+ # 2:生产状态 (default at baidu)
121
+ # Notice: ios only
122
+ attribute :deploy_status, Integer, default: ->(_, _) { 1 }
123
+
124
+ # optional
125
+ # 用户指定本次请求签名的失效时间。格式为unix时间戳形式。
126
+ attribute :expires, Integer
127
+
128
+ # optional
129
+ # API版本号,默认使用最高版本。
130
+ attribute :v, Integer
131
+
132
+ def non_nil_attributes
133
+ attributes.reject { |_, v| v.nil? }
134
+ end
135
+
136
+ def messages=(msg = {})
137
+ message = {}
138
+ message[:title] = msg[:title].to_s
139
+ message[:description] = msg[:description].to_s
140
+ case device_type
141
+ when 3
142
+ message[:custom_content] = msg[:custom_content]
143
+ when 4
144
+ message[:aps] = msg[:aps]
145
+ msg[:custom_content].each { |k, v| message[k] = v }
146
+ end
147
+ super(message.to_json)
148
+ end
149
+
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,5 @@
1
+ module Baidu
2
+ module Push
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rspec'
4
+ require 'logger'
5
+
6
+ describe Baidu::Push::AsyncClient do
7
+
8
+ subject { Baidu::Push::AsyncClient.setup(api_key: '',
9
+ secret_key: '',
10
+ logger: Logger.new(STDOUT)) }
11
+
12
+ context 'push message' do
13
+ it 'should push a message, async' do
14
+ msg = Baidu::Push::Message.new msg_keys: "#{Time.now.to_i}_test",
15
+ user_id: '',
16
+ message_type: 1
17
+ msg.messages = {title: 'test', description: 'test', custom_content: {}}
18
+ res = subject.future.push_msg(msg)
19
+ expect(res.value.status).to eql 200
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rspec'
4
+ require 'logger'
5
+
6
+ describe Baidu::Push::Client do
7
+
8
+ subject { Baidu::Push::Client.setup(api_key: '',
9
+ secret_key: '',
10
+ logger: Logger.new(STDOUT)) }
11
+
12
+ context 'push message' do
13
+ it 'should push a message, sync' do
14
+ msg = Baidu::Push::Message.new msg_keys: "#{Time.now.to_i}_test",
15
+ user_id: '',
16
+ message_type: 1
17
+ msg.messages = {title: 'test', description: 'test', custom_content: {}}
18
+ res = subject.push_msg(msg)
19
+ expect(res.status).to eql 200
20
+ end
21
+ end
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: baidu-push
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - scorix
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: celluloid
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: virtus
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: ''
98
+ email:
99
+ - scorix@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - Gemfile
106
+ - LICENSE.txt
107
+ - README.md
108
+ - Rakefile
109
+ - baidu-push.gemspec
110
+ - lib/baidu/push.rb
111
+ - lib/baidu/push/api.rb
112
+ - lib/baidu/push/async_client.rb
113
+ - lib/baidu/push/client.rb
114
+ - lib/baidu/push/configuration.rb
115
+ - lib/baidu/push/message.rb
116
+ - lib/baidu/push/version.rb
117
+ - spec/baidu/push/async_client_spec.rb
118
+ - spec/baidu/push/client_spec.rb
119
+ homepage: ''
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.4.5
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: Baidu push client
143
+ test_files:
144
+ - spec/baidu/push/async_client_spec.rb
145
+ - spec/baidu/push/client_spec.rb