ghazel-em-gcm 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: 6111301e6d59ec7719dadce064d9080c566acd4b
4
+ data.tar.gz: 4e693f1b0ba08d6e80aed637226f0b15cdcb8b20
5
+ SHA512:
6
+ metadata.gz: fd2fefb61e21ff9a34bba5996fef11fec5332bf4895fdfe86fc5ede09f6eba5da6dba9a849f9b4f36b281c99085661bb4207a4d7985f76e03bd6eb38334f0cc6
7
+ data.tar.gz: 591504c0cc765b2ddf33a80ab91b423777b29d16b0d9d59842986a2e4c1c1dade7ae7e611cf1d7104703d62e9b341d6b2fa3b80ec42873969f64a064e136a8ab
@@ -0,0 +1,58 @@
1
+ em-gcm
2
+ ======
3
+
4
+ Google Cloud Messaging for Android for Event Machine
5
+
6
+ See [Google's Documention](http://developer.android.com/guide/google/gcm/index.html) to learn more.
7
+
8
+ This project is based on groupme/em-c2dm and doesn't include spec yet
9
+
10
+ ## Usage
11
+
12
+ require "em-gcm"
13
+
14
+ EM::GCM.token = "abcedfg..."
15
+
16
+ EM.run do
17
+ #plain old c2dm compatible send
18
+ EM::GCM.push_plain(["registration_id"], :alert => "hi!", :collapse_key => "required")
19
+ #new json style send and support broadcase
20
+ EM::GCM.push_json(["registration_id1", "registration_id2"], :alert => "hi!", :collapse_key => "required")
21
+ end
22
+
23
+ ### Custom Params
24
+
25
+ You can add custom params (which will be converted to `data.<KEY>`):
26
+
27
+ EM::GCM.push_plain(["registration_id"],
28
+ :alert => "Hello!",
29
+ :collapse_key => "required",
30
+ :custom => "data",
31
+ :awesome => true
32
+ )
33
+
34
+
35
+ ### Response Callback
36
+
37
+ You can register a response callback to check success and handle errors:
38
+
39
+ EM::GCM.push_plain(["registration_id1"], :alert => "hi!") do |response|
40
+ if response.success?
41
+ puts "success! id=#{response.id}" # ID of sent message
42
+ else
43
+ case response.error
44
+ when "InvalidToken"
45
+ # reauthenticate
46
+ when "InvalidRegistration"
47
+ # clear our registration id
48
+ when "RetryAfter"
49
+ # pause sending for response.retry_after seconds
50
+ end
51
+ end
52
+ end
53
+
54
+
55
+
56
+ ## Contributing
57
+
58
+ Please feel free to fork and update this!
@@ -0,0 +1,22 @@
1
+ # -*- mode: ruby; encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "em-gcm/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ghazel-em-gcm"
7
+ s.version = EventMachine::GCM::VERSION
8
+ s.authors = ["Zeng Xin"]
9
+ s.email = ["samuelzx@hotmail.com"]
10
+ s.homepage = "https://github.com/zengxin/em-gcm"
11
+ s.summary = %q{Google Cloud Messaging for Android for Event Machine}
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_dependency "eventmachine", ">= 1.0.0.beta.3"
19
+ s.add_dependency "em-http-request", ">= 1.0.0.beta.4"
20
+ s.add_dependency "uuid"
21
+
22
+ end
@@ -0,0 +1,43 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require "eventmachine"
4
+ require "em-http-request"
5
+ require "logger"
6
+ require "uuid"
7
+ require "em-gcm/client"
8
+ require "em-gcm/notification"
9
+
10
+ $uuid = UUID.new
11
+
12
+ module EventMachine
13
+ module GCM
14
+ class << self
15
+ def push_plain(registration_ids, options, &block)
16
+ notification = Notification.new(registration_ids, options)
17
+ Client.new(notification).deliver_plain(block)
18
+ end
19
+
20
+ def push_json(registration_ids, options, &block)
21
+ notification = Notification.new(registration_ids, options)
22
+ Client.new(notification).deliver_json(block)
23
+ end
24
+
25
+ def token=(token)
26
+ logger.info("setting new auth token")
27
+ @token = token
28
+ end
29
+
30
+ def token
31
+ @token
32
+ end
33
+
34
+ def logger
35
+ @logger ||= Logger.new(STDOUT)
36
+ end
37
+
38
+ def logger=(new_logger)
39
+ @logger = new_logger
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,64 @@
1
+ require "em-gcm/response"
2
+ require "em-gcm/log_message"
3
+
4
+ module EventMachine
5
+ module GCM
6
+ class Client
7
+ URL = "https://android.googleapis.com/gcm/send"
8
+
9
+ def initialize(notification)
10
+ @notification = notification
11
+ end
12
+
13
+ def deliver_plain(block = nil)
14
+ verify_token
15
+ @start = Time.now.to_f
16
+
17
+ http = EventMachine::HttpRequest.new(URL).post(
18
+ :query => @notification.params,
19
+ :head => @notification.headers_plain
20
+ )
21
+
22
+ http.callback do
23
+ response = Response.new(http, @start)
24
+ LogMessage.new(@notification, response).log
25
+ block.call(response) if block
26
+ end
27
+
28
+ http.errback do |e|
29
+ EM::GCM.logger.error(e.inspect)
30
+ end
31
+ end
32
+
33
+ def deliver_json(block = nil)
34
+ verify_token
35
+ @start = Time.now.to_f
36
+
37
+ params = {:dry_run => "true"}
38
+
39
+ http = EventMachine::HttpRequest.new(URL).post(
40
+ #uncomment this if you want to test send and do not want receiver to receive message
41
+ #:query => params,
42
+ :body => @notification.body,
43
+ :head => @notification.headers_json
44
+ )
45
+
46
+ http.callback do
47
+ response = Response.new(http, @start, false)
48
+ LogMessage.new(@notification, response).log
49
+ block.call(response) if block
50
+ end
51
+
52
+ http.errback do |e|
53
+ EM::GCM.logger.error(e.inspect)
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def verify_token
60
+ raise "token not set!" unless EM::GCM.token
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,30 @@
1
+ module EventMachine
2
+ module GCM
3
+ class LogMessage
4
+ def initialize(notification, response)
5
+ @notification, @response = notification, response
6
+ end
7
+
8
+ def log
9
+ if @response.success?
10
+ EM::GCM.logger.info(message)
11
+ else
12
+ EM::GCM.logger.error(message)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def message
19
+ parts = [
20
+ "CODE=#{@response.status}",
21
+ "GUID=#{@notification.uuid}",
22
+ "TIME=#{@response.duration}",
23
+ "TOKEN=#{@notification.registration_ids}"
24
+ ]
25
+ parts << "ERROR=#{@response.error}" unless @response.success?
26
+ parts.join(" ")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,60 @@
1
+ require 'json'
2
+
3
+ module EventMachine
4
+ module GCM
5
+ class Notification
6
+ attr_reader :uuid, :options, :registration_ids
7
+
8
+ def initialize(registration_ids, options = {})
9
+ @registration_ids, @options = registration_ids, options
10
+ raise ArgumentError.new("missing options") if options.nil? || options.empty?
11
+ @uuid = $uuid.generate
12
+ end
13
+
14
+ def params
15
+ @params ||= generate_params
16
+ end
17
+
18
+ def body
19
+ @body ||= generate_body
20
+ end
21
+
22
+ def headers_plain
23
+ {
24
+ "Authorization" => "key=#{EM::GCM.token}",
25
+ "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8",
26
+ "User-Agent" => "em-c2dm 1.0.0"
27
+ }
28
+ end
29
+
30
+ def headers_json
31
+ {
32
+ "Authorization" => "key=#{EM::GCM.token}",
33
+ "Content-Type" => "application/json",
34
+ "User-Agent" => "em-c2dm 1.0.0"
35
+ }
36
+ end
37
+
38
+
39
+ private
40
+
41
+ def generate_params
42
+ params = { "registration_id" => @registration_ids[0] }
43
+ params["collapse_key"] = @options.delete(:collapse_key) || @options.delete("collapse_key")
44
+ @options.each do |k,v|
45
+ params["data.#{k}"] = v
46
+ end
47
+ params
48
+ end
49
+
50
+ def generate_body
51
+ body_hash = {}
52
+ body_hash[:collapse_key] = @options.delete(:collapse_key) || @options.delete("collapse_key")
53
+ body_hash[:data] = @options
54
+ body_hash[:registration_ids] = @registration_ids
55
+ body_hash.to_json
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,76 @@
1
+ module EventMachine
2
+ module GCM
3
+ # Header errors
4
+ # InvalidToken - Authentication token is invalid. Reauthenticate.
5
+ # Retry_After - Service is down for maintenance. Call retry_after for seconds to wait.
6
+ #
7
+ # Body errors
8
+ # Quota_Exceeded - Too many messages sent by the sender. Retry after a while.
9
+ # Device_Quota_Exceeded - Too any messages sent by the sender to a specific device. Retry after a while.
10
+ # InvalidRegistration - Missing or bad registration_id. Sender should stop sending messages to this device.
11
+ # NotRegistered - The registration_id is no longer valid, for example user has uninstalled the application or turned off notifications. Sender should stop sending messages to this device.
12
+ # MessageTooBig - The payload of the message is too big, see the limitations. Reduce the size of the message.
13
+ # MissingCollapseKey - Collapse key is required. Include collapse key in the request.
14
+ class Response
15
+ # Common
16
+ attr_accessor :id
17
+ attr_accessor :status
18
+ attr_accessor :duration
19
+ attr_accessor :error
20
+ attr_accessor :body
21
+
22
+ # Service-specific
23
+ attr_accessor :retry_after
24
+
25
+ def initialize(http = {}, start = nil, is_plain = true)
26
+ @http = http
27
+ @duration = Time.now.to_f - start.to_f if start
28
+ if http.kind_of?(Hash)
29
+ @id = http[:id]
30
+ @status = http[:status]
31
+ @retry_after = http[:retry_after]
32
+ @error = http[:error]
33
+ else
34
+ parse_body(http.response)
35
+ parse_headers(http.response_header)
36
+ end
37
+ @is_plain = is_plain
38
+ end
39
+
40
+ def success?
41
+ @error.nil?
42
+ end
43
+
44
+ private
45
+
46
+ def parse_body(body)
47
+ if @is_plain
48
+ body =~ (/^id=(.*)$/)
49
+ @id = $1
50
+
51
+ body =~ (/^Error=(.*)$/)
52
+ @error = $1
53
+ else
54
+ @body = body
55
+ end
56
+ end
57
+
58
+ # These are messed up because of EM::HttpRequest's messed up parsing
59
+ def parse_headers(headers)
60
+ @status = headers.status
61
+ @retry_after = headers["RETRY_AFTER"].to_i
62
+
63
+ case @status
64
+ when 200
65
+ # noop
66
+ when 401
67
+ @error = "InvalidToken"
68
+ when 502, 503
69
+ @error = "RetryAfter"
70
+ else
71
+ @error = "Unknown error: #{headers.status} (#{@http.response})"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,5 @@
1
+ module EventMachine
2
+ module GCM
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghazel-em-gcm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Zeng Xin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eventmachine
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0.beta.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0.beta.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: em-http-request
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0.beta.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0.beta.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: uuid
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
+ description:
56
+ email:
57
+ - samuelzx@hotmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - README.md
63
+ - em-gcm.gemspec
64
+ - lib/em-gcm.rb
65
+ - lib/em-gcm/client.rb
66
+ - lib/em-gcm/log_message.rb
67
+ - lib/em-gcm/notification.rb
68
+ - lib/em-gcm/response.rb
69
+ - lib/em-gcm/version.rb
70
+ homepage: https://github.com/zengxin/em-gcm
71
+ licenses: []
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.0.14
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Google Cloud Messaging for Android for Event Machine
93
+ test_files: []