timehop / apns

A Go package to interface with the Apple Push Notification Service
https://godoc.org/github.com/timehop/apns
MIT License
185 stars 47 forks source link

New HTTP/2 Push Notification Provider API from Apple #57

Closed nathany closed 8 years ago

nathany commented 9 years ago

Apple announced a new provider API coming later in 2015 that is based on HTTP/2. https://developer.apple.com/videos/wwdc/2015/?id=720 (at about 20 minutes)

This uses a request/response cycle with standard http status codes. The connection is left open after a notification failed, and there is no need to resend notifications. There is also no need for a separate feedback service.

There will be no need to keep the existing APNS provider API as the new API applies to older devices running existing versions of iOS and OS X. The video mentions some other changes, such as 4K payloads and ~100-character device tokens.

nathany commented 9 years ago

It may be a while yet before we have access to documentation and a development environment to use with https://github.com/bradfitz/http2. Longer still before this can be used in production.

JSON serialization remains the same but pretty much everything else is different.

nathany commented 8 years ago

The HTTP/2 library has moved to the x/net repo, though the client still is not ready. I also haven't seen any documentation from Apple yet, though I don't know where to look. https://github.com/golang/net/tree/master/http2

taylortrimble commented 8 years ago

The best I've found is the second half of this video. There they mention the service will be available for development "this summer", and it will be released for production use "later this year". They also mention it will be documented "later this year."

This may imply it will be development-ready before being documented. Perhaps you could send messages to the API shown in the video and expect results? It appeared complete. I'm not sure which certificate you would use; my impression is they missed their mark on having it development-ready by now, and we'll have to wait for clearer instructions. Unless someone wants to try the video's API with a prod cert. :wink:

nathany commented 8 years ago

Once we have a working http2 client, I'll do some more looking around for updates from Apple. May not be fully in place until Go 1.6 though (February).

nathany commented 8 years ago

nslookup does resolve api.push.apple.com and api.sandbox.push.apple.com exists as well

in the video @gokult says "When you establish a connection, it uses the same client certificates that you already have today with the current provider API."

It seems like the http2 client code is underway, so it would be interesting to try POSTing to the sandbox to see what happens. https://godoc.org/golang.org/x/net/http2

slides

headers

"The header frame also contains optional parameters like expiration, ID, priority, things of that nature."

:authority = api.push.apple.com
:method = POST
:path = /3/device/ad2bcd38f6773cdad050411...
content-length = 41
apns-id = de305d54-75b4-431b-adb2-eb6b9e546014
apns-expiration = 0

"This post request is made to a URI that includes the device token and has a body, the JSON body that's exactly like the current provider API that you use today."

{ "aps" : { "alert" : "Hello HTTP/2" } }

200 OK or a 400 with a JSON payload that has the reason for why your request failed.

status 410, 410 meaning gone, that the device token is no longer active for your application.

"The new provider API will be available in APNS development environments this summer. And we will be rolling it out to production later this year. You can also access technical support and developer forums, and please direct general inquiries to Paul, our Core OS evangelist."

Talk by https://twitter.com/gokult

nathany commented 8 years ago

Wow. That actually worked!

I used Go 1.6 which isn't due out until early February. For the most part it's just a regular client Post, with the only odd bit is setting up the client to use the right certificate.

nathany commented 8 years ago

Stay tuned, we’ll be going live with the new protocol and publishing new documentation soon. Paul Danbold

dennislysenko commented 8 years ago

@nathany Awesome work! Presumably "this summer" meant this past summer and they will be rolling out the API right around now? Or are they dragging it out for another year?

nathany commented 8 years ago

I didn't get a date from anyone. Hoping we have some news from Apple by the time Go 1.6 rolls out on ~February 1st. Meanwhile, I'm going to play with it a little more.

It's such a dramatic change that most of the code in timehop/apns won't be necessary anymore. So I'll likely start a fresh package that is only for Go 1.6+ and only HTTP/2. I'll drop a link here once I have something.

nathany commented 8 years ago

So far I'm thinking something like this:

cert, err := certificate.Load(filename, password)
if err != nil {
    log.Fatal(err)
}

service := push.Service{
    Client: push.NewClient(cert),
    Host:   push.Sandbox,
}

p := payload.APS{
    Alert: payload.Alert{Body: "Hello HTTP/2"},
    Badge: badge.New(42),
}

err = service.Push(deviceToken, push.Headers{}, p)
if err != nil {
    log.Fatal(err)
}

A set of little packages that can be used together, but left open for customization. We're waiting on Apple for documentation before releasing anything. I'm looking forward to getting feedback from you all.

NOTE: NewClient would just return an http.Client setup for TLS. certificate.Decode could also be used to decode a .p12 from memory instead of disk. service.Push would use the json.Marshaller interface and service.PushBytes could be used to serialize once to send multiple notifications.

nathany commented 8 years ago

Tada. https://developer.apple.com/news/?id=12172015b and Go 1.6 beta on the same day!

nathany commented 8 years ago

Here is a library for HTTP/2 Push

https://github.com/RobotsAndPencils/buford

dennislysenko commented 8 years ago

Nathan, fantastic! Not sure if I will end up using this library since our backend is Rails, but I can certainly use it as a point of reference when I migrate to the new APNs API.

On Fri, Dec 18, 2015, 1:10 AM Nathan Youngman notifications@github.com wrote:

Here is a library for HTTP/2 Push

https://github.com/RobotsAndPencils/buford

— Reply to this email directly or view it on GitHub https://github.com/timehop/apns/issues/57#issuecomment-165681750.

nathany commented 8 years ago

RobotsAndPencils has this working in a Rails backend via Sidekiq and go-workers, though I've also done implementations using a JSON API wrapped in a Ruby gem. It's all closed source though, I'm not sure if I should even be talking about it. Good luck!

I'm closing this issue, but left a note in #53 related projects.