fcm

package module
v0.0.0-...-3fe457a Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2020 License: MIT Imports: 13 Imported by: 0

README

go-fcm for FCM HTTP v1 API

GoDoc Build Status Go Report Card

Golang client library for Firebase Cloud Messaging v1 API.

The Legacy FCM HTTP Protocol has no construct to make a distinction between Android, iOS and Web notifications. The new HTTP v1 API does.

With this library, you:

Getting Started

CLI App

Usage
go install github.com/tevjef/go-fcm/cmd/fcm-send

NAME:
   go-fcm - Send messages to devices through Firebase Cloud Messaging.

USAGE:
   go-fcm [global options]

VERSION:
   1.0.0

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --topic value, -t value       The name of the topic to send a message to.
   --token value, -k value       The device topic or registration id to send a message to.
   --condition value, -c value   The condition to send a message to, e.g. 'foo' in topics && 'bar' in topics
   --title value                 The notification title.
   --body value                  The notification body.
   --validate-only               Validate the message, but don't send it.
   --credentials-location value  Location of the Firebase Admin SDK JSON credentials. [$CREDENTIALS_LOCATION]
   --project-id value            The id of your Firebase project. [$PROJECT_ID]
   --help, -h                    show help
   --version, -v                 print the version

As package

Usage
go get github.com/tevjef/go-fcm

Example
import (
	"encoding/json"
	"log"

	"github.com/tevjef/go-fcm"
)

func main() {
	// Create the message to be sent.
	msg := &fcm.SendRequest{
		ValidateOnly: true,
		Message: &fcm.Message{
			Token: "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
			Notification: &fcm.Notification{
				Title: "FCM Message",
				Body:  "This is a Firebase Cloud Messaging Topic Message!",
			},
			Apns: &fcm.ApnsConfig{
				Payload: &fcm.ApnsPayload{
					Aps: &fcm.ApsDictionary{
						Alert: &fcm.ApnsAlert{
							LaunchImage: "UILaunchImageFileKey",
						},
						Badge:            1,
						Category:         "NEW_MESSAGE_CATEGORY",
						ContentAvailable: int(fcm.ApnsContentAvailable),
					},
				},
			},
			Android: &fcm.AndroidConfig{
				Priority: string(fcm.AndroidHighPriority),
				TTL:      "84000s",
				Notification: &fcm.AndroidNotification{
					Icon:        "ic_notification",
					Color:       "#rrggbb",
					ClickAction: "MainActivity",
				},
			},
		},
	}

	// Create a FCM client to send the message.
	client, err := fcm.NewClient("projectID", "sa.json")
	if err != nil {
		log.Fatalln(err)
	}

	// Send the message and receive the response without retries.
	response, err := client.Send(msg)
	if err != nil {
		log.Fatalln(err)
	}

	log.Printf("%#v\n", response)
}
Example JSON sent to FCM HTTP v1 API
{
   "validate_only": true,
   "message": {
     "token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
     or
     "topic": "cats", 
     or
     "condition": "'dogs' in topics || 'cats' in topics", 
     "apns": {
       "headers": {
         "apns-expiration": "14567890",
         "apns-priority": "10",
         "apns-topic": "my-topic",
         "apns-collapse-id": "my-collapse-id"
       },
       "payload": {
         "acme1": "bar",
         "acme2": [
           "bang",
           "whiz"
         ],
         "aps": {
           "alert": {
             "action-loc-key": "PLAY",
             "body": "Acme message received from Johnny Appleseed",
             "launch-image": "UILaunchImageFileKey",
             "loc-args": [
               "Jenna",
               "Frank"
             ],
             "loc-key": "GAME_PLAY_REQUEST_FORMAT",
             "title": "Acme title",
             "title-loc-args": [
               "Jenna",
               "Frank"
             ],
             "title-loc-key": "GAME_PLAY_REQUEST_FORMAT"
           },
           "badge": 1,
           "category": "NEW_MESSAGE_CATEGORY",
           "content-available": 1,
           "sound": "chime.aiff",
           "thread-id": "my-thread-id"
         }
       }
     },
     "android": {
       "collapse_key": "my-collapse-key",
       "priority": "HIGH",
       "ttl": "84000s",
       "restricted_package_name": "com.github.go-fcm",
       "data": {
         "acme1": "bar",
         "acme2": [
           "bang",
           "whiz"
         ]
       },
       "notification": {
         "title": "FCM Message",
         "body": "This is a Firebase Cloud Messaging Topic Message!",
         "icon": "ic_notification",
         "sound": "res_raw_notification_sound.mp3",
         "tag": "my-notification-tag",
         "color": "#rrggbb",
         "click_action": "MainActivity",
         "body_loc_key": "notification_body",
         "body_loc_args": [
           "Jenna",
           "Frank"
         ],
         "title_loc_key": "notification_title",
         "title_loc_args": [
           "Jenna",
           "Frank"
         ]
       }
     },
     "notification": {
       "title": "FCM Message",
       "body": "This is a Firebase Cloud Messaging Topic Message!"
     }
   }
 }

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidMessage occurs if push notitication message is nil.
	ErrInvalidMessage = errors.New("message is invalid")

	// ErrInvalidTarget occurs if message topic is empty.
	ErrInvalidTarget = errors.New("target is invalid. topic, token or condition maybe used")

	// ErrInvalidTimeToLive occurs if TimeToLive more then 2419200.
	ErrInvalidTimeToLive = errors.New("messages time-to-live is invalid")

	// ErrInvalidApnsPriority occurs if the priority is not 5 or 10.
	ErrInvalidApnsPriority = errors.New("apns message priority is invalid")
)

Functions

This section is empty.

Types

type AndroidConfig

type AndroidConfig struct {
	// An identifier of a group of messages that can be collapsed, so that
	// only the last message gets sent when delivery can be resumed.
	// A maximum of 4 different collapse keys is allowed at any given time.
	CollapseKey string `json:"collapse_key,omitempty"`

	// Message priority. Can take "normal" and "high" values.
	Priority string `json:"priority,omitempty"`

	// A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".
	TTL string `json:"ttl,omitempty"`

	// Package name of the application where the registration tokens must match in order to receive the message.
	RestrictedPackageName string `json:"restricted_package_name,omitempty"`

	// Arbitrary key/value payload. If present, it will override google.firebase.fcm.v1.Message.data.
	// An object containing a list of "key": value pairs.
	// Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
	Data map[string]string `json:"data,omitempty"`
	// Notification to send to android devices.
	Notification *AndroidNotification `json:"notification,omitempty"`
}

AndroidConfig represents android specific options for messages sent through FCM connection server.

type AndroidMessagePriority

type AndroidMessagePriority string

AndroidMessagePriority represents the priority of a message to send to Android devices.

var (
	// AndroidNormalPriority is the default priority for data messages. Normal priority messages won't open network connections on
	// a sleeping device, and their delivery may be delayed to conserve the battery. For less
	// time-sensitive messages, such as notifications of new email or other data to sync, choose normal
	// delivery priority.
	AndroidNormalPriority AndroidMessagePriority = "normal"

	// AndroidHighPriority is the default priority for notification messages. FCM attempts to deliver high priority
	// messages immediately, allowing the FCM service to wake a sleeping device when possible and open a
	// network connection to your app server. Apps with instant messaging, chat, or voice call alerts,
	// for example, generally need to open a network connection and make sure FCM delivers the message
	// to the device without delay. Set high priority if the message is time-critical and requires the
	// user's immediate interaction, but beware that setting your messages to high priority contributes
	// more to battery drain compared with normal priority messages.
	AndroidHighPriority AndroidMessagePriority = "high"
)

type AndroidNotification

type AndroidNotification struct {
	// The notification's title. If present, it will override
	// google.firebase.fcm.v1.Notification.title
	Title string `json:"title,omitempty"`

	// The notification's body text. If present, it will override
	// google.firebase.fcm.v1.Notification.body.
	Body string `json:"body,omitempty"`

	// The notification's icon. Sets the notification icon to myicon
	// for drawable resource myicon. If you don't send this key in
	// the request, FCM displays the launcher icon specified in your
	// app manifest.
	Icon string `json:"icon,omitempty"`

	// The sound to play when the device receives the notification.
	// Supports "default" or the filename of a sound resource bundled
	// in the app. Sound files must reside in /res/raw/.
	Sound string `json:"sound,omitempty"`

	// Identifier used to replace existing notifications in the
	// notification drawer. If not specified, each request creates
	// a new notification. If specified and a notification with the
	// same tag is already being shown, the new notification
	// replaces the existing one in the notification drawer.
	Tag string `json:"tag,omitempty"`

	// The notification's icon color, expressed in #rrggbb format.
	Color string `json:"color,omitempty"`

	// The action associated with a user click on the notification.
	// If specified, an activity with a matching intent filter is
	// launched when a user clicks on the notification.
	ClickAction string `json:"click_action,omitempty"`

	// The key to the body string in the app's string resources to
	// use to localize the body text to the user's current localization.
	BodyLocKey string `json:"body_loc_key,omitempty"`

	// Variable string values to be used in place of the format specifiers
	// in body_loc_key to use to localize the body text to the user's
	// current localization.
	BodyLocArgs []string `json:"body_loc_args,omitempty"`

	// The key to the title string in the app's string resources to use to
	// localize the title text to the user's current localization.
	TitleLocKey string `json:"title_loc_key,omitempty"`

	// Variable string values to be used in place of the format specifiers
	// in title_loc_key to use to localize the title text to the user's
	// current localization.
	TitleLocArgs []string `json:"title_loc_args,omitempty"`
}

AndroidNotification represents a notification to send to android devices.

type ApnsAlert

type ApnsAlert struct {
	// A short string describing the purpose of the notification.
	// Apple Watch displays this string as part of the notification interface.
	// This string is displayed only briefly and should be crafted so that
	// it can be understood quickly. This key was added in iOS 8.2.
	Title string `json:"title,omitempty"`

	// The text of the alert message.
	Body string `json:"body,omitempty"`

	// The key to a title string in the Localizable.strings file for the current
	// localization. The key string can be formatted with %@ and %n$@ specifiers
	// to take the variables specified in the title-loc-args array.
	TitleLocKey string `json:"title-loc-key,omitempty"`

	// Variable string values to appear in place of the format specifiers in title-loc-key.
	TitleLocArgs []string `json:"title-loc-args,omitempty"`
	// If a string is specified, the system displays an alert that includes
	// the Close and View buttons. The string is used as a key to get a
	// localized string in the current localization to use for the right button’s
	// title instead of “View”.
	ActionLocKey string `json:"action-loc-key,omitempty"`

	// A key to an alert-message string in a Localizable.strings file for the current
	// localization (which is set by the user’s language preference). The key string
	// can be formatted with %@ and %n$@ specifiers to take the variables specified in
	// the loc-args array.
	LocKey string `json:"loc-key,omitempty"`

	// Variable string values to appear in place of the format specifiers in loc-key.
	LocArgs []string `json:"loc-args,omitempty"`

	// The filename of an image file in the app bundle, with or without the filename
	// extension. The image is used as the launch image when users tap the action button
	// or move the action slider. If this property is not specified, the system either uses
	// the previous snapshot, uses the image identified by the UILaunchImageFile key in the
	//  app’s Info.plist file, or falls back to Default.png.
	LaunchImage string `json:"launch-image,omitempty"`
}

ApnsAlert represents a APNS alert

type ApnsConfig

type ApnsConfig struct {
	Headers *ApnsHeaders           `json:"headers,omitempty"`
	Payload map[string]interface{} `json:"payload,omitempty"`
}

ApnsConfig represents Apple Push Notification Service specific options.

type ApnsContentAvailability

type ApnsContentAvailability int

ApnsContentAvailability represents the content-available key in a APNS notification which may wither be 1 or 0.

const (
	// ApnsContentUnavailable flags the notification to be delievered directly to the user
	// without first waking your app up.
	ApnsContentUnavailable ApnsContentAvailability = 0

	// ApnsContentAvailable flags the notification to be delivered to the user’s device in the background.
	// iOS wakes up your app in the background and gives it up to 30 seconds to run.
	ApnsContentAvailable ApnsContentAvailability = 1
)

type ApnsHeaders

type ApnsHeaders struct {

	// If this value is nonzero, APNs stores the notification and tries to deliver it at least
	// once, repeating the attempt as needed if it is unable to deliver the notification the
	// first time. If the value is 0, APNs treats the notification as if it expires immediately
	// and does not store the notification or attempt to redeliver it.
	Expiration string `json:"apns-expiration,omitempty"`

	// If you omit this header, the APNs server sets the priority to 10.
	Priority string `json:"apns-priority,omitempty"`

	// If you are using a provider token instead of a certificate, you must specify a value for
	// this request header. The topic you provide should be provisioned for the your team named
	// in your developer account.
	Topic string `json:"apns-topic,omitempty"`

	// Multiple notifications with the same collapse identifier are displayed to the user as
	//  a single notification. The value of this key must not exceed 64 bytes.
	CollapseID string `json:"apns-collapse-id,omitempty"`
}

ApnsHeaders represents a collection of APNS headers

type ApnsMessagePriority

type ApnsMessagePriority string

ApnsMessagePriority represents the priority of the notification. Specify one of the following values:

var (
	// ApnsNormalPriority sends the push message at a time that takes into account power considerations
	// for the device. Notifications with this priority might be grouped and delivered
	// in bursts. They are throttled, and in some cases are not delivered.
	ApnsNormalPriority ApnsMessagePriority = "5"

	// ApnsHighPriority sends the push message immediately. Notifications with this priority
	// must trigger an alert, sound, or badge on the target device. It is an error
	// to use this priority for a push notification that contains only the
	// content-available key.
	ApnsHighPriority ApnsMessagePriority = "10"
)

type ApnsPayload

type ApnsPayload struct {
	Aps *ApsDictionary `json:"aps,omitempty"`
}

ApnsPayload defines an APNS notification.

func (*ApnsPayload) MustToMap

func (payload *ApnsPayload) MustToMap() map[string]interface{}

MustToMap converts a ApnsPayload struct to a map[string]interface{}. It exits the program is this operation fails.

func (*ApnsPayload) ToMap

func (payload *ApnsPayload) ToMap() (map[string]interface{}, error)

ToMap converts a ApnsPayload struct to a map[string]interface{}. It also returns an error if the operation fails.

type ApsDictionary

type ApsDictionary struct {
	// Include this key when you want the system to display a standard
	// alert or a banner. The notification settings for your app on
	// the user’s device determine whether an alert or banner is displayed.
	Alert *ApnsAlert `json:"alert,omitempty"`

	// Include this key when you want the system to modify the badge of
	// your app icon. If this key is not included in the dictionary,
	// the badge is not changed. To remove the badge, set the value of this key to 0.
	Badge int `json:"badge,omitempty"`

	// Include this key when you want the system to play a sound. The value of
	// this key is the name of a sound file in your app’s main bundle or in the
	// Library/Sounds folder of your app’s data container. If the sound file
	// cannot be found, or if you specify defaultfor the value, the system plays
	// the default alert sound.
	Sound string `json:"sound,omitempty"`

	// Provide this key with a string value that represents the notification’s type.
	// This value corresponds to the value in the "identifier" property of one of
	// your app’s registered categories.
	Category string `json:"category,omitempty"`

	// Provide this key with a string value that represents the app-specific identifier
	// for grouping notifications. If you provide a Notification Content app extension,
	// you can use this value to group your notifications together.
	ThreadID string `json:"thread-id,omitempty"`

	// Include this key with a value of 1 to configure a background update notification.
	// When this key is present, the system wakes up your app in the background and
	// delivers the notification to its app delegate.
	ContentAvailable int `json:"content-available,omitempty"`

	// The notification service app extension flag. If the value is 1, the system passes
	// the notification to your notification service app extension before delivery.
	// Use your extension to modify the notification’s content.
	MutableContent int `json:"mutable-content,omitempty"`
}

ApsDictionary defines an APNS notification.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client abstracts the interaction between the application server and the FCM server via HTTP protocol. The developer must obtain a service account private key in JSON and the Firebase project id from the Firebase console and pass it to the `Client` so that it can perform authorized requests on the application server's behalf.

func NewClient

func NewClient(projectID string, jsonKey []byte, opts ...Option) (*Client, error)

NewClient creates new Firebase Cloud Messaging Client based on a service account JSON key file.

func (*Client) Send

func (c *Client) Send(req *SendRequest) (*Message, error)

Send sends a message to the FCM server.

type HttpError

type HttpError struct {
	RequestDump  string
	ResponseDump string
	Err          error
}

HttpError contains the dump of the request and response for debugging purposes.

func (HttpError) Error

func (fcmError HttpError) Error() string

type Message

type Message struct {
	// The identifier of the message sent, in the format of projects/*/messages/{message_id}.
	Name string `json:"name,omitempty"`

	// Registration token to send a message to.
	Token string `json:"token,omitempty"`

	// Topic name to send a message to, e.g. "weather". Note: "/topics/" prefix should not be provided.
	Topic string `json:"topic,omitempty"`

	// Condition to send a message to, e.g. "'foo' in topics && 'bar' in topics".
	Condition string `json:"condition,omitempty"`

	// Apple Push Notification Service specific options.
	Apns *ApnsConfig `json:"apns,omitempty"`

	// Webpush protocol options.
	Webpush *WebpushConfig `json:"webpush,omitempty"`

	// Android specific options for messages sent through FCM connection server.
	Android *AndroidConfig `json:"android,omitempty"`

	// Basic notification template to use across all platforms.
	Notification *Notification `json:"notification,omitempty"`

	// Arbitrary key/value payload.
	// An object containing a list of "key": value pairs.
	// Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
	Data map[string]string `json:"data,omitempty"`
}

Message represents list of targets, options, and payload for HTTP JSON messages.

func (Message) MessageID

func (msg Message) MessageID() string

MessageID returns the message id the successful send request.

func (*Message) Validate

func (msg *Message) Validate() error

Validate returns an error if the message is not well-formed.

type Notification

type Notification struct {
	// The notification's title.
	Title string `json:"title,omitempty"`

	// The notification's body text.
	Body string `json:"body,omitempty"`
}

Notification specifies the basic notification template to use across all platforms.

type Option

type Option func(*Client) error

Option configurates Client with defined option.

func WithEndpoint

func WithEndpoint(endpoint string) Option

WithEndpoint returns Option to configure FCM Endpoint.

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) Option

WithHTTPClient returns Option to configure HTTP Client.

type SendRequest

type SendRequest struct {
	// Flag for testing the request without actually delivering the message.
	ValidateOnly bool `json:"validate_only,omitempty"`
	// Message to send.
	Message *Message `json:"message,omitempty"`
}

SendRequest has a flag for testing and the actual message to send.

type WebpushConfig

type WebpushConfig struct {

	// An object containing a list of "key": value pairs.
	// Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
	Headers map[string]string `json:"headers,omitempty"`

	// An object containing a list of "key": value pairs.
	// Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
	Data map[string]string `json:"data,omitempty"`

	// A web notification to send.
	Notification *WebpushNotification `json:"notification,omitempty"`
}

WebpushConfig represents the Webpush protocol outlined in https://tools.ietf.org/html/rfc8030 https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#WebpushConfig

type WebpushNotification

type WebpushNotification struct {
	// The notification's title. If present, it will override
	// google.firebase.fcm.v1.Notification.title.
	Title string `json:"title,omitempty"`

	// The notification's body text. If present, it will override
	// google.firebase.fcm.v1.Notification.body.
	Body string `json:"body,omitempty"`

	// The URL to use for the notification's icon.
	Icon string `json:"icon,omitempty"`
}

WebpushNotification represents a web notification to send via webpush protocol. https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#AndroidNotification

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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