diff --git a/README.md b/README.md index b23bde1..bda9932 100644 --- a/README.md +++ b/README.md @@ -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: . +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: . ```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] diff --git a/index.d.ts b/index.d.ts index 37a1839..1911e95 100644 --- a/index.d.ts +++ b/index.d.ts @@ -10,7 +10,7 @@ declare class Pusher { channel: string | Array, event: string, data: any, - socketId?: string + params?: Pusher.TriggerParams ): Promise trigger( @@ -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 = diff --git a/lib/events.js b/lib/events.js index ae9434e..573ecdd 100644 --- a/lib/events.js +++ b/lib/events.js @@ -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 { @@ -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 }) } diff --git a/lib/pusher.js b/lib/pusher.js index 2778a68..384763d 100644 --- a/lib/pusher.js +++ b/lib/pusher.js @@ -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 @@ -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 @@ -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) { diff --git a/tests/integration/pusher/trigger.js b/tests/integration/pusher/trigger.js index 0deecbd..652f33e 100644 --- a/tests/integration/pusher/trigger.js +++ b/tests/integration/pusher/trigger.js @@ -99,7 +99,7 @@ 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 @@ -107,18 +107,23 @@ 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=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) }) @@ -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) }) @@ -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) }) @@ -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")