azurepush

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

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

Go to latest
Published: Mar 27, 2025 License: MIT Imports: 18 Imported by: 0

README

azurepush

build status

Go client for Azure Notification Hubs (iOS + Android) with dynamic SAS authentication.

✨ Features

  • ✅ Device registration (iOS + Android)
  • ✅ Push notification sending with per-user tagging
  • ✅ Auto-refreshing SAS token generation
  • ✅ YAML config loading (with support for full connection strings)
  • ✅ Single unified client struct with minimal boilerplate

☁️ Azure Setup

1. Create a Notification Hub
  • Azure Portal → Create ResourceNotification Hub
  • Create or choose an existing Namespace (e.g. mynamespace)
  • Create a Hub inside it (e.g. myhubname)
2. Get Access Credentials
  • In Azure Portal → Your Notification Hub → Access Policies
  • Click DefaultFullSharedAccessSignature (or create your own)
  • Copy the Connection String, which looks like:
Endpoint=sb://mynamespace.servicebus.windows.net/;
SharedAccessKeyName=DefaultFullSharedAccessSignature;
SharedAccessKey=YOUR_SECRET_KEY
🔍 Azure Notification Hubs vs AWS SNS: Device Management Capabilities

The table below compares the core device management and introspection features between AWS SNS and Azure Notification Hubs:

Task AWS SNS ✅ Azure Notification Hubs ❌
List all devices ✅ Yes ❌ No
Browse per-user endpoints ✅ Yes ❌ No
Store/send custom metadata ✅ Yes ✅ Yes (via tags or payload)
View registrations in UI ✅ Yes ❌ No
Delete devices by user ✅ Yes ❌ (You must track them)
Send to user/group ✅ Yes (topic/endpoint) ✅ Yes (tags)

SNS is both:

  • A messaging bus
  • A device registry (platform endpoint management)

Azure Notification Hubs:

  • Delegates token management to you
  • Is intentionally stateless and write-only
  • Does not provide introspection over installations

📦 Install

go get github.com/kataras/azurepush@latest

🛠 Configuration Setup

Option 1: Use Individual Fields
# configuration.yml
HubName: "myhubname"
Namespace: "mynamespace"
KeyName: "DefaultFullSharedAccessSignature"
KeyValue: "YOUR_SECRET_KEY"
TokenValidity: "2h"
# configuration.yml
HubName: "myhubname"
ConnectionString: "Endpoint=sb://mynamespace.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=YOUR_SECRET_KEY"
TokenValidity: "2h"

The library will auto-extract Namespace, KeyName, and KeyValue from the connection string.

📱 Mobile Device Tokens

In your mobile apps:

  • For iOS (APNs), get the APNs device token
  • For Android (GCM, FCM, FCMV1), get the FCM registration token

Then send it to your backend for registration using this package.

🚀 Example Usage

package main

import (
	"github.com/kataras/azurepush"
)

func main() {
	cfg, _ := azurepush.LoadConfiguration("configuration.yml")
	client := azurepush.NewClient(*cfg)

	id, err := client.RegisterDevice(context.Background(), azurepush.Installation{
		Platform:    "gcm", // or "apns"
		PushChannel: "gcm-or-apns-token",
		Tags:        []string{"user:42"},
	})
	if err != nil {
		panic(err)
	}

	_ = client.SendNotification(context.Background(), azurepush.Notification{
		Title: "Welcome",
		Body:  "Hello from AzurePush!",
		Data: map[string]any{"key": "value"},
	}, "user:42")
}

📖 License

This software is licensed under the MIT License.

Documentation

Index

Constants

View Source
const (
	// InstallationApple is the platform type for Apple devices (iOS).
	InstallationApple = "apns"
	// InstallationGCM is the platform type for Google Cloud Messaging (deprecated).
	InstallationAndroid = "gcm"
	// InstallationGCM is the platform type for Google Cloud Messaging (deprecated).
	InstallationFCM = "fcm"
	// InstallationFCMV1 is the platform type for Firebase Cloud Messaging (V1).
	InstallationFCMV1 = "FCMV1"
	// InstallationBaidu is the platform type for Baidu Push.
	InstallationBaidu = "baidu"
	// InstallationWNS is the platform type for Windows Notification Service.
	InstallationWNS = "wns"
	// InstallationMPNS is the platform type for Microsoft Push Notification Service.
	InstallationMPNS = "mpns"
)

Installation types for Azure Notification Hubs.

Variables

View Source
var DefaultTokenValidity = time.Hour * 24 * 7

1 week.

Functions

func GenerateSASToken

func GenerateSASToken(resourceUri, keyName, key string, duration time.Duration) (string, error)

GenerateSASToken creates a Shared Access Signature (SAS) token for Azure Notification Hub.

Ported from: https://learn.microsoft.com/en-us/rest/api/eventhub/generate-sas-token#nodejs.

func ValidateSASToken

func ValidateSASToken(ctx context.Context, httpClient *http.Client, namespace, hubName, token string) error

ValidateSASToken checks if a SAS token is valid. Expecting 404 or 200 if token is valid

Types

type Client

type Client struct {
	Config       Configuration
	TokenManager *TokenManager

	// HTTPClient is the client used for HTTP requests.
	// It can be overridden for testing.
	HTTPClient *http.Client
}

Client provides a high-level interface for interacting with Azure Notification Hubs. It encapsulates configuration and token management, and offers methods for device registration, existence checking, and push notification sending without requiring the caller to manually handle SAS tokens or repeated hub information.

Example usage:

client := azurepush.NewClient(cfg)
id, err := client.RegisterDevice(context.Background(), installation)
err = client.SendNotification(context.Background(), azurepush.Notification{...}, "user:123")

func NewClient

func NewClient(cfg Configuration) *Client

NewClient creates and validates a new push notification client. NewClient creates a new Azure Notification Hub client with the given configuration. It automatically initializes a TokenManager for SAS token generation and reuse.

This method also validates and tests connectivity to the Azure Notification Hub.

Example:

client := azurepush.NewClient(azureCfg)
err := client.SendNotification(context.Background(), notification, "user:42")

func (*Client) DeleteDevice

func (c *Client) DeleteDevice(ctx context.Context, installationID string) error

DeleteDevice deletes a registered device installation from Azure Notification Hubs using its installation ID.

This operation is idempotent — if the installation does not exist, Azure will return 404, and this function will still return nil.

Example:

err := client.DeleteDevice(context.Background(), "device-uuid-123")

func (*Client) DeviceExists

func (c *Client) DeviceExists(ctx context.Context, installationID string) (bool, error)

DeviceExists checks if a device installation with the given ID exists in Azure Notification Hub. Returns true if the device is found (HTTP 200), false if not found (HTTP 404).

func (*Client) RegisterDevice

func (c *Client) RegisterDevice(ctx context.Context, installation Installation) (string, error)

RegisterDevice registers a device installation with Azure Notification Hubs. Read more at: https://learn.microsoft.com/en-us/answers/questions/1324518/sending-notification-registering-device-in-notific.

You use the tags you assign during registration to send notifications, as this is how you target specific devices. For example, if you register a device with the tag "user:123", you can send a notification to that device by targeting the "user:123" tag.

func (*Client) SendNotification

func (c *Client) SendNotification(ctx context.Context, notification Notification, tags ...string) error

SendNotification sends a cross-platform push notification to all devices for a given user (e.g. tag with "user:42").

func (*Client) ValidateToken

func (c *Client) ValidateToken(ctx context.Context) error

ValidateToken performs a simple GET request to a dummy installation ID to verify if the SAS token is valid and authorized. Returns nil if authorized (even if installation doesn't exist), or an error if unauthorized.

type Configuration

type Configuration struct {
	// HubName is the name of your Azure Notification Hub instance.
	// You can find this in the Azure Portal under your Notification Hub resource.
	// Example: "myhubname"
	HubName string `yaml:"HubName"`

	// ConnectionString is the full connection string for the Azure Notification Hub.
	// This is used to extract the Namespace, KeyName, and KeyValue.
	// Example: "Endpoint=sb://<namespace>.servicebus.windows.net/;SharedAccessKeyName=<name>;SharedAccess
	// Key=<key>"
	// ConnectionString is the full connection string for the Azure Notification Hub.
	//
	// If this field is present, the individual fields (Namespace, KeyName, KeyValue) are ignored.
	ConnectionString string `yaml:"ConnectionString"`

	// Namespace is the Azure Service Bus namespace where the Notification Hub lives.
	// This should be the prefix (without .servicebus.windows.net).
	// Example: "my-namespace"
	Namespace string `yaml:"Namespace"`

	// KeyName is the name of the Shared Access Policy with send or full access.
	// You can find this under "Access Policies" in your Notification Hub (left menu > Settings > Access Policies).
	// Example: "DefaultFullSharedAccessSignature"
	KeyName string `yaml:"KeyName"`

	// KeyValue is the primary or secondary key associated with the KeyName.
	// To get this, go to the Notification Hub > Access Policies > select your policy > copy "Primary Key".
	// You may also use the connection string to parse out these values, but we use manual fields here.
	// Example: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=="
	// KeyValue is the value of the SharedAccessKey.
	// In the Azure Portal, go to Notification Hub → Access Policies → select a policy (e.g. DefaultFullSharedAccessSignature)
	// → copy the **Connection String**. From it, extract:
	// - KeyName from `SharedAccessKeyName` (e.g. DefaultFullSharedAccessSignature)
	// - KeyValue from `SharedAccessKey`
	// Example Connection String:
	//   Endpoint=sb://<namespace>.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=YOUR_SECRET_KEY
	// Use the value of `SharedAccessKey` as KeyValue.
	KeyValue string `yaml:"KeyValue"`

	// TokenValidity is how long each generated SAS token should remain valid.
	// It must be a valid Go duration string (e.g., "1h", "30m").
	// Example: 2 * time.Hour
	//
	// Defaults to 1 week.
	TokenValidity time.Duration `yaml:"TokenValidity"`

	// ConnectivityCheck enables the connectivity check.
	// If enabled, the NewClient will check the connection to the Azure Notification Hub before sending messages.
	//
	// Defaults to false.
	ConnectivityCheck bool `yaml:"ConnectivityCheck"`
}

Configuration holds Azure Notification Hub credentials and settings.

The Validate method MUST be called after loading the configuration to ensure all required fields are present.

func LoadConfiguration

func LoadConfiguration(path string) (*Configuration, error)

LoadConfiguration loads a YAML config from the given path.

func (*Configuration) Validate

func (cfg *Configuration) Validate() error

Validate checks the AzureConfig for required fields. It also parses the connection string if available. If the connection string is present, it will override the individual fields.

type Installation

type Installation struct {
	// InstallationID is a unique identifier for the installation (usually a device ID or UUID).
	// This is used to update or delete installations.
	InstallationID string `json:"installationId"`

	// Platform is the platform type for the device.
	// Valid values: "apns" for iOS and "gcm", "FCMV1" for Android.
	// Platform	| Value
	// Apple	| "apns"
	// FCM		| "gcm" or "fcm" and "FCMV1" (see https://learn.microsoft.com/en-us/azure/notification-hubs/firebase-migration-rest)
	// Baidu	| "baidu"
	// WNS		| "wns"
	// MPNS		| "mpns"
	Platform string `json:"platform"`

	// PushChannel is the device-specific token to receive notifications.
	// For APNs: the device token from Apple.
	// For FCM: the registration token from Firebase.
	// Ref: https://learn.microsoft.com/en-us/rest/api/notificationhubs/installation#pushchannel
	PushChannel string `json:"pushChannel"`

	// Tags is an optional list of tags to categorize this device.
	// These are used for targeting groups of installations (e.g., "user:123").
	Tags []string `json:"tags,omitempty"`

	// Templates defines push notification templates for the device.
	// This is optional and only needed for advanced templated notifications.
	Templates map[string]Template `json:"templates,omitempty"`
}

Installation represents a device installation for Azure Notification Hubs.

func (Installation) Validate

func (i Installation) Validate() error

Validate checks if the installation has all required fields set.

type Notification

type Notification struct {
	Title string
	Body  string
	Data  map[string]any // any custom data.
}

Notification holds the title, body and custom data for a notification sent to both iOS and Android.

type Template

type Template struct {
	Body string   `json:"body"`
	Tags []string `json:"tags,omitempty"`
}

Template is used for advanced push templates (optional).

type TokenManager

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

TokenManager manages the lifecycle of SAS tokens.

func NewTokenManager

func NewTokenManager(cfg Configuration) *TokenManager

NewTokenManager creates a new TokenManager.

func (*TokenManager) GetToken

func (tm *TokenManager) GetToken() (string, error)

GetToken returns a valid SAS token, refreshing it if necessary.

Jump to

Keyboard shortcuts

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