first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { snakeCase } from 'change-case';
|
||||
import type {
|
||||
JsonObject,
|
||||
IDataObject,
|
||||
IExecuteFunctions,
|
||||
ILoadOptionsFunctions,
|
||||
IHookFunctions,
|
||||
IWebhookFunctions,
|
||||
IHttpRequestMethods,
|
||||
IRequestOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
|
||||
export async function pagerDutyApiRequest(
|
||||
this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions,
|
||||
method: IHttpRequestMethods,
|
||||
resource: string,
|
||||
|
||||
body: any = {},
|
||||
query: IDataObject = {},
|
||||
uri?: string,
|
||||
headers: IDataObject = {},
|
||||
): Promise<any> {
|
||||
const authenticationMethod = this.getNodeParameter('authentication', 0);
|
||||
|
||||
const options: IRequestOptions = {
|
||||
headers: {
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
},
|
||||
method,
|
||||
body,
|
||||
qs: query,
|
||||
uri: uri || `https://api.pagerduty.com${resource}`,
|
||||
json: true,
|
||||
qsStringifyOptions: {
|
||||
arrayFormat: 'brackets',
|
||||
},
|
||||
};
|
||||
|
||||
if (!Object.keys(body as IDataObject).length) {
|
||||
delete options.form;
|
||||
}
|
||||
if (!Object.keys(query).length) {
|
||||
delete options.qs;
|
||||
}
|
||||
|
||||
options.headers = Object.assign({}, options.headers, headers);
|
||||
|
||||
try {
|
||||
if (authenticationMethod === 'apiToken') {
|
||||
const credentials = await this.getCredentials('pagerDutyApi');
|
||||
|
||||
options.headers.Authorization = `Token token=${credentials.apiToken}`;
|
||||
|
||||
return await this.helpers.request(options);
|
||||
} else {
|
||||
return await this.helpers.requestOAuth2.call(this, 'pagerDutyOAuth2Api', options);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new NodeApiError(this.getNode(), error as JsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
export async function pagerDutyApiRequestAllItems(
|
||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||
propertyName: string,
|
||||
method: IHttpRequestMethods,
|
||||
endpoint: string,
|
||||
|
||||
body: any = {},
|
||||
query: IDataObject = {},
|
||||
): Promise<any> {
|
||||
const returnData: IDataObject[] = [];
|
||||
|
||||
let responseData;
|
||||
query.limit = 100;
|
||||
query.offset = 0;
|
||||
|
||||
do {
|
||||
responseData = await pagerDutyApiRequest.call(this, method, endpoint, body, query);
|
||||
query.offset++;
|
||||
returnData.push.apply(returnData, responseData[propertyName] as IDataObject[]);
|
||||
} while (responseData.more);
|
||||
|
||||
return returnData;
|
||||
}
|
||||
|
||||
export function keysToSnakeCase(elements: IDataObject[] | IDataObject): IDataObject[] {
|
||||
if (!Array.isArray(elements)) {
|
||||
elements = [elements];
|
||||
}
|
||||
for (const element of elements) {
|
||||
for (const key of Object.keys(element)) {
|
||||
if (key !== snakeCase(key)) {
|
||||
element[snakeCase(key)] = element[key];
|
||||
delete element[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
@@ -0,0 +1,606 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const incidentOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
description: 'Create an incident',
|
||||
action: 'Create an incident',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get an incident',
|
||||
action: 'Get an incident',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
description: 'Get many incidents',
|
||||
action: 'Get many incidents',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
description: 'Update an incident',
|
||||
action: 'Update an incident',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export const incidentFields: INodeProperties[] = [
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* incident:create */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Title',
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
description: 'A succinct description of the nature, symptoms, cause, or effect of the incident',
|
||||
},
|
||||
{
|
||||
displayName: 'Service Name or ID',
|
||||
name: 'serviceId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getServices',
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
description:
|
||||
'The incident will be created on this service. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Email',
|
||||
name: 'email',
|
||||
type: 'string',
|
||||
placeholder: 'name@email.com',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
description: 'The email address of a valid user associated with the account making the request',
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Escalation Policy Name or ID',
|
||||
name: 'escalationPolicyId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getEscalationPolicies',
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'Delegate this incident to the specified escalation policy. Cannot be specified if an assignee is given. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Incident Details',
|
||||
name: 'details',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Additional details about the incident which will go in the body',
|
||||
},
|
||||
{
|
||||
displayName: 'Incident Key',
|
||||
name: 'incidentKey',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'Sending subsequent requests referencing the same service and with the same incident_key will result in those requests being rejected if an open incident matches that incident_key',
|
||||
},
|
||||
{
|
||||
displayName: 'Priority Name or ID',
|
||||
name: 'priorityId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getPriorities',
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'The incident will be created on this service. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Urgency',
|
||||
name: 'urgency',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Hight',
|
||||
value: 'high',
|
||||
},
|
||||
{
|
||||
name: 'Low',
|
||||
value: 'low',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
description: 'The urgency of the incident',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Conference Bridge',
|
||||
name: 'conferenceBridgeUi',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValues: false,
|
||||
},
|
||||
placeholder: 'Add Conference Bridge',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Conference Bridge',
|
||||
name: 'conferenceBridgeValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Conference Number',
|
||||
name: 'conferenceNumber',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'Phone numbers should be formatted like +1 415-555-1212,,,,1234#, where a comma (,) represents a one-second wait and pound (#) completes access code input',
|
||||
},
|
||||
{
|
||||
displayName: 'Conference URL',
|
||||
name: 'conferenceUrl',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'An URL for the conference bridge. This could be a link to a web conference or Slack channel.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* incident:get */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Incident ID',
|
||||
name: 'incidentId',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for the incident',
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* incident:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: ['getAll'],
|
||||
resource: ['incident'],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: ['getAll'],
|
||||
resource: ['incident'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 500,
|
||||
},
|
||||
default: 100,
|
||||
description: 'Max number of results to return',
|
||||
},
|
||||
{
|
||||
displayName: 'Options',
|
||||
name: 'options',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Date Range',
|
||||
name: 'dateRange',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'All',
|
||||
value: 'all',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
description: 'When set to all, the since and until parameters and defaults are ignored',
|
||||
},
|
||||
{
|
||||
displayName: 'Incident Key',
|
||||
name: 'incidentKey',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'Incident de-duplication key. Incidents with child alerts do not have an incident key; querying by incident key will return incidents whose alerts have alert_key matching the given incident key.',
|
||||
},
|
||||
{
|
||||
displayName: 'Include',
|
||||
name: 'include',
|
||||
type: 'multiOptions',
|
||||
options: [
|
||||
{
|
||||
name: 'Acknowledgers',
|
||||
value: 'acknowledgers',
|
||||
},
|
||||
{
|
||||
name: 'Assignees',
|
||||
value: 'assignees',
|
||||
},
|
||||
{
|
||||
name: 'Conference Bridge',
|
||||
value: 'conferenceBridge',
|
||||
},
|
||||
{
|
||||
name: 'Escalation Policies',
|
||||
value: 'escalationPolicies',
|
||||
},
|
||||
{
|
||||
name: 'First Trigger Log Entries',
|
||||
value: 'firstTriggerLogEntries',
|
||||
},
|
||||
{
|
||||
name: 'Priorities',
|
||||
value: 'priorities',
|
||||
},
|
||||
{
|
||||
name: 'Services',
|
||||
value: 'services',
|
||||
},
|
||||
{
|
||||
name: 'Teams',
|
||||
value: 'teams',
|
||||
},
|
||||
{
|
||||
name: 'Users',
|
||||
value: 'users',
|
||||
},
|
||||
],
|
||||
default: [],
|
||||
description: 'Additional details to include',
|
||||
},
|
||||
{
|
||||
displayName: 'Service Names or IDs',
|
||||
name: 'serviceIds',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getServices',
|
||||
},
|
||||
default: [],
|
||||
description:
|
||||
'Returns only the incidents associated with the passed service(s). Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Since',
|
||||
name: 'since',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
description:
|
||||
'The start of the date range over which you want to search. (the limit on date ranges is 6 months).',
|
||||
},
|
||||
{
|
||||
displayName: 'Sort By',
|
||||
name: 'sortBy',
|
||||
type: 'string',
|
||||
default: '',
|
||||
placeholder: 'created_at:asc,resolved_at:desc',
|
||||
description:
|
||||
'Used to specify both the field you wish to sort the results on (incident_number/created_at/resolved_at/urgency), as well as the direction (asc/desc) of the results. The sort_by field and direction should be separated by a colon. A maximum of two fields can be included, separated by a comma.',
|
||||
},
|
||||
{
|
||||
displayName: 'Statuses',
|
||||
name: 'statuses',
|
||||
type: 'multiOptions',
|
||||
options: [
|
||||
{
|
||||
name: 'Acknowledged',
|
||||
value: 'acknowledged',
|
||||
},
|
||||
{
|
||||
name: 'Resolved',
|
||||
value: 'resolved',
|
||||
},
|
||||
{
|
||||
name: 'Triggered',
|
||||
value: 'triggered',
|
||||
},
|
||||
],
|
||||
default: [],
|
||||
description: 'Returns only the incidents associated with the passed service(s)',
|
||||
},
|
||||
{
|
||||
displayName: 'Team IDs',
|
||||
name: 'teamIds',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'Team IDs. Only results related to these teams will be returned. Account must have the teams ability to use this parameter. (multiples IDs can be added separated by comma)',
|
||||
},
|
||||
{
|
||||
displayName: 'Timezone Name or ID',
|
||||
name: 'timeZone',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTimezones',
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'Time zone in which dates in the result will be rendered. If not set dates will return UTC. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Until',
|
||||
name: 'until',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
description:
|
||||
'The end of the date range over which you want to search. (the limit on date ranges is 6 months).',
|
||||
},
|
||||
{
|
||||
displayName: 'Urgencies',
|
||||
name: 'urgencies',
|
||||
type: 'multiOptions',
|
||||
options: [
|
||||
{
|
||||
name: 'High',
|
||||
value: 'high',
|
||||
},
|
||||
{
|
||||
name: 'Low',
|
||||
value: 'low',
|
||||
},
|
||||
],
|
||||
default: [],
|
||||
description:
|
||||
'Urgencies of the incidents to be returned. Defaults to all urgencies. Account must have the urgencies ability to do this',
|
||||
},
|
||||
{
|
||||
displayName: 'User IDs',
|
||||
name: 'userIds',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'Returns only the incidents currently assigned to the passed user(s). This expects one or more user IDs (multiple IDs can be added separated by comma).',
|
||||
},
|
||||
],
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* incident:update */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Incident ID',
|
||||
name: 'incidentId',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for the incident',
|
||||
},
|
||||
{
|
||||
displayName: 'Email',
|
||||
name: 'email',
|
||||
type: 'string',
|
||||
placeholder: 'name@email.com',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
description: 'The email address of a valid user associated with the account making the request',
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Escalation Level',
|
||||
name: 'escalationLevel',
|
||||
type: 'number',
|
||||
default: 0,
|
||||
typeOptions: {
|
||||
minValue: 0,
|
||||
},
|
||||
description: 'Escalate the incident to this level in the escalation policy',
|
||||
},
|
||||
{
|
||||
displayName: 'Escalation Policy Name or ID',
|
||||
name: 'escalationPolicyId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getEscalationPolicies',
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'Delegate this incident to the specified escalation policy. Cannot be specified if an assignee is given. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Priority Name or ID',
|
||||
name: 'priorityId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getPriorities',
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'The incident will be created on this service. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Resolution',
|
||||
name: 'resolution',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The resolution for this incident if status is set to resolved',
|
||||
},
|
||||
{
|
||||
displayName: 'Status',
|
||||
name: 'status',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Acknowledged',
|
||||
value: 'acknowledged',
|
||||
},
|
||||
{
|
||||
name: 'Resolved',
|
||||
value: 'resolved',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
description: 'The new status of the incident',
|
||||
},
|
||||
{
|
||||
displayName: 'Title',
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'A succinct description of the nature, symptoms, cause, or effect of the incident',
|
||||
},
|
||||
{
|
||||
displayName: 'Urgency',
|
||||
name: 'urgency',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'High',
|
||||
value: 'high',
|
||||
},
|
||||
{
|
||||
name: 'Low',
|
||||
value: 'low',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
description: 'The urgency of the incident',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Conference Bridge',
|
||||
name: 'conferenceBridgeUi',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValues: false,
|
||||
},
|
||||
placeholder: 'Add Conference Bridge',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incident'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Conference Bridge',
|
||||
name: 'conferenceBridgeValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Conference Number',
|
||||
name: 'conferenceNumber',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'Phone numbers should be formatted like +1 415-555-1212,,,,1234#, where a comma (,) represents a one-second wait and pound (#) completes access code input',
|
||||
},
|
||||
{
|
||||
displayName: 'Conference URL',
|
||||
name: 'conferenceUrl',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'An URL for the conference bridge. This could be a link to a web conference or Slack channel.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { IDataObject } from 'n8n-workflow';
|
||||
|
||||
export interface IIncident {
|
||||
assignments?: IDataObject[];
|
||||
body?: IDataObject;
|
||||
conference_bridge?: IDataObject;
|
||||
escalation_level?: number;
|
||||
escalation_policy?: IDataObject;
|
||||
incident_key?: string;
|
||||
priority?: IDataObject;
|
||||
resolution?: string;
|
||||
status?: string;
|
||||
service?: IDataObject;
|
||||
title?: string;
|
||||
type?: string;
|
||||
urgency?: string;
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const incidentNoteOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incidentNote'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
description: 'Create a incident note',
|
||||
action: 'Create an incident note',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
description: "Get many incident's notes",
|
||||
action: 'Get many incident notes',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export const incidentNoteFields: INodeProperties[] = [
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* incidentNote:create */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Incident ID',
|
||||
name: 'incidentId',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incidentNote'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for the incident',
|
||||
},
|
||||
{
|
||||
displayName: 'Content',
|
||||
name: 'content',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incidentNote'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
description: 'The note content',
|
||||
},
|
||||
{
|
||||
displayName: 'Email',
|
||||
name: 'email',
|
||||
type: 'string',
|
||||
placeholder: 'name@email.com',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incidentNote'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
description: 'The email address of a valid user associated with the account making the request',
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* incidentNote:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Incident ID',
|
||||
name: 'incidentId',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['incidentNote'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for the incident',
|
||||
},
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: ['getAll'],
|
||||
resource: ['incidentNote'],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: ['getAll'],
|
||||
resource: ['incidentNote'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 500,
|
||||
},
|
||||
default: 100,
|
||||
description: 'Max number of results to return',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,159 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const logEntryOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['logEntry'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get a log entry',
|
||||
action: 'Get a log entry',
|
||||
},
|
||||
{
|
||||
name: 'Get Many',
|
||||
value: 'getAll',
|
||||
description: 'Get many log entries',
|
||||
action: 'Get many log entries',
|
||||
},
|
||||
],
|
||||
default: 'get',
|
||||
},
|
||||
];
|
||||
|
||||
export const logEntryFields: INodeProperties[] = [
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* logEntry:get */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Log Entry ID',
|
||||
name: 'logEntryId',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['logEntry'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for the log entry',
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* logEntry:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: ['getAll'],
|
||||
resource: ['logEntry'],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: ['getAll'],
|
||||
resource: ['logEntry'],
|
||||
returnAll: [false],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 500,
|
||||
},
|
||||
default: 100,
|
||||
description: 'Max number of results to return',
|
||||
},
|
||||
{
|
||||
displayName: 'Options',
|
||||
name: 'options',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['logEntry'],
|
||||
operation: ['getAll'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Include',
|
||||
name: 'include',
|
||||
type: 'multiOptions',
|
||||
options: [
|
||||
{
|
||||
name: 'Channels',
|
||||
value: 'channels',
|
||||
},
|
||||
{
|
||||
name: 'Incidents',
|
||||
value: 'incidents',
|
||||
},
|
||||
{
|
||||
name: 'Services',
|
||||
value: 'services',
|
||||
},
|
||||
{
|
||||
name: 'Teams',
|
||||
value: 'teams',
|
||||
},
|
||||
],
|
||||
default: [],
|
||||
description: 'Additional details to include',
|
||||
},
|
||||
{
|
||||
displayName: 'Is Overview',
|
||||
name: 'isOverview',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
'Whether to return a subset of log entries that show only the most important changes to the incident',
|
||||
},
|
||||
{
|
||||
displayName: 'Since',
|
||||
name: 'since',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
description:
|
||||
'The start of the date range over which you want to search. (the limit on date ranges is 6 months).',
|
||||
},
|
||||
{
|
||||
displayName: 'Timezone Name or ID',
|
||||
name: 'timeZone',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTimezones',
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'Time zone in which dates in the result will be rendered. If not set dates will return UTC. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Until',
|
||||
name: 'until',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
description:
|
||||
'The end of the date range over which you want to search. (the limit on date ranges is 6 months).',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"node": "n8n-nodes-base.pagerDuty",
|
||||
"nodeVersion": "1.0",
|
||||
"codexVersion": "1.0",
|
||||
"categories": ["Communication", "Development"],
|
||||
"resources": {
|
||||
"credentialDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/credentials/pagerduty/"
|
||||
}
|
||||
],
|
||||
"primaryDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.pagerduty/"
|
||||
}
|
||||
],
|
||||
"generic": [
|
||||
{
|
||||
"label": "Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide",
|
||||
"icon": "🏭",
|
||||
"url": "https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/"
|
||||
},
|
||||
{
|
||||
"label": "How to automate every step of an incident response workflow",
|
||||
"url": "https://n8n.io/blog/creating-custom-incident-response-workflows-with-n8n/"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
import { snakeCase } from 'change-case';
|
||||
import moment from 'moment-timezone';
|
||||
import type {
|
||||
IExecuteFunctions,
|
||||
IDataObject,
|
||||
ILoadOptionsFunctions,
|
||||
INodeExecutionData,
|
||||
INodePropertyOptions,
|
||||
INodeType,
|
||||
INodeTypeDescription,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeConnectionTypes } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
keysToSnakeCase,
|
||||
pagerDutyApiRequest,
|
||||
pagerDutyApiRequestAllItems,
|
||||
} from './GenericFunctions';
|
||||
import { incidentFields, incidentOperations } from './IncidentDescription';
|
||||
import type { IIncident } from './IncidentInterface';
|
||||
import { incidentNoteFields, incidentNoteOperations } from './IncidentNoteDescription';
|
||||
import { logEntryFields, logEntryOperations } from './LogEntryDescription';
|
||||
import { userFields, userOperations } from './UserDescription';
|
||||
|
||||
export class PagerDuty implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'PagerDuty',
|
||||
name: 'pagerDuty',
|
||||
icon: 'file:pagerDuty.svg',
|
||||
group: ['output'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
description: 'Consume PagerDuty API',
|
||||
defaults: {
|
||||
name: 'PagerDuty',
|
||||
},
|
||||
usableAsTool: true,
|
||||
inputs: [NodeConnectionTypes.Main],
|
||||
outputs: [NodeConnectionTypes.Main],
|
||||
credentials: [
|
||||
{
|
||||
name: 'pagerDutyApi',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
authentication: ['apiToken'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'pagerDutyOAuth2Api',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
authentication: ['oAuth2'],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Authentication',
|
||||
name: 'authentication',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'API Token',
|
||||
value: 'apiToken',
|
||||
},
|
||||
{
|
||||
name: 'OAuth2',
|
||||
value: 'oAuth2',
|
||||
},
|
||||
],
|
||||
default: 'apiToken',
|
||||
},
|
||||
{
|
||||
displayName: 'Resource',
|
||||
name: 'resource',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
options: [
|
||||
{
|
||||
name: 'Incident',
|
||||
value: 'incident',
|
||||
},
|
||||
{
|
||||
name: 'Incident Note',
|
||||
value: 'incidentNote',
|
||||
},
|
||||
{
|
||||
name: 'Log Entry',
|
||||
value: 'logEntry',
|
||||
},
|
||||
{
|
||||
name: 'User',
|
||||
value: 'user',
|
||||
},
|
||||
],
|
||||
default: 'incident',
|
||||
},
|
||||
// INCIDENT
|
||||
...incidentOperations,
|
||||
...incidentFields,
|
||||
// INCIDENT NOTE
|
||||
...incidentNoteOperations,
|
||||
...incidentNoteFields,
|
||||
// LOG ENTRY
|
||||
...logEntryOperations,
|
||||
...logEntryFields,
|
||||
// USER
|
||||
...userOperations,
|
||||
...userFields,
|
||||
],
|
||||
};
|
||||
|
||||
methods = {
|
||||
loadOptions: {
|
||||
// Get all the available escalation policies to display them to user so that they can
|
||||
// select them easily
|
||||
async getEscalationPolicies(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||
const returnData: INodePropertyOptions[] = [];
|
||||
const escalationPolicies = await pagerDutyApiRequestAllItems.call(
|
||||
this,
|
||||
'escalation_policies',
|
||||
'GET',
|
||||
'/escalation_policies',
|
||||
);
|
||||
for (const escalationPolicy of escalationPolicies) {
|
||||
const escalationPolicyName = escalationPolicy.name;
|
||||
const escalationPolicyId = escalationPolicy.id;
|
||||
returnData.push({
|
||||
name: escalationPolicyName,
|
||||
value: escalationPolicyId,
|
||||
});
|
||||
}
|
||||
return returnData;
|
||||
},
|
||||
// Get all the available priorities to display them to user so that they can
|
||||
// select them easily
|
||||
async getPriorities(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||
const returnData: INodePropertyOptions[] = [];
|
||||
const priorities = await pagerDutyApiRequestAllItems.call(
|
||||
this,
|
||||
'priorities',
|
||||
'GET',
|
||||
'/priorities',
|
||||
);
|
||||
for (const priority of priorities) {
|
||||
const priorityName = priority.name;
|
||||
const priorityId = priority.id;
|
||||
const priorityDescription = priority.description;
|
||||
returnData.push({
|
||||
name: priorityName,
|
||||
value: priorityId,
|
||||
description: priorityDescription,
|
||||
});
|
||||
}
|
||||
return returnData;
|
||||
},
|
||||
// Get all the available services to display them to user so that they can
|
||||
// select them easily
|
||||
async getServices(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||
const returnData: INodePropertyOptions[] = [];
|
||||
const services = await pagerDutyApiRequestAllItems.call(
|
||||
this,
|
||||
'services',
|
||||
'GET',
|
||||
'/services',
|
||||
);
|
||||
for (const service of services) {
|
||||
const serviceName = service.name;
|
||||
const serviceId = service.id;
|
||||
returnData.push({
|
||||
name: serviceName,
|
||||
value: serviceId,
|
||||
});
|
||||
}
|
||||
return returnData;
|
||||
},
|
||||
// Get all the timezones to display them to user so that they can
|
||||
// select them easily
|
||||
async getTimezones(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||
const returnData: INodePropertyOptions[] = [];
|
||||
for (const timezone of moment.tz.names()) {
|
||||
const timezoneName = timezone;
|
||||
const timezoneId = timezone;
|
||||
returnData.push({
|
||||
name: timezoneName,
|
||||
value: timezoneId,
|
||||
});
|
||||
}
|
||||
return returnData;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||
const items = this.getInputData();
|
||||
const returnData: INodeExecutionData[] = [];
|
||||
const length = items.length;
|
||||
let responseData;
|
||||
const qs: IDataObject = {};
|
||||
const resource = this.getNodeParameter('resource', 0);
|
||||
const operation = this.getNodeParameter('operation', 0);
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'incident') {
|
||||
//https://api-reference.pagerduty.com/#!/Incidents/post_incidents
|
||||
if (operation === 'create') {
|
||||
const title = this.getNodeParameter('title', i) as string;
|
||||
const serviceId = this.getNodeParameter('serviceId', i) as string;
|
||||
const email = this.getNodeParameter('email', i) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||
const conferenceBridge = (this.getNodeParameter('conferenceBridgeUi', i) as IDataObject)
|
||||
.conferenceBridgeValues as IDataObject;
|
||||
const body: IIncident = {
|
||||
type: 'incident',
|
||||
title,
|
||||
service: {
|
||||
id: serviceId,
|
||||
type: 'service_reference',
|
||||
},
|
||||
};
|
||||
if (additionalFields.details) {
|
||||
body.body = {
|
||||
type: 'incident_body',
|
||||
details: additionalFields.details,
|
||||
};
|
||||
}
|
||||
if (additionalFields.priorityId) {
|
||||
body.priority = {
|
||||
id: additionalFields.priorityId,
|
||||
type: 'priority_reference',
|
||||
};
|
||||
}
|
||||
if (additionalFields.escalationPolicyId) {
|
||||
body.escalation_policy = {
|
||||
id: additionalFields.escalationPolicyId,
|
||||
type: 'escalation_policy_reference',
|
||||
};
|
||||
}
|
||||
if (additionalFields.urgency) {
|
||||
body.urgency = additionalFields.urgency as string;
|
||||
}
|
||||
if (additionalFields.incidentKey) {
|
||||
body.incident_key = additionalFields.incidentKey as string;
|
||||
}
|
||||
if (conferenceBridge) {
|
||||
body.conference_bridge = {
|
||||
conference_number: conferenceBridge.conferenceNumber,
|
||||
conference_url: conferenceBridge.conferenceUrl,
|
||||
};
|
||||
}
|
||||
responseData = await pagerDutyApiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
'/incidents',
|
||||
{ incident: body },
|
||||
{},
|
||||
undefined,
|
||||
{ from: email },
|
||||
);
|
||||
responseData = responseData.incident;
|
||||
}
|
||||
//https://api-reference.pagerduty.com/#!/Incidents/get_incidents_id
|
||||
if (operation === 'get') {
|
||||
const incidentId = this.getNodeParameter('incidentId', i) as string;
|
||||
responseData = await pagerDutyApiRequest.call(this, 'GET', `/incidents/${incidentId}`);
|
||||
responseData = responseData.incident;
|
||||
}
|
||||
//https://api-reference.pagerduty.com/#!/Incidents/get_incidents
|
||||
if (operation === 'getAll') {
|
||||
const returnAll = this.getNodeParameter('returnAll', 0);
|
||||
const options = this.getNodeParameter('options', 0);
|
||||
if (options.userIds) {
|
||||
options.userIds = (options.userIds as string).split(',');
|
||||
}
|
||||
if (options.teamIds) {
|
||||
options.teamIds = (options.teamIds as string).split(',');
|
||||
}
|
||||
if (options.include) {
|
||||
options.include = (options.include as string[]).map((e) => snakeCase(e));
|
||||
}
|
||||
if (options.sortBy) {
|
||||
options.sortBy = options.sortBy as string;
|
||||
}
|
||||
Object.assign(qs, keysToSnakeCase(options)[0]);
|
||||
if (returnAll) {
|
||||
responseData = await pagerDutyApiRequestAllItems.call(
|
||||
this,
|
||||
'incidents',
|
||||
'GET',
|
||||
'/incidents',
|
||||
{},
|
||||
qs,
|
||||
);
|
||||
} else {
|
||||
qs.limit = this.getNodeParameter('limit', 0);
|
||||
responseData = await pagerDutyApiRequest.call(this, 'GET', '/incidents', {}, qs);
|
||||
responseData = responseData.incidents;
|
||||
}
|
||||
}
|
||||
//https://api-reference.pagerduty.com/#!/Incidents/put_incidents_id
|
||||
if (operation === 'update') {
|
||||
const incidentId = this.getNodeParameter('incidentId', i) as string;
|
||||
const email = this.getNodeParameter('email', i) as string;
|
||||
const conferenceBridge = (this.getNodeParameter('conferenceBridgeUi', i) as IDataObject)
|
||||
.conferenceBridgeValues as IDataObject;
|
||||
const updateFields = this.getNodeParameter('updateFields', i);
|
||||
const body: IIncident = {
|
||||
type: 'incident',
|
||||
};
|
||||
if (updateFields.title) {
|
||||
body.title = updateFields.title as string;
|
||||
}
|
||||
if (updateFields.escalationLevel) {
|
||||
body.escalation_level = updateFields.escalationLevel as number;
|
||||
}
|
||||
if (updateFields.details) {
|
||||
body.body = {
|
||||
type: 'incident_body',
|
||||
details: updateFields.details,
|
||||
};
|
||||
}
|
||||
if (updateFields.priorityId) {
|
||||
body.priority = {
|
||||
id: updateFields.priorityId,
|
||||
type: 'priority_reference',
|
||||
};
|
||||
}
|
||||
if (updateFields.escalationPolicyId) {
|
||||
body.escalation_policy = {
|
||||
id: updateFields.escalationPolicyId,
|
||||
type: 'escalation_policy_reference',
|
||||
};
|
||||
}
|
||||
if (updateFields.urgency) {
|
||||
body.urgency = updateFields.urgency as string;
|
||||
}
|
||||
if (updateFields.resolution) {
|
||||
body.resolution = updateFields.resolution as string;
|
||||
}
|
||||
if (updateFields.status) {
|
||||
body.status = updateFields.status as string;
|
||||
}
|
||||
if (conferenceBridge) {
|
||||
body.conference_bridge = {
|
||||
conference_number: conferenceBridge.conferenceNumber,
|
||||
conference_url: conferenceBridge.conferenceUrl,
|
||||
};
|
||||
}
|
||||
responseData = await pagerDutyApiRequest.call(
|
||||
this,
|
||||
'PUT',
|
||||
`/incidents/${incidentId}`,
|
||||
{ incident: body },
|
||||
{},
|
||||
undefined,
|
||||
{ from: email },
|
||||
);
|
||||
responseData = responseData.incident;
|
||||
}
|
||||
}
|
||||
if (resource === 'incidentNote') {
|
||||
//https://api-reference.pagerduty.com/#!/Incidents/post_incidents_id_notes
|
||||
if (operation === 'create') {
|
||||
const incidentId = this.getNodeParameter('incidentId', i) as string;
|
||||
const content = this.getNodeParameter('content', i) as string;
|
||||
const email = this.getNodeParameter('email', i) as string;
|
||||
const body: IDataObject = {
|
||||
content,
|
||||
};
|
||||
responseData = await pagerDutyApiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
`/incidents/${incidentId}/notes`,
|
||||
{ note: body },
|
||||
{},
|
||||
undefined,
|
||||
{ from: email },
|
||||
);
|
||||
}
|
||||
//https://api-reference.pagerduty.com/#!/Incidents/get_incidents_id_notes
|
||||
if (operation === 'getAll') {
|
||||
const incidentId = this.getNodeParameter('incidentId', i) as string;
|
||||
const returnAll = this.getNodeParameter('returnAll', 0);
|
||||
if (returnAll) {
|
||||
responseData = await pagerDutyApiRequestAllItems.call(
|
||||
this,
|
||||
'notes',
|
||||
'GET',
|
||||
`/incidents/${incidentId}/notes`,
|
||||
{},
|
||||
qs,
|
||||
);
|
||||
} else {
|
||||
qs.limit = this.getNodeParameter('limit', 0);
|
||||
responseData = await pagerDutyApiRequest.call(
|
||||
this,
|
||||
'GET',
|
||||
`/incidents/${incidentId}/notes`,
|
||||
{},
|
||||
qs,
|
||||
);
|
||||
responseData = responseData.notes;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resource === 'logEntry') {
|
||||
//https://api-reference.pagerduty.com/#!/Log_Entries/get_log_entries_id
|
||||
if (operation === 'get') {
|
||||
const logEntryId = this.getNodeParameter('logEntryId', i) as string;
|
||||
responseData = await pagerDutyApiRequest.call(
|
||||
this,
|
||||
'GET',
|
||||
`/log_entries/${logEntryId}`,
|
||||
);
|
||||
responseData = responseData.log_entry;
|
||||
}
|
||||
//https://api-reference.pagerduty.com/#!/Log_Entries/get_log_entries
|
||||
if (operation === 'getAll') {
|
||||
const options = this.getNodeParameter('options', i);
|
||||
Object.assign(qs, options);
|
||||
keysToSnakeCase(qs);
|
||||
const returnAll = this.getNodeParameter('returnAll', 0);
|
||||
if (returnAll) {
|
||||
responseData = await pagerDutyApiRequestAllItems.call(
|
||||
this,
|
||||
'log_entries',
|
||||
'GET',
|
||||
'/log_entries',
|
||||
{},
|
||||
qs,
|
||||
);
|
||||
} else {
|
||||
qs.limit = this.getNodeParameter('limit', 0);
|
||||
responseData = await pagerDutyApiRequest.call(this, 'GET', '/log_entries', {}, qs);
|
||||
responseData = responseData.log_entries;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resource === 'user') {
|
||||
//https://developer.pagerduty.com/api-reference/reference/REST/openapiv3.json/paths/~1users~1%7Bid%7D/get
|
||||
if (operation === 'get') {
|
||||
const userId = this.getNodeParameter('userId', i) as string;
|
||||
responseData = await pagerDutyApiRequest.call(this, 'GET', `/users/${userId}`);
|
||||
responseData = responseData.user;
|
||||
}
|
||||
}
|
||||
|
||||
const executionData = this.helpers.constructExecutionMetaData(
|
||||
this.helpers.returnJsonArray(responseData as IDataObject[]),
|
||||
{ itemData: { item: i } },
|
||||
);
|
||||
|
||||
returnData.push(...executionData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
const executionErrorData = this.helpers.constructExecutionMetaData(
|
||||
this.helpers.returnJsonArray({ error: error.message }),
|
||||
{ itemData: { item: i } },
|
||||
);
|
||||
returnData.push(...executionErrorData);
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [returnData];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
|
||||
export const userOperations: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['user'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get a user',
|
||||
action: 'Get a user',
|
||||
},
|
||||
],
|
||||
default: 'get',
|
||||
},
|
||||
];
|
||||
|
||||
export const userFields: INodeProperties[] = [
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* user:get */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'User ID',
|
||||
name: 'userId',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['user'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
description: 'Unique identifier for the user',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 66 56"><use xlink:href="#a" x=".5" y=".5"/><symbol id="a" overflow="visible"><path fill="#25c151" fill-rule="nonzero" stroke="none" d="M6.704 54.434H0v-33.65c0-3.455 1.418-5.544 2.604-6.704 2.63-2.58 6.2-2.656 6.782-2.656h10.546c3.765 0 5.93 1.52 7.117 2.8 2.346 2.553 2.372 5.853 2.32 6.73v12.687c0 3.662-1.496 5.828-2.733 6.988-2.553 2.398-5.93 2.45-6.73 2.424H6.704zm13.46-18.102c.36 0 1.367-.103 1.908-.62.413-.387.62-1.083.62-2.1v-13.02c0-.36-.077-1.315-.593-1.857-.5-.516-1.444-.62-2.166-.62h-10.6c-2.63 0-2.63 1.985-2.63 2.656v15.55zM57.296 0H64v33.677c0 3.455-1.418 5.544-2.604 6.704-2.63 2.58-6.2 2.656-6.782 2.656H44.068c-3.765 0-5.93-1.52-7.117-2.8-2.346-2.553-2.372-5.853-2.32-6.73v-12.67c0-3.662 1.496-5.828 2.733-6.988 2.553-2.398 5.93-2.45 6.73-2.424h13.202zm-13.46 18.117c-.36 0-1.367.103-1.908.62-.413.387-.62 1.083-.62 2.1v13.02c0 .36.077 1.315.593 1.857.5.516 1.444.62 2.166.62h10.598c2.656-.026 2.656-2 2.656-2.682V18.117z"/></symbol></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
Reference in New Issue
Block a user