Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 73 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,81 @@ You can trigger a batch of up to 10 events.

### Excluding event recipients

In order to avoid the client that triggered the event from also receiving it, the `trigger` function takes an optional `socketId` parameter. For more informaiton see: <http://pusher.com/docs/publisher_api_guide/publisher_excluding_recipients>.
In order to avoid the client that triggered the event from also receiving it, a `socket_id` parameter can be added to the `params` object. For more information see: <http://pusher.com/docs/publisher_api_guide/publisher_excluding_recipients>.

```javascript
const socketId = "1302.1081607"
pusher.trigger(channel, event, data, socketId)
pusher.trigger(channel, event, data, { socket_id: "1302.1081607" })

pusher.triggerBatch([
{ channel: channel, name: name, data: data, socket_id: "1302.1081607" },
])
```

### Fetch subscriber and user counts at the time of publish [[EXPERIMENTAL](https://pusher.com/docs/lab#experimental-program)]

For the channels that were published to, you can request for the number of subscribers or user to be returned in the response body.

#### Regular triggering

```javascript
pusher
.trigger("presence-my-channel", "event", "test", { info: "user_count,subscription_count" })
.then(response => {
if (response.status !== 200) {
throw Error("unexpected status")
}
// Parse the response body as JSON
return response.json()
)
.then(body => {
const channelsInfo = body.channels
// Do something with channelsInfo
})
.catch(error => {
// Handle error
})
```

#### Batch triggering

```javascript
const batch = [
{
channel: "my-channel",
name: "event",
data: "test1",
info: "subscription_count",
},
{
channel: "presence-my-channel",
name: "event",
data: "test2",
info: "user_count,subscription_count",
},
]
pusher
.triggerBatch(batch)
.then((response) => {
if (response.status !== 200) {
throw Error("unexpected status")
}
// Parse the response body as JSON
return response.json()
})
.then((body) => {
body.batch.forEach((attributes, i) => {
process.stdout.write(
`channel: ${batch[i].channel}, name: ${batch[i].name}, subscription_count: ${attributes.subscription_count}`
)
if ("user_count" in attributes) {
process.stdout.write(`, user_count: ${attributes.user_count}`)
}
process.stdout.write("\n")
})
})
.catch((error) => {
console.error(error)
})
```

### End-to-end encryption [BETA]
Expand Down
9 changes: 8 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ declare class Pusher {
channel: string | Array<string>,
event: string,
data: any,
socketId?: string
params?: Pusher.TriggerParams
): Promise<Response>

trigger(
Expand Down Expand Up @@ -61,10 +61,17 @@ declare namespace Pusher {

export type Options = ClusterOptions | HostOptions

export interface TriggerParams {
socket_id?: string
info?: string
}

export interface BatchEvent {
channel: string
name: string
data: any
socket_id?: string
info?: string
}

type ReservedParams =
Expand Down
10 changes: 3 additions & 7 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,14 @@ function encrypt(pusher, channel, data) {
})
}

exports.trigger = function (pusher, channels, eventName, data, socketId) {
exports.trigger = function (pusher, channels, eventName, data, params) {
if (channels.length === 1 && util.isEncryptedChannel(channels[0])) {
const channel = channels[0]
const event = {
name: eventName,
data: encrypt(pusher, channel, data),
channels: [channel],
}
if (socketId) {
event.socket_id = socketId
...params,
}
return pusher.post({ path: "/events", body: event })
} else {
Expand All @@ -49,9 +47,7 @@ exports.trigger = function (pusher, channels, eventName, data, socketId) {
name: eventName,
data: ensureJSON(data),
channels: channels,
}
if (socketId) {
event.socket_id = socketId
...params,
}
return pusher.post({ path: "/events", body: event })
}
Expand Down
16 changes: 10 additions & 6 deletions lib/pusher.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,14 @@ Pusher.prototype.authenticate = function (socketId, channel, data) {
* @param {String|String[]} channel list of at most 100 channels
* @param {String} event event name
* @param data event data, objects are JSON-encoded
* @param {String} [socketId] id of a socket that should not receive the event
* @param {Object} [params] additional optional request body parameters
* @param {String} [params.socket_id] id of a socket that should not receive the event
* @param {String} [params.info] a comma separate list of attributes to be returned in the response. Experimental, see https://pusher.com/docs/lab#experimental-program
* @see RequestError
*/
Pusher.prototype.trigger = function (channels, event, data, socketId) {
if (socketId) {
validateSocketId(socketId)
Pusher.prototype.trigger = function (channels, event, data, params) {
if (params && params.socket_id) {
validateSocketId(params.socket_id)
}
if (!(channels instanceof Array)) {
// add single channel to array for multi trigger compatibility
Expand All @@ -150,7 +152,7 @@ Pusher.prototype.trigger = function (channels, event, data, socketId) {
for (let i = 0; i < channels.length; i++) {
validateChannel(channels[i])
}
return events.trigger(this, channels, event, data, socketId)
return events.trigger(this, channels, event, data, params)
}

/* Triggers a batch of events
Expand All @@ -159,7 +161,9 @@ Pusher.prototype.trigger = function (channels, event, data, socketId) {
* {
* name: string,
* channel: string,
* data: any JSON-encodable data
* data: any JSON-encodable data,
* socket_id: [optional] string,
* info: [optional] string experimental, see https://pusher.com/docs/lab#experimental-program
* }
*/
Pusher.prototype.triggerBatch = function (batch) {
Expand Down
44 changes: 35 additions & 9 deletions tests/integration/pusher/trigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,26 +99,31 @@ describe("Pusher", function () {
.catch(done)
})

it("should add socket_id to the request body", function (done) {
it("should add params to the request body", function (done) {
nock("http://api.pusherapp.com")
.filteringPath(function (path) {
return path
.replace(/auth_timestamp=[0-9]+/, "auth_timestamp=X")
.replace(/auth_signature=[0-9a-f]{64}/, "auth_signature=Y")
})
.post(
"/apps/1234/events?auth_key=f00d&auth_timestamp=X&auth_version=1.0&body_md5=0478e1ed73804ae1be97cfa6554cf039&auth_signature=Y",
"/apps/1234/events?auth_key=f00d&auth_timestamp=X&auth_version=1.0&body_md5=2e4f053f1c325dedbe21abd8f1852b53&auth_signature=Y",
{
name: "my_event",
data: '{"some":"data "}',
channels: ["test_channel"],
socket_id: "123.567",
info: "user_count,subscription_count",
}
)
.reply(200, "{}")

const params = {
socket_id: "123.567",
info: "user_count,subscription_count",
}
pusher
.trigger("test_channel", "my_event", { some: "data " }, "123.567")
.trigger("test_channel", "my_event", { some: "data " }, params)
.then(() => done())
.catch(done)
})
Expand All @@ -131,20 +136,31 @@ describe("Pusher", function () {
.replace(/auth_signature=[0-9a-f]{64}/, "auth_signature=Y")
})
.post(
"/apps/1234/events?auth_key=f00d&auth_timestamp=X&auth_version=1.0&body_md5=cf87d666b4a829a54fc44b313584b2d7&auth_signature=Y",
"/apps/1234/events?auth_key=f00d&auth_timestamp=X&auth_version=1.0&body_md5=d3a47b3241328a6432adf60c8e91b6fb&auth_signature=Y",
{
name: "my_event",
data: '{"some":"data "}',
channels: ["test_channel"],
info: "subscription_count",
}
)
.reply(200, "OK")
.reply(200, '{"channels":{"test_channel":{"subscription_count":123}}}')

pusher
.trigger("test_channel", "my_event", { some: "data " })
.trigger(
"test_channel",
"my_event",
{ some: "data " },
{ info: "subscription_count" }
)
.then((response) => {
expect(response.status).to.equal(200)
done()
return response.text().then((body) => {
expect(body).to.equal(
'{"channels":{"test_channel":{"subscription_count":123}}}'
)
done()
})
})
.catch(done)
})
Expand Down Expand Up @@ -286,7 +302,12 @@ describe("Pusher", function () {
.reply(200, "{}")

pusher
.trigger("test_channel", "my_event", { some: "data " }, "123.567")
.trigger(
"test_channel",
"my_event",
{ some: "data " },
{ socket_id: "123.567" }
)
.then(() => done())
.catch(done)
})
Expand Down Expand Up @@ -317,7 +338,12 @@ describe("Pusher", function () {
.reply(200)

pusher
.trigger("test_channel", "my_event", { some: "data " }, "123.567")
.trigger(
"test_channel",
"my_event",
{ some: "data " },
{ socket_id: "123.567" }
)
.catch((error) => {
expect(error).to.be.a(Pusher.RequestError)
expect(error.message).to.equal("Request failed with an error")
Expand Down