n8n/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts

2581 lines
99 KiB
TypeScript
Raw Normal View History

2020-02-10 12:55:28 -08:00
import {
IExecuteFunctions,
} from 'n8n-core';
2020-02-10 12:55:28 -08:00
import {
IDataObject,
ILoadOptionsFunctions,
INodeExecutionData,
INodePropertyOptions,
2020-02-10 12:55:28 -08:00
INodeType,
INodeTypeDescription,
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
NodeApiError,
NodeOperationError,
2020-02-10 12:55:28 -08:00
} from 'n8n-workflow';
2020-02-10 12:55:28 -08:00
import {
accountFields,
accountOperations,
} from './AccountDescription';
2020-02-10 12:55:28 -08:00
import {
IAccount,
} from './AccountInterface';
import {
attachmentFields,
attachmentOperations,
} from './AttachmentDescription';
import {
IAttachment,
} from './AttachmentInterface';
import {
ICampaignMember,
} from './CampaignMemberInterface';
import {
caseFields,
caseOperations,
} from './CaseDescription';
import {
ICase,
ICaseComment,
} from './CaseInterface';
2020-02-10 12:55:28 -08:00
import {
contactFields,
contactOperations,
} from './ContactDescription';
2020-02-10 12:55:28 -08:00
import {
IContact,
} from './ContactInterface';
import {
customObjectFields,
customObjectOperations,
} from './CustomObjectDescription';
import {
flowFields,
flowOperations,
} from './FlowDescription';
2020-02-10 12:55:28 -08:00
import {
getQuery,
salesforceApiRequest,
salesforceApiRequestAllItems,
2020-10-16 02:13:04 -07:00
sortOptions,
} from './GenericFunctions';
import {
leadFields,
leadOperations,
} from './LeadDescription';
2020-02-10 12:55:28 -08:00
import {
ILead,
} from './LeadInterface';
2020-02-10 12:55:28 -08:00
import {
INote,
} from './NoteInterface';
2020-02-10 12:55:28 -08:00
import {
opportunityFields,
opportunityOperations,
} from './OpportunityDescription';
import {
IOpportunity,
} from './OpportunityInterface';
import {
searchFields,
searchOperations,
} from './SearchDescription';
import {
taskFields,
taskOperations,
} from './TaskDescription';
2020-02-10 12:55:28 -08:00
import {
ITask,
} from './TaskInterface';
import {
userFields,
userOperations,
} from './UserDescription';
:sparkles: Added logging to n8n (#1381) * Added logging to n8n This commit adds logging to n8n using the Winston library. For now, this commit only allows logging to console (default behavior) or file (need to pass in config via environment variables). Other logging methods can be further implemented using hooks. These were skipped for now as it would require adding more dependencies. Logging level is notice by default, meaning no additional messages would be displayed at the moment. Logging level can be set to info or debug as well to enrich the generated logs. The ILogger interface was added to the workflow project as it would make it available for all other projects but the implementation was done on the cli project. * Lint fixes and logging level naming. Also fixed the way we use the logger as it was not working previously * Improvements to logging framework Using appropriate single quotes Improving the way the logger is declared * Improved naming for Log Types * Removed logger global variable, replacing it by a proxy * Add logging to CLI commands * Remove unused GenericHelpers * Changed back some messages to console instead of logger and added npm shortcuts for worker and webhook * Fix typos * Adding basic file rotation to logs as suggested by @mutdmour * Fixed linting issues * Correcting comment to correctly reflect space usage * Added settings for log files rotation * Correcting config type from String to Number * Changed default file settings to number To reflect previous changes to the type * Changed the way log messages are added to be called statically. Also minor naming improvements * Applying latest corrections sent by @ivov * :zap: Some logging improvements * Saving logs to a folder inside n8n home instead of root * Fixed broken tests and linting * Changed some log messages to improve formatting * Adding quotes to names on log messages * Added execution and session IDs to logs. Also removed unnecessary line breaks * :zap: Added file caller to log messages (#1657) This is done using callsites library which already existed in the project as another library's dependency. So in fact it does not add any new dependency. * Adding logs to help debug Salesforce node * :zap: Add function name to logs and add more logs * :zap: Improve some error messages * :zap: Improve some more log messages * :zap: Rename logging env variables to match others Co-authored-by: dali <servfrdali@yahoo.fr> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-05-01 20:43:01 -07:00
import {
LoggerProxy as Logger,
} from 'n8n-workflow';
2020-02-10 12:55:28 -08:00
export class Salesforce implements INodeType {
description: INodeTypeDescription = {
displayName: 'Salesforce',
name: 'salesforce',
icon: 'file:salesforce.svg',
2020-02-10 12:55:28 -08:00
group: ['output'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Consume Salesforce API',
defaults: {
name: 'Salesforce',
color: '#429fd9',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'salesforceOAuth2Api',
required: true,
displayOptions: {
show: {
authentication: [
'oAuth2',
],
},
},
},
{
name: 'salesforceJwtApi',
required: true,
displayOptions: {
show: {
authentication: [
'jwt',
],
},
},
2020-02-10 12:55:28 -08:00
},
],
properties: [
{
displayName: 'Authentication',
name: 'authentication',
type: 'options',
options: [
{
name: 'OAuth2',
value: 'oAuth2',
},
{
name: 'OAuth2 JWT',
value: 'jwt',
},
],
default: 'oAuth2',
description: 'OAuth Authorization Flow',
},
2020-02-10 12:55:28 -08:00
{
displayName: 'Resource',
name: 'resource',
type: 'options',
options: [
{
name: 'Account',
value: 'account',
description: 'Represents an individual account, which is an organization or person involved with your business (such as customers, competitors, and partners).',
},
{
name: 'Attachment',
value: 'attachment',
description: 'Represents a file that a has uploaded and attached to a parent object.',
},
{
name: 'Case',
value: 'case',
description: 'Represents a case, which is a customer issue or problem.',
2020-02-10 12:55:28 -08:00
},
{
name: 'Contact',
value: 'contact',
description: 'Represents a contact, which is an individual associated with an account.',
},
{
name: 'Custom Object',
value: 'customObject',
description: 'Represents a custom object.',
},
{
name: 'Flow',
value: 'flow',
description: 'Represents an autolaunched flow.',
},
{
name: 'Lead',
value: 'lead',
description: 'Represents a prospect or potential.',
},
2020-02-10 12:55:28 -08:00
{
name: 'Opportunity',
value: 'opportunity',
description: 'Represents an opportunity, which is a sale or pending deal.',
},
{
name: 'Search',
value: 'search',
description: 'Search records',
},
2020-02-10 12:55:28 -08:00
{
name: 'Task',
value: 'task',
description: 'Represents a business activity such as making a phone call or other to-do items. In the user interface, and records are collectively referred to as activities.',
},
{
name: 'User',
value: 'user',
description: 'Represents a person, which is one user in system.',
},
2020-02-10 12:55:28 -08:00
],
default: 'lead',
description: 'Resource to consume.',
},
...leadOperations,
...leadFields,
...contactOperations,
...contactFields,
...customObjectOperations,
...customObjectFields,
2020-02-10 12:55:28 -08:00
...opportunityOperations,
...opportunityFields,
...accountOperations,
...accountFields,
...searchOperations,
...searchFields,
2020-02-10 12:55:28 -08:00
...caseOperations,
...caseFields,
...taskOperations,
...taskFields,
...attachmentOperations,
...attachmentFields,
...userOperations,
...userFields,
...flowOperations,
...flowFields,
2020-02-10 12:55:28 -08:00
],
};
methods = {
loadOptions: {
// Get all the lead statuses to display them to user so that he can
// select them easily
async getLeadStatuses(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const qs = {
q: 'SELECT id, MasterLabel FROM LeadStatus',
};
const statuses = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
for (const status of statuses) {
const statusName = status.MasterLabel;
const statusId = status.Id;
returnData.push({
name: statusName,
value: statusId,
});
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the users to display them to user so that he can
// select them easily
async getUsers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const qs = {
q: 'SELECT id, Name FROM User',
};
const users = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
for (const user of users) {
const userName = user.Name;
const userId = user.Id;
returnData.push({
name: userName,
value: userId,
});
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the users and case queues to display them to user so that he can
// select them easily
async getCaseOwners(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const qsQueues = {
2021-04-24 10:45:33 -07:00
q: 'SELECT Queue.Id, Queue.Name FROM QueuesObject where Queue.Type=\'Queue\' and SobjectType = \'Case\'',
};
const queues = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qsQueues);
for (const queue of queues) {
const queueName = queue.Queue.Name;
const queueId = queue.Queue.Id;
returnData.push({
name: `Queue: ${queueName}`,
value: queueId,
});
}
const qsUsers = {
q: 'SELECT id, Name FROM User',
};
const users = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qsUsers);
const userPrefix = returnData.length > 0 ? 'User: ' : '';
for (const user of users) {
const userName = user.Name;
const userId = user.Id;
returnData.push({
name: userPrefix + userName,
value: userId,
});
}
sortOptions(returnData);
return returnData;
},
// Get all the users and lead queues to display them to user so that he can
// select them easily
async getLeadOwners(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const qsQueues = {
2021-04-24 10:45:33 -07:00
q: 'SELECT Queue.Id, Queue.Name FROM QueuesObject where Queue.Type=\'Queue\' and SobjectType = \'Lead\'',
};
const queues = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qsQueues);
for (const queue of queues) {
const queueName = queue.Queue.Name;
const queueId = queue.Queue.Id;
returnData.push({
name: `Queue: ${queueName}`,
value: queueId,
});
}
const qsUsers = {
q: 'SELECT id, Name FROM User',
};
const users = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qsUsers);
const userPrefix = returnData.length > 0 ? 'User: ' : '';
for (const user of users) {
const userName = user.Name;
const userId = user.Id;
returnData.push({
name: userPrefix + userName,
value: userId,
});
}
sortOptions(returnData);
return returnData;
},
2020-02-10 12:55:28 -08:00
// Get all the lead sources to display them to user so that he can
// select them easily
async getLeadSources(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/lead/describe');
2020-02-10 12:55:28 -08:00
for (const field of fields) {
if (field.name === 'LeadSource') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the lead custom fields to display them to user so that he can
// select them easily
async getCustomFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const resource = this.getNodeParameter('resource', 0) as string;
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/${resource}/describe`);
for (const field of fields) {
if (field.custom === true) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
return returnData;
},
// Get all the external id fields to display them to user so that he can
// select them easily
async getExternalIdFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
let resource = this.getCurrentNodeParameter('resource') as string;
resource = (resource === 'customObject') ? this.getCurrentNodeParameter('customObject') as string : resource;
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/${resource}/describe`);
for (const field of fields) {
if (field.externalId === true || field.idLookup === true) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
}
sortOptions(returnData);
return returnData;
},
2020-02-10 12:55:28 -08:00
// Get all the accounts to display them to user so that he can
// select them easily
async getAccounts(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const qs = {
q: 'SELECT id, Name FROM Account',
};
const accounts = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
for (const account of accounts) {
const accountName = account.Name;
const accountId = account.Id;
returnData.push({
name: accountName,
value: accountId,
});
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the campaigns to display them to user so that he can
// select them easily
async getCampaigns(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const qs = {
q: 'SELECT id, Name FROM Campaign',
};
const campaigns = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
for (const campaign of campaigns) {
const campaignName = campaign.Name;
const campaignId = campaign.Id;
returnData.push({
name: campaignName,
value: campaignId,
});
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the stages to display them to user so that he can
// select them easily
async getStages(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/opportunity/describe');
for (const field of fields) {
if (field.name === 'StageName') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the stages to display them to user so that he can
// select them easily
async getAccountTypes(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/account/describe');
for (const field of fields) {
if (field.name === 'Type') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the account sources to display them to user so that he can
// select them easily
async getAccountSources(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/account/describe');
for (const field of fields) {
if (field.name === 'AccountSource') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the case types to display them to user so that he can
// select them easily
async getCaseTypes(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/case/describe');
for (const field of fields) {
if (field.name === 'Type') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the case statuses to display them to user so that he can
// select them easily
async getCaseStatuses(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/case/describe');
for (const field of fields) {
if (field.name === 'Status') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the case reasons to display them to user so that he can
// select them easily
async getCaseReasons(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/case/describe');
for (const field of fields) {
if (field.name === 'Reason') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the case origins to display them to user so that he can
// select them easily
async getCaseOrigins(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/case/describe');
for (const field of fields) {
if (field.name === 'Origin') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the case priorities to display them to user so that he can
// select them easily
async getCasePriorities(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/case/describe');
for (const field of fields) {
if (field.name === 'Priority') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the task statuses to display them to user so that he can
// select them easily
async getTaskStatuses(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/task/describe');
for (const field of fields) {
if (field.name === 'Status') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the task subjects to display them to user so that he can
// select them easily
async getTaskSubjects(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/task/describe');
for (const field of fields) {
if (field.name === 'Subject') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the task call types to display them to user so that he can
// select them easily
async getTaskCallTypes(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/task/describe');
for (const field of fields) {
if (field.name === 'CallType') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the task call priorities to display them to user so that he can
// select them easily
async getTaskPriorities(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/task/describe');
for (const field of fields) {
if (field.name === 'Priority') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the task recurrence types to display them to user so that he can
// select them easily
async getTaskRecurrenceTypes(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/task/describe');
for (const field of fields) {
if (field.name === 'RecurrenceType') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the task recurrence instances to display them to user so that he can
// select them easily
async getTaskRecurrenceInstances(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
2020-02-10 12:55:28 -08:00
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/task/describe');
for (const field of fields) {
if (field.name === 'RecurrenceInstance') {
for (const pickValue of field.picklistValues) {
const pickValueName = pickValue.label;
const pickValueId = pickValue.value;
returnData.push({
name: pickValueName,
value: pickValueId,
});
}
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
2020-02-10 12:55:28 -08:00
return returnData;
},
// Get all the custom objects recurrence instances to display them to user so that he can
// select them easily
async getCustomObjects(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { sobjects: objects } = await salesforceApiRequest.call(this, 'GET', '/sobjects');
for (const object of objects) {
if (object.custom === true) {
const objectName = object.label;
const objectId = object.name;
returnData.push({
name: objectName,
value: objectId,
});
}
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
return returnData;
},
// Get all the custom objects fields recurrence instances to display them to user so that he can
// select them easily
async getCustomObjectFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const customObject = this.getCurrentNodeParameter('customObject') as string;
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/${customObject}/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
2020-10-16 02:13:04 -07:00
sortOptions(returnData);
return returnData;
},
// Get all the account fields recurrence instances to display them to user so that he can
// select them easily
async getAccountFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/account/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
sortOptions(returnData);
return returnData;
},
// Get all the attachment fields recurrence instances to display them to user so that he can
// select them easily
async getAtachmentFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/attachment/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
sortOptions(returnData);
return returnData;
},
// Get all the case fields recurrence instances to display them to user so that he can
// select them easily
async getCaseFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/case/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
sortOptions(returnData);
return returnData;
},
// Get all the lead fields recurrence instances to display them to user so that he can
// select them easily
async getLeadFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/lead/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
sortOptions(returnData);
return returnData;
},
// Get all the opportunity fields recurrence instances to display them to user so that he can
// select them easily
async getOpportunityFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/opportunity/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
sortOptions(returnData);
return returnData;
},
// Get all the opportunity fields recurrence instances to display them to user so that he can
// select them easily
async getTaskFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/task/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
sortOptions(returnData);
return returnData;
},
// Get all the users fields recurrence instances to display them to user so that he can
// select them easily
async getUserFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/user/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
sortOptions(returnData);
return returnData;
},
// Get all the contact fields recurrence instances to display them to user so that he can
// select them easily
async getContactFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/contact/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
sortOptions(returnData);
return returnData;
},
2020-02-10 12:55:28 -08:00
},
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: IDataObject[] = [];
let responseData;
const qs: IDataObject = {};
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
:sparkles: Added logging to n8n (#1381) * Added logging to n8n This commit adds logging to n8n using the Winston library. For now, this commit only allows logging to console (default behavior) or file (need to pass in config via environment variables). Other logging methods can be further implemented using hooks. These were skipped for now as it would require adding more dependencies. Logging level is notice by default, meaning no additional messages would be displayed at the moment. Logging level can be set to info or debug as well to enrich the generated logs. The ILogger interface was added to the workflow project as it would make it available for all other projects but the implementation was done on the cli project. * Lint fixes and logging level naming. Also fixed the way we use the logger as it was not working previously * Improvements to logging framework Using appropriate single quotes Improving the way the logger is declared * Improved naming for Log Types * Removed logger global variable, replacing it by a proxy * Add logging to CLI commands * Remove unused GenericHelpers * Changed back some messages to console instead of logger and added npm shortcuts for worker and webhook * Fix typos * Adding basic file rotation to logs as suggested by @mutdmour * Fixed linting issues * Correcting comment to correctly reflect space usage * Added settings for log files rotation * Correcting config type from String to Number * Changed default file settings to number To reflect previous changes to the type * Changed the way log messages are added to be called statically. Also minor naming improvements * Applying latest corrections sent by @ivov * :zap: Some logging improvements * Saving logs to a folder inside n8n home instead of root * Fixed broken tests and linting * Changed some log messages to improve formatting * Adding quotes to names on log messages * Added execution and session IDs to logs. Also removed unnecessary line breaks * :zap: Added file caller to log messages (#1657) This is done using callsites library which already existed in the project as another library's dependency. So in fact it does not add any new dependency. * Adding logs to help debug Salesforce node * :zap: Add function name to logs and add more logs * :zap: Improve some error messages * :zap: Improve some more log messages * :zap: Rename logging env variables to match others Co-authored-by: dali <servfrdali@yahoo.fr> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-05-01 20:43:01 -07:00
Logger.debug(`Running "Salesforce" node named "${this.getNode.name}" resource "${resource}" operation "${operation}"`);
for (let i = 0; i < items.length; i++) {
2020-02-10 12:55:28 -08:00
if (resource === 'lead') {
//https://developer.salesforce.com/docs/api-explorer/sobject/Lead/post-lead
if (operation === 'create' || operation === 'upsert') {
2020-02-10 12:55:28 -08:00
const company = this.getNodeParameter('company', i) as string;
const lastname = this.getNodeParameter('lastname', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const body: ILead = {
Company: company,
LastName: lastname,
};
if (additionalFields.email !== undefined) {
2020-02-10 12:55:28 -08:00
body.Email = additionalFields.email as string;
}
if (additionalFields.city !== undefined) {
2020-02-10 12:55:28 -08:00
body.City = additionalFields.city as string;
}
if (additionalFields.phone !== undefined) {
2020-02-10 12:55:28 -08:00
body.Phone = additionalFields.phone as string;
}
if (additionalFields.state !== undefined) {
2020-02-10 12:55:28 -08:00
body.State = additionalFields.state as string;
}
if (additionalFields.title !== undefined) {
2020-02-10 12:55:28 -08:00
body.Title = additionalFields.title as string;
}
if (additionalFields.jigsaw !== undefined) {
2020-02-10 12:55:28 -08:00
body.Jigsaw = additionalFields.jigsaw as string;
}
if (additionalFields.rating !== undefined) {
2020-02-10 12:55:28 -08:00
body.Rating = additionalFields.rating as string;
}
if (additionalFields.status !== undefined) {
2020-02-10 12:55:28 -08:00
body.Status = additionalFields.status as string;
}
if (additionalFields.street !== undefined) {
2020-02-10 12:55:28 -08:00
body.Street = additionalFields.street as string;
}
if (additionalFields.country !== undefined) {
2020-02-10 12:55:28 -08:00
body.Country = additionalFields.country as string;
}
if (additionalFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = additionalFields.owner as string;
}
if (additionalFields.website !== undefined) {
2020-02-10 12:55:28 -08:00
body.Website = additionalFields.website as string;
}
if (additionalFields.industry !== undefined) {
2020-02-10 12:55:28 -08:00
body.Industry = additionalFields.industry as string;
}
if (additionalFields.firstname !== undefined) {
body.FirstName = additionalFields.firstname as string;
2020-02-10 12:55:28 -08:00
}
if (additionalFields.leadSource !== undefined) {
2020-02-10 12:55:28 -08:00
body.LeadSource = additionalFields.leadSource as string;
}
if (additionalFields.postalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.PostalCode = additionalFields.postalCode as string;
}
if (additionalFields.salutation !== undefined) {
2020-02-10 12:55:28 -08:00
body.Salutation = additionalFields.salutation as string;
}
if (additionalFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = additionalFields.description as string;
}
if (additionalFields.annualRevenue !== undefined) {
2020-02-10 12:55:28 -08:00
body.AnnualRevenue = additionalFields.annualRevenue as number;
}
if (additionalFields.isUnreadByOwner !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsUnreadByOwner = additionalFields.isUnreadByOwner as boolean;
}
if (additionalFields.numberOfEmployees !== undefined) {
2020-02-10 12:55:28 -08:00
body.NumberOfEmployees = additionalFields.numberOfEmployees as number;
}
if (additionalFields.mobilePhone !== undefined) {
body.MobilePhone = additionalFields.mobilePhone as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
let endpoint = '/sobjects/lead';
let method = 'POST';
if (operation === 'upsert') {
method = 'PATCH';
const externalId = this.getNodeParameter('externalId', 0) as string;
const externalIdValue = this.getNodeParameter('externalIdValue', i) as string;
endpoint = `/sobjects/lead/${externalId}/${externalIdValue}`;
if (body[externalId] !== undefined) {
delete body[externalId];
}
}
responseData = await salesforceApiRequest.call(this, method, endpoint, body);
2020-02-10 12:55:28 -08:00
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Lead/patch-lead-id
if (operation === 'update') {
const leadId = this.getNodeParameter('leadId', i) as string;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const body: ILead = {};
if (!Object.keys(updateFields).length) {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(this.getNode(), 'You must add at least one update field');
2020-02-10 12:55:28 -08:00
}
if (updateFields.lastname !== undefined) {
2020-02-10 12:55:28 -08:00
body.LastName = updateFields.lastname as string;
}
if (updateFields.company !== undefined) {
2020-02-10 12:55:28 -08:00
body.Company = updateFields.company as string;
}
if (updateFields.email !== undefined) {
2020-02-10 12:55:28 -08:00
body.Email = updateFields.email as string;
}
if (updateFields.city !== undefined) {
2020-02-10 12:55:28 -08:00
body.City = updateFields.city as string;
}
if (updateFields.phone !== undefined) {
2020-02-10 12:55:28 -08:00
body.Phone = updateFields.phone as string;
}
if (updateFields.state !== undefined) {
2020-02-10 12:55:28 -08:00
body.State = updateFields.state as string;
}
if (updateFields.title !== undefined) {
2020-02-10 12:55:28 -08:00
body.Title = updateFields.title as string;
}
if (updateFields.jigsaw !== undefined) {
2020-02-10 12:55:28 -08:00
body.Jigsaw = updateFields.jigsaw as string;
}
if (updateFields.rating !== undefined) {
2020-02-10 12:55:28 -08:00
body.Rating = updateFields.rating as string;
}
if (updateFields.status !== undefined) {
2020-02-10 12:55:28 -08:00
body.Status = updateFields.status as string;
}
if (updateFields.street !== undefined) {
2020-02-10 12:55:28 -08:00
body.Street = updateFields.street as string;
}
if (updateFields.country !== undefined) {
2020-02-10 12:55:28 -08:00
body.Country = updateFields.country as string;
}
if (updateFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = updateFields.owner as string;
}
if (updateFields.website !== undefined) {
2020-02-10 12:55:28 -08:00
body.Website = updateFields.website as string;
}
if (updateFields.industry !== undefined) {
2020-02-10 12:55:28 -08:00
body.Industry = updateFields.industry as string;
}
if (updateFields.firstname !== undefined) {
body.FirstName = updateFields.firstname as string;
2020-02-10 12:55:28 -08:00
}
if (updateFields.leadSource !== undefined) {
2020-02-10 12:55:28 -08:00
body.LeadSource = updateFields.leadSource as string;
}
if (updateFields.postalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.PostalCode = updateFields.postalCode as string;
}
if (updateFields.salutation !== undefined) {
2020-02-10 12:55:28 -08:00
body.Salutation = updateFields.salutation as string;
}
if (updateFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = updateFields.description as string;
}
if (updateFields.annualRevenue !== undefined) {
2020-02-10 12:55:28 -08:00
body.AnnualRevenue = updateFields.annualRevenue as number;
}
if (updateFields.isUnreadByOwner !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsUnreadByOwner = updateFields.isUnreadByOwner as boolean;
}
if (updateFields.numberOfEmployees !== undefined) {
2020-02-10 12:55:28 -08:00
body.NumberOfEmployees = updateFields.numberOfEmployees as number;
}
if (updateFields.mobilePhone !== undefined) {
body.MobilePhone = updateFields.mobilePhone as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/lead/${leadId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Lead/get-lead-id
if (operation === 'get') {
const leadId = this.getNodeParameter('leadId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/lead/${leadId}`);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, 'Lead', returnAll) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, 'Lead', returnAll, limit) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Lead/delete-lead-id
if (operation === 'delete') {
const leadId = this.getNodeParameter('leadId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/lead/${leadId}`);
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Lead/get-lead
if (operation === 'getSummary') {
responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/lead');
}
//https://developer.salesforce.com/docs/api-explorer/sobject/CampaignMember
if (operation === 'addToCampaign') {
const leadId = this.getNodeParameter('leadId', i) as string;
const campaignId = this.getNodeParameter('campaignId', i) as string;
const options = this.getNodeParameter('options', i) as IDataObject;
const body: ICampaignMember = {
LeadId: leadId,
CampaignId: campaignId,
};
if (options.status) {
body.Status = options.status as string;
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/CampaignMember', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note
if (operation === 'addNote') {
const leadId = this.getNodeParameter('leadId', i) as string;
const title = this.getNodeParameter('title', i) as string;
const options = this.getNodeParameter('options', i) as IDataObject;
const body: INote = {
Title: title,
ParentId: leadId,
};
if (options.body) {
body.Body = options.body as string;
}
if (options.owner) {
body.OwnerId = options.owner as string;
}
if (options.isPrivate) {
body.IsPrivate = options.isPrivate as boolean;
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body);
}
}
if (resource === 'contact') {
//https://developer.salesforce.com/docs/api-explorer/sobject/Contact/post-contact
if (operation === 'create' || operation === 'upsert') {
2020-02-10 12:55:28 -08:00
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const lastname = this.getNodeParameter('lastname', i) as string;
2020-02-10 12:55:28 -08:00
const body: IContact = {
LastName: lastname,
};
if (additionalFields.fax !== undefined) {
2020-02-10 12:55:28 -08:00
body.Fax = additionalFields.fax as string;
}
if (additionalFields.email !== undefined) {
2020-02-10 12:55:28 -08:00
body.Email = additionalFields.email as string;
}
if (additionalFields.phone !== undefined) {
2020-02-10 12:55:28 -08:00
body.Phone = additionalFields.phone as string;
}
if (additionalFields.title !== undefined) {
2020-02-10 12:55:28 -08:00
body.Title = additionalFields.title as string;
}
if (additionalFields.jigsaw !== undefined) {
2020-02-10 12:55:28 -08:00
body.Jigsaw = additionalFields.jigsaw as string;
}
if (additionalFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = additionalFields.owner as string;
}
if (additionalFields.acconuntId !== undefined) {
2020-02-10 12:55:28 -08:00
body.AccountId = additionalFields.acconuntId as string;
}
if (additionalFields.birthdate !== undefined) {
2020-02-10 12:55:28 -08:00
body.Birthdate = additionalFields.birthdate as string;
}
if (additionalFields.firstName !== undefined) {
2020-02-10 12:55:28 -08:00
body.FirstName = additionalFields.firstName as string;
}
if (additionalFields.homePhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.HomePhone = additionalFields.homePhone as string;
}
if (additionalFields.otherCity !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherCity = additionalFields.otherCity as string;
}
if (additionalFields.department !== undefined) {
2020-02-10 12:55:28 -08:00
body.Department = additionalFields.department as string;
}
if (additionalFields.leadSource !== undefined) {
2020-02-10 12:55:28 -08:00
body.LeadSource = additionalFields.leadSource as string;
}
if (additionalFields.otherPhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherPhone = additionalFields.otherPhone as string;
}
if (additionalFields.otherState !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherState = additionalFields.otherState as string;
}
if (additionalFields.salutation !== undefined) {
2020-02-10 12:55:28 -08:00
body.Salutation = additionalFields.salutation as string;
}
if (additionalFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = additionalFields.description as string;
}
if (additionalFields.mailingCity !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingCity = additionalFields.mailingCity as string;
}
if (additionalFields.mobilePhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.MobilePhone = additionalFields.mobilePhone as string;
}
if (additionalFields.otherStreet !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherStreet = additionalFields.otherStreet as string;
}
if (additionalFields.mailingState !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingState = additionalFields.mailingState as string;
}
if (additionalFields.otherCountry !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherCountry = additionalFields.otherCountry as string;
}
if (additionalFields.assistantName !== undefined) {
2020-02-10 12:55:28 -08:00
body.AssistantName = additionalFields.assistantName as string;
}
if (additionalFields.mailingStreet !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingStreet = additionalFields.mailingStreet as string;
}
if (additionalFields.assistantPhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.AssistantPhone = additionalFields.assistantPhone as string;
}
if (additionalFields.mailingCountry !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingCountry = additionalFields.mailingCountry as string;
}
if (additionalFields.otherPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherPostalCode = additionalFields.otherPostalCode as string;
}
if (additionalFields.emailBouncedDate !== undefined) {
2020-02-10 12:55:28 -08:00
body.EmailBouncedDate = additionalFields.emailBouncedDate as string;
}
if (additionalFields.mailingPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingPostalCode = additionalFields.mailingPostalCode as string;
}
if (additionalFields.emailBouncedReason !== undefined) {
2020-02-10 12:55:28 -08:00
body.EmailBouncedReason = additionalFields.emailBouncedReason as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
let endpoint = '/sobjects/contact';
let method = 'POST';
if (operation === 'upsert') {
method = 'PATCH';
const externalId = this.getNodeParameter('externalId', 0) as string;
const externalIdValue = this.getNodeParameter('externalIdValue', i) as string;
endpoint = `/sobjects/contact/${externalId}/${externalIdValue}`;
if (body[externalId] !== undefined) {
delete body[externalId];
}
}
responseData = await salesforceApiRequest.call(this, method, endpoint, body);
2020-02-10 12:55:28 -08:00
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Contact/patch-contact-id
if (operation === 'update') {
const contactId = this.getNodeParameter('contactId', i) as string;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const body: IContact = {};
if (!Object.keys(updateFields).length) {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(this.getNode(), 'You must add at least one update field');
2020-02-10 12:55:28 -08:00
}
if (updateFields.lastName !== undefined) {
body.LastName = updateFields.lastName as string;
}
if (updateFields.fax !== undefined) {
2020-02-10 12:55:28 -08:00
body.Fax = updateFields.fax as string;
}
if (updateFields.email !== undefined) {
2020-02-10 12:55:28 -08:00
body.Email = updateFields.email as string;
}
if (updateFields.phone !== undefined) {
2020-02-10 12:55:28 -08:00
body.Phone = updateFields.phone as string;
}
if (updateFields.title !== undefined) {
2020-02-10 12:55:28 -08:00
body.Title = updateFields.title as string;
}
if (updateFields.jigsaw !== undefined) {
2020-02-10 12:55:28 -08:00
body.Jigsaw = updateFields.jigsaw as string;
}
if (updateFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = updateFields.owner as string;
}
if (updateFields.acconuntId !== undefined) {
2020-02-10 12:55:28 -08:00
body.AccountId = updateFields.acconuntId as string;
}
if (updateFields.birthdate !== undefined) {
2020-02-10 12:55:28 -08:00
body.Birthdate = updateFields.birthdate as string;
}
if (updateFields.firstName !== undefined) {
2020-02-10 12:55:28 -08:00
body.FirstName = updateFields.firstName as string;
}
if (updateFields.homePhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.HomePhone = updateFields.homePhone as string;
}
if (updateFields.otherCity !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherCity = updateFields.otherCity as string;
}
if (updateFields.department !== undefined) {
2020-02-10 12:55:28 -08:00
body.Department = updateFields.department as string;
}
if (updateFields.leadSource !== undefined) {
2020-02-10 12:55:28 -08:00
body.LeadSource = updateFields.leadSource as string;
}
if (updateFields.otherPhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherPhone = updateFields.otherPhone as string;
}
if (updateFields.otherState !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherState = updateFields.otherState as string;
}
if (updateFields.salutation !== undefined) {
2020-02-10 12:55:28 -08:00
body.Salutation = updateFields.salutation as string;
}
if (updateFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = updateFields.description as string;
}
if (updateFields.mailingCity !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingCity = updateFields.mailingCity as string;
}
if (updateFields.mobilePhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.MobilePhone = updateFields.mobilePhone as string;
}
if (updateFields.otherStreet !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherStreet = updateFields.otherStreet as string;
}
if (updateFields.mailingState !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingState = updateFields.mailingState as string;
}
if (updateFields.otherCountry !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherCountry = updateFields.otherCountry as string;
}
if (updateFields.assistantName !== undefined) {
2020-02-10 12:55:28 -08:00
body.AssistantName = updateFields.assistantName as string;
}
if (updateFields.mailingStreet !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingStreet = updateFields.mailingStreet as string;
}
if (updateFields.assistantPhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.AssistantPhone = updateFields.assistantPhone as string;
}
if (updateFields.mailingCountry !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingCountry = updateFields.mailingCountry as string;
}
if (updateFields.otherPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.OtherPostalCode = updateFields.otherPostalCode as string;
}
if (updateFields.emailBouncedDate !== undefined) {
2020-02-10 12:55:28 -08:00
body.EmailBouncedDate = updateFields.emailBouncedDate as string;
}
if (updateFields.mailingPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.MailingPostalCode = updateFields.mailingPostalCode as string;
}
if (updateFields.emailBouncedReason !== undefined) {
2020-02-10 12:55:28 -08:00
body.EmailBouncedReason = updateFields.emailBouncedReason as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/contact/${contactId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Contact/get-contact-id
if (operation === 'get') {
const contactId = this.getNodeParameter('contactId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/contact/${contactId}`);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, 'Contact', returnAll) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, 'Contact', returnAll, limit) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Contact/delete-contact-id
if (operation === 'delete') {
const contactId = this.getNodeParameter('contactId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/contact/${contactId}`);
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Contact/get-contact
if (operation === 'getSummary') {
responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/contact');
}
//https://developer.salesforce.com/docs/api-explorer/sobject/CampaignMember
if (operation === 'addToCampaign') {
const contactId = this.getNodeParameter('contactId', i) as string;
const campaignId = this.getNodeParameter('campaignId', i) as string;
const options = this.getNodeParameter('options', i) as IDataObject;
const body: ICampaignMember = {
ContactId: contactId,
CampaignId: campaignId,
};
if (options.status) {
body.Status = options.status as string;
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/CampaignMember', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note
if (operation === 'addNote') {
const contactId = this.getNodeParameter('contactId', i) as string;
const title = this.getNodeParameter('title', i) as string;
const options = this.getNodeParameter('options', i) as IDataObject;
const body: INote = {
Title: title,
ParentId: contactId,
};
if (options.body !== undefined) {
2020-02-10 12:55:28 -08:00
body.Body = options.body as string;
}
if (options.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = options.owner as string;
}
if (options.isPrivate !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsPrivate = options.isPrivate as boolean;
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body);
}
}
if (resource === 'customObject') {
if (operation === 'create' || operation === 'upsert') {
const customObject = this.getNodeParameter('customObject', i) as string;
const customFieldsUi = this.getNodeParameter('customFieldsUi', i) as IDataObject;
const body: IDataObject = {};
if (customFieldsUi) {
const customFields = (customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
let endpoint = `/sobjects/${customObject}`;
let method = 'POST';
if (operation === 'upsert') {
method = 'PATCH';
const externalId = this.getNodeParameter('externalId', 0) as string;
const externalIdValue = this.getNodeParameter('externalIdValue', i) as string;
endpoint = `/sobjects/${customObject}/${externalId}/${externalIdValue}`;
if (body[externalId] !== undefined) {
delete body[externalId];
}
}
responseData = await salesforceApiRequest.call(this, method, endpoint, body);
}
if (operation === 'update') {
const recordId = this.getNodeParameter('recordId', i) as string;
const customObject = this.getNodeParameter('customObject', i) as string;
const customFieldsUi = this.getNodeParameter('customFieldsUi', i) as IDataObject;
const body: IDataObject = {};
if (customFieldsUi) {
const customFields = (customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/${customObject}/${recordId}`, body);
}
if (operation === 'get') {
const customObject = this.getNodeParameter('customObject', i) as string;
const recordId = this.getNodeParameter('recordId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/${customObject}/${recordId}`);
}
if (operation === 'getAll') {
const customObject = this.getNodeParameter('customObject', i) as string;
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, customObject, returnAll) as string;
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, customObject, returnAll, limit) as string;
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
}
if (operation === 'delete') {
const customObject = this.getNodeParameter('customObject', i) as string;
const recordId = this.getNodeParameter('recordId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/${customObject}/${recordId}`);
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
}
}
2020-02-10 12:55:28 -08:00
if (resource === 'opportunity') {
//https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/post-opportunity
if (operation === 'create' || operation === 'upsert') {
2020-02-10 12:55:28 -08:00
const name = this.getNodeParameter('name', i) as string;
const closeDate = this.getNodeParameter('closeDate', i) as string;
const stageName = this.getNodeParameter('stageName', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const body: IOpportunity = {
Name: name,
CloseDate: closeDate,
StageName: stageName,
};
if (additionalFields.type !== undefined) {
2020-02-10 12:55:28 -08:00
body.Type = additionalFields.type as string;
}
if (additionalFields.ammount !== undefined) {
2020-02-10 12:55:28 -08:00
body.Amount = additionalFields.ammount as number;
}
if (additionalFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = additionalFields.owner as string;
}
if (additionalFields.nextStep !== undefined) {
2020-02-10 12:55:28 -08:00
body.NextStep = additionalFields.nextStep as string;
}
if (additionalFields.accountId !== undefined) {
2020-02-10 12:55:28 -08:00
body.AccountId = additionalFields.accountId as string;
}
if (additionalFields.campaignId !== undefined) {
2020-02-10 12:55:28 -08:00
body.CampaignId = additionalFields.campaignId as string;
}
if (additionalFields.leadSource !== undefined) {
2020-02-10 12:55:28 -08:00
body.LeadSource = additionalFields.leadSource as string;
}
if (additionalFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = additionalFields.description as string;
}
if (additionalFields.probability !== undefined) {
2020-02-10 12:55:28 -08:00
body.Probability = additionalFields.probability as number;
}
if (additionalFields.pricebook2Id !== undefined) {
2020-02-10 12:55:28 -08:00
body.Pricebook2Id = additionalFields.pricebook2Id as string;
}
if (additionalFields.forecastCategoryName !== undefined) {
2020-02-10 12:55:28 -08:00
body.ForecastCategoryName = additionalFields.forecastCategoryName as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
let endpoint = '/sobjects/opportunity';
let method = 'POST';
if (operation === 'upsert') {
method = 'PATCH';
const externalId = this.getNodeParameter('externalId', 0) as string;
const externalIdValue = this.getNodeParameter('externalIdValue', i) as string;
endpoint = `/sobjects/opportunity/${externalId}/${externalIdValue}`;
if (body[externalId] !== undefined) {
delete body[externalId];
}
}
responseData = await salesforceApiRequest.call(this, method, endpoint, body);
2020-02-10 12:55:28 -08:00
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/post-opportunity
if (operation === 'update') {
const opportunityId = this.getNodeParameter('opportunityId', i) as string;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const body: IOpportunity = {};
if (updateFields.name !== undefined) {
2020-02-10 12:55:28 -08:00
body.Name = updateFields.name as string;
}
if (updateFields.closeDate !== undefined) {
2020-02-10 12:55:28 -08:00
body.CloseDate = updateFields.closeDate as string;
}
if (updateFields.stageName !== undefined) {
2020-02-10 12:55:28 -08:00
body.StageName = updateFields.stageName as string;
}
if (updateFields.type !== undefined) {
2020-02-10 12:55:28 -08:00
body.Type = updateFields.type as string;
}
if (updateFields.ammount !== undefined) {
2020-02-10 12:55:28 -08:00
body.Amount = updateFields.ammount as number;
}
if (updateFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = updateFields.owner as string;
}
if (updateFields.nextStep !== undefined) {
2020-02-10 12:55:28 -08:00
body.NextStep = updateFields.nextStep as string;
}
if (updateFields.accountId !== undefined) {
2020-02-10 12:55:28 -08:00
body.AccountId = updateFields.accountId as string;
}
if (updateFields.campaignId !== undefined) {
2020-02-10 12:55:28 -08:00
body.CampaignId = updateFields.campaignId as string;
}
if (updateFields.leadSource !== undefined) {
2020-02-10 12:55:28 -08:00
body.LeadSource = updateFields.leadSource as string;
}
if (updateFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = updateFields.description as string;
}
if (updateFields.probability !== undefined) {
2020-02-10 12:55:28 -08:00
body.Probability = updateFields.probability as number;
}
if (updateFields.pricebook2Id !== undefined) {
2020-02-10 12:55:28 -08:00
body.Pricebook2Id = updateFields.pricebook2Id as string;
}
if (updateFields.forecastCategoryName !== undefined) {
2020-02-10 12:55:28 -08:00
body.ForecastCategoryName = updateFields.forecastCategoryName as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/opportunity/${opportunityId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/get-opportunity-id
if (operation === 'get') {
const opportunityId = this.getNodeParameter('opportunityId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/opportunity/${opportunityId}`);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, 'Opportunity', returnAll) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, 'Opportunity', returnAll, limit) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/delete-opportunity-id
if (operation === 'delete') {
const opportunityId = this.getNodeParameter('opportunityId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/opportunity/${opportunityId}`);
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/get-opportunity
if (operation === 'getSummary') {
responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/opportunity');
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note
if (operation === 'addNote') {
const opportunityId = this.getNodeParameter('opportunityId', i) as string;
const title = this.getNodeParameter('title', i) as string;
const options = this.getNodeParameter('options', i) as IDataObject;
const body: INote = {
Title: title,
ParentId: opportunityId,
};
if (options.body !== undefined) {
2020-02-10 12:55:28 -08:00
body.Body = options.body as string;
}
if (options.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = options.owner as string;
}
if (options.isPrivate !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsPrivate = options.isPrivate as boolean;
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body);
}
}
if (resource === 'account') {
//https://developer.salesforce.com/docs/api-explorer/sobject/Account/post-account
if (operation === 'create' || operation === 'upsert') {
2020-02-10 12:55:28 -08:00
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const name = this.getNodeParameter('name', i) as string;
2020-02-10 12:55:28 -08:00
const body: IAccount = {
Name: name,
};
if (additionalFields.fax !== undefined) {
2020-02-10 12:55:28 -08:00
body.Fax = additionalFields.fax as string;
}
if (additionalFields.type !== undefined) {
2020-02-10 12:55:28 -08:00
body.Type = additionalFields.type as string;
}
if (additionalFields.jigsaw !== undefined) {
2020-02-10 12:55:28 -08:00
body.Jigsaw = additionalFields.jigsaw as string;
}
if (additionalFields.phone !== undefined) {
2020-02-10 12:55:28 -08:00
body.Phone = additionalFields.phone as string;
}
if (additionalFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = additionalFields.owner as string;
}
if (additionalFields.sicDesc !== undefined) {
2020-02-10 12:55:28 -08:00
body.SicDesc = additionalFields.sicDesc as string;
}
if (additionalFields.website !== undefined) {
2020-02-10 12:55:28 -08:00
body.Website = additionalFields.website as string;
}
if (additionalFields.industry !== undefined) {
2020-02-10 12:55:28 -08:00
body.Industry = additionalFields.industry as string;
}
if (additionalFields.parentId !== undefined) {
2020-02-10 12:55:28 -08:00
body.ParentId = additionalFields.parentId as string;
}
if (additionalFields.billingCity !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingCity = additionalFields.billingCity as string;
}
if (additionalFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = additionalFields.description as string;
}
if (additionalFields.billingState !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingState = additionalFields.billingState as string;
}
if (additionalFields.shippingCity !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingCity = additionalFields.shippingCity as string;
}
if (additionalFields.accountSource !== undefined) {
2020-02-10 12:55:28 -08:00
body.AccountSource = additionalFields.accountSource as string;
}
if (additionalFields.annualRevenue !== undefined) {
2020-02-10 12:55:28 -08:00
body.AnnualRevenue = additionalFields.annualRevenue as number;
}
if (additionalFields.billingStreet !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingStreet = additionalFields.billingStreet as string;
}
if (additionalFields.shippingState !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingState = additionalFields.shippingState as string;
}
if (additionalFields.billingCountry !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingCountry = additionalFields.billingCountry as string;
}
if (additionalFields.shippingStreet !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingStreet = additionalFields.shippingStreet as string;
}
if (additionalFields.shippingCountry !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingCountry = additionalFields.shippingCountry as string;
}
if (additionalFields.billingPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingPostalCode = additionalFields.billingPostalCode as string;
}
if (additionalFields.numberOfEmployees !== undefined) {
2020-02-10 12:55:28 -08:00
body.NumberOfEmployees = additionalFields.numberOfEmployees as string;
}
if (additionalFields.shippingPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingPostalCode = additionalFields.shippingPostalCode as string;
}
if (additionalFields.shippingPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingPostalCode = additionalFields.shippingPostalCode as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
let endpoint = '/sobjects/account';
let method = 'POST';
if (operation === 'upsert') {
method = 'PATCH';
const externalId = this.getNodeParameter('externalId', 0) as string;
const externalIdValue = this.getNodeParameter('externalIdValue', i) as string;
endpoint = `/sobjects/account/${externalId}/${externalIdValue}`;
if (body[externalId] !== undefined) {
delete body[externalId];
}
}
responseData = await salesforceApiRequest.call(this, method, endpoint, body);
2020-02-10 12:55:28 -08:00
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Account/patch-account-id
if (operation === 'update') {
const accountId = this.getNodeParameter('accountId', i) as string;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const body: IAccount = {};
if (updateFields.name !== undefined) {
2020-02-10 12:55:28 -08:00
body.Name = updateFields.name as string;
}
if (updateFields.fax !== undefined) {
2020-02-10 12:55:28 -08:00
body.Fax = updateFields.fax as string;
}
if (updateFields.type !== undefined) {
2020-02-10 12:55:28 -08:00
body.Type = updateFields.type as string;
}
if (updateFields.jigsaw !== undefined) {
2020-02-10 12:55:28 -08:00
body.Jigsaw = updateFields.jigsaw as string;
}
if (updateFields.phone !== undefined) {
2020-02-10 12:55:28 -08:00
body.Phone = updateFields.phone as string;
}
if (updateFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = updateFields.owner as string;
}
if (updateFields.sicDesc !== undefined) {
2020-02-10 12:55:28 -08:00
body.SicDesc = updateFields.sicDesc as string;
}
if (updateFields.website !== undefined) {
2020-02-10 12:55:28 -08:00
body.Website = updateFields.website as string;
}
if (updateFields.industry !== undefined) {
2020-02-10 12:55:28 -08:00
body.Industry = updateFields.industry as string;
}
if (updateFields.parentId !== undefined) {
2020-02-10 12:55:28 -08:00
body.ParentId = updateFields.parentId as string;
}
if (updateFields.billingCity !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingCity = updateFields.billingCity as string;
}
if (updateFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = updateFields.description as string;
}
if (updateFields.billingState !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingState = updateFields.billingState as string;
}
if (updateFields.shippingCity !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingCity = updateFields.shippingCity as string;
}
if (updateFields.accountSource !== undefined) {
2020-02-10 12:55:28 -08:00
body.AccountSource = updateFields.accountSource as string;
}
if (updateFields.annualRevenue !== undefined) {
2020-02-10 12:55:28 -08:00
body.AnnualRevenue = updateFields.annualRevenue as number;
}
if (updateFields.billingStreet !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingStreet = updateFields.billingStreet as string;
}
if (updateFields.shippingState !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingState = updateFields.shippingState as string;
}
if (updateFields.billingCountry !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingCountry = updateFields.billingCountry as string;
}
if (updateFields.shippingStreet !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingStreet = updateFields.shippingStreet as string;
}
if (updateFields.shippingCountry !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingCountry = updateFields.shippingCountry as string;
}
if (updateFields.billingPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.BillingPostalCode = updateFields.billingPostalCode as string;
}
if (updateFields.numberOfEmployees !== undefined) {
2020-02-10 12:55:28 -08:00
body.NumberOfEmployees = updateFields.numberOfEmployees as string;
}
if (updateFields.shippingPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingPostalCode = updateFields.shippingPostalCode as string;
}
if (updateFields.shippingPostalCode !== undefined) {
2020-02-10 12:55:28 -08:00
body.ShippingPostalCode = updateFields.shippingPostalCode as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/account/${accountId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Account/get-account-id
if (operation === 'get') {
const accountId = this.getNodeParameter('accountId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/account/${accountId}`);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, 'Account', returnAll) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, 'Account', returnAll, limit) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Account/delete-account-id
if (operation === 'delete') {
const accountId = this.getNodeParameter('accountId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/account/${accountId}`);
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Account/get-account
if (operation === 'getSummary') {
responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/account');
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note
if (operation === 'addNote') {
const accountId = this.getNodeParameter('accountId', i) as string;
const title = this.getNodeParameter('title', i) as string;
const options = this.getNodeParameter('options', i) as IDataObject;
const body: INote = {
Title: title,
ParentId: accountId,
};
if (options.body !== undefined) {
2020-02-10 12:55:28 -08:00
body.Body = options.body as string;
}
if (options.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = options.owner as string;
}
if (options.isPrivate !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsPrivate = options.isPrivate as boolean;
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body);
}
}
if (resource === 'case') {
//https://developer.salesforce.com/docs/api-explorer/sobject/Case/post-case
if (operation === 'create') {
const type = this.getNodeParameter('type', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const body: ICase = {
Type: type,
};
if (additionalFields.origin !== undefined) {
2020-02-10 12:55:28 -08:00
body.Origin = additionalFields.origin as string;
}
if (additionalFields.reason !== undefined) {
2020-02-10 12:55:28 -08:00
body.Reason = additionalFields.reason as string;
}
if (additionalFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = additionalFields.owner as string;
}
if (additionalFields.subject !== undefined) {
2020-02-10 12:55:28 -08:00
body.Subject = additionalFields.subject as string;
}
if (additionalFields.parentId !== undefined) {
2020-02-10 12:55:28 -08:00
body.ParentId = additionalFields.parentId as string;
}
if (additionalFields.priority !== undefined) {
2020-02-10 12:55:28 -08:00
body.Priority = additionalFields.priority as string;
}
if (additionalFields.accountId !== undefined) {
2020-02-10 12:55:28 -08:00
body.AccountId = additionalFields.accountId as string;
}
if (additionalFields.contactId !== undefined) {
2020-02-10 12:55:28 -08:00
body.ContactId = additionalFields.contactId as string;
}
if (additionalFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = additionalFields.description as string;
}
if (additionalFields.isEscalated !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsEscalated = additionalFields.isEscalated as boolean;
}
if (additionalFields.suppliedName !== undefined) {
2020-02-10 12:55:28 -08:00
body.SuppliedName = additionalFields.suppliedName as string;
}
if (additionalFields.suppliedEmail !== undefined) {
2020-02-10 12:55:28 -08:00
body.SuppliedEmail = additionalFields.suppliedEmail as string;
}
if (additionalFields.suppliedPhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.SuppliedPhone = additionalFields.suppliedPhone as string;
}
if (additionalFields.suppliedCompany !== undefined) {
2020-02-10 12:55:28 -08:00
body.SuppliedCompany = additionalFields.suppliedCompany as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/case', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Case/patch-case-id
if (operation === 'update') {
const caseId = this.getNodeParameter('caseId', i) as string;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const body: ICase = {};
if (updateFields.type !== undefined) {
2020-02-10 12:55:28 -08:00
body.Type = updateFields.type as string;
}
if (updateFields.origin !== undefined) {
2020-02-10 12:55:28 -08:00
body.Origin = updateFields.origin as string;
}
if (updateFields.reason !== undefined) {
2020-02-10 12:55:28 -08:00
body.Reason = updateFields.reason as string;
}
if (updateFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = updateFields.owner as string;
}
if (updateFields.subject !== undefined) {
2020-02-10 12:55:28 -08:00
body.Subject = updateFields.subject as string;
}
if (updateFields.parentId !== undefined) {
2020-02-10 12:55:28 -08:00
body.ParentId = updateFields.parentId as string;
}
if (updateFields.priority !== undefined) {
2020-02-10 12:55:28 -08:00
body.Priority = updateFields.priority as string;
}
if (updateFields.accountId !== undefined) {
2020-02-10 12:55:28 -08:00
body.AccountId = updateFields.accountId as string;
}
if (updateFields.contactId !== undefined) {
2020-02-10 12:55:28 -08:00
body.ContactId = updateFields.contactId as string;
}
if (updateFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = updateFields.description as string;
}
if (updateFields.isEscalated !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsEscalated = updateFields.isEscalated as boolean;
}
if (updateFields.suppliedName !== undefined) {
2020-02-10 12:55:28 -08:00
body.SuppliedName = updateFields.suppliedName as string;
}
if (updateFields.suppliedEmail !== undefined) {
2020-02-10 12:55:28 -08:00
body.SuppliedEmail = updateFields.suppliedEmail as string;
}
if (updateFields.suppliedPhone !== undefined) {
2020-02-10 12:55:28 -08:00
body.SuppliedPhone = updateFields.suppliedPhone as string;
}
if (updateFields.suppliedCompany !== undefined) {
2020-02-10 12:55:28 -08:00
body.SuppliedCompany = updateFields.suppliedCompany as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/case/${caseId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Case/get-case-id
if (operation === 'get') {
const caseId = this.getNodeParameter('caseId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/case/${caseId}`);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, 'Case', returnAll) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, 'Case', returnAll, limit) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Case/delete-case-id
if (operation === 'delete') {
const caseId = this.getNodeParameter('caseId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/case/${caseId}`);
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Case/get-case
if (operation === 'getSummary') {
responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/case');
}
//https://developer.salesforce.com/docs/api-explorer/sobject/CaseComment/post-casecomment
if (operation === 'addComment') {
const caseId = this.getNodeParameter('caseId', i) as string;
const options = this.getNodeParameter('options', i) as IDataObject;
const body: ICaseComment = {
ParentId: caseId,
};
if (options.commentBody !== undefined) {
2020-02-10 12:55:28 -08:00
body.CommentBody = options.commentBody as string;
}
if (options.isPublished !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsPublished = options.isPublished as boolean;
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/casecomment', body);
}
}
if (resource === 'task') {
//https://developer.salesforce.com/docs/api-explorer/sobject/Task/post-task
if (operation === 'create') {
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const status = this.getNodeParameter('status', i) as string;
const body: ITask = {
Status: status,
};
if (additionalFields.whoId !== undefined) {
2020-02-10 12:55:28 -08:00
body.WhoId = additionalFields.whoId as string;
}
if (additionalFields.whatId !== undefined) {
2020-02-10 12:55:28 -08:00
body.WhatId = additionalFields.whatId as string;
}
if (additionalFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = additionalFields.owner as string;
}
if (additionalFields.subject !== undefined) {
2020-02-10 12:55:28 -08:00
body.Subject = additionalFields.subject as string;
}
if (additionalFields.callType !== undefined) {
2020-02-10 12:55:28 -08:00
body.CallType = additionalFields.callType as string;
}
if (additionalFields.priority !== undefined) {
2020-02-10 12:55:28 -08:00
body.Priority = additionalFields.priority as string;
}
if (additionalFields.callObject !== undefined) {
2020-02-10 12:55:28 -08:00
body.CallObject = additionalFields.callObject as string;
}
if (additionalFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = additionalFields.description as string;
}
if (additionalFields.activityDate !== undefined) {
2020-02-10 12:55:28 -08:00
body.ActivityDate = additionalFields.activityDate as string;
}
if (additionalFields.isReminderSet !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsReminderSet = additionalFields.isReminderSet as boolean;
}
if (additionalFields.recurrenceType !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceType = additionalFields.recurrenceType as string;
}
if (additionalFields.callDisposition !== undefined) {
2020-02-10 12:55:28 -08:00
body.CallDisposition = additionalFields.callDisposition as string;
}
if (additionalFields.reminderDateTime !== undefined) {
2020-02-10 12:55:28 -08:00
body.ReminderDateTime = additionalFields.reminderDateTime as string;
}
if (additionalFields.recurrenceInstance !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceInstance = additionalFields.recurrenceInstance as string;
}
if (additionalFields.recurrenceInterval !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceInterval = additionalFields.recurrenceInterval as number;
}
if (additionalFields.recurrenceDayOfMonth !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceDayOfMonth = additionalFields.recurrenceDayOfMonth as number;
}
if (additionalFields.callDurationInSeconds !== undefined) {
2020-02-10 12:55:28 -08:00
body.CallDurationInSeconds = additionalFields.callDurationInSeconds as number;
}
if (additionalFields.recurrenceEndDateOnly !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceEndDateOnly = additionalFields.recurrenceEndDateOnly as string;
}
if (additionalFields.recurrenceMonthOfYear !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceMonthOfYear = additionalFields.recurrenceMonthOfYear as string;
}
if (additionalFields.recurrenceDayOfWeekMask !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceDayOfWeekMask = additionalFields.recurrenceDayOfWeekMask as string;
}
if (additionalFields.recurrenceStartDateOnly !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceStartDateOnly = additionalFields.recurrenceStartDateOnly as string;
}
if (additionalFields.recurrenceTimeZoneSidKey !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceTimeZoneSidKey = additionalFields.recurrenceTimeZoneSidKey as string;
}
if (additionalFields.recurrenceRegeneratedType !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceRegeneratedType = additionalFields.recurrenceRegeneratedType as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/task', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Task/patch-task-id
if (operation === 'update') {
const taskId = this.getNodeParameter('taskId', i) as string;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const body: ITask = {};
if (updateFields.whoId !== undefined) {
2020-02-10 12:55:28 -08:00
body.WhoId = updateFields.whoId as string;
}
if (updateFields.status !== undefined) {
2020-02-10 12:55:28 -08:00
body.Status = updateFields.status as string;
}
if (updateFields.whatId !== undefined) {
2020-02-10 12:55:28 -08:00
body.WhatId = updateFields.whatId as string;
}
if (updateFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = updateFields.owner as string;
}
if (updateFields.subject !== undefined) {
2020-02-10 12:55:28 -08:00
body.Subject = updateFields.subject as string;
}
if (updateFields.callType !== undefined) {
2020-02-10 12:55:28 -08:00
body.CallType = updateFields.callType as string;
}
if (updateFields.priority !== undefined) {
2020-02-10 12:55:28 -08:00
body.Priority = updateFields.priority as string;
}
if (updateFields.callObject !== undefined) {
2020-02-10 12:55:28 -08:00
body.CallObject = updateFields.callObject as string;
}
if (updateFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = updateFields.description as string;
}
if (updateFields.activityDate !== undefined) {
2020-02-10 12:55:28 -08:00
body.ActivityDate = updateFields.activityDate as string;
}
if (updateFields.isReminderSet !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsReminderSet = updateFields.isReminderSet as boolean;
}
if (updateFields.recurrenceType !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceType = updateFields.recurrenceType as string;
}
if (updateFields.callDisposition !== undefined) {
2020-02-10 12:55:28 -08:00
body.CallDisposition = updateFields.callDisposition as string;
}
if (updateFields.reminderDateTime !== undefined) {
2020-02-10 12:55:28 -08:00
body.ReminderDateTime = updateFields.reminderDateTime as string;
}
if (updateFields.recurrenceInstance !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceInstance = updateFields.recurrenceInstance as string;
}
if (updateFields.recurrenceInterval !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceInterval = updateFields.recurrenceInterval as number;
}
if (updateFields.recurrenceDayOfMonth !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceDayOfMonth = updateFields.recurrenceDayOfMonth as number;
}
if (updateFields.callDurationInSeconds !== undefined) {
2020-02-10 12:55:28 -08:00
body.CallDurationInSeconds = updateFields.callDurationInSeconds as number;
}
if (updateFields.recurrenceEndDateOnly !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceEndDateOnly = updateFields.recurrenceEndDateOnly as string;
}
if (updateFields.recurrenceMonthOfYear !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceMonthOfYear = updateFields.recurrenceMonthOfYear as string;
}
if (updateFields.recurrenceDayOfWeekMask !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceDayOfWeekMask = updateFields.recurrenceDayOfWeekMask as string;
}
if (updateFields.recurrenceStartDateOnly !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceStartDateOnly = updateFields.recurrenceStartDateOnly as string;
}
if (updateFields.recurrenceTimeZoneSidKey !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceTimeZoneSidKey = updateFields.recurrenceTimeZoneSidKey as string;
}
if (updateFields.recurrenceRegeneratedType !== undefined) {
2020-02-10 12:55:28 -08:00
body.RecurrenceRegeneratedType = updateFields.recurrenceRegeneratedType as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/task/${taskId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Task/get-task-id
if (operation === 'get') {
const taskId = this.getNodeParameter('taskId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/task/${taskId}`);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, 'Task', returnAll) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, 'Task', returnAll, limit) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Task/delete-task-id
if (operation === 'delete') {
const taskId = this.getNodeParameter('taskId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/task/${taskId}`);
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Task/get-task
if (operation === 'getSummary') {
responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/task');
}
}
if (resource === 'attachment') {
//https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/post-attachment
if (operation === 'create') {
const name = this.getNodeParameter('name', i) as string;
const parentId = this.getNodeParameter('parentId', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string;
const body: IAttachment = {
Name: name,
ParentId: parentId,
};
if (items[i].binary && items[i].binary![binaryPropertyName]) {
body.Body = items[i].binary![binaryPropertyName].data;
body.ContentType = items[i].binary![binaryPropertyName].mimeType;
} else {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(this.getNode(), `The property ${binaryPropertyName} does not exist`);
2020-02-10 12:55:28 -08:00
}
if (additionalFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = additionalFields.description as string;
}
if (additionalFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = additionalFields.owner as string;
}
if (additionalFields.isPrivate !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsPrivate = additionalFields.isPrivate as boolean;
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/attachment', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/patch-attachment-id
if (operation === 'update') {
const attachmentId = this.getNodeParameter('attachmentId', i) as string;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const body: IAttachment = {};
if (updateFields.binaryPropertyName !== undefined) {
2020-02-10 12:55:28 -08:00
const binaryPropertyName = updateFields.binaryPropertyName as string;
if (items[i].binary && items[i].binary![binaryPropertyName]) {
body.Body = items[i].binary![binaryPropertyName].data;
body.ContentType = items[i].binary![binaryPropertyName].mimeType;
} else {
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
throw new NodeOperationError(this.getNode(), `The property ${binaryPropertyName} does not exist`);
2020-02-10 12:55:28 -08:00
}
}
if (updateFields.name !== undefined) {
2020-02-10 12:55:28 -08:00
body.Name = updateFields.name as string;
}
if (updateFields.description !== undefined) {
2020-02-10 12:55:28 -08:00
body.Description = updateFields.description as string;
}
if (updateFields.owner !== undefined) {
2020-02-10 12:55:28 -08:00
body.OwnerId = updateFields.owner as string;
}
if (updateFields.isPrivate !== undefined) {
2020-02-10 12:55:28 -08:00
body.IsPrivate = updateFields.isPrivate as boolean;
}
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/attachment/${attachmentId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/get-attachment-id
if (operation === 'get') {
const attachmentId = this.getNodeParameter('attachmentId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/attachment/${attachmentId}`);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, 'Attachment', returnAll) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, 'Attachment', returnAll, limit) as string;
2020-02-10 12:55:28 -08:00
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/delete-attachment-id
if (operation === 'delete') {
const attachmentId = this.getNodeParameter('attachmentId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/attachment/${attachmentId}`);
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
2020-02-10 12:55:28 -08:00
}
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/get-attachment-id
if (operation === 'getSummary') {
responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/attachment');
}
}
if (resource === 'user') {
//https://developer.salesforce.com/docs/api-explorer/sobject/User/get-user-id
if (operation === 'get') {
const userId = this.getNodeParameter('userId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/user/${userId}`);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
try {
if (returnAll) {
qs.q = getQuery(options, 'User', returnAll) as string;
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = getQuery(options, 'User', returnAll, limit) as string;
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
} catch (error) {
throw new NodeApiError(this.getNode(), error);
}
}
}
if (resource === 'flow') {
//https://developer.salesforce.com/docs/atlas.en-us.api_action.meta/api_action/actions_obj_flow.htm
if (operation === 'invoke') {
const apiName = this.getNodeParameter('apiName', i) as string;
const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean;
let variables = {};
if (jsonParameters) {
variables = this.getNodeParameter('variablesJson', i) as object;
} else {
// Input variables are defined in UI
const setInputVariable = this.getNodeParameter('variablesUi', i, {}) as IDataObject;
if (setInputVariable!.variablesValues !== undefined) {
for (const inputVariableData of setInputVariable!.variablesValues as IDataObject[]) {
// @ts-ignore
variables[inputVariableData!.name as string] = inputVariableData!.value;
}
}
}
const body = {
inputs: [
variables,
],
};
responseData = await salesforceApiRequest.call(this, 'POST', `/actions/custom/flow/${apiName}`, body);
}
//https://developer.salesforce.com/docs/atlas.en-us.api_action.meta/api_action/actions_obj_flow.htm
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
responseData = await salesforceApiRequest.call(this, 'GET', '/actions/custom/flow');
responseData = responseData.actions;
if (returnAll === false) {
const limit = this.getNodeParameter('limit', i) as number;
responseData = responseData.splice(0, limit);
}
}
}
if (resource === 'search') {
//https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm
if (operation === 'query') {
qs.q = this.getNodeParameter('query', i) as string;
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
}
2020-02-10 12:55:28 -08:00
if (Array.isArray(responseData)) {
returnData.push.apply(returnData, responseData as IDataObject[]);
} else {
if (responseData === undefined) {
// Make sure that always valid JSON gets returned which also matches the
// Salesforce default response
responseData = {
errors: [],
success: true,
};
}
2020-02-10 12:55:28 -08:00
returnData.push(responseData as IDataObject);
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}