Making HTTP Requests
diff --git a/packages/cli/snippets/throttle-configuration.js b/packages/cli/snippets/throttle-configuration.js
new file mode 100644
index 000000000..349d79a63
--- /dev/null
+++ b/packages/cli/snippets/throttle-configuration.js
@@ -0,0 +1,33 @@
+const App = {
+ version: require('./package.json').version,
+ platformVersion: require('zapier-platform-core').version,
+
+ // default throttle used for each action
+ throttle: {
+ window: 600,
+ limit: 50,
+ scope: ['account'],
+ },
+
+ creates: {
+ upload_video: {
+ noun: 'Video',
+ display: {
+ label: 'Upload Video',
+ description: 'Upload a video.',
+ },
+ operation: {
+ perform: () => {},
+ inputFields: [],
+ // overwrites the default, for this action
+ throttle: {
+ window: 600,
+ limit: 5,
+ scope: ['account'],
+ },
+ },
+ },
+ },
+};
+
+module.exports = App;
diff --git a/packages/schema/docs/build/schema.md b/packages/schema/docs/build/schema.md
index d6c776cad..0d2150b54 100644
--- a/packages/schema/docs/build/schema.md
+++ b/packages/schema/docs/build/schema.md
@@ -58,6 +58,7 @@ This is automatically generated by the `npm run docs` command in `zapier-platfor
* [/SearchOrCreatesSchema](#searchorcreatesschema)
* [/SearchSchema](#searchschema)
* [/SearchesSchema](#searchesschema)
+* [/ThrottleObjectSchema](#throttleobjectschema)
* [/TriggerSchema](#triggerschema)
* [/TriggersSchema](#triggersschema)
* [/VersionSchema](#versionschema)
@@ -126,6 +127,7 @@ Key | Required | Type | Description
`searchOrCreates` | no | [/SearchOrCreatesSchema](#searchorcreatesschema) | All the search-or-create combos for your app. You can create your own here, or Zapier will automatically register any from resources that define a search, a create, and a get (or define a searchOrCreate directly). Register non-resource search-or-creates here as well.
`searchAndCreates` | no | [/SearchAndCreatesSchema](#searchandcreatesschema) | An alias for "searchOrCreates".
`flags` | no | [/AppFlagsSchema](#appflagsschema) | Top-level app options
+`throttle` | no | [/ThrottleObjectSchema](#throttleobjectschema) | Zapier uses this configuration to apply throttling when the limit for the window is exceeded. When set here, it is the default throttle configuration used on each action of the integration. And when set in an action's operation object, it gets overwritten for that action only.
@@ -390,6 +392,7 @@ Key | Required | Type | Description
`outputFields` | no | [/DynamicFieldsSchema](#dynamicfieldsschema) | What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.
`sample` | **yes** (with exceptions, see description) | `object` | What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample
`lock` | no | [/LockObjectSchema](#lockobjectschema) | **INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.
+`throttle` | no | [/ThrottleObjectSchema](#throttleobjectschema) | Zapier uses this configuration to apply throttling when the limit for the window is exceeded.
#### Examples
@@ -422,6 +425,7 @@ Key | Required | Type | Description
`outputFields` | no | [/DynamicFieldsSchema](#dynamicfieldsschema) | What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.
`sample` | **yes** (with exceptions, see description) | `object` | What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample
`lock` | no | [/LockObjectSchema](#lockobjectschema) | **INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.
+`throttle` | no | [/ThrottleObjectSchema](#throttleobjectschema) | Zapier uses this configuration to apply throttling when the limit for the window is exceeded.
`shouldLock` | no | `boolean` | Should this action be performed one at a time (avoid concurrency)?
#### Examples
@@ -543,6 +547,7 @@ Key | Required | Type | Description
`outputFields` | no | [/DynamicFieldsSchema](#dynamicfieldsschema) | What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.
`sample` | **yes** (with exceptions, see description) | `object` | What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample
`lock` | no | [/LockObjectSchema](#lockobjectschema) | **INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.
+`throttle` | no | [/ThrottleObjectSchema](#throttleobjectschema) | Zapier uses this configuration to apply throttling when the limit for the window is exceeded.
#### Examples
@@ -2056,6 +2061,38 @@ Key | Required | Type | Description
-----
+## /ThrottleObjectSchema
+
+Zapier uses this configuration to apply throttling when the limit for the window is exceeded.
+
+#### Details
+
+* **Type** - `object`
+* [**Source Code**](https://github.com/zapier/zapier-platform/blob/zapier-platform-schema@15.3.0/packages/schema/lib/schemas/ThrottleObjectSchema.js)
+
+#### Properties
+
+Key | Required | Type | Description
+--- | -------- | ---- | -----------
+`window` | **yes** | `integer` | The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocations begins at zero at the start of each window.
+`limit` | **yes** | `integer` | The maximum number of invocations for an action, allowed within the timeframe window.
+`scope` | no | `array`[`string` in (`'user'`, `'auth'`, `'account'`)] | The granularity to throttle by. You can set the scope to one or more of the following: 'user' - Throttles based on user ids. 'auth' - Throttles based on auth ids. 'account' - Throttles based on account ids for all users under a single account. By default, throttling is scoped to the account.
+
+#### Examples
+
+* `{ window: 60, limit: 100 }`
+* `{ window: 600, limit: 100, scope: [ 'account', 'user' ] }`
+* `{ window: 3600, limit: 10, scope: [ 'auth' ] }`
+
+#### Anti-Examples
+
+* `{ window: 60, limit: 100, scope: [ 'zap' ] }` - _Invalid scope provided: `zap`._
+* `{ limit: 10 }` - _Missing required key: `window`._
+* `{ window: 600 }` - _Missing required key: `limit`._
+* `{}` - _Missing required keys: `window` and `limit`._
+
+-----
+
## /TriggerSchema
How will Zapier get notified of new objects?
diff --git a/packages/schema/exported-schema.json b/packages/schema/exported-schema.json
index cbf36c5f3..d42976806 100644
--- a/packages/schema/exported-schema.json
+++ b/packages/schema/exported-schema.json
@@ -75,6 +75,10 @@
"description": "Top-level app options",
"$ref": "/AppFlagsSchema"
},
+ "throttle": {
+ "description": "Zapier uses this configuration to apply throttling when the limit for the window is exceeded. When set here, it is the default throttle configuration used on each action of the integration. And when set in an action's operation object, it gets overwritten for that action only.",
+ "$ref": "/ThrottleObjectSchema"
+ },
"legacy": {
"description": "**INTERNAL USE ONLY**. Zapier uses this to hold properties from a legacy Web Builder app.",
"type": "object",
@@ -652,6 +656,31 @@
"minProperties": 1
}
},
+ "ThrottleObjectSchema": {
+ "id": "/ThrottleObjectSchema",
+ "description": "Zapier uses this configuration to apply throttling when the limit for the window is exceeded.",
+ "type": "object",
+ "required": ["window", "limit"],
+ "properties": {
+ "window": {
+ "description": "The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocations begins at zero at the start of each window.",
+ "type": "integer"
+ },
+ "limit": {
+ "description": "The maximum number of invocations for an action, allowed within the timeframe window.",
+ "type": "integer"
+ },
+ "scope": {
+ "description": "The granularity to throttle by. You can set the scope to one or more of the following: 'user' - Throttles based on user ids. 'auth' - Throttles based on auth ids. 'account' - Throttles based on account ids for all users under a single account. By default, throttling is scoped to the account.",
+ "type": "array",
+ "items": {
+ "enum": ["user", "auth", "account"],
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
"BasicDisplaySchema": {
"id": "/BasicDisplaySchema",
"description": "Represents user information for a trigger, search, or create.",
@@ -737,6 +766,10 @@
"lock": {
"description": "**INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.",
"$ref": "/LockObjectSchema"
+ },
+ "throttle": {
+ "description": "Zapier uses this configuration to apply throttling when the limit for the window is exceeded.",
+ "$ref": "/ThrottleObjectSchema"
}
},
"additionalProperties": false
@@ -954,6 +987,10 @@
"lock": {
"description": "**INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.",
"$ref": "/LockObjectSchema"
+ },
+ "throttle": {
+ "description": "Zapier uses this configuration to apply throttling when the limit for the window is exceeded.",
+ "$ref": "/ThrottleObjectSchema"
}
},
"additionalProperties": false
@@ -1318,6 +1355,10 @@
"description": "**INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.",
"$ref": "/LockObjectSchema"
},
+ "throttle": {
+ "description": "Zapier uses this configuration to apply throttling when the limit for the window is exceeded.",
+ "$ref": "/ThrottleObjectSchema"
+ },
"shouldLock": {
"description": "Should this action be performed one at a time (avoid concurrency)?",
"type": "boolean"
diff --git a/packages/schema/lib/schemas/AppSchema.js b/packages/schema/lib/schemas/AppSchema.js
index 93ced5db4..07c57597a 100644
--- a/packages/schema/lib/schemas/AppSchema.js
+++ b/packages/schema/lib/schemas/AppSchema.js
@@ -16,6 +16,7 @@ const VersionSchema = require('./VersionSchema');
const MiddlewaresSchema = require('./MiddlewaresSchema');
const HydratorsSchema = require('./HydratorsSchema');
const AppFlagsSchema = require('./AppFlagsSchema');
+const ThrottleObjectSchema = require('./ThrottleObjectSchema');
module.exports = makeSchema(
{
@@ -105,6 +106,11 @@ module.exports = makeSchema(
description: 'Top-level app options',
$ref: AppFlagsSchema.id,
},
+ throttle: {
+ description:
+ `Zapier uses this configuration to apply throttling when the limit for the window is exceeded. When set here, it is the default throttle configuration used on each action of the integration. And when set in an action's operation object, it gets overwritten for that action only.`,
+ $ref: ThrottleObjectSchema.id,
+ },
legacy: {
description:
'**INTERNAL USE ONLY**. Zapier uses this to hold properties from a legacy Web Builder app.',
@@ -150,5 +156,6 @@ module.exports = makeSchema(
MiddlewaresSchema,
HydratorsSchema,
AppFlagsSchema,
+ ThrottleObjectSchema,
]
);
diff --git a/packages/schema/lib/schemas/BasicActionOperationSchema.js b/packages/schema/lib/schemas/BasicActionOperationSchema.js
index affbf8a96..fd2e9cc11 100644
--- a/packages/schema/lib/schemas/BasicActionOperationSchema.js
+++ b/packages/schema/lib/schemas/BasicActionOperationSchema.js
@@ -34,6 +34,7 @@ BasicActionOperationSchema.properties = {
outputFields: BasicActionOperationSchema.properties.outputFields,
sample: BasicActionOperationSchema.properties.sample,
lock: BasicActionOperationSchema.properties.lock,
+ throttle: BasicActionOperationSchema.properties.throttle,
};
BasicActionOperationSchema.examples = [
diff --git a/packages/schema/lib/schemas/BasicOperationSchema.js b/packages/schema/lib/schemas/BasicOperationSchema.js
index cf2361d8b..beaa37cb0 100644
--- a/packages/schema/lib/schemas/BasicOperationSchema.js
+++ b/packages/schema/lib/schemas/BasicOperationSchema.js
@@ -9,6 +9,7 @@ const RequestSchema = require('./RequestSchema');
const ResultsSchema = require('./ResultsSchema');
const KeySchema = require('./KeySchema');
const LockObjectSchema = require('./LockObjectSchema');
+const ThrottleObjectSchema = require('./ThrottleObjectSchema');
module.exports = makeSchema(
{
@@ -56,6 +57,11 @@ module.exports = makeSchema(
'**INTERNAL USE ONLY**. Zapier uses this configuration for internal operation locking.',
$ref: LockObjectSchema.id,
},
+ throttle: {
+ description:
+ 'Zapier uses this configuration to apply throttling when the limit for the window is exceeded.',
+ $ref: ThrottleObjectSchema.id,
+ },
},
examples: [
{
@@ -75,5 +81,5 @@ module.exports = makeSchema(
],
additionalProperties: false,
},
- [DynamicFieldsSchema, FunctionSchema, KeySchema, LockObjectSchema, RequestSchema, ResultsSchema]
+ [DynamicFieldsSchema, FunctionSchema, KeySchema, LockObjectSchema, RequestSchema, ResultsSchema, ThrottleObjectSchema]
);
diff --git a/packages/schema/lib/schemas/ThrottleObjectSchema.js b/packages/schema/lib/schemas/ThrottleObjectSchema.js
new file mode 100644
index 000000000..648ab1f51
--- /dev/null
+++ b/packages/schema/lib/schemas/ThrottleObjectSchema.js
@@ -0,0 +1,70 @@
+'use strict';
+
+const makeSchema = require('../utils/makeSchema');
+
+module.exports = makeSchema({
+ id: '/ThrottleObjectSchema',
+ description:
+ 'Zapier uses this configuration to apply throttling when the limit for the window is exceeded.',
+ type: 'object',
+ required: ['window', 'limit'],
+ properties: {
+ window: {
+ description:
+ 'The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocations begins at zero at the start of each window.',
+ type: 'integer',
+ },
+ limit: {
+ description:
+ 'The maximum number of invocations for an action, allowed within the timeframe window.',
+ type: 'integer',
+ },
+ scope: {
+ description: `The granularity to throttle by. You can set the scope to one or more of the following: 'user' - Throttles based on user ids. 'auth' - Throttles based on auth ids. 'account' - Throttles based on account ids for all users under a single account. By default, throttling is scoped to the account.`,
+ type: 'array',
+ items: {
+ enum: ['user', 'auth', 'account'],
+ type: 'string',
+ },
+ },
+ },
+ examples: [
+ {
+ window: 60,
+ limit: 100,
+ },
+ {
+ window: 600,
+ limit: 100,
+ scope: ['account', 'user'],
+ },
+ {
+ window: 3600,
+ limit: 10,
+ scope: ['auth'],
+ },
+ ],
+ antiExamples: [
+ {
+ example: {
+ window: 60,
+ limit: 100,
+ scope: ['zap'],
+ },
+ reason: 'Invalid scope provided: `zap`.',
+ },
+ {
+ example: {limit: 10},
+ reason: 'Missing required key: `window`.',
+ },
+ {
+ example: {window: 600},
+ reason: 'Missing required key: `limit`.',
+ },
+ {
+ example: {},
+ reason: 'Missing required keys: `window` and `limit`.',
+ },
+ ],
+ additionalProperties: false,
+});
diff --git a/packages/schema/test/index.js b/packages/schema/test/index.js
index 31ab86fed..faface52f 100644
--- a/packages/schema/test/index.js
+++ b/packages/schema/test/index.js
@@ -9,7 +9,7 @@ const appDefinition = require('../examples/definition.json');
const copy = (o) => JSON.parse(JSON.stringify(o));
-const NUM_SCHEMAS = 53; // changes regularly as we expand
+const NUM_SCHEMAS = 54; // changes regularly as we expand
describe('app', () => {
describe('validation', () => {