Develop a Function
Introduction
- PubNub provides integrations with popular services through the Integration Catalog.
- Functions are implemented as a JavaScript module with a default export function. Guidelines to write code for each event type are documented here.
- PubNub provides libraries to assist in your Functions development.
- Asynchronous operations in PubNub Functions are handled through Promises. Refer to Promises.
- You can chain up to 5 functions to execute consecutively. Refer to Chaining Functions.
Development Guidelines
Code Structure
All Event Types except the On Request should have the following structure:
export default (request) => {
// Your business logic here
return request.ok();
// request.abort(); to fail execution
};
For all Event Types except On Request and On Interval, the request
object has two methods ok()
and abort()
. response
object isn't available. For detailed attributes refer to On Request and On Interval.
On Request
The On Request function should have the following structure:
export default (request, response) => {
// Your code here
return response.send();
};
For the On Request event type, the request
object has only one method json()
, a response
object only has send()
. For detailed attributes refer to On Request.
On Interval
The On Interval function should have the following structure:
export default (event) => {
// Your code here
return event.ok();
};
For the On Interval event type, the event
object has only one method ok()
. For detailed attributes refer to On Interval Inputs/Outputs.
Promises
Asynchronous operations in PubNub Functions are handled via Promises based on ES6 Promise standards. promise
is implicitly available to every Function.
const Promise = require('promise'); // No need to add this line
Learn more
Learn more about Promise and Promise.all()
Promise.all()
You can leverage the Promise.all() for parallel execution of multiple asynchronous functions.
Take the following example where we fetch a user name from the KV Store and fetch an IP address for that user from an external web service. When both are available (and not before), the logic to update the request object will execute.
export default (request) => {
const store = require('kvstore');
const xhr = require("xhr");
const fullName = store.get('fullName');
const ipAddress = xhr.fetch("https://httpbin.org/ip");
return Promise.all([fullName, ipAddress])
.then((values) => {
request.message.fullNameResult = values[0];
request.message.ip = JSON.parse(values[1].body).origin;
return request.ok();
})
.catch((err) => {
console.log(err);
return request.abort(err);
});
};
Libraries
The PubNub Functions runtime provides custom built-in libraries to support functionality not found natively as part of the JavaScript language.
A library can be imported using the require()
method.
const xhr = require(xhr); // Example of importing a library
The following libraries are available in PubNub Functions:
Library Name | Description |
---|---|
XHR | The XHR library is used to enable the developer to send HTTP or HTTPS requests to a remote web server and load the response data back into a Function. This library is perfect for third-party authentication or triggering webhooks from a Function. |
KV Store | This library allows access to the KV store . It's a persistent key value store that acts as a database for your PubNub Functions . The KV store database is globally distributed and eventually consistent. Data in the KV store is shared at a subscribe key level. |
Advanced Math | Global (lat-long) coordinate and geometry functions. |
Crypto | The Crypto library provides encryption and decryption functionality in an Function. |
Utils | Simple utility functions that didn't belong anywhere else. |
Codec/auth | Provides an encoder for HTTP basic auth credentials. |
Codec/base64 | Provides an encoder and decoder for Base64 strings. |
Codec/query_string | Provides an encoder and decoder for URI query parameters. |
PubNub | The PubNub library allows you to leverage many of the client SDK features supported by the PubNub Platform. |
vault | Read-only database to retrieve secrets. |
Note
Some JavaScript features that you may expect to see, but aren't yet available in Functions:
- Native node modules
- async/await
- Access to process and some other global variables
- Ability to install third-party modules via npm
Webhooks On Request
You can use an on Request event type to create webhooks.
Let's take an example to learn how On Request can be used to create webhooks. Let's say that you want to check whether the given username already exists in the database or not. For this, let's assume that a username
is passed as a query parameter to the webhook.
The following code shows how you can extract the passed username from the query parameter and checks whether it already exists in the database or not.
export default (request, response) => { const db = require('kvstore'); const username = request.params.username; return db.get(username).then((dataFromDb) => { if (!dataFromDb) { console.log('The username does not exist.'); db.set(username, {}); response.status = 200; return response.send('Username is available'); } else { console.log('The username already exists.'); response.status = 409; return response.send('Username already exists'); } }); };
Click Save.
Click Restart Module.
We're done! You can test the function from the HTTP client on the left side.
Chaining
PubNub Functions can be linked to execute in sequential way or depending on a specific condition. It's done using the pubnub.publish()
, pubnub.signal()
or the pubnub.triggerRequestFunction()
methods. In the below examples, we have used pubnub.publish()
but the same is applicable to the other two methods.
Tip
It's recommended that functions that you would like to chain with each other are in the same Module, so it's easier to start/stop their execution.
Chain Functions
Let's take an example, you want to capture a publish messages sent on hello-world, and send it to your hello-logger
function.
Create an On Before Publish or Fire "hello-logger" function:
export default (request) => { console.log(request) // show what we have inside return request.ok() // done };
Create an On Before Publish or Fire
hello-world
functionexport default (request) => { const pubnub = require('pubnub'); pubnub.publish({ "channel": "hello-logger", "message":request.message }).then((publishResponse) => { console.log(`Publish Status: ${publishResponse[0]}:${publishResponse[1]} with TT ${publishResponse[2]}`); }).catch((err) => { console.error(err); }); return request.ok(); // Return a promise when you're done };
Click Save.
Click Restart Module.
Open a debug console tab on your browser to http://www.pubnub.com/docs/console/
Enter hello_world, hello-logger for the channel in the debug console.
Click Subscribe.
Back on the PubNub Functions screen, click Publish on the test payload.
Fork Functions
Let's take an example, you want to capture a publish messages sent on hello-world, edit the message to include "Hello": "World"
and would like to send the newer message to hello-universe channel along with the original hello-world channel.
Create a new Before Publish or Fire Function with:
export default (request) => { const db = require('kvstore'); const pubnub = require('pubnub'); console.log('The message ', request.message, ' was published on ', request.channels[0], ' via ', request.meta.clientip); request.message.hello = 'world!'; // augment hello = world // To fork return pubnub.publish and include request.ok in the .then() return pubnub.publish({ "channel": "hello_universe", "message": request.message }).then((publishResponse) => { console.log(`Publish Status: ${publishResponse[0]}:${publishResponse[1]} with TT ${publishResponse[2]}`); return request.ok(); }).catch((err) => { console.error(err); }); // To chain functions make pubnub.publish a synchronous operation. Meaning dont return the pubnub.publish, let pubnub publish // the message and then only `return` request.ok(). // pubnub.publish({ // "channel": "hello-logger", // "message":request.message // }).then((publishResponse) => { // console.log(`Publish Status: ${publishResponse[0]}:${publishResponse[1]} with TT ${publishResponse[2]}`); // }).catch((err) => { // console.error(err); // }); // return request.ok(); };
Click Save.
Click Restart Module.
Open a debug console tab on your browser to http://www.pubnub.com/docs/console/
Enter hello-world, hello-universe for the channel in the debug console.
Click Subscribe.
Back on the PubNub Functions screen, click Publish on the test payload.
Avoid infinite loops: You can chain/fork publishes across as many channels as you wish, however it's important not to create a scenario where an infinite loop is possible (for example, publishing to A, which publishes to B, which Publishes back to A.) The system is designed to detect and not allow infinite loops to happen, however, it's important to take care that your logic also doesn't encourage or rely on this behavior.
Recursion limit
The maximum recursion limit you can do is 3
hops from one Function to another: using publish
or fire
, you can execute a maximum of three Functions.
The combined maximum number within a single Function execution of KV store
operations, XHRs
, publish
and fire
is 3
.
Request/Response Objects
All Event Types except On Request
request
Methods
Method | Arguments | Description |
---|---|---|
ok | message:String (Optional) | Returns a promise that resolves to the value of the request object. |
abort | message:String (Optional) | Returns a promise that resolves to the value of the request object, with an error code. |
request
Attributes
Attribute | Type | Definition |
---|---|---|
message | Object | The actual user message sent to the channel. |
verb | String | Method used by the publishing client when sending the message to PubNub. |
pubkey | String | The Publish Key used when sending the message. |
subkey | String | The Subscribe Key to retrieve the message. |
channels | Array | The list of channels on which the message was sent on. |
version | String | API Version. |
meta.clientip | String | IP of the publishing client. |
meta.origin | String | Origin defined on the publishing client. |
meta.useragent | String | The Publishing client's useragent string. |
params | Object | URL Parameters made on the request. |
uri | String | The URI of the request. |
On Request Inputs/Outputs
request
Attributes
Attribute | Type | Definition |
---|---|---|
verb | String | Method used by the publishing client when sending the message to PubNub. Always set to rest . |
pubkey | String | The Publish Key used when sending the message. |
subkey | String | The Subscribe Key to retrieve the message. |
version | String | API Version. |
meta.clientip | String | IP of the publishing client. |
meta.origin | String | Origin defined on the publishing client. |
meta.useragent | String | The Publishing client's useragent string. |
params | Object | URL Parameters made on the request. |
uri | String | The full path of the URI of the request minus PubNub hostname information. |
path | String | The path minus PubNub and key specific information. This is the path configured, by you, for the Function itself. |
method | String | The HTTP method of the request, such as GET, PUT, POST, DELETE. |
body | Object | The body content if passed in the request. |
headers | Object | The header information passed in the request. |
response
Methods
Method | Arguments | Description |
---|---|---|
send | body:String (Optional) | Returns a promise that resolves to the value of the response object. |
response
Attributes
Attribute | Type | Definition |
---|---|---|
status | Object | The HTTP status code to use when returning the response to the calling application or user. |
body | Object | The body content returned to the calling application or user. |
headers | Object | Header information returned to the calling application or user. |
On Interval Inputs/Outputs
event
Methods
Method | Arguments | Description |
---|---|---|
ok | N/A | Returns a promise that resolves to the value of the response object. |
event
Attributes
Attribute | Type | Definition |
---|---|---|
verb | String | Method used by the publishing client when sending the message to PubNub. Always set to interval . |
pubkey | String | The Publish Key used when sending the message. |
subkey | String | The Subscribe Key to retrieve the message. |
execInterval | Number | Duration of the interval specified for the function, in milliseconds. |
lastTimestamp | Number | Timestamp of last function execution. |
timestamp | Number | Timestamp of current function execution. |