Platform CLI tutorial
This tutorial walks you through the process of building, testing, and pushing an example app to Zapier using Platform CLI. We’ll use a mock API for recipes in this tutorial, but for production Zapier apps, you’d want to connect to a real API.
Prerequisites
-
You’ll need a Zapier account.
-
Your dev environment meets the requirements for running Platform CLI with the proper version of Node.js installed.
-
Install the Platform CLI tool
To see a list of all the available commands in Platform CLI, try zapier help
.
- Next you’ll need to identify yourself via the CLI.
Zapier writes your deploy key to ~/.zapierrc
. You’ll want to keep that file safe and not check it into source control.
1. Start an integration
Use the init
command to setup the needed structure. You’ll be presented with a list of available templates to start with.
Inside the directory, you’ll see a few files. package.json
is a typical requirements file of any Node.js application. It’s pre-populated with a few dependencies, most notably the zapier-platform-core
, which is what makes your app work with the Zapier Platform. There is also an index.js
file and a test directory (more on those later). Before we go any further, we need to install the dependencies for our app:
index.js
index.js
is the entry point to your app. This is where the Platform will look to understand how your app will interact with Zapier. Open the app directory you created in your code editor of choice.
You may see the following in index.js
:
- a single
module.exports
definition which will be interpreted by Zapier triggers
will describe ways to trigger off of data in your appsearches
will describe ways to find data in your appcreates
will describe ways to create data in your appresources
are purely optional but convenient ways to describe CRUD-like objects in your app (see an example resources app)beforeRequest
&afterResponse
are hooks into the HTTP client to manipulate the request/response on every call
2. Add a trigger
Add a trigger configured to read data from a mock API:
The scaffold creates a new file recipe.js
in the triggers
folder. When building your own integration, you’ll likely name your JS files with nouns like contact.js
, lead.js
or order.js
.
Open triggers/recipe.js
(file created by zapier scaffold trigger recipe
) and replace it with:
To try out the trigger locally, try running zapier invoke
. The command will ask you which action you’d like to invoke. Now we only have one trigger recipe
, so you can choose that one.
Let’s review the code. The function definition for listRecipes
handles the API work, making the HTTP request and returning the parsed response data.
In JavaScript, async/await
are syntactic sugar built on top of Promises. Be sure to use await
or .then()
when you call asynchronous functions.
The listRecipes
function receives two arguments, a z
object and a bundle
object.
- The Z Object is a collection of utilities needed when working with APIs. In our snippet, we use
z.request
to make the HTTP call. - The Bundle Object contains any data needed to make API calls, like authentication credentials or data for a POST body. In our snippet the Bundle is not used, since we don’t require any of those to make our simple GET request.
It is possible to accomplish the same tasks using alternate Node.js libraries, but it is preferable to use the z
object as there are features built into these utilities that augment the Zapier experience like logging of HTTP calls and error handling.
In module.exports
, we export some metadata plus our listRecipes
function and a sample. We’ll explain later how Zapier uses this metadata and exposes it to the end user. For now, know that it satisfies the minimum info required to define a trigger.
As well as defining the trigger, the scaffold
command has done the following:
index.js
file now includes:
In test/triggers folder, the recipe.test.js
file was created:
You should be able to run the test with zapier test
and see it pass:
For this example, we’ll stick to a single test, but you can see what multiple tests look like in another of the example apps.
3. Modify a trigger
To let users tweak the cuisine style of recipes they are triggering on, you can provide an input field a user can fill out.
In triggers/recipe.js
, replace the file with:
See how the input field key "style"
was added in the following places:
- In the
inputFields
onoperation
- this defines the field as exposed in the Zap Editor for the user to see. The field is not required, so it could be null. - In the
listRecipes
function - we use the provided style via the bundlebundle.inputData.style
.
Since you are developing locally, rerun zapier invoke
to verify everything still works. This time, let’s skip those interactive prompts. Specify the action type (trigger
), the key (recipe
), and the input data in the command, and you’ll see:
Let’s also tweak the test. In test/trigger, replace the recipe.test.js
file with:
You can run your test again and make sure everything still works:
4. Deploy an integration
To take your local app integration and make it available to use in a Zap, you’ll need to push it to Zapier.
You can have many versions of an app, which simplifies making breaking changes and testing in the future. For now, you will push a single version.
Since this is your first time pushing your app version, you’ll need to register your app with Zapier. Run the zapier register
command and Zapier will ask you to provide a name and some details about your app. Follow the prompt and then you can push your app using zapier push
:
Zapier will ask you to provide a name and some details about your app with the zapier register
command. Follow the prompts and then push your app again.
Log in and visit the Zap editor to create a Zap with your new integration.
For the trigger step, choose your app and the “New Recipe” trigger, where you can see the label and description that were defined in triggers/recipe.js
.
In the Zap editor, see the input field "style"
and fill it out. Run the trigger test and the listRecipes
function associated with the trigger runs, making the API request and returning the result to Zapier.
Go back to your terminal. Use the zapier logs --type http
command to see the HTTP requests Zapier made.
5. Add authentication
Authentication is crucial to interacting with most APIs. Zapier supports a number of different authentication schemes. In this example, you are going to set it up to include an API Key in a header.
For different types of authentication, see these example apps:
Define the authentication
section for the example app you’ve built. In index.js
, add the following to module.exports
:
The above snippet defines the two required properties of authentication
:
fields
is where we define our auth fields. This works similar to theinputFields
of triggers. When users connect their account to Zapier, they’ll be prompted to fill in this field, and the value they enter becomes available in thebundle.authData
. Not every authentication type will includeinputFields
.test
is a function used during the account connection process to verify that the user entered valid credentials. The goal of the function is to make an authenticated API request whose response indicates if the credentials are correct. A profile in the connected app, such as a/me
endpoint, is a common choice. If valid, the test function can return anything. On invalid credentials, the test needs to raise an error. Sincez.request()
already throws an error for non-2xx responses, we don’t need to throw an error explicitly in this case.
Next, make sure the API key is included in all the requests your app makes.
In index.js
, edit the file to include:
The helper function addApiKeyToHeader
, adds the user-provided API key as a request header called My-Auth-Header
. The name chosen is illustrative, the header would be whatever the API you are integrating with requires. Sometimes, an API would require it in a query parameter instead of a header, and/or encoded first. You’ll want to reference the API documentation for the expected format.
Finally, to ensure the helper function takes effect, it needs to be registered in the app.
In index.js
, edit module.exports
to also include:
beforeRequest
is a list of functions that are called before every HTTP request that uses z.request
. It’s where you add headers, query params, or whatever is needed to be within all outbound requests. With this addition, every outgoing HTTP request made by z.request
will now have the API key added in a header.
The zapier invoke
command has auth test
subcommand that essentially calls the authentication.test
function for you to verify the credentials locally. But first, you need to initialize the auth credentials with the auth start
subcommand:
Next, run the auth test
subcommand to verify the credentials. You’ll know you have the right API key if you can see the response data from the /me
endpoint:
To check progress, re-push the app.
Re-push the app to Zapier to deploy the changes:
Go back to your Zap at https://zapier.com/app/zaps. It will now have a new “Account” item in your “New Recipe” trigger.
Add an account by entering any value you like for the API key, the mock API does not care.
As soon as you add the account, Zapier will run your app’s authentication.test
function to confirm the credentials are valid.
We can verify the header is present in the request by looking at the logs again.
You can see from the detailed log that the request included our auth header. The value appears as :censored:6:b1af149262:
, which is intentional. Zapier does not log authentication credentials in plain text.
6. Invite team members to help manage your integration
Share your integration with your team of fellow developers so it shows up in their developer dashboard.
From the Zapier CLI, run either of these:
zapier team:add user@example.com admin
to invite a team member as an admin for the app.zapier team:add user@example.com collaborator
to invite a team member as a collaborator for the app.
Replace the example email address with the user you want to invite.
7. Share users to your integration
Once you have at least one trigger or action, you’ll want to share your integration with some of your users. Early feedback helps make sure you’re building functionality that will be used.
From the Zapier CLI, run zapier users:add user@example.com 1.0.0
to email this user to let them view and use the app version 1.0.0 in their Zaps.
Replace the example email address with the user you want to invite. You’ll see a confirmation prompt, type Y
.
The alternative way to invite anyone to use your app in their Zaps is via a link to the app. Run zapier users:links
to see a public sharing link per specific version or a link to all versions. The link looks something like https://zapier.com/platform/public-invite/1/222dcd03aed943a8676dc80e2427a40d/
. You can put this in your help docs, post it to your website, add it to your email campaign, etc. Access shared via these links cannot be revoked once shared with your users.
8. Modify your integration
If you need to make any changes to your integration in a new version. Versions helps to track and manage changes to your integration over time.
Public integrations or private integrations with more than 5 users require a new version to make any edits. It is still recommended to make changes for private integrations with fewer than 5 users in a new version as well and consider Zapier’s best practices when doing so.
Integrations created with the Platform CLI cannot be edited in the Platform UI. You can’t add triggers or actions, edit code or configurations - these options will be grayed out in the UI.
The following details of your CLI integration can be managed from the UI if preferred:
- Invite team members
- Monitor integration usage
- Submit your integration to be made publicly available
- Promote a new integration version to public
- Migrate users between versions
Learn more
- Z object
- Bundle object for functionalities available within the
perform
functions - Different authentication schemes and search/create implementations examples
- Interactive tutorial that uses the GitHub API (a little outdated)
- About different types of support available to help you build your integration
Need help? Tell us about your problem and we’ll connect you with the right resource or contact support.