Plugin services are Node.js apps with a specific structure that will be explained below. Node.js apps are lightweight Javascript apps that run on the server instead of the browser. Node.js is a popular framework with many existing 3rd party libraries available that you can re-use in your plugins.
To get started, from the Developer tools, create or edit a plugin, then add a new backend service. This will initialize your service with sample code that you should then download and unzip. The unzipped folder represents everything that makes your service.
znHttp
library for communicating with our REST API and our znFirebase
library for communicating with Firebase. You can add your own files, but do not modify existing files.requestify
for making HTTP requests and firebase
if you don’t use our znFirebase
library. You should use npm install
to install additional node modules here. Pure Javascript modules are recommended. Native modules or dependencies must be built against Amazon Linux libraries. Modules count against your service file size.The sample plugin.js will take a form ID, then query the API and return the form data to the user.
The eventData
object passed into your function is used to fetch request data from the user, including query string parameters or form post data. It is also used to send response data back to the user. In this example, eventData.request.query.id
fetches an id
paramter from the query string for the form ID. Using the included znHttp
library, it makes a request to the REST API and fetches the form by that ID. Then it uses eventData.response
to return HTTP 200 on success and sends the API response to the user.
You will also notice some error checking logic, in case the API returns an error or the user makes an invalid request.
The eventData
object contains the request and the response objects for getting data from the user and sending data to the user.
Name | Type | Description |
---|---|---|
headers | Object |
HTTP request headers |
body | Object |
HTTP POST data. Corresponds to req.body |
method | String |
GET , POST , PUT , or DELETE |
params | Object |
Contains request's workspaceId , pluginNamespace , and pluginRoute |
query | Object |
Contains query string parameters. Corresponds to req.query |
originalUrl | String |
Request URL. Corresponds to req.originalUrl |
Name | Description |
---|---|
set | Set response HTTP headers. Corresponds to res.set |
status | Set response HTTP status code. Corresponds to res.status |
send | Send response body. Corresponds to res.send |
end | Ends the response. |
znHttp is an included library for connecting to the Zengine REST API. API requests will be made as the user accessing the service. When used in conjunction with frontend plugin code, the user accessing your frontend plugin will be the user making the API requests. This means the plugin service can only access what the acting user has permission to access. When saving data, that user will be considered the “created by user.”
When using offline services and executing them by a webhook instead of the Zengine app, the user making the request will be a special “integration” user with the same permissions as the workspace admin.
Note: Services shutdown immediately when the response is sent to the user, cancelling any open HTTP requests. Because of this, the response must be sent only when all HTTP requests are completed, inside the success or error callbacks.
znFirebase is an included library for connecting to Firebase. This library is a wrapper for the official Firebase Javascript API version 2.3.1.
If you have set the Firebase URL and Firebase secret in your plugin settings, the znFirebase
will automatically initialize an instance of your Firebase and authenticate with authWithCustomToken
method, the custom token will be generated with following data:
The number 1
is the workspace id the backend service request was made against (ex: https://plugins.zenginehq.com/workspaces/1/testBackendService/testRoute) and the value server
means this is backend service access.
Learn more about how to setup Firebase security rules.
You will need to download and install Node.js to run your service locally. Next, browse to your service directory from the command line and run npm start
. You should see Listening on port 3000
, indicating your service is running at http://localhost:3000
. We recommend using the Google Chrome extension Postman to make requests to your service. This will allow you to easily make requests and send HTTP headers you will need for offline plugins.
Note that when you make code changes, you will need to stop and restart the local service runner in order for those changes to be reflected. Press Ctrl + C to stop the running service, and run npm start
again to start it back up.
The route for plugin service requests follows a specific convention: /workspaces/{workspaceId}/{pluginNamespace}/{serviceRoute}
So, for example, if you’re using workspace 123
, your plugin namespace is documentationPlugin
, and your plugin service’s route is do-something
, you would run this locally by making a request to http://localhost:3000/workspaces/123/documentationPlugin/do-something
.
When you upload your service and run it in Zengine, requests would go to https://plugins.zenginehq.com/workspaces/123/documentationPlugin/do-something
.
If your plugin service uses znHttp
, you will need to send the Authorization
header with an API access token for znHttp
to use when running your service locally:
Authorization: Bearer user_access_token
Note that you can find a temporary access token here: https://platform.zenginehq.com/account/developer
When using the znFirebase library to access data protected by security rules you will need to send two headers:
X-Firebase-Url: your_firebase_url
X-Firebase-Secret: your_firebase_secret
When using the Developer tools and testing your plugin in draft mode, the znPluginData
service will automatically make requests to your draft service. In draft mode, your user will be making requests to the service, so actions will be taken under your account. Keep in mind this will not be the case when you publish the plugin and other users are accessing your plugin.
To use the draft version when accessing the service directly, you will need to manually pass in the draft HTTP header X-Plugin-Draft
. This header value must be a valid access token for the plugin developer. By default, this will make requests as the plugin developer user. You can optionally pass a second HTTP authorization header to specify an access token different from the developer token.
X-Plugin-Draft: developer_access_token
Authorization: Bearer user_access_token