✨ Add Onfleet Node & Trigger (#2845)

* feat: added Onfleet nodes

Added Onfleet nodes for working with different endpoints like:
organizations, administrators, workers, hubs, teams, destinations, recipients,
containers and webhooks.

* style: fixed typos, arrays uniformity, unnecesary files

* refactor: changed add to create in comments and labels

* feat: added name field to onfleet trigger node

* feat: added team endpoints to onfleet node

Added team auto-dispatch and driver time estimate endpoints to Onfleet
node

* style: remove dots in descriptions and fixed some typos

* feat: added fixes according to comments made on the n8n PR

added new fixed collections, refactored the code according to comments
made on the n8n pr

* fix: fixed recipient and destination cretion

* docs: added docstrings for format some functions

added docstrings for new functions addded for formatting the destination
and recipient objects

* style: formatting the code according to n8n nodelinter

* fix: typos and better descriptions

* [INT-510] n8n: Address additional problems from n8n code review (#5)

* Fixed some error creating a worker, moving some fields under additional fields collection

* Fixed returned values for delete operations, making some changes for style code

* Added operational error since required property is not working for dateTime fields

* ⚡ Improvements to #2593

* ⚡ Improvements

* 🐛 Fix issue with wrong interface

* ⚡ Improvements

* ⚡ Improvements

* ⚡ Minor improvement

Co-authored-by: Santiago Botero Ruiz <santiago.botero@devsavant.ai>
Co-authored-by: ilsemaj <james.li.upenn@gmail.com>
Co-authored-by: Santiago Botero Ruiz <39206812+YokySantiago@users.noreply.github.com>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
authored and GitHub committed 2022-02-28 09:48:17 +01:00
1 parent 2ec4ed6592
commit 401e626a64
21 files changed
+5593

No files matched your search

@@ -0,0 +1,18 @@
import {
ICredentialType,
NodePropertyTypes,
} from 'n8n-workflow';
export class OnfleetApi implements ICredentialType {
name = 'onfleetApi';
displayName = 'Onfleet API';
documentationUrl = 'onfleet';
properties = [
{
displayName: 'API Key',
name: 'apiKey',
type: 'string' as NodePropertyTypes,
default: '',
},
];
}
@@ -0,0 +1,123 @@
import {
ICredentialDataDecryptedObject,
IDataObject,
IExecuteFunctions,
IHookFunctions,
ILoadOptionsFunctions,
INodePropertyOptions,
IWebhookFunctions,
JsonObject,
NodeApiError
} from 'n8n-workflow';
import {
OptionsWithUri,
} from 'request';
import * as moment from 'moment-timezone';
export async function onfleetApiRequest(
this: IWebhookFunctions | IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions,
method: string,
resource: string,
body: any = {}, // tslint:disable-line:no-any
qs?: any, // tslint:disable-line:no-any
uri?: string): Promise<any> { // tslint:disable-line:no-any
const credentials = await this.getCredentials('onfleetApi') as ICredentialDataDecryptedObject;
const options: OptionsWithUri = {
headers: {
'Content-Type': 'application/json',
'User-Agent': 'n8n-onfleet',
},
auth: {
user: credentials.apiKey as string,
pass: '',
},
method,
body,
qs,
uri: uri || `https://onfleet.com/api/v2/${resource}`,
json: true,
};
try {
//@ts-ignore
return await this.helpers.request(options);
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
}
}
export async function onfleetApiRequestAllItems(
this: IWebhookFunctions | IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions,
propertyName: string,
method: string,
endpoint: string,
// tslint:disable-next-line: no-any
body: any = {},
query: IDataObject = {},
): Promise<any> { // tslint:disable-line:no-any
const returnData: IDataObject[] = [];
let responseData;
do {
responseData = await onfleetApiRequest.call(this, method, endpoint, body, query);
query.lastId = responseData['lastId'];
returnData.push.apply(returnData, responseData[propertyName]);
} while (
responseData['lastId'] !== undefined
);
return returnData;
}
export const resourceLoaders = {
async getTeams(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
try {
const teams = await onfleetApiRequest.call(this, 'GET', 'teams') as IDataObject[];
return teams.map(({ name = '', id: value = '' }) => ({ name, value })) as INodePropertyOptions[];
} catch (error) {
return [];
}
},
async getWorkers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
try {
const workers = await onfleetApiRequest.call(this, 'GET', 'workers') as IDataObject[];
return workers.map(({ name = '', id: value = '' }) => ({ name, value })) as INodePropertyOptions[];
} catch (error) {
return [];
}
},
async getAdmins(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
try {
const admins = await onfleetApiRequest.call(this, 'GET', 'admins') as IDataObject[];
return admins.map(({ name = '', id: value = '' }) => ({ name, value })) as INodePropertyOptions[];
} catch (error) {
return [];
}
},
async getHubs(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
try {
const hubs = await onfleetApiRequest.call(this, 'GET', 'hubs') as IDataObject[];
return hubs.map(({ name = '', id: value = '' }) => ({ name, value })) as INodePropertyOptions[];
} catch (error) {
return [];
}
},
async getTimezones(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData = [] as INodePropertyOptions[];
for (const timezone of moment.tz.names()) {
returnData.push({
name: timezone,
value: timezone,
});
}
return returnData;
},
};
@@ -0,0 +1,230 @@
import {
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
INodeCredentialTestResult,
INodeExecutionData,
INodeType,
INodeTypeDescription,
} from 'n8n-workflow';
import {
taskFields,
taskOperations,
} from './descriptions/TaskDescription';
import {
IExecuteFunctions,
} from 'n8n-core';
import {
destinationFields,
destinationOperations,
} from './descriptions/DestinationDescription';
import {
resourceLoaders,
} from './GenericFunctions';
import {
recipientFields,
recipientOperations,
} from './descriptions/RecipientDescription';
import {
organizationFields,
organizationOperations,
} from './descriptions/OrganizationDescription';
import {
adminFields,
adminOperations,
} from './descriptions/AdministratorDescription';
import {
hubFields,
hubOperations,
} from './descriptions/HubDescription';
import {
workerFields,
workerOperations,
} from './descriptions/WorkerDescription';
// import {
// webhookFields,
// webhookOperations,
// } from './descriptions/WebhookDescription';
import {
containerFields,
containerOperations,
} from './descriptions/ContainerDescription';
import {
teamFields,
teamOperations,
} from './descriptions/TeamDescription';
import {
OptionsWithUri,
} from 'request';
import { Onfleet as OnfleetMethods } from './Onfleet';
export class Onfleet implements INodeType {
description: INodeTypeDescription = {
displayName: 'Onfleet',
name: 'onfleet',
icon: 'file:Onfleet.svg',
group: ['input'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Consume Onfleet API',
defaults: {
color: '#AA81F3',
name: 'Onfleet',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'onfleetApi',
required: true,
testedBy: 'onfleetApiTest',
},
],
properties: [
// List of option resources
{
displayName: 'Resource',
name: 'resource',
type: 'options',
options: [
{
name: 'Admin',
value: 'admin',
},
{
name: 'Container',
value: 'container',
},
{
name: 'Destination',
value: 'destination',
},
{
name: 'Hub',
value: 'hub',
},
{
name: 'Organization',
value: 'organization',
},
{
name: 'Recipient',
value: 'recipient',
},
{
name: 'Task',
value: 'task',
},
{
name: 'Team',
value: 'team',
},
// {
// name: 'Webhook',
// value: 'webhook',
// },
{
name: 'Worker',
value: 'worker',
},
],
default: 'task',
description: 'The resource to perform operations on',
},
// Operations & fields
...adminOperations,
...adminFields,
...containerOperations,
...containerFields,
...destinationOperations,
...destinationFields,
...hubOperations,
...hubFields,
...organizationOperations,
...organizationFields,
...recipientOperations,
...recipientFields,
...taskOperations,
...taskFields,
...teamOperations,
...teamFields,
// ...webhookOperations,
// ...webhookFields,
...workerOperations,
...workerFields,
],
};
methods = {
credentialTest: {
async onfleetApiTest(this: ICredentialTestFunctions, credential: ICredentialsDecrypted): Promise<INodeCredentialTestResult> {
const credentials = credential.data as IDataObject;
const options: OptionsWithUri = {
headers: {
'Content-Type': 'application/json',
'User-Agent': 'n8n-onfleet',
},
auth: {
user: credentials.apiKey as string,
pass: '',
},
method: 'GET',
uri: 'https://onfleet.com/api/v2/auth/test',
json: true,
};
try {
await this.helpers.request(options);
return {
status: 'OK',
message: 'Authentication successful',
};
} catch (error) {
return {
status: 'Error',
message: `Auth settings are not valid: ${error}`,
};
}
},
},
loadOptions: resourceLoaders,
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
const items = this.getInputData();
const operations: { [key: string]: Function } = {
task: OnfleetMethods.executeTaskOperations,
destination: OnfleetMethods.executeDestinationOperations,
organization: OnfleetMethods.executeOrganizationOperations,
admin: OnfleetMethods.executeAdministratorOperations,
recipient: OnfleetMethods.executeRecipientOperations,
hub: OnfleetMethods.executeHubOperations,
worker: OnfleetMethods.executeWorkerOperations,
webhook: OnfleetMethods.executeWebhookOperations,
container: OnfleetMethods.executeContainerOperations,
team: OnfleetMethods.executeTeamOperations,
};
const responseData = await operations[resource].call(this, `${resource}s`, operation, items);
// Map data to n8n data
return [this.helpers.returnJsonArray(responseData)];
}
}
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Group 2</title>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="WIP-Illustrations" transform="translate(-1086.000000, -1490.000000)">
<g id="Group-2" transform="translate(1086.000000, 1490.000000)">
<rect id="Rectangle" fill="#AA81F3" x="0" y="0" width="60" height="60"></rect>
<g id="Icon_white" transform="translate(13.000000, 22.000000)" fill="#FFFFFF">
<path d="M19.5506423,10.0656088 C20.0318974,10.5200534 20.7568258,11.1320386 21.6949686,11.8773277 C22.6331113,12.5983796 23.8636622,13.422439 25.3378865,14.0647206 C26.0871823,14.3555651 26.8913047,14.5979355 27.7502535,14.6221726 C28.1766821,14.6221726 28.6092024,14.6221726 29.0112636,14.4888688 C29.2244779,14.4646318 29.4133248,14.3555651 29.6021717,14.2767947 C29.7910186,14.1677281 29.9798655,14.0889577 30.1626206,13.9556539 C30.5098552,13.7132835 30.8570899,13.422439 31.1251307,13.0528242 C31.3931715,12.6832093 31.6368449,12.2832981 31.8500592,11.8288536 C32.227753,10.9260238 32.4653346,9.90806807 32.5201611,8.84769752 C32.5749876,7.78126771 32.4409673,6.69060085 32.0937326,5.64840808 C31.746498,4.63651161 31.186049,3.70338553 30.3819267,3.11563728 C29.6082635,2.55818533 28.6152943,2.34611122 27.5431311,2.50365199 C27.0070496,2.61271868 26.4466006,2.7460224 25.9105191,2.98233355 C25.6424783,3.09140024 25.3744375,3.22470397 25.0820294,3.35800769 C24.8139886,3.51554846 24.5459478,3.64885219 24.277907,3.81245221 C23.2057439,4.45473381 22.1640399,5.2484969 21.1710707,6.1028526 C20.6898156,6.55729713 20.1781014,6.98144535 19.7273056,7.46012691 C19.4836321,7.70249732 19.2460505,7.91457143 19.0328362,8.18117888 L18.3079078,8.9264679 C17.369765,9.91412733 16.2976019,10.9502608 15.2254388,11.8591499 C14.1289083,12.792276 12.9775513,13.6466317 11.6921739,14.3919207 C10.4311638,15.1129727 9.01176605,15.7249579 7.43398053,15.9370321 C6.62985818,16.0460987 5.80136849,16.0158024 4.99724614,15.8279654 C4.19312379,15.6401283 3.41946062,15.2705134 2.773726,14.7615356 C2.12799139,14.2525577 1.622369,13.6405724 1.24467517,13.0043501 C0.866981339,12.3620685 0.574573211,11.7016091 0.385726296,11.0047942 C0.19687938,10.3382755 0.0933181685,9.64751988 0.0384916447,8.98100124 C-0.0163348792,8.31448261 -0.0163348792,7.64796398 0.0628589886,7.01174165 C0.190787544,5.72111921 0.538022195,4.49714863 1.12283845,3.37618547 C1.41524658,2.81873353 1.76857306,2.30975566 2.19500158,1.85531114 C2.59706276,1.40086662 3.0783178,1.00095544 3.61439937,0.710110945 C4.15048094,0.419266451 4.71092985,0.201133081 5.27747059,0.122362697 C5.8379195,0.0193552722 6.39836841,0.0496515736 6.93444998,0.098125656 C7.97615393,0.231429382 8.88992933,0.60710352 9.6635925,1.00095544 C11.2170107,1.85531114 12.3440003,2.83691131 13.2273166,3.69126701 C14.0862654,4.54562271 14.7015409,5.29091173 15.1279694,5.79383033 L15.7432448,6.56335639 L15.0183163,5.89683775 C14.5370613,5.44239323 13.8121328,4.83040794 12.8739901,4.10935597 C11.9358473,3.38830399 10.7052965,2.56424459 9.23107215,1.921963 C8.48177632,1.63111851 7.67765397,1.3887481 6.8187051,1.36451106 C5.9902154,1.34027402 5.13126653,1.52205182 4.43679723,2.03102969 C4.08956258,2.2734001 3.74232792,2.56424459 3.47428714,2.93385947 C3.20624636,3.30347435 2.93820557,3.70338553 2.74935866,4.15783005 C2.34729748,5.06065983 2.10362404,6.1028526 2.0792567,7.16928242 C2.02443018,8.23571223 2.15845057,9.32637908 2.50568522,10.3685718 C2.85291987,11.3804683 3.41336878,12.3135944 4.21749113,12.8710464 C4.9911543,13.4284983 5.98412357,13.6405724 7.0562867,13.4587946 C7.19030709,13.4587946 7.32432748,13.4042613 7.45834788,13.3800242 C7.59236827,13.3557872 7.72638866,13.3254909 7.86040905,13.2709575 L8.26247023,13.1376538 L8.6645314,12.980113 C8.79855179,12.9255797 8.93257218,12.8710464 9.06659258,12.792276 L9.46865375,12.6044389 C9.73669453,12.4468981 10.0047353,12.3135944 10.2727761,12.1499944 C11.3449392,11.5077128 12.3866432,10.7139497 13.3796125,9.85959399 C14.3725817,8.98100124 15.2802653,8.1024085 16.2732345,7.06021573 L16.998163,6.31492671 C17.2418365,6.04831926 17.5098773,5.80594885 17.7474589,5.5696377 C18.2591731,5.06065983 18.7891628,4.58197827 19.3252444,4.13359301 C20.4217749,3.20046693 21.5731319,2.34611122 22.8585092,1.60082221 C24.1195193,0.879770234 25.5389171,0.267784944 27.1167026,0.0557108339 C27.920825,-0.0533558513 28.7493146,0.00117749129 29.553437,0.18901456 C30.3575593,0.376851629 31.1312225,0.776762809 31.7525898,1.27968141 C32.3983244,1.78865928 32.8795794,2.40064457 33.2816406,3.0368669 C33.6593345,3.67914849 33.9517426,4.33960786 34.1405895,5.03642279 C34.3294364,5.70294143 34.4329976,6.3936971 34.4878241,7.06021573 C34.5426507,7.72673436 34.5426507,8.36295669 34.4634568,9.02947533 C34.3294364,10.3079792 33.9822018,11.5622461 33.4217528,12.652913 C33.1293447,13.2103649 32.7760182,13.7193428 32.3495897,14.1737873 C31.9475285,14.6282318 31.4662735,15.028143 30.9058246,15.3189875 C30.6377838,15.4765283 30.369743,15.585595 30.0773349,15.6946616 C29.7849268,15.773432 29.516886,15.8824987 29.218386,15.9067358 C28.6579371,16.0158024 28.0913964,15.9855061 27.5553148,15.9309728 C26.5136108,15.773432 25.5998354,15.3977579 24.8261723,14.9978467 C23.2727541,14.143491 22.1457644,13.1315945 21.2624482,12.2832981 C20.4034993,11.4289424 19.7882239,10.6836534 19.3617954,10.1807348 L18.74652,9.41120872 C18.8257138,9.3990902 19.5506423,10.0656088 19.5506423,10.0656088 Z" id="Path"></patLine truncated
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,164 @@
import {
IDataObject,
INodeType,
INodeTypeDescription,
IWebhookResponseData,
NodeApiError,
NodeOperationError
} from 'n8n-workflow';
import {
IHookFunctions,
IWebhookFunctions,
} from 'n8n-core';
import {
eventDisplay,
eventNameField,
} from './descriptions/OnfleetWebhookDescription';
import {
onfleetApiRequest,
} from './GenericFunctions';
import {
webhookMapping,
} from './WebhookMapping';
export class OnfleetTrigger implements INodeType {
description: INodeTypeDescription = {
displayName: 'Onfleet Trigger',
name: 'onfleetTrigger',
icon: 'file:Onfleet.svg',
group: ['trigger'],
version: 1,
subtitle: '={{$parameter["triggerOn"]}}',
description: 'Starts the workflow when Onfleet events occur',
defaults: {
name: 'Onfleet Trigger',
color: '#AA81F3',
},
inputs: [],
outputs: ['main'],
credentials: [
{
name: 'onfleetApi',
required: true,
testedBy: 'onfleetApiTest',
},
],
webhooks: [
{
name: 'setup',
httpMethod: 'GET',
responseMode: 'onReceived',
path: 'webhook',
},
{
name: 'default',
httpMethod: 'POST',
responseMode: 'onReceived',
path: 'webhook',
},
],
properties: [
eventDisplay,
eventNameField,
],
};
// @ts-ignore (because of request)
webhookMethods = {
default: {
async checkExists(this: IHookFunctions): Promise<boolean> {
const webhookData = this.getWorkflowStaticData('node') as IDataObject;
const webhookUrl = this.getNodeWebhookUrl('default') as string;
// Webhook got created before so check if it still exists
const endpoint = '/webhooks';
const webhooks = await onfleetApiRequest.call(this, 'GET', endpoint);
for (const webhook of webhooks) {
if (webhook.url === webhookUrl && webhook.trigger === event) {
webhookData.webhookId = webhook.id;
return true;
}
}
return false;
},
async create(this: IHookFunctions): Promise<boolean> {
const { name = '' } = this.getNodeParameter('additionalFields') as IDataObject;
const triggerOn = this.getNodeParameter('triggerOn') as string;
const webhookData = this.getWorkflowStaticData('node') as IDataObject;
const webhookUrl = this.getNodeWebhookUrl('default') as string;
if (webhookUrl.includes('//localhost')) {
throw new NodeOperationError(this.getNode(), 'The Webhook can not work on "localhost". Please, either setup n8n on a custom domain or start with "--tunnel"!');
}
// Webhook name according to the field
let newWebhookName = `n8n-webhook:${webhookUrl}`;
if (name) {
newWebhookName = `n8n-webhook:${name}`;
}
const path = `/webhooks`;
const body = {
name: newWebhookName,
url: webhookUrl,
trigger: webhookMapping[triggerOn].key,
};
try {
const webhook = await onfleetApiRequest.call(this, 'POST', path, body);
if (webhook.id === undefined) {
throw new NodeApiError(this.getNode(), webhook, { message: 'Onfleet webhook creation response did not contain the expected data' });
}
webhookData.id = webhook.id as string;
} catch (error) {
const { httpCode = '' } = error as { httpCode: string };
if (httpCode === '422') {
throw new NodeOperationError(this.getNode(), 'A webhook with the identical URL probably exists already. Please delete it manually in Onfleet!');
}
throw error;
}
return true;
},
async delete(this: IHookFunctions): Promise<boolean> {
const webhookData = this.getWorkflowStaticData('node') as IDataObject;
// Get the data of the already registered webhook
const endpoint = `/webhooks/${webhookData.id}`;
await onfleetApiRequest.call(this, 'DELETE', endpoint);
return true;
},
},
};
/**
* Triggered function when an Onfleet webhook is executed
* @returns {Promise<IWebhookResponseData>} Response data
*/
async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
const req = this.getRequestObject();
if (this.getWebhookName() === 'setup') {
/* -------------------------------------------------------------------------- */
/* Validation request */
/* -------------------------------------------------------------------------- */
const res = this.getResponseObject();
res.status(200).send(req.query.check);
return { noWebhookResponse: true };
}
const returnData: IDataObject = this.getBodyData();
return {
workflowData: [
this.helpers.returnJsonArray(returnData),
],
};
}
}
@@ -0,0 +1,91 @@
import {
OnfleetWebhooksMapping,
} from './interfaces';
export const webhookMapping: OnfleetWebhooksMapping = {
taskStarted: {
name: 'Task Started',
value: 'taskStarted',
key: 0,
},
taskEta: {
name: 'Task ETA',
value: 'taskEta',
key: 1,
},
taskArrival: {
name: 'Task Arrival',
value: 'taskArrival',
key: 2,
},
taskCompleted: {
name: 'Task Completed',
value: 'taskCompleted',
key: 3,
},
taskFailed: {
name: 'Task Failed',
value: 'taskFailed',
key: 4,
},
workerDuty: {
name: 'Worker Duty',
value: 'workerDuty',
key: 5,
},
taskCreated: {
name: 'Task Created',
value: 'taskCreated',
key: 6,
},
taskUpdated: {
name: 'Task Updated',
value: 'taskUpdated',
key: 7,
},
taskDeleted: {
name: 'Task Deleted',
value: 'taskDeleted',
key: 8,
},
taskAssigned: {
name: 'Task Assigned',
value: 'taskAssigned',
key: 9,
},
taskUnassigned: {
name: 'Task Unassigned',
value: 'taskUnassigned',
key: 10,
},
taskDelayed: {
name: 'Task Delayed',
value: 'taskDelayed',
key: 12,
},
taskCloned: {
name: 'Task Cloned',
value: 'taskCloned',
key: 13,
},
smsRecipientResponseMissed: {
name: 'SMS Recipient Response Missed',
value: 'smsRecipientResponseMissed',
key: 14,
},
workerCreated: {
name: 'Worker Created',
value: 'workerCreated',
key: 15,
},
workerDeleted: {
name: 'Worker Deleted',
value: 'workerDeleted',
key: 16,
},
SMSRecipientOptOut: {
name: 'SMS Recipient Opt Out',
value: 'SMSRecipientOptOut',
key: 17,
},
};
@@ -0,0 +1,209 @@
import {
INodeProperties
} from 'n8n-workflow';
export const adminOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'admin',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new Onfleet admin',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an Onfleet admin',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all Onfleet admins',
},
{
name: 'Update',
value: 'update',
description: 'Update an Onfleet admin',
},
],
default: 'getAll',
},
];
const adminNameField = {
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'The administrator\'s name',
} as INodeProperties;
const adminEmailField = {
displayName: 'Email',
name: 'email',
type: 'string',
default: '',
description: 'The administrator\'s email address',
} as INodeProperties;
const adminPhoneField = {
displayName: 'Phone',
name: 'phone',
type: 'string',
default: '',
description: 'The administrator\'s phone number',
} as INodeProperties;
const adminReadOnlyField = {
displayName: 'Read Only',
name: 'isReadOnly',
type: 'boolean',
default: false,
description: 'Whether this administrator can perform write operations',
} as INodeProperties;
export const adminFields: INodeProperties[] = [
{
displayName: 'Admin ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'admin',
],
},
hide: {
operation: [
'create',
'getAll',
],
},
},
default: '',
required: true,
description: 'The ID of the admin object for lookup',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'admin',
],
operation: [
'getAll',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: [
'admin',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 64,
},
default: 64,
description: 'How many results to return',
},
{
displayOptions: {
show: {
resource: [
'admin',
],
operation: [
'create',
],
},
},
required: true,
...adminNameField,
},
{
displayOptions: {
show: {
resource: [
'admin',
],
operation: [
'create',
],
},
},
required: true,
...adminEmailField,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'admin',
],
operation: [
'create',
],
},
},
options: [
adminPhoneField,
adminReadOnlyField,
],
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'admin',
],
operation: [
'update',
],
},
},
options: [
adminNameField,
adminPhoneField,
adminReadOnlyField,
],
},
];
@@ -0,0 +1,219 @@
import {
INodeProperties
} from 'n8n-workflow';
export const containerOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'container',
],
},
},
options: [
{
name: 'Add Tasks',
value: 'addTask',
description: 'Add task at index (or append)',
},
{
name: 'Get',
value: 'get',
description: 'Get container information',
},
{
name: 'Update Tasks',
value: 'updateTask',
description: 'Fully replace a container\'s tasks',
},
],
default: 'get',
},
];
const containerTypeField = {
displayName: 'Container Type',
name: 'containerType',
type: 'options',
options: [
{
name: 'Organizations',
value: 'organizations',
},
{
name: 'Teams',
value: 'teams',
},
{
name: 'Workers',
value: 'workers',
},
],
default: '',
description: 'Container type',
} as INodeProperties;
const containerIdField = {
displayName: 'Container ID',
name: 'containerId',
type: 'string',
default: '',
description: 'The object ID according to the container chosen',
} as INodeProperties;
const insertTypeField = {
displayName: 'Insert Type',
name: 'type',
type: 'options',
options: [
{
name: 'Append',
value: -1,
},
{
name: 'Prepend',
value: 0,
},
{
name: 'At Specific Index',
value: 1,
},
],
default: '',
} as INodeProperties;
const indexField = {
displayName: 'Index',
name: 'index',
type: 'number',
default: 0,
description: 'The index given indicates the position where the tasks are going to be inserted',
} as INodeProperties;
const tasksField = {
displayName: 'Task IDs',
name: 'tasks',
type: 'string',
typeOptions: {
multipleValues: true,
multipleValueButtonText: 'Add Task',
},
default: [],
description: 'Task\'s ID that are going to be used',
} as INodeProperties;
const considerDependenciesField = {
displayName: 'Consider Dependencies',
name: 'considerDependencies',
type: 'boolean',
default: false,
description: 'Whether to include the target task\'s dependency family (parent and child tasks) in the resulting assignment operation',
} as INodeProperties;
export const containerFields: INodeProperties[] = [
{
...containerTypeField,
displayOptions: {
show: {
resource: [
'container',
],
operation: [
'get',
'addTask',
],
},
},
required: true,
},
{
...containerIdField,
displayOptions: {
show: {
resource: [
'container',
],
operation: [
'get',
'addTask',
'updateTask',
],
},
},
required: true,
},
{
...insertTypeField,
displayOptions: {
show: {
resource: [
'container',
],
operation: [
'addTask',
],
},
},
required: true,
},
{
...indexField,
displayOptions: {
show: {
resource: [
'container',
],
operation: [
'addTask',
],
type: [
1,
],
},
},
required: true,
},
{
...tasksField,
displayOptions: {
show: {
resource: [
'container',
],
operation: [
'addTask',
'updateTask',
],
},
},
required: true,
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Option',
default: {},
displayOptions: {
show: {
resource: [
'container',
],
operation: [
'addTask',
'updateTask',
],
},
},
options: [
{
...considerDependenciesField,
required: false,
},
],
},
];
@@ -0,0 +1,402 @@
import {
INodeProperties
} from 'n8n-workflow';
export const destinationOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'destination',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new destination',
},
{
name: 'Get',
value: 'get',
description: 'Get a specific destination',
},
],
default: 'get',
},
];
const unparsedField = {
displayName: 'Unparsed Address',
name: 'unparsed',
type: 'boolean',
description: 'Whether or not the address is specified in a single unparsed string',
default: false,
} as INodeProperties;
const unparsedAddressField = {
displayName: 'Destination Address',
name: 'address',
type: 'string',
description: 'The destination\'s street address details',
default: '',
} as INodeProperties;
const unparsedAddressNumberField = {
displayName: 'Number',
name: 'addressNumber',
type: 'string',
description: 'The number component of this address, it may also contain letters',
default: '',
} as INodeProperties;
const unparsedAddressStreetField = {
displayName: 'Street',
name: 'addressStreet',
type: 'string',
description: 'The name of the street',
default: '',
} as INodeProperties;
const unparsedAddressCityField = {
displayName: 'City',
name: 'addressCity',
type: 'string',
description: 'The name of the municipality',
default: '',
} as INodeProperties;
const unparsedAddressCountryField = {
displayName: 'Country',
name: 'addressCountry',
type: 'string',
description: 'The name of the country',
default: '',
} as INodeProperties;
const unparsedAddressStateField = {
displayName: 'State',
name: 'addressState',
type: 'string',
default: '',
} as INodeProperties;
const addressNameField = {
displayName: 'Address Name',
name: 'addressName',
type: 'string',
default: '',
description: 'A name associated with this address',
} as INodeProperties;
const addressApartmentField = {
displayName: 'Apartment',
name: 'addressApartment',
type: 'string',
default: '',
description: 'The suite or apartment number, or any additional relevant information',
} as INodeProperties;
const addressNoteField = {
displayName: 'Address Notes',
name: 'addressNotes',
type: 'string',
default: '',
description: 'Notes about the destination',
} as INodeProperties;
const addressPostalCodeField = {
displayName: 'Postal Code',
name: 'addressPostalCode',
type: 'string',
default: '',
description: 'The postal or zip code',
} as INodeProperties;
export const destinationExternalField = {
displayName: 'Destination',
name: 'destination',
type: 'fixedCollection',
placeholder: 'Add Destination',
default: {},
options: [
{
displayName: 'Destination Properties',
name: 'destinationProperties',
default: {},
values: [
{
...unparsedField,
required: false,
},
{
...unparsedAddressField,
displayOptions: {
show: {
unparsed: [
true,
],
},
},
required: true,
},
{
...unparsedAddressNumberField,
displayOptions: {
show: {
unparsed: [
false,
],
},
},
required: true,
},
{
...unparsedAddressStreetField,
displayOptions: {
show: {
unparsed: [
false,
],
},
},
required: true,
},
{
...unparsedAddressCityField,
displayOptions: {
show: {
unparsed: [
false,
],
},
},
required: true,
},
{
...unparsedAddressStateField,
displayOptions: {
show: {
unparsed: [
false,
],
},
},
required: true,
},
{
...unparsedAddressCountryField,
displayOptions: {
show: {
unparsed: [
false,
],
},
},
required: true,
},
{
displayOptions: {
show: {
unparsed: [
false,
],
},
},
...addressPostalCodeField,
required: false,
},
{
...addressNameField,
required: false,
},
{
...addressApartmentField,
required: false,
},
{
...addressNoteField,
required: false,
},
],
},
],
} as INodeProperties;
export const destinationFields: INodeProperties[] = [
{
displayName: 'Destination ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'destination',
],
},
hide: {
operation: [
'create',
],
},
},
default: '',
required: true,
description: 'The ID of the destination object for lookup',
},
{
...unparsedField,
displayOptions: {
show: {
resource: [
'destination',
],
operation: [
'create',
],
},
},
required: true,
},
{
...unparsedAddressField,
displayOptions: {
show: {
resource: [
'destination',
],
operation: [
'create',
],
unparsed: [
true,
],
},
},
required: true,
},
{
...unparsedAddressNumberField,
displayOptions: {
show: {
resource: [
'destination',
],
operation: [
'create',
],
unparsed: [
false,
],
},
},
required: true,
},
{
...unparsedAddressStreetField,
displayOptions: {
show: {
resource: [
'destination',
],
operation: [
'create',
],
unparsed: [
false,
],
},
},
required: true,
},
{
...unparsedAddressCityField,
displayOptions: {
show: {
resource: [
'destination',
],
operation: [
'create',
],
unparsed: [
false,
],
},
},
required: true,
},
{
...unparsedAddressCountryField,
displayOptions: {
show: {
resource: [
'destination',
],
operation: [
'create',
],
unparsed: [
false,
],
},
},
required: true,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'destination',
],
operation: [
'create',
],
unparsed: [
true,
],
},
},
options: [
addressApartmentField,
addressNameField,
addressNoteField,
],
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'destination',
],
operation: [
'create',
],
unparsed: [
false,
],
},
},
options: [
addressApartmentField,
addressNameField,
addressNoteField,
addressPostalCodeField,
],
},
];
@@ -0,0 +1,199 @@
import {
INodeProperties
} from 'n8n-workflow';
import {
destinationExternalField,
} from './DestinationDescription';
export const hubOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'hub',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new Onfleet hub',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all Onfleet hubs',
},
{
name: 'Update',
value: 'update',
description: 'Update an Onfleet hub',
},
],
default: 'getAll',
},
];
const nameField = {
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'A name to identify the hub',
} as INodeProperties;
const teamsField = {
displayName: 'Teams Names/IDs',
name: 'teams',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTeams',
},
default: [],
description: 'These are the teams that this Hub will be assigned to',
} as INodeProperties;
export const hubFields: INodeProperties[] = [
{
displayName: 'Hub ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'hub',
],
operation: [
'update',
],
},
},
default: '',
required: true,
description: 'The ID of the hub object for lookup',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'hub',
],
operation: [
'getAll',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: [
'hub',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 64,
},
default: 64,
description: 'How many results to return',
},
{
...nameField,
displayOptions: {
show: {
resource: [
'hub',
],
operation: [
'create',
],
},
},
required: true,
},
{
...destinationExternalField,
displayOptions: {
show: {
resource: [
'hub',
],
operation: [
'create',
],
},
},
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'hub',
],
operation: [
'create',
],
},
},
options: [
{
...teamsField,
required: false,
},
],
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'hub',
],
operation: [
'update',
],
},
},
options: [
{
...destinationExternalField,
required: false,
},
nameField,
{
...teamsField,
required: false,
},
],
},
];
@@ -0,0 +1,43 @@
import {
INodeProperties
} from 'n8n-workflow';
import {
webhookMapping,
} from '../WebhookMapping';
const sort = (a: { name: string }, b: { name: string }) => {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
};
export const eventDisplay: INodeProperties = {
displayName: 'Trigger On',
name: 'triggerOn',
type: 'options',
options: Object.keys(webhookMapping).map((webhook) => {
const { name, value } = webhookMapping[webhook];
return { name, value };
}).sort(sort),
required: true,
default: [],
};
export const eventNameField = {
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
options: [
{
displayName: 'Name',
name: 'name',
type: 'string',
required: false,
default: '',
description: 'A name for the webhook for identification',
},
],
} as INodeProperties;
@@ -0,0 +1,53 @@
import {
INodeProperties
} from 'n8n-workflow';
export const organizationOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'organization',
],
},
},
options: [
{
name: 'Get My Organization',
value: 'get',
description: 'Retrieve your own organization\'s details',
},
{
name: 'Get Delegatee Details',
value: 'getDelegatee',
description: 'Retrieve the details of an organization with which you are connected',
},
],
default: 'get',
},
];
export const organizationFields: INodeProperties[] = [
{
displayName: 'Organization ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'organization',
],
operation: [
'getDelegatee',
],
},
},
default: '',
required: true,
description: 'The ID of the delegatees for lookup',
},
];
@@ -0,0 +1,329 @@
import {
INodeProperties
} from 'n8n-workflow';
export const recipientOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'recipient',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new Onfleet recipient',
},
{
name: 'Get',
value: 'get',
description: 'Get a specific Onfleet recipient',
},
{
name: 'Update',
value: 'update',
description: 'Update an Onfleet recipient',
},
],
default: 'get',
},
];
const additionalRecipientFields: INodeProperties[] = [
{
displayName: 'Recipient Notes',
name: 'recipientNotes',
type: 'string',
default: '',
description: 'Notes for this recipient: these are global notes that should not be task- or destination-specific',
required: false,
},
{
displayName: 'Skip Recipient SMS Notifications',
name: 'recipientSkipSMSNotifications',
type: 'boolean',
default: false,
description: 'Whether this recipient has requested to skip SMS notifications',
required: false,
},
];
const recipientName = {
displayName: 'Recipient Name',
name: 'recipientName',
type: 'string',
description: 'The recipient\'s complete name',
default: '',
} as INodeProperties;
const recipientPhone = {
displayName: 'Recipient Phone',
name: 'recipientPhone',
type: 'string',
description: 'A unique, valid phone number as per the organization\'s country if there\'s no leading + sign. If a phone number has a leading + sign, it will disregard the organization\'s country setting.',
default: '',
} as INodeProperties;
const updateFields: INodeProperties[] = [
{
...recipientName,
required: false,
},
{
displayName: 'Recipient Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes for this recipient: these are global notes that should not be task- or destination-specific',
},
{
...recipientPhone,
required: false,
},
{
displayName: 'Skip Recipient SMS Notifications',
name: 'skipSMSNotifications',
type: 'boolean',
default: false,
description: 'Whether this recipient has requested to skip SMS notifications',
},
];
export const recipientExternalField = {
displayName: 'Recipient',
name: 'recipient',
type: 'fixedCollection',
placeholder: 'Add Recipient',
default: {},
options: [
{
displayName: 'Recipient Properties',
name: 'recipientProperties',
default: {},
values: [
{
...recipientName,
required: true,
},
{
...recipientPhone,
required: true,
},
...additionalRecipientFields,
],
},
],
} as INodeProperties;
export const recipientFields: INodeProperties[] = [
{
displayName: 'Get By',
name: 'getBy',
type: 'options',
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'get',
],
},
},
options: [
{
name: 'ID',
value: 'id',
},
{
name: 'Phone',
value: 'phone',
},
{
name: 'Name',
value: 'name',
},
],
description: 'The variable that is used for looking up a recipient',
required: true,
default: 'id',
},
{
displayName: 'Recipient ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'get',
],
getBy: [
'id',
],
},
},
default: '',
required: true,
description: 'The ID of the recipient object for lookup',
},
{
displayName: 'Recipient ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'update',
],
},
},
default: '',
required: true,
description: 'The ID of the recipient object for lookup',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'get',
],
getBy: [
'name',
],
},
},
default: '',
required: true,
description: 'The name of the recipient for lookup',
},
{
displayName: 'Phone',
name: 'phone',
type: 'string',
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'get',
],
getBy: [
'phone',
],
},
},
default: '',
required: true,
description: 'The phone of the recipient for lookup',
},
{
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'create',
],
},
},
...recipientName,
required: true,
},
{
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'create',
],
},
},
...recipientPhone,
required: true,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'create',
],
},
},
options: additionalRecipientFields,
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Update Fields',
default: {},
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'update',
],
},
},
options: updateFields,
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'recipient',
],
operation: [
'create',
],
},
},
options: [
{
displayName: 'Skip Recipient Phone Number Validation',
name: 'recipientSkipPhoneNumberValidation',
type: 'boolean',
default: false,
description: 'Whether to skip validation for this recipient\'s phone number',
required: false,
},
],
},
];
@@ -0,0 +1,453 @@
import {
INodeProperties
} from 'n8n-workflow';
import {
destinationExternalField,
} from './DestinationDescription';
import {
recipientExternalField,
} from './RecipientDescription';
export const taskOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'task',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new Onfleet task',
},
{
name: 'Clone',
value: 'clone',
description: 'Clone an Onfleet task',
},
{
name: 'Complete',
value: 'complete',
description: 'Force-complete a started Onfleet task',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an Onfleet task',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all Onfleet tasks',
},
{
name: 'Get',
value: 'get',
description: 'Get a specific Onfleet task',
},
{
name: 'Update',
value: 'update',
description: 'Update an Onfleet task',
},
],
default: 'get',
},
];
const merchantIdField = {
displayName: 'Merchant ID',
name: 'merchant',
type: 'string',
default: '',
description: 'The ID of the organization that will be displayed to the recipient of the task',
} as INodeProperties;
const executorIdField = {
displayName: 'Executor ID',
name: 'executor',
type: 'string',
default: '',
description: 'The ID of the organization that will be responsible for fulfilling the task',
} as INodeProperties;
const completeAfterField = {
displayName: 'Complete After',
name: 'completeAfter',
type: 'dateTime',
default: null,
description: 'The earliest time the task should be completed',
} as INodeProperties;
const completeBeforeField = {
displayName: 'Complete Before',
name: 'completeBefore',
type: 'dateTime',
default: null,
description: 'The latest time the task should be completed',
} as INodeProperties;
const pickupTaskField = {
displayName: 'Pick Up Task',
name: 'pickupTask',
type: 'boolean',
default: false,
description: 'Whether the task is a pickup task',
} as INodeProperties;
const notesField = {
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Notes for the task',
} as INodeProperties;
const quantityField = {
displayName: 'Quantity',
name: 'quantity',
type: 'number',
default: 0,
description: 'The number of units to be dropped off while completing this task, for route optimization purposes',
} as INodeProperties;
const serviceTimeField = {
displayName: 'Service Time',
name: 'serviceTime',
type: 'number',
default: 0,
description: 'The number of minutes to be spent by the worker on arrival at this task\'s destination, for route optimization purposes',
} as INodeProperties;
export const taskFields: INodeProperties[] = [
{
displayName: 'Task ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'task',
],
},
hide: {
operation: [
'create',
'getAll',
],
},
},
default: '',
required: true,
description: 'The ID of the task object for lookup',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'getAll',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 64,
},
default: 64,
description: 'How many results to return',
},
{
...destinationExternalField,
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'create',
],
},
},
default: {},
required: true,
},
{
displayName: 'Complete as a Success',
name: 'success',
type: 'boolean',
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'complete',
],
},
},
description: 'Whether the task\'s completion was successful',
required: true,
default: true,
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'getAll',
],
},
},
options: [
{
displayName: 'From',
name: 'from',
type: 'dateTime',
default: '',
description: 'The starting time of the range. Tasks created or completed at or after this time will be included.',
},
{
displayName: 'State',
name: 'state',
type: 'multiOptions',
options: [
{
name: '[All]',
value: 'all',
},
{
name: 'Active',
value: 2,
},
{
name: 'Assigned',
value: 1,
},
{
name: 'Completed',
value: 3,
},
{
name: 'Unassigned',
value: 0,
},
],
default: ['all'],
description: 'The state of the tasks',
},
{
displayName: 'To',
name: 'to',
type: 'dateTime',
default: '',
description: 'The ending time of the range. Defaults to current time if not specified.',
},
],
},
{
displayName: 'Override Fields',
name: 'overrideFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'clone',
],
},
},
options: [
{
...completeAfterField,
},
{
...completeBeforeField,
},
{
displayName: 'Include Barcodes',
name: 'includeBarcodes',
type: 'boolean',
default: false,
},
{
displayName: 'Include Dependencies',
name: 'includeDependencies',
type: 'boolean',
default: false,
},
{
displayName: 'Include Metadata',
name: 'includeMetadata',
type: 'boolean',
default: false,
},
{
...notesField,
required: false,
},
{
...pickupTaskField,
required: false,
},
{
...serviceTimeField,
required: false,
},
],
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'update',
],
},
},
options: [
completeAfterField,
completeBeforeField,
executorIdField,
merchantIdField,
notesField,
pickupTaskField,
quantityField,
serviceTimeField,
],
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'complete',
],
},
},
options: [
{
displayName: 'Notes',
name: 'notes',
type: 'string',
default: '',
description: 'Completion Notes',
},
],
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'task',
],
operation: [
'create',
],
},
},
options: [
completeAfterField,
completeBeforeField,
executorIdField,
merchantIdField,
notesField,
pickupTaskField,
quantityField,
recipientExternalField,
{
displayName: 'Recipient Name Override',
name: 'recipientName',
type: 'string',
default: '',
description: 'Override the recipient name for this task only',
},
{
displayName: 'Recipient Notes Override',
name: 'recipientNotes',
type: 'string',
default: '',
description: 'Override the recipient notes for this task only',
},
{
displayName: 'Recipient Skip SMS Notifications Override',
name: 'recipientSkipSMSNotifications',
type: 'boolean',
default: false,
description: 'Whether to override the recipient notification settings for this task',
},
serviceTimeField,
{
displayName: 'Use Merchant For Proxy Override',
name: 'useMerchantForProxy',
type: 'boolean',
default: false,
description: 'Whether to override the organization ID with the merchant\'s org ID for this task',
},
],
},
];
@@ -0,0 +1,600 @@
import {
INodeProperties
} from 'n8n-workflow';
export const teamOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'team',
],
},
},
options: [
{
name: 'Auto-Dispatch',
value: 'autoDispatch',
description: 'Automatically dispatch tasks assigned to a team to on-duty drivers',
},
{
name: 'Create',
value: 'create',
description: 'Create a new Onfleet team',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an Onfleet team',
},
{
name: 'Get',
value: 'get',
description: 'Get a specific Onfleet team',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all Onfleet teams',
},
{
name: 'Get Time Estimates',
value: 'getTimeEstimates',
description: 'Get estimated times for upcoming tasks for a team, returns a selected driver',
},
{
name: 'Update',
value: 'update',
description: 'Update an Onfleet team',
},
],
default: 'getAll',
},
];
const nameField = {
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'A unique name for the team',
} as INodeProperties;
const workersField = {
displayName: 'Workers Names/IDs',
name: 'workers',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getWorkers',
},
default: [],
description: 'A list of workers',
} as INodeProperties;
const managersField = {
displayName: 'Administrators Names/IDs',
name: 'managers',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getAdmins',
},
default: [],
description: 'A list of managing administrators',
} as INodeProperties;
const hubField = {
displayName: 'Hub Name/ID',
name: 'hub',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getHubs',
},
default: '',
description: 'The team\'s hub',
} as INodeProperties;
const enableSelfAssignmentField = {
displayName: 'Self Assignment',
name: 'enableSelfAssignment',
type: 'boolean',
default: false,
description: 'Whether or not to allow drivers to self-assign tasks that are in the Team\'s unassigned container',
} as INodeProperties;
const maxTasksPerRouteField = {
displayName: 'Max Number Of Tasks Per Route',
name: 'maxTasksPerRoute',
type: 'number',
default: 100,
typeOptions: {
maxValue: 200,
minValue: 1,
},
description: 'Total number of tasks allowed on a route',
} as INodeProperties;
const serviceTimeField = {
displayName: 'Service Time',
name: 'serviceTime',
type: 'number',
default: 2,
typeOptions: {
minValue: 0,
},
description: 'The default service time to apply in Minutes to the tasks when no task service time exists',
} as INodeProperties;
const routeEndField = {
displayName: 'Route End',
name: 'routeEnd',
type: 'options',
options: [
{
name: 'Team’s Hub',
value: 'team_hub',
},
{
name: 'Worker Routing Address',
value: 'worker_routing_address',
},
{
name: 'Hub',
value: 'hub',
},
{
name: 'End Anywhere',
value: 'anywhere',
},
],
default: '',
description: 'Where the route will end',
} as INodeProperties;
const maxAllowedDelayField = {
displayName: 'Max Allowed Delay',
name: 'maxAllowedDelay',
type: 'number',
default: 10,
description: 'Max allowed time in minutes that a task can be late',
typeOptions: {
minValue: 1,
},
} as INodeProperties;
const longitudeDropOffField = {
displayName: 'Drop Off Longitude',
name: 'dropOffLongitude',
type: 'number',
typeOptions: {
numberPrecision: 14,
},
default: 0,
description: 'The longitude for drop off location',
} as INodeProperties;
const latitudeDropOffField = {
displayName: 'Drop Off Latitude',
name: 'dropOffLatitude',
type: 'number',
typeOptions: {
numberPrecision: 14,
},
default: 0,
description: 'The latitude for drop off location',
} as INodeProperties;
const longitudePickupField = {
displayName: 'Pick Up Longitude',
name: 'pickupLongitude',
type: 'number',
typeOptions: {
numberPrecision: 14,
},
default: 0,
description: 'The longitude for pickup location',
} as INodeProperties;
const latitudePickupField = {
displayName: 'Pick Up Latitude',
name: 'pickupLatitude',
type: 'number',
typeOptions: {
numberPrecision: 14,
},
default: 0,
description: 'The latitude for pickup location',
} as INodeProperties;
const pickupTimeField = {
displayName: 'Pick Up Time',
name: 'pickupTime',
type: 'dateTime',
default: '',
description: 'If the request includes pickupLocation, pickupTime must be present if the time is fewer than 3 hours in the future',
} as INodeProperties;
const restrictedVehicleTypesField = {
displayName: 'Restricted Vehicle Types',
name: 'restrictedVehicleTypes',
type: 'options',
options: [
{
name: 'Car',
value: 'CAR',
},
{
name: 'Motorcycle',
value: 'MOTORCYCLE',
},
{
name: 'Bicycle',
value: 'BICYCLE',
},
{
name: 'Truck',
value: 'TRUCK',
},
],
default: 'CAR',
description: 'Vehicle types to ignore in the query',
} as INodeProperties;
const serviceTimeEstimateField = {
displayName: 'Service Time',
name: 'serviceTime',
type: 'number',
default: 120,
typeOptions: {
minValue: 0,
},
description: 'The expected time a worker will take at the pickupLocation, dropoffLocation, or both (as applicable) Unit: seconds',
} as INodeProperties;
export const teamFields: INodeProperties[] = [
{
displayName: 'Team ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'get',
'update',
'delete',
'getTimeEstimates',
'autoDispatch',
],
},
},
default: '',
required: true,
description: 'The ID of the team object for lookup',
},
{
...nameField,
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'create',
],
},
},
required: true,
},
{
...workersField,
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'create',
],
},
},
required: true,
},
{
...managersField,
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'create',
],
},
},
required: true,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'create',
],
},
},
options: [
hubField,
enableSelfAssignmentField,
],
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'getAll',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 64,
},
default: 64,
description: 'How many results to return',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'update',
],
},
},
options: [
managersField,
hubField,
nameField,
enableSelfAssignmentField,
workersField,
],
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'autoDispatch',
],
},
},
options: [
{
displayName: 'Ending Route',
name: 'endingRoute',
type: 'fixedCollection',
placeholder: 'Add Route',
default: {},
options: [
{
displayName: 'Ending Route Properties',
name: 'endingRouteProperties',
type: 'fixedCollection',
default: {},
values: [
{
...routeEndField,
required: true,
},
{
...hubField,
displayOptions: {
show: {
routeEnd: [
'hub',
],
},
},
required: false,
},
],
},
],
},
maxAllowedDelayField,
maxTasksPerRouteField,
{
displayName: 'Schedule Time Window',
name: 'scheduleTimeWindow',
type: 'fixedCollection',
placeholder: 'Add Time Window',
default: {},
options: [
{
displayName: 'Schedule Time Window Properties',
name: 'scheduleTimeWindowProperties',
type: 'fixedCollection',
default: {},
values: [
{
displayName: 'Start Time',
name: 'startTime',
type: 'dateTime',
default: '',
},
{
displayName: 'End Time',
name: 'endTime',
type: 'dateTime',
default: '',
},
],
},
],
},
serviceTimeField,
{
displayName: 'Task Time Window',
name: 'taskTimeWindow',
type: 'fixedCollection',
placeholder: 'Add Time Window',
default: {},
options: [
{
displayName: 'Task Time Window Properties',
name: 'taskTimeWindowProperties',
type: 'fixedCollection',
default: {},
values: [
{
displayName: 'Start Time',
name: 'startTime',
type: 'dateTime',
default: '',
},
{
displayName: 'End Time',
name: 'endTime',
type: 'dateTime',
default: '',
},
],
},
],
},
],
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'team',
],
operation: [
'getTimeEstimates',
],
},
},
options: [
{
displayName: 'Drop Off',
name: 'dropOff',
type: 'fixedCollection',
placeholder: 'Add Drop Off',
default: {},
options: [
{
displayName: 'DropOff Properties',
name: 'dropOffProperties',
type: 'fixedCollection',
default: {},
values: [
{
...longitudeDropOffField,
required: true,
},
{
...latitudeDropOffField,
required: true,
},
],
},
],
},
{
displayName: 'Pick Up',
name: 'pickUp',
type: 'fixedCollection',
default: {},
placeholder: 'Add Pick Up',
options: [
{
displayName: 'Pick Up Properties',
name: 'pickUpProperties',
type: 'fixedCollection',
default: {},
values: [
{
...longitudePickupField,
required: true,
},
{
...latitudePickupField,
required: true,
},
{
...pickupTimeField,
required: false,
},
],
},
],
},
{
...restrictedVehicleTypesField,
required: false,
},
{
...serviceTimeEstimateField,
required: false,
},
],
},
];
@@ -0,0 +1,161 @@
import {
INodeProperties
} from 'n8n-workflow';
import {
webhookMapping,
} from '../WebhookMapping';
export const webhookOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'webhook',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new Onfleet webhook',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an Onfleet webhook',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all Onfleet webhooks',
},
],
default: 'getAll',
},
];
const urlField = {
displayName: 'URL',
name: 'url',
type: 'string',
default: '',
description: 'The URL that Onfleet should issue a request against as soon as the trigger condition is met. It must be HTTPS and have a valid certificate.',
} as INodeProperties;
const nameField = {
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'A name for the webhook for identification',
} as INodeProperties;
const triggerField = {
displayName: 'Trigger',
name: 'trigger',
type: 'options',
options: Object.entries(webhookMapping).map(([key, value]) => {
return {
name: value.name,
value: value.key,
};
}),
default: '',
description: 'The number corresponding to the trigger condition on which the webhook should fire',
} as INodeProperties;
const thresholdField = {
displayName: 'Threshold',
name: 'threshold',
type: 'number',
default: 0,
description: 'For trigger Task Eta, the time threshold in seconds; for trigger Task Arrival, the distance threshold in meters',
} as INodeProperties;
export const webhookFields: INodeProperties[] = [
{
displayName: 'Webhook ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'webhook',
],
operation: [
'delete',
],
},
},
default: '',
required: true,
description: 'The ID of the webhook object for lookup',
},
{
...urlField,
displayOptions: {
show: {
resource: [
'webhook',
],
operation: [
'create',
],
},
},
required: true,
},
{
...nameField,
displayOptions: {
show: {
resource: [
'webhook',
],
operation: [
'create',
],
},
},
required: true,
},
{
...triggerField,
displayOptions: {
show: {
resource: [
'webhook',
],
operation: [
'create',
],
},
},
required: true,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'webhook',
],
operation: [
'create',
],
},
},
options: [
thresholdField,
],
},
];
@@ -0,0 +1,754 @@
import {
INodeProperties
} from 'n8n-workflow';
export const workerOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: ['worker'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new Onfleet worker',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete an Onfleet worker',
},
{
name: 'Get',
value: 'get',
description: 'Get a specific Onfleet worker',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all Onfleet workers',
},
{
name: 'Get Schedule',
value: 'getSchedule',
description: 'Get a specific Onfleet worker schedule',
},
// {
// name: 'Set Worker\'s Schedule',
// value: 'setSchedule',
// description: 'Set the worker\'s schedule',
// },
{
name: 'Update',
value: 'update',
description: 'Update an Onfleet worker',
},
],
default: 'get',
},
];
const byLocationField = {
displayName: 'Search by Location',
name: 'byLocation',
type: 'boolean',
default: false,
description: 'Whether to search for only those workers who are currently within a certain target area',
} as INodeProperties;
const nameField = {
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'The worker\'s name',
} as INodeProperties;
const phoneField = {
displayName: 'Phone',
name: 'phone',
type: 'string',
default: '',
description: 'A list of worker’s phone numbers',
} as INodeProperties;
const capacityField = {
displayName: 'Capacity',
name: 'capacity',
type: 'number',
default: 0,
description: 'The maximum number of units this worker can carry, for route optimization purposes',
} as INodeProperties;
const displayNameField = {
displayName: 'Display Name',
name: 'displayName',
type: 'string',
default: '',
description: 'This value is used in place of the worker\'s actual name within sms notifications, delivery tracking pages, and across organization boundaries',
} as INodeProperties;
const vehicleTypeField = {
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Bicycle',
value: 'BICYCLE',
},
{
name: 'Car',
value: 'CAR',
},
{
name: 'Motorcycle',
value: 'MOTORCYCLE',
},
{
name: 'Truck',
value: 'TRUCK',
},
],
default: '',
description: 'Whether the worker has vehicle or not. If it\'s not provided, this worker will be treated as if on foot.',
} as INodeProperties;
const vehicleDescriptionField = {
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
description: 'The vehicle\'s make, model, year, or any other relevant identifying details',
} as INodeProperties;
const vehicleLicensePlateField = {
displayName: 'License Plate',
name: 'licensePlate',
type: 'string',
default: '',
description: 'The vehicle\'s license plate number',
} as INodeProperties;
const vehicleColorField = {
displayName: 'Color',
name: 'color',
type: 'string',
default: '',
description: 'The vehicle\'s color',
} as INodeProperties;
const teamsField = {
displayName: 'Teams Names/IDs',
name: 'teams',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTeams',
},
default: [],
description: 'One or more teams of which the worker is a member',
} as INodeProperties;
const teamsFilterField = {
displayName: 'Teams ID/Name',
name: 'teams',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getTeams',
},
default: [],
description: 'A list of the teams that workers must be part of',
} as INodeProperties;
const statesFilterField = {
displayName: 'States',
name: 'states',
type: 'multiOptions',
options: [
{
name: 'Active (On-Duty, Active Task)',
value: 2,
},
{
name: 'Idle (On-Duty, No Active Task)',
value: 1,
},
{
name: 'Off-Duty',
value: 0,
},
],
default: [],
description: 'List of worker states',
} as INodeProperties;
const phonesFilterField = {
displayName: 'Phones',
name: 'phones',
type: 'string',
typeOptions: {
multipleValues: true,
multipleValueButtonText: 'Add Phone',
},
default: [],
description: 'A list of workers\' phone numbers',
} as INodeProperties;
const filterField = {
displayName: 'Fields to Return',
name: 'filter',
type: 'multiOptions',
options: [
{
name: 'Account Status',
value: 'accountStatus',
},
{
name: 'Active Task',
value: 'activeTask',
},
{
name: 'Capacity',
value: 'capacity',
},
{
name: 'Delay Time',
value: 'delayTime',
},
{
name: 'Display Name',
value: 'displayName',
},
{
name: 'Image Url',
value: 'imageUrl',
},
{
name: 'Location',
value: 'location',
},
{
name: 'Metadata',
value: 'metadata',
},
{
name: 'Name',
value: 'name',
},
{
name: 'On Duty',
value: 'onDuty',
},
{
name: 'Organization',
value: 'organization',
},
{
name: 'Phone',
value: 'phone',
},
{
name: 'Tasks',
value: 'tasks',
},
{
name: 'Teams',
value: 'teams',
},
{
name: 'Time Created',
value: 'timeCreated',
},
{
name: 'Time Last Modified',
value: 'timeLastModified',
},
{
name: 'Time Last Seen',
value: 'timeLastSeen',
},
{
name: 'User Data',
value: 'userData',
},
{
name: 'Vehicle',
value: 'vehicle',
},
{
name: 'Worker ID',
value: 'id',
},
],
default: [],
description: 'A list of fields to show in the response, if all are not desired',
} as INodeProperties;
const longitudeFilterField = {
displayName: 'Longitude',
name: 'longitude',
type: 'number',
typeOptions: {
numberPrecision: 14,
},
default: 0,
description: 'The longitude component of the coordinate pair',
} as INodeProperties;
const latitudeFilterField = {
displayName: 'Latitude',
name: 'latitude',
type: 'number',
typeOptions: {
numberPrecision: 14,
},
default: 0,
description: 'The latitude component of the coordinate pair',
} as INodeProperties;
const radiusFilterField = {
displayName: 'Radius',
name: 'radius',
type: 'number',
typeOptions: {
maxValue: 10000,
minValue: 0,
},
default: 1000,
description: 'The length in meters of the radius of the spherical area in which to look for workers. Defaults to 1000 if missing. Maximum value is 10000.',
} as INodeProperties;
const scheduleDateField = {
displayName: 'Date',
name: 'date',
type: 'dateTime',
default: '',
description: 'Schedule\'s date',
} as INodeProperties;
const scheduleTimezoneField = {
displayName: 'Timezone',
name: 'timezone',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getTimezones',
},
default: '',
description: 'A valid timezone',
} as INodeProperties;
const scheduleStartField = {
displayName: 'Start',
name: 'start',
type: 'dateTime',
default: '',
description: 'Start time',
} as INodeProperties;
const scheduleEndField = {
displayName: 'End',
name: 'end',
type: 'dateTime',
default: '',
description: 'End time',
} as INodeProperties;
export const workerFields: INodeProperties[] = [
{
...byLocationField,
required: true,
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'getAll',
],
},
},
},
{
displayName: 'Worker ID',
name: 'id',
type: 'string',
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'get',
'getSchedule',
'setSchedule',
'update',
'delete',
],
},
},
default: '',
required: true,
description: 'The ID of the worker object for lookup',
},
{
...nameField,
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'create',
],
},
},
required: true,
},
{
...phoneField,
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'create',
],
},
},
required: true,
},
{
...teamsField,
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'create',
],
},
},
required: true,
},
{
...longitudeFilterField,
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'getAll',
],
byLocation: [
true,
],
},
},
required: true,
},
{
...latitudeFilterField,
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'getAll',
],
byLocation: [
true,
],
},
},
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'getAll',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 64,
},
default: 64,
description: 'How many results to return',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'create',
],
},
},
options: [
capacityField,
displayNameField,
{
displayName: 'Vehicle',
name: 'vehicle',
type: 'fixedCollection',
placeholder: 'Add Vehicle',
default: {},
options: [
{
displayName: 'Vehicle Properties',
name: 'vehicleProperties',
values: [
{
...vehicleTypeField,
required: true,
},
{
...vehicleDescriptionField,
required: false,
},
{
...vehicleLicensePlateField,
required: false,
},
{
...vehicleColorField,
required: false,
},
],
},
],
},
],
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'update',
],
},
},
options: [
capacityField,
displayNameField,
nameField,
teamsField,
],
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'getAll',
],
byLocation: [
true,
],
},
},
options: [
radiusFilterField,
],
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'getAll',
],
byLocation: [
false,
],
},
},
options: [
statesFilterField,
teamsFilterField,
phonesFilterField,
],
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'getAll',
],
},
},
options: [
filterField,
],
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'get',
],
},
},
options: [
{
displayName: 'Analytics',
name: 'analytics',
type: 'boolean',
default: true,
required: false,
description: 'Whether a more detailed response is needed, includes basic worker duty event, traveled distance (meters) and time analytics',
},
{
...filterField,
required: false,
},
],
},
{
displayName: 'Schedule',
name: 'schedule',
type: 'fixedCollection',
placeholder: 'Add Schedule',
displayOptions: {
show: {
resource: [
'worker',
],
operation: [
'setSchedule',
],
},
},
default: {},
typeOptions: {
multipleValues: true,
multipleValueButtonText: 'Add Schedule',
},
options: [
{
displayName: 'Schedule Properties',
name: 'scheduleProperties',
default: {},
values: [
{
...scheduleDateField,
required: true,
},
{
...scheduleTimezoneField,
required: true,
},
{
displayName: 'Shifts',
name: 'shifts',
type: 'fixedCollection',
default: {},
placeholder: 'Add Shift',
typeOptions: {
multipleValues: true,
},
options: [
{
displayName: 'Shifts Properties',
name: 'shiftsProperties',
default: {},
values: [
{
...scheduleStartField,
required: true,
},
{
...scheduleEndField,
required: true,
},
],
},
],
},
],
},
],
},
];
@@ -0,0 +1,184 @@
export interface OnfleetRecipient {
name?: string;
phone?: string;
notes?: string;
skipSMSNotifications?: boolean;
skipPhoneNumberValidation?: boolean;
}
export interface OnfleetDestinationAddress {
name?: string;
number?: string;
street?: string;
apartment?: string;
city?: string;
state?: string;
postalCode?: string;
country?: string;
unparsed?: string;
}
export interface OnfleetDestinationOptions {
language?: string;
}
export interface OnfleetDestination {
address: OnfleetDestinationAddress;
location?: [number, number];
notes?: string;
options?: OnfleetDestinationOptions;
}
export interface OnfleetTask {
merchant?: string;
executor?: string;
destination: OnfleetDestination;
recipients: OnfleetRecipient[];
completeAfter?: number;
completeBefore?: number;
pickupTask?: boolean;
notes?: string;
quantity?: number;
serviceTime?: number;
}
export interface OnfleetTaskUpdate {
merchant?: string;
executor?: string;
completeAfter?: number;
completeBefore?: number;
pickupTask?: boolean;
notes?: string;
quantity?: number;
serviceTime?: number;
}
export interface OnfleetListTaskFilters {
from?: number;
to?: number;
lastId?: string;
state?: string;
worker?: string;
completeBeforeBefore?: number;
completeAfterAfter?: number;
dependencies?: string;
}
export interface OnfleetCloneOverrideTaskOptions {
completeAfter?: number;
completeBefore?: number;
destination?: OnfleetDestination;
notes?: string;
pickupTask?: boolean;
recipients?: OnfleetRecipient[];
serviceTime?: number;
}
export interface OnfleetCloneTaskOptions {
includeMetadata?: boolean;
includeBarcodes?: boolean;
includeDependencies?: boolean;
overrides?: OnfleetCloneOverrideTaskOptions;
}
export interface OnfleetCloneTask {
options?: OnfleetCloneTaskOptions;
}
export interface OnfleetTaskCompletionDetails {
success: boolean;
notes?: string;
}
export interface OnfleetTaskComplete {
completionDetails: OnfleetTaskCompletionDetails;
}
export interface OnfleetAdmins {
name?: string;
email?: string;
phone?: string;
isReadOnly?: boolean;
}
export interface OnfleetHubs extends OnfleetDestination {
name?: string;
teams?: string[];
}
export interface OnfleetVehicle {
type?: string;
description?: string;
licensePlate?: string;
color?: string;
}
export interface OnfleetWorker {
name?: string;
phone?: string;
vehicle?: OnfleetVehicle;
teams?: string[];
capacity?: number;
displayName?: string;
}
export interface OnfleetWorkerFilter {
[key: string]: string | undefined;
filter?: string;
teams?: string;
states?: string;
phones?: string;
analytics?: string;
}
export interface OnfleetWorkerScheduleEntry {
date?: string;
timezone?: string;
shifts?: [[number, number]];
}
export interface OnfleetWebhook {
url?: string;
name?: string;
trigger?: number;
threshold?: number;
}
export interface OnfleetTeams {
name?: string;
workers?: string[];
managers?: string[];
hub?: string;
enableSelfAssignment?: boolean;
}
export interface OnfleetWorkerSchedule {
entries: OnfleetWorkerScheduleEntry[];
}
export interface OnfleetWebhookMapping {
key: number;
name: string;
value: string;
}
export interface OnfleetWebhooksMapping {
[key: string]: OnfleetWebhookMapping;
}
export interface OnfleetWorkerEstimates {
dropoffLocation?: string;
pickupLocation?: string;
pickupTime?: number;
restrictedVehicleTypes?: string;
serviceTime?: number;
}
export interface OnfleetTeamAutoDispatch {
maxTasksPerRoute?: number;
taskTimeWindow?: [number, number];
scheduleTimeWindow?: [number, number];
serviceTime?: number;
routeEnd?: string;
maxAllowedDelay?: number;
}
+3
View File
@@ -210,6 +210,7 @@
"dist/credentials/OAuth1Api.credentials.js",
"dist/credentials/OAuth2Api.credentials.js",
"dist/credentials/OneSimpleApi.credentials.js",
"dist/credentials/OnfleetApi.credentials.js",
"dist/credentials/OpenWeatherMapApi.credentials.js",
"dist/credentials/OrbitApi.credentials.js",
"dist/credentials/OuraApi.credentials.js",
@@ -543,6 +544,8 @@
"dist/nodes/NextCloud/NextCloud.node.js",
"dist/nodes/NocoDB/NocoDB.node.js",
"dist/nodes/NoOp/NoOp.node.js",
"dist/nodes/Onfleet/Onfleet.node.js",
"dist/nodes/Onfleet/OnfleetTrigger.node.js",
"dist/nodes/Notion/Notion.node.js",
"dist/nodes/Notion/NotionTrigger.node.js",
"dist/nodes/OneSimpleApi/OneSimpleApi.node.js",
+1
View File
@@ -13,6 +13,7 @@ import { INode, IStatusCodeMessages, JsonObject } from '.';
* Top-level properties where an error message can be found in an API response.
*/
const ERROR_MESSAGE_PROPERTIES = [
'cause',
'error',
'message',
'Message',