buford

package module
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2016 License: MIT Imports: 0 Imported by: 0

README

Buford

Apple Push Notification (APN) Provider for Go 1.6 and HTTP/2.

Please see releases for updates.

GoDoc Build Status MIT

Documentation

Buford uses Apple's new HTTP/2 Notification API that was announced at WWDC 2015 and released on December 17, 2015.

API documentation is available from GoDoc.

Also see Apple's Local and Remote Notification Programming Guide, especially the sections on the JSON payload and the Notification API.

Terminology

APN Apple Push Notification

Provider The Buford library is used to create a provider of push notifications.

Service Apple provides the push notification service that Buford communications with.

Client An http.Client provides an HTTP/2 client to communication with the APN Service.

Notification A payload sent to a device token with some headers.

Device Token An identifier for an application on a given device.

Payload The JSON sent to a device.

Headers HTTP/2 headers are used to set priority and expiration.

Installation

This library requires Go 1.6.2 or better.

Buford depends on several packages outside of the standard library, including the http2 package. Its certificate package depends on the pkcs12 and pushpackage depends on pkcs7. They can be retrieved or updated with:

go get -u golang.org/x/net/http2
go get -u golang.org/x/crypto/pkcs12
go get -u github.com/aai/gocrypto/pkcs7

I am still looking for feedback on the API so it may change. Please copy Buford and its dependencies into a vendor/ folder at the root of your project.

Examples
package main

import (
	"encoding/json"
	"fmt"

	"github.com/RobotsAndPencils/buford/certificate"
	"github.com/RobotsAndPencils/buford/payload"
	"github.com/RobotsAndPencils/buford/payload/badge"
	"github.com/RobotsAndPencils/buford/push"
)

// set these variables appropriately
const (
	filename = "/path/to/certificate.p12"
	password = ""
	host = push.Development
	deviceToken = "c2732227a1d8021cfaf781d71fb2f908c61f5861079a00954a5453f1d0281433"
)

func main() {
	// load a certificate and use it to connect to the APN service:
	cert, err := certificate.Load(filename, password)
	exitOnError(err)

	client, err := push.NewClient(cert)
	exitOnError(err)

	service := push.NewService(client, host)

	// construct a payload to send to the device:
	p := payload.APS{
		Alert: payload.Alert{Body: "Hello HTTP/2"},
		Badge: badge.New(42),
	}
	b, err := json.Marshal(p)
	exitOnError(err)

	// push the notification:
	id, err := service.Push(deviceToken, nil, b)
	exitOnError(err)

	fmt.Println("apns-id:", id)
}

See example/push for the complete listing.

Concurrent use

HTTP/2 can send multiple requests over a single connection, but service.Push waits for a response before returning. Instead, you can wrap a Service in a queue to handle responses independently, allowing you to send multiple notifications at once.

queue := push.NewQueue(service, workers)

// process responses
go func() {
	for {
		// Response blocks until a response is available
		log.Println(queue.Response())
	}
}()

// send the notifications
for i := 0; i < number; i++ {
	queue.Push(deviceToken, nil, b)
}

// done sending notifications, wait for all responses
queue.Wait()

It's important to set up a goroutine to handle responses before sending any notifications, otherwise Push will block waiting for room to return a Response.

You can configure the number of workers used to send notifications concurrently, but be aware that a larger number isn't necessarily better, as Apple limits the number of concurrent streams. From the Apple Push Notification documentation:

"The APNs server allows multiple concurrent streams for each connection. The exact number of streams is based on server load, so do not assume a specific number of streams."

See example/concurrent/ for a complete listing.

Headers

You can specify an ID, expiration, priority, and other parameters via the Headers struct.

headers := &push.Headers{
	ID:          "922D9F1F-B82E-B337-EDC9-DB4FC8527676",
	Expiration:  time.Now().Add(time.Hour),
	LowPriority: true,
}

id, err := service.Push(deviceToken, headers, b)

If no ID is specified APNS will generate and return a unique ID. When an expiration is specified, APNS will store and retry sending the notification until that time, otherwise APNS will not store or retry the notification. LowPriority should always be set when sending a ContentAvailable payload.

Custom values

To add custom values to an APS payload, use the Map method as follows:

p := payload.APS{
	Alert: payload.Alert{Body: "Message received from Bob"},
}
pm := p.Map()
pm["acme2"] = []string{"bang", "whiz"}

b, err := json.Marshal(pm)
if err != nil {
	log.Fatal(b)
}

service.Push(deviceToken, nil, b)
Error responses

If service.Push or queue.Response returns an error, it could be an HTTP error, or it could be an error response from Apple. To access the Reason and HTTP Status code, you must convert the error to a push.Error as follows:

if e, ok := err.(*push.Error); ok {
	switch e.Reason {
	case push.ErrBadDeviceToken:
		// handle error
	}
}
Website Push

Before you can send push notifications through Safari and the Notification Center, you must provide a push package, which is a signed zip file containing some JSON and icons.

Use pushpackage to write a zip to a http.ResponseWriter or to a file. It will create the manifest.json and signature files for you.

pkg := pushpackage.New(w)
pkg.EncodeJSON("website.json", website)
pkg.File("icon.iconset/icon_128x128@2x.png", "static/icon_128x128@2x.png")
// other icons... (required)
if err := pkg.Sign(cert, nil); err != nil {
	log.Fatal(err)
}

NOTE: The filenames added to the zip may contain forward slashes but not back slashes or drive letters.

See example/website/ and the Safari Push Notifications documentation.

Wallet (Passbook) Pass

A pass is a signed zip file with a .pkpass extension and a application/vnd.apple.pkpass MIME type. You can use pushpackage to write a .pkpass that contains a pass.json file.

See example/wallet/ and the Wallet Developer Guide.

Documentation

Overview

Package buford is a Go 1.6+ HTTP/2 provider for Apple Push Notification Service (APNS).

Please see the README for usage.

Directories

Path Synopsis
Package certificate loads Push Services certificates exported from your Keychain in Personal Information Exchange format (*.p12).
Package certificate loads Push Services certificates exported from your Keychain in Personal Information Exchange format (*.p12).
example
Package payload serializes a JSON payload to push.
Package payload serializes a JSON payload to push.
badge
Package badge allows you to preserve, set or clear the number displayed on your App icon.
Package badge allows you to preserve, set or clear the number displayed on your App icon.
Package push sends notifications over HTTP/2 to Apple's Push Notification Service.
Package push sends notifications over HTTP/2 to Apple's Push Notification Service.
Package pushpackage creates website push packages and wallet pass packages.
Package pushpackage creates website push packages and wallet pass packages.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL