ghazel-em-gcm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []