The Golang library for interacting with the Pusher HTTP API.
This package lets you trigger events to your client and query the state of your Pusher channels. When used with a server, you can validate Pusher webhooks and authenticate private- or presence-channels.
In order to use this library, you need to have a free account on http://pusher.com. After registering, you will need the application credentials for your app.
###Table of Contents
$ go get github.com/pusher/pusher-http-go
package main
import "github.com/pusher/pusher-http-go"
func main(){
// instantiate a client
client := pusher.Client{
AppId: "your_app_id",
Key: "your_app_key",
Secret: "your_app_secret",
}
data := map[string]string{"message": "hello world"}
// trigger an event on a channel, along with a data payload
client.Trigger("test_channel", "my_event", data)
}
The easiest way to configure the library is by creating a new Pusher
instance:
client := pusher.Client{
AppId: "your_app_id",
Key: "your_app_key",
Secret: "your_app_secret",
}
client := pusher.ClientFromURL("http://key:secret@api.pusherapp.com/apps/app_id")
client := pusher.ClientFromEnv("PUSHER_URL")
This is particularly relevant if you are using Pusher as a Heroku add-on, which stores credentials in a "PUSHER_URL"
environment variable.
To ensure requests occur over HTTPS, set the Secure
property of a pusher.Client
to true
.
client.Secure = true
This is false
by default.
If you wish to set a time-limit for each HTTP request, create a http.Client
instance with your specified Timeout
field and set it as the Pusher instance's Client
:
httpClient := &http.Client{Timeout: time.Second * 3}
pusherClient.HttpClient = httpClient
If you do not specifically set a HTTP client, a default one is created with a timeout of 5 seconds.
Changing the pusher.Client
's Host
property will make sure requests are sent to your specified host.
client.Host = "foo.bar.com"
By default, this is "api.pusherapp.com"
.
As of version 1.0.0, this library is compatible with Google App Engine's urlfetch library. Simply pass in the HTTP client returned by urlfetch.Client
to your Pusher initialization struct.
package helloworldapp
import (
"appengine"
"appengine/urlfetch"
"fmt"
"github.com/pusher/pusher-http-go"
"net/http"
)
func init() {
http.HandleFunc("/", handler)
}
func handler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
urlfetchClient := urlfetch.Client(c)
client := pusher.Client{
AppId: "app_id",
Key: "key",
Secret: "secret",
HttpClient: urlfetchClient,
}
client.Trigger("test_channel", "my_event", map[string]string{"message": "hello world"})
fmt.Fprint(w, "Hello, world!")
}
It is possible to trigger an event on one or more channels. Channel names can contain only characters which are alphanumeric, _
or `-`` and have to be at most 200 characters long. Event name can be at most 200 characters long too.
#####func (c *Client) Trigger
Argument | Description |
---|---|
channel string |
The name of the channel you wish to trigger on. |
event string |
The name of the event you wish to trigger |
data interface{} |
The payload you wish to send. Must be marshallable into JSON. |
data := map[string]string{"hello": "world"}
client.Trigger("greeting_channel", "say_hello", data)
#####func (c. *Client) TriggerMulti
Argument | Description |
---|---|
channels []string |
A slice of channel names you wish to send an event on. The maximum length is 10. |
event string |
As above. |
data interface{} |
As above. |
######Example
client.TriggerMulti([]string{"a_channel", "another_channel"}, "event", data)
func (c *Client) TriggerExclusive
and func (c *Client) TriggerMultiExclusive
follow the patterns above, except a socket_id
is given as the last parameter.
These methods allow you to exclude a recipient whose connection has that socket_id
from receiving the event. You can read more here.
######Examples
On one channel:
client.TriggerExclusive("a_channel", "event", data, "123.12")
On multiple channels:
client.TriggerMultiExclusive([]string{"a_channel", "another_channel"}, "event", data, "123.12")
Application security is very important so Pusher provides a mechanism for authenticating a user’s access to a channel at the point of subscription.
This can be used both to restrict access to private channels, and in the case of presence channels notify subscribers of who else is also subscribed via presence events.
This library provides a mechanism for generating an authentication signature to send back to the client and authorize them.
For more information see our docs.
Argument | Description |
---|---|
params []byte |
The request body sent by the client |
Return Value | Description |
---|---|
response []byte |
The response to send back to the client, carrying an authentication signature |
err error |
Any errors generated |
######Example
func pusherAuth(res http.ResponseWriter, req *http.Request) {
params, _ := ioutil.ReadAll(req.Body)
response, err := client.AuthenticatePrivateChannel(params)
if err != nil {
panic(err)
}
fmt.Fprintf(res, string(response))
}
func main() {
http.HandleFunc("/pusher/auth", pusherAuth)
http.ListenAndServe(":5000", nil)
}
Using presence channels is similar to private channels, but in order to identify a user, clients are sent a user_id and, optionally, custom data.
Argument | Description |
---|---|
params []byte |
The request body sent by the client |
member pusher.MemberData |
A struct representing what to assign to a channel member, consisting of a UserId and any custom UserInfo . See below |
pusher.MemberData
type MemberData struct {
UserId string
UserInfo map[string]string
}
params, _ := ioutil.ReadAll(req.Body)
presenceData := pusher.MemberData{
UserId: "1",
UserInfo: map[string]string{
"twitter": "jamiepatel",
},
}
response, err := client.AuthenticatePresenceChannel(params, presenceData)
if err != nil {
panic(err)
}
fmt.Fprintf(res, response)
This library allows you to query our API to retrieve information about your application's channels, their individual properties, and, for presence-channels, the users currently subscribed to them.
Argument | Description |
---|---|
additionalQueries map[string]string |
A map with query options. A key with "filter_by_prefix" will filter the returned channels. To get number of users subscribed to a presence-channel, specify an "info" key with value "user_count" . Pass in nil if you do not wish to specify any query attributes. |
Return Value | Description |
---|---|
channels *pusher.ChannelsList |
A struct representing the list of channels. See below. |
err error |
Any errors encountered |
pusher.ChannelsList
type ChannelsList struct {
Channels map[string]ChannelListItem
}
pusher.ChannelsListItem
type ChannelListItem struct {
UserCount int
}
######Example
channelsParams := map[string]string{
"filter_by_prefix": "presence-",
"info": "user_count",
}
channels, err := client.Channels(channelsParams)
//channels=> &{Channels:map[presence-chatroom:{UserCount:4} presence-notifications:{UserCount:31} ]}
Argument | Description |
---|---|
name string |
The name of the channel |
additionalQueries map[string]string |
A map with query options. An "info" key can have comma-separated vales of "user_count" , for presence-channels, and "subscription_count" , for all-channels. Note that the subscription count is not allowed by default. Please contact us if you wish to enable this.Pass in nil if you do not wish to specify any query attributes. |
Return Value | Description |
---|---|
channel *pusher.Channel |
A struct representing a channel. See below. |
err error |
Any errors encountered |
######Custom Types
pusher.Channel
type Channel struct {
Name string
Occupied bool
UserCount int
SubscriptionCount int
}
channelParams := map[string]string{
"info": "user_count,subscription_count",
}
channel, err := client.Channel("presence-chatroom", channelParams)
//channel=> &{Name:presence-chatroom Occupied:true UserCount:42 SubscriptionCount:42}
Argument | Description |
---|---|
name string |
The channel name |
Return Value | Description |
---|---|
users *pusher.Users |
A struct representing a list of the users subscribed to the presence-channel. See below |
err error |
Any errors encountered. |
pusher.Users
type Users struct {
List []User
}
pusher.User
type User struct {
Id string
}
users, err := client.GetChannelUsers("presence-chatroom")
//users=> &{List:[{Id:13} {Id:90}]}
On your dashboard, you can set up webhooks to POST a payload to your server after certain events. Such events include channels being occupied or vacated, members being added or removed in presence-channels, or after client-originated events. For more information see https://pusher.com/docs/webhooks.
This library provides a mechanism for checking that these POST requests are indeed from Pusher, by checking the token and authentication signature in the header of the request.
Argument | Description |
---|---|
header http.Header |
The header of the request to verify |
body []byte |
The body of the request |
Return Value | Description |
---|---|
webhook *pusher.Webhook |
If the webhook is valid, this method will return a representation of that webhook that includes its timestamp and associated events. If invalid, this value will be nil . |
err error |
If the webhook is invalid, an error value will be passed. |
pusher.Webhook
type Webhook struct {
TimeMs int
Events []WebhookEvent
}
pusher.WebhookEvent
type WebhookEvent struct {
Name string
Channel string
Event string
Data string
SocketId string
}
func pusherWebhook(res http.ResponseWriter, req *http.Request) {
body, _ := ioutil.ReadAll(req.Body)
webhook, err := client.Webhook(req.Header, body)
if err != nil {
fmt.Println("Webhook is invalid :(")
} else {
fmt.Printf("%+v\n", webhook.Events)
}
}
Feature | Supported |
---|---|
Trigger event on single channel | ✔ |
Trigger event on multiple channels | ✔ |
Excluding recipients from events | ✔ |
Authenticating private channels | ✔ |
Authenticating presence channels | ✔ |
Get the list of channels in an application | ✔ |
Get the state of a single channel | ✔ |
Get a list of users in a presence channel | ✔ |
WebHook validation | ✔ |
Heroku add-on support | ✔ |
Debugging & Logging | ✔ |
Cluster configuration | ✔ |
Timeouts | ✔ |
HTTPS | ✔ |
HTTP Proxy configuration | ✘ |
HTTP KeepAlive | ✘ |
These are helpers that have been implemented to to ensure interactions with the HTTP API only occur if they will not be rejected e.g. channel naming conventions.
Helper Functionality | Supported |
---|---|
Channel name validation | ✔ |
Limit to 10 channels per trigger | ✔ |
Limit event name length to 200 chars | ✔ |
Feel more than free to fork this repo, improve it in any way you'd prefer, and send us a pull request :)
Simply type:
$ go test
This code is free to use under the terms of the MIT license.