apns

package module
v0.0.0-...-d85c39e Latest Latest
Warning

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

Go to latest
Published: Dec 11, 2014 License: MIT Imports: 13 Imported by: 0

README

apns

GoDoc Build Status

A Go package to interface with the Apple Push Notification Service

Features

This library implements a few features that we couldn't find in any one library elsewhere:

  • Long Lived Clients - Apple's documentation say that you should hold a persistent connection open and not create new connections for every payload
  • Use of New Protocol - Apple came out with v2 of their API with support for variable length payloads. This library uses that protocol.
  • Robust Send Guarantees - APNS has asynchronous feedback on whether a push sent. That means that if you send pushes after a bad send, those pushes will be lost forever. Our library records the last N pushes, detects errors, and is able to resend the pushes that could have been lost. More reading

Install

go get github.com/timehop/apns

Usage

Sending a push notification (basic)
c, _ := apns.NewClient(apns.ProductionGateway, apnsCert, apnsKey)

p := apns.NewPayload()
p.APS.Alert.Body = "I am a push notification!"
p.APS.Badge = 5
p.APS.Sound = "turn_down_for_what.aiff"

m := apns.NewNotification()
m.Payload = p
m.DeviceToken = "A_DEVICE_TOKEN"
m.Priority = apns.PriorityImmediate

c.Send(m)
Sending a push notification with error handling
c, err := apns.NewClient(apns.ProductionGateway, apnsCert, apnsKey)
if err != nil {
	log.Fatal("could not create new client", err.Error()
}

go func() {
	for f := range c.FailedNotifs {
		fmt.Println("Notif", f.Notif.ID, "failed with", f.Err.Error())
	}
}()

p := apns.NewPayload()
p.APS.Alert.Body = "I am a push notification!"
p.APS.Badge = 5
p.APS.Sound = "turn_down_for_what.aiff"
p.APS.ContentAvailable = 1

p.SetCustomValue("link", "zombo://dot/com")
p.SetCustomValue("game", map[string]int{"score": 234})

m := apns.NewNotification()
m.Payload = p
m.DeviceToken = "A_DEVICE_TOKEN"
m.Priority = apns.PriorityImmediate
m.Identifier = 12312, // Integer for APNS
m.ID = "user_id:timestamp", // ID not sent to Apple – to identify error notifications

c.Send(m)
Retrieving feedback
f, err := apns.NewFeedback(s.Address(), DummyCert, DummyKey)
if err != nil {
	log.Fatal("Could not create feedback", err.Error())
}

for ft := range f.Receive() {
	fmt.Println("Feedback for token:", ft.DeviceToken)
}

Running the tests

We use Ginkgo for our testing framework and Gomega for our matchers. To run the tests:

go get github.com/onsi/ginkgo/ginkgo
go get github.com/onsi/gomega
ginkgo -randomizeAllSpecs

Contributing

  • Fork the repo
  • Make your changes
  • Run the tests
  • Submit a pull request

If you need any ideas on what to work on, check out the TODO

License

MIT License

Documentation

Overview

A Go package to interface with the Apple Push Notification Service

Features

This library implements a few features that we couldn't find in any one library elsewhere:

Long Lived Clients     - Apple's documentation say that you should hold a
                         persistent connection open and not create new
                         connections for every payload
                         See: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW6)

Use of New Protocol    - Apple came out with v2 of their API with support for
                         variable length payloads. This library uses that
                         protocol.

Robust Send Guarantees - APNS has asynchronous feedback on whether a push
                         sent. That means that if you send pushes after a
                         bad send, those pushes will be lost forever. Our
                         library records the last N pushes, detects errors,
                         and is able to resend the pushes that could have
                         been lost.
                         See: http://redth.codes/the-problem-with-apples-push-notification-ser/

Index

Constants

View Source
const (
	ProductionGateway = "gateway.push.apple.com:2195"
	SandboxGateway    = "gateway.sandbox.push.apple.com:2195"

	ProductionFeedbackGateway = "feedback.push.apple.com:2196"
	SandboxFeedbackGateway    = "feedback.sandbox.push.apple.com:2196"
)
View Source
const (
	// Error strings based on the codes specified here:
	// https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW12
	ErrProcessing         = "Processing error"
	ErrMissingDeviceToken = "Missing device token"
	ErrMissingTopic       = "Missing topic"
	ErrMissingPayload     = "Missing payload"
	ErrInvalidTokenSize   = "Invalid token size"
	ErrInvalidTopicSize   = "Invalid topic size"
	ErrInvalidPayloadSize = "Invalid payload size"
	ErrInvalidToken       = "Invalid token"
	ErrShutdown           = "Shutdown"
	ErrUnknown            = "None (unknown)"
)
View Source
const (
	PriorityImmediate     = 10
	PriorityPowerConserve = 5
)

Variables

This section is empty.

Functions

This section is empty.

Types

type APS

type APS struct {
	Alert            Alert  `json:"alert,omitempty"`
	Badge            int    `json:"badge,omitempty"`
	Sound            string `json:"sound,omitempty"`
	ContentAvailable int    `json:"content-available,omitempty"`
	Category         string `json:"category,omitempty"`
}

type Alert

type Alert struct {
	Body         string   `json:"body,omitempty"`
	LocKey       string   `json:"loc-key,omitempty"`
	LocArgs      []string `json:"loc-args,omitempty"`
	ActionLocKey string   `json:"action-loc-key,omitempty"`
	LaunchImage  string   `json:"launch-image,omitempty"`
}

type Client

type Client struct {
	Conn         *Conn
	FailedNotifs chan NotificationResult
	// contains filtered or unexported fields
}

func NewClient

func NewClient(gw string, cert string, key string) (Client, error)

func NewClientWithCert

func NewClientWithCert(gw string, cert tls.Certificate) Client

func NewClientWithFiles

func NewClientWithFiles(gw string, certFile string, keyFile string) (Client, error)

func (*Client) Send

func (c *Client) Send(n Notification) error

type Conn

type Conn struct {
	NetConn net.Conn
	Conf    *tls.Config
	// contains filtered or unexported fields
}

Conn is a wrapper for the actual TLS connections made to Apple

func NewConn

func NewConn(gw string, crt string, key string) (Conn, error)

NewConnWithFiles creates a new Conn from certificate and key in the specified files

func NewConnWithCert

func NewConnWithCert(gw string, cert tls.Certificate) Conn

func NewConnWithFiles

func NewConnWithFiles(gw string, certFile string, keyFile string) (Conn, error)

NewConnWithFiles creates a new Conn from certificate and key in the specified files

func (*Conn) Close

func (c *Conn) Close() error

func (*Conn) Connect

func (c *Conn) Connect() error

Connect actually creates the TLS connection

func (*Conn) Read

func (c *Conn) Read(p []byte) (int, error)

Read reads data from the connection

func (*Conn) Write

func (c *Conn) Write(p []byte) (int, error)

Write writes data from the connection

type Error

type Error struct {
	Command    uint8
	Status     uint8
	Identifier uint32
	ErrStr     string
}

func NewError

func NewError(p []byte) Error

func (*Error) Error

func (e *Error) Error() string

type Feedback

type Feedback struct {
	Conn *Conn
}

func NewFeedback

func NewFeedback(gw string, cert string, key string) (Feedback, error)

func NewFeedbackWithCert

func NewFeedbackWithCert(gw string, cert tls.Certificate) Feedback

func NewFeedbackWithFiles

func NewFeedbackWithFiles(gw string, certFile string, keyFile string) (Feedback, error)

func (Feedback) Receive

func (f Feedback) Receive() <-chan FeedbackTuple

type FeedbackTuple

type FeedbackTuple struct {
	Timestamp   time.Time
	TokenLength uint16
	DeviceToken string
}

type Notification

type Notification struct {
	ID          string
	DeviceToken string
	Identifier  uint32
	Expiration  *time.Time
	Priority    int
	Payload     *Payload
}

func NewNotification

func NewNotification() Notification

func (Notification) ToBinary

func (n Notification) ToBinary() ([]byte, error)

type NotificationResult

type NotificationResult struct {
	Notif Notification
	Err   Error
}

type Payload

type Payload struct {
	APS APS
	// contains filtered or unexported fields
}

func NewPayload

func NewPayload() *Payload

func (*Payload) MarshalJSON

func (p *Payload) MarshalJSON() ([]byte, error)

func (*Payload) SetCustomValue

func (p *Payload) SetCustomValue(key string, value interface{}) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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