apnotic 0.9.2 → 0.10.0
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/README.md +81 -0
- data/apnotic.gemspec +1 -1
- data/lib/apnotic.rb +1 -0
- data/lib/apnotic/connection.rb +20 -3
- data/lib/apnotic/notification.rb +2 -1
- data/lib/apnotic/push.rb +38 -0
- data/lib/apnotic/version.rb +1 -1
- metadata +5 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 9493fd00daf33a8bd13d087bcd119929b236372e
         | 
| 4 | 
            +
              data.tar.gz: 68215cff5cfc93dd0aafdccf2188da4f6fe9b085
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 5bad7e789438d5e5710a433501dff4e41fa50633f22fe0eb9814653919b41a8ea34a84747854c17a0ccdb850e84f720cf9d31f293a79e6a5b5c82ba2b80d7b77
         | 
| 7 | 
            +
              data.tar.gz: 54014458ff59af3703d94b00ffe61a3074c05ba962b60c8183f084a89a113d5051f50235c0d43b0e8c8c4a8db850ab504382b7dab8432940b8a8a4ea1762b0dd
         | 
    
        data/.ruby-version
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            ruby-2.3. | 
| 1 | 
            +
            ruby-2.3.1
         | 
    
        data/README.md
    CHANGED
    
    | @@ -28,6 +28,10 @@ gem 'apnotic' | |
| 28 28 | 
             
            ## Usage
         | 
| 29 29 |  | 
| 30 30 | 
             
            ### Standalone
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            #### Sync pushes
         | 
| 33 | 
            +
            Sync pushes are blocking calls that will wait for an APNs response before proceeding.
         | 
| 34 | 
            +
             | 
| 31 35 | 
             
            ```ruby
         | 
| 32 36 | 
             
            require 'apnotic'
         | 
| 33 37 |  | 
| @@ -53,6 +57,42 @@ response.body     # => "" | |
| 53 57 | 
             
            connection.close
         | 
| 54 58 | 
             
            ```
         | 
| 55 59 |  | 
| 60 | 
            +
            #### Async pushes
         | 
| 61 | 
            +
            If you are sending out a considerable amount of push notifications, you may consider using async pushes to send out multiple requests in non-blocking calls. This allows to take full advantage of HTTP/2 streams.
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            ```ruby
         | 
| 64 | 
            +
            require 'apnotic'
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            # create a persistent connection
         | 
| 67 | 
            +
            connection = Apnotic::Connection.new(cert_path: "apns_certificate.pem", cert_pass: "pass")
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            # create a notification for a specific device token
         | 
| 70 | 
            +
            token = "6c267f26b173cd9595ae2f6702b1ab560371a60e7c8a9e27419bd0fa4a42e58f"
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            notification       = Apnotic::Notification.new(token)
         | 
| 73 | 
            +
            notification.alert = "Notification from Apnotic!"
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            # prepare push
         | 
| 76 | 
            +
            push = connection.prepare_push(notification)
         | 
| 77 | 
            +
            push.on(:response) do |response|
         | 
| 78 | 
            +
              # read the response
         | 
| 79 | 
            +
              response.ok?      # => true
         | 
| 80 | 
            +
              response.status   # => '200'
         | 
| 81 | 
            +
              response.headers  # => {":status"=>"200", "apns-id"=>"6f2cd350-bfad-4af0-a8bc-0d501e9e1799"}
         | 
| 82 | 
            +
              response.body     # => ""
         | 
| 83 | 
            +
            end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            # send
         | 
| 86 | 
            +
            connection.push_async(push)
         | 
| 87 | 
            +
             | 
| 88 | 
            +
            # wait for all requests to be completed
         | 
| 89 | 
            +
            connection.join
         | 
| 90 | 
            +
             | 
| 91 | 
            +
            # close the connection
         | 
| 92 | 
            +
            connection.close
         | 
| 93 | 
            +
            ```
         | 
| 94 | 
            +
             | 
| 95 | 
            +
             | 
| 56 96 | 
             
            ### With Sidekiq / Rescue / ...
         | 
| 57 97 | 
             
            A practical usage of a Sidekiq / Rescue worker probably has to:
         | 
| 58 98 |  | 
| @@ -93,6 +133,7 @@ end | |
| 93 133 |  | 
| 94 134 | 
             
            > The official [APNs Provider API documentation](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html) explains how to interpret the responses given by the APNS.
         | 
| 95 135 |  | 
| 136 | 
            +
            You may also consider using async pushes instead in a Sidekiq / Rescue worker.
         | 
| 96 137 |  | 
| 97 138 |  | 
| 98 139 | 
             
            ## Objects
         | 
| @@ -129,10 +170,26 @@ Apnotic::Connection.development(options) | |
| 129 170 |  | 
| 130 171 | 
             
             Returns the path to the certificate
         | 
| 131 172 |  | 
| 173 | 
            +
            ##### Blocking calls
         | 
| 174 | 
            +
             | 
| 132 175 | 
             
             * **push(notification, timeout: 30)** → **`Apnotic::Response` or `nil`**
         | 
| 133 176 |  | 
| 134 177 | 
             
             Sends a notification. Returns `nil` in case a timeout occurs.
         | 
| 135 178 |  | 
| 179 | 
            +
            ##### Non-blocking calls
         | 
| 180 | 
            +
             | 
| 181 | 
            +
             * **prepare_push(notification)** → **`Apnotic::Push`**
         | 
| 182 | 
            +
             | 
| 183 | 
            +
             Prepares an async push.
         | 
| 184 | 
            +
             | 
| 185 | 
            +
             ```ruby
         | 
| 186 | 
            +
             push = client.prepare_push(notification)
         | 
| 187 | 
            +
             ```
         | 
| 188 | 
            +
             | 
| 189 | 
            +
             * **push_async(push)**
         | 
| 190 | 
            +
             | 
| 191 | 
            +
              Sends the push asynchronously.
         | 
| 192 | 
            +
             | 
| 136 193 |  | 
| 137 194 | 
             
            ### `Apnotic::ConnectionPool`
         | 
| 138 195 | 
             
            For your convenience, a wrapper around the [Connection Pool](https://github.com/mperham/connection_pool) gem is here for you. To create a new connection pool:
         | 
| @@ -172,6 +229,7 @@ These are all Accessor attributes. | |
| 172 229 | 
             
            | `priority` | "
         | 
| 173 230 | 
             
            | `topic` | "
         | 
| 174 231 | 
             
            | `url_args` | Values for [Safari push notifications](https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html#//apple_ref/doc/uid/TP40013225-CH3-SW12).
         | 
| 232 | 
            +
            | `mutable_content` | Key for [UNNotificationServiceExtension](https://developer.apple.com/reference/usernotifications/unnotificationserviceextension).
         | 
| 175 233 |  | 
| 176 234 | 
             
            For example:
         | 
| 177 235 |  | 
| @@ -218,6 +276,29 @@ The response to a call to `connection.push`. | |
| 218 276 | 
             
             Returns the body of the response in Hash format if a valid JSON was returned, otherwise just the RAW body.
         | 
| 219 277 |  | 
| 220 278 |  | 
| 279 | 
            +
            ### `Apnotic::Push`
         | 
| 280 | 
            +
            The push object to be sent in an async call.
         | 
| 281 | 
            +
             | 
| 282 | 
            +
            #### Methods
         | 
| 283 | 
            +
             | 
| 284 | 
            +
             * **on(event, &block)**
         | 
| 285 | 
            +
             | 
| 286 | 
            +
             Allows to set a callback for the request. Available events are:
         | 
| 287 | 
            +
             | 
| 288 | 
            +
              * `:response`: triggered when a response is fully received (called once).
         | 
| 289 | 
            +
             | 
| 290 | 
            +
             Even if Apnotic is thread-safe, the async callbacks will be executed in a different thread, so ensure that your code in the callbacks is thread-safe.
         | 
| 291 | 
            +
             | 
| 292 | 
            +
             ```ruby
         | 
| 293 | 
            +
             push.on(:response) { |response| p response.headers }
         | 
| 294 | 
            +
             ```
         | 
| 295 | 
            +
             | 
| 296 | 
            +
             * **http2_request**  → **`NetHttp2::Request`**
         | 
| 297 | 
            +
             
         | 
| 298 | 
            +
             Returns the HTTP/2 request of the push.
         | 
| 299 | 
            +
             | 
| 300 | 
            +
             | 
| 301 | 
            +
             | 
| 221 302 | 
             
            ## Getting Your APNs Certificate
         | 
| 222 303 |  | 
| 223 304 | 
             
            > These instructions come from another great gem, [apn_on_rails](https://github.com/PRX/apn_on_rails).
         | 
    
        data/apnotic.gemspec
    CHANGED
    
    | @@ -18,7 +18,7 @@ Gem::Specification.new do |spec| | |
| 18 18 | 
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 19 19 | 
             
              spec.require_paths = ["lib"]
         | 
| 20 20 |  | 
| 21 | 
            -
              spec.add_dependency "net-http2", "~> 0. | 
| 21 | 
            +
              spec.add_dependency "net-http2", "~> 0.12.0"
         | 
| 22 22 | 
             
              spec.add_dependency "connection_pool", "~> 2.0"
         | 
| 23 23 |  | 
| 24 24 | 
             
              spec.add_development_dependency "bundler", "~> 1.3"
         | 
    
        data/lib/apnotic.rb
    CHANGED
    
    
    
        data/lib/apnotic/connection.rb
    CHANGED
    
    | @@ -17,9 +17,9 @@ module Apnotic | |
| 17 17 | 
             
                end
         | 
| 18 18 |  | 
| 19 19 | 
             
                def initialize(options={})
         | 
| 20 | 
            -
                  @url | 
| 21 | 
            -
                  @cert_path | 
| 22 | 
            -
                  @cert_pass | 
| 20 | 
            +
                  @url             = options[:url] || APPLE_PRODUCTION_SERVER_URL
         | 
| 21 | 
            +
                  @cert_path       = options[:cert_path]
         | 
| 22 | 
            +
                  @cert_pass       = options[:cert_pass]
         | 
| 23 23 | 
             
                  @connect_timeout = options[:connect_timeout] || 30
         | 
| 24 24 |  | 
| 25 25 | 
             
                  raise "Cert file not found: #{@cert_path}" unless @cert_path && (@cert_path.respond_to?(:read) || File.exist?(@cert_path))
         | 
| @@ -37,10 +37,27 @@ module Apnotic | |
| 37 37 | 
             
                  Apnotic::Response.new(headers: response.headers, body: response.body) if response
         | 
| 38 38 | 
             
                end
         | 
| 39 39 |  | 
| 40 | 
            +
                def push_async(push)
         | 
| 41 | 
            +
                  @client.call_async(push.http2_request)
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def prepare_push(notification)
         | 
| 45 | 
            +
                  request       = Apnotic::Request.new(notification)
         | 
| 46 | 
            +
                  http2_request = @client.prepare_request(:post, request.path,
         | 
| 47 | 
            +
                    body:    request.body,
         | 
| 48 | 
            +
                    headers: request.headers
         | 
| 49 | 
            +
                  )
         | 
| 50 | 
            +
                  Apnotic::Push.new(http2_request)
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 40 53 | 
             
                def close
         | 
| 41 54 | 
             
                  @client.close
         | 
| 42 55 | 
             
                end
         | 
| 43 56 |  | 
| 57 | 
            +
                def join
         | 
| 58 | 
            +
                  @client.join
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 44 61 | 
             
                private
         | 
| 45 62 |  | 
| 46 63 | 
             
                def ssl_context
         | 
    
        data/lib/apnotic/notification.rb
    CHANGED
    
    | @@ -5,7 +5,7 @@ module Apnotic | |
| 5 5 |  | 
| 6 6 | 
             
              class Notification
         | 
| 7 7 | 
             
                attr_reader :token
         | 
| 8 | 
            -
                attr_accessor :alert, :badge, :sound, :content_available, :category, :custom_payload, :url_args
         | 
| 8 | 
            +
                attr_accessor :alert, :badge, :sound, :content_available, :category, :custom_payload, :url_args, :mutable_content
         | 
| 9 9 | 
             
                attr_accessor :apns_id, :expiration, :priority, :topic
         | 
| 10 10 |  | 
| 11 11 | 
             
                def initialize(token)
         | 
| @@ -28,6 +28,7 @@ module Apnotic | |
| 28 28 | 
             
                  aps.merge!(category: category) if category
         | 
| 29 29 | 
             
                  aps.merge!('content-available' => content_available) if content_available
         | 
| 30 30 | 
             
                  aps.merge!('url-args' => url_args) if url_args
         | 
| 31 | 
            +
                  aps.merge!('mutable-content' => mutable_content) if mutable_content
         | 
| 31 32 |  | 
| 32 33 | 
             
                  n = { aps: aps }
         | 
| 33 34 | 
             
                  n.merge!(custom_payload) if custom_payload
         | 
    
        data/lib/apnotic/push.rb
    ADDED
    
    | @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            module Apnotic
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              class Push
         | 
| 4 | 
            +
                attr_reader :http2_request
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def initialize(http2_request)
         | 
| 7 | 
            +
                  @http2_request = http2_request
         | 
| 8 | 
            +
                  @headers       = {}
         | 
| 9 | 
            +
                  @data          = ''
         | 
| 10 | 
            +
                  @events        = {}
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  listen_for_http2_events
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def on(event, &block)
         | 
| 16 | 
            +
                  raise ArgumentError, 'on event must provide a block' unless block_given?
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  @events[event] ||= []
         | 
| 19 | 
            +
                  @events[event] << block
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def emit(event, arg)
         | 
| 23 | 
            +
                  return unless @events[event]
         | 
| 24 | 
            +
                  @events[event].each { |b| b.call(arg) }
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                private
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def listen_for_http2_events
         | 
| 30 | 
            +
                  @http2_request.on(:headers) { |headers| @headers.merge!(headers) }
         | 
| 31 | 
            +
                  @http2_request.on(:body_chunk) { |chunk| @data << chunk }
         | 
| 32 | 
            +
                  @http2_request.on(:close) do
         | 
| 33 | 
            +
                    response = Apnotic::Response.new(headers: @headers, body: @data)
         | 
| 34 | 
            +
                    emit(:response, response)
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
    
        data/lib/apnotic/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: apnotic
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.10.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Roberto Ostinelli
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016- | 
| 11 | 
            +
            date: 2016-06-28 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: net-http2
         | 
| @@ -16,14 +16,14 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - "~>"
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: 0. | 
| 19 | 
            +
                    version: 0.12.0
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - "~>"
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: 0. | 
| 26 | 
            +
                    version: 0.12.0
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: connection_pool
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -103,6 +103,7 @@ files: | |
| 103 103 | 
             
            - lib/apnotic/connection.rb
         | 
| 104 104 | 
             
            - lib/apnotic/connection_pool.rb
         | 
| 105 105 | 
             
            - lib/apnotic/notification.rb
         | 
| 106 | 
            +
            - lib/apnotic/push.rb
         | 
| 106 107 | 
             
            - lib/apnotic/request.rb
         | 
| 107 108 | 
             
            - lib/apnotic/response.rb
         | 
| 108 109 | 
             
            - lib/apnotic/version.rb
         |