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

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,99 @@
import type { INodeProperties } from 'n8n-workflow';
export const callOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['call'],
},
},
options: [
{
name: 'Make',
value: 'make',
description: 'Make a voice call',
action: 'Make a call',
},
],
default: 'make',
},
];
export const callFields: INodeProperties[] = [
// ----------------------------------
// call: make
// ----------------------------------
{
displayName: 'From',
name: 'from',
type: 'string',
default: '',
placeholder: '+14156667777',
description: 'Caller ID for the call to make',
required: true,
displayOptions: {
show: {
resource: ['call'],
operation: ['make'],
},
},
},
{
displayName: 'To',
name: 'to',
type: 'string',
default: '',
placeholder: '+14156667778',
required: true,
description: 'Phone number to make the call to',
displayOptions: {
show: {
resource: ['call'],
operation: ['make'],
},
},
},
{
displayName: 'Answer Method',
name: 'answer_method',
type: 'options',
required: true,
description: 'HTTP verb to be used when invoking the Answer URL',
default: 'POST',
options: [
{
name: 'GET',
value: 'GET',
},
{
name: 'POST',
value: 'POST',
},
],
displayOptions: {
show: {
resource: ['call'],
operation: ['make'],
},
},
},
{
displayName: 'Answer URL',
name: 'answer_url',
type: 'string',
default: '',
description:
'URL to be invoked by Plivo once the call is answered. It should return the XML to handle the call once answered.',
required: true,
displayOptions: {
show: {
resource: ['call'],
operation: ['make'],
},
},
},
];
@@ -0,0 +1,47 @@
import type {
IExecuteFunctions,
IHookFunctions,
IDataObject,
JsonObject,
IHttpRequestMethods,
IRequestOptions,
} from 'n8n-workflow';
import { NodeApiError } from 'n8n-workflow';
/**
* Make an API request to Plivo.
*
*/
export async function plivoApiRequest(
this: IHookFunctions | IExecuteFunctions,
method: IHttpRequestMethods,
endpoint: string,
body: IDataObject = {},
qs: IDataObject = {},
) {
const credentials = await this.getCredentials<{
authId: string;
authToken: string;
}>('plivoApi');
const options: IRequestOptions = {
headers: {
'user-agent': 'plivo-n8n',
},
method,
form: body,
qs,
uri: `https://api.plivo.com/v1/Account/${credentials.authId}${endpoint}/`,
auth: {
user: credentials.authId,
pass: credentials.authToken,
},
json: true,
};
try {
return await this.helpers.request(options);
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
}
}
@@ -0,0 +1,86 @@
import type { INodeProperties } from 'n8n-workflow';
export const mmsOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['mms'],
},
},
options: [
{
name: 'Send',
value: 'send',
description: 'Send an MMS message (US/Canada only)',
action: 'Send an MMS',
},
],
default: 'send',
},
];
export const mmsFields: INodeProperties[] = [
// ----------------------------------
// mms: send
// ----------------------------------
{
displayName: 'From',
name: 'from',
type: 'string',
default: '',
description: 'Plivo Number to send the MMS from',
placeholder: '+14156667777',
required: true,
displayOptions: {
show: {
resource: ['mms'],
operation: ['send'],
},
},
},
{
displayName: 'To',
name: 'to',
type: 'string',
default: '',
description: 'Phone number to send the MMS to',
placeholder: '+14156667778',
required: true,
displayOptions: {
show: {
operation: ['send'],
resource: ['mms'],
},
},
},
{
displayName: 'Message',
name: 'message',
type: 'string',
default: '',
description: 'Message to send',
displayOptions: {
show: {
resource: ['mms'],
operation: ['send'],
},
},
},
{
displayName: 'Media URLs',
name: 'media_urls',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['mms'],
operation: ['send'],
},
},
description: 'Comma-separated list of media URLs of the files from your file server',
},
];
@@ -0,0 +1,18 @@
{
"node": "n8n-nodes-base.plivo",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"categories": ["Communication", "Development"],
"resources": {
"credentialDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/credentials/plivo/"
}
],
"primaryDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.plivo/"
}
]
}
}
@@ -0,0 +1,149 @@
import {
type IExecuteFunctions,
type IDataObject,
type INodeExecutionData,
type INodeType,
type INodeTypeDescription,
NodeConnectionTypes,
} from 'n8n-workflow';
import { callFields, callOperations } from './CallDescription';
import { plivoApiRequest } from './GenericFunctions';
import { mmsFields, mmsOperations } from './MmsDescription';
import { smsFields, smsOperations } from './SmsDescription';
export class Plivo implements INodeType {
description: INodeTypeDescription = {
displayName: 'Plivo',
name: 'plivo',
icon: 'file:plivo.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Send SMS/MMS messages or make phone calls',
defaults: {
name: 'Plivo',
},
usableAsTool: true,
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
credentials: [
{
name: 'plivoApi',
required: true,
},
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Call',
value: 'call',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-resource-with-plural-option
name: 'MMS',
value: 'mms',
},
{
name: 'SMS',
value: 'sms',
},
],
default: 'sms',
required: true,
},
...smsOperations,
...smsFields,
...mmsOperations,
...mmsFields,
...callOperations,
...callFields,
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: IDataObject[] = [];
const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0);
for (let i = 0; i < items.length; i++) {
let responseData;
if (resource === 'sms') {
// *********************************************************************
// sms
// *********************************************************************
if (operation === 'send') {
// ----------------------------------
// sms: send
// ----------------------------------
const body = {
src: this.getNodeParameter('from', i) as string,
dst: this.getNodeParameter('to', i) as string,
text: this.getNodeParameter('message', i) as string,
} as IDataObject;
responseData = await plivoApiRequest.call(this, 'POST', '/Message', body);
}
} else if (resource === 'call') {
// *********************************************************************
// call
// *********************************************************************
if (operation === 'make') {
// ----------------------------------
// call: make
// ----------------------------------
// https://www.plivo.com/docs/voice/api/call#make-a-call
const body = {
from: this.getNodeParameter('from', i) as string,
to: this.getNodeParameter('to', i) as string,
answer_url: this.getNodeParameter('answer_url', i) as string,
answer_method: this.getNodeParameter('answer_method', i) as string,
} as IDataObject;
responseData = await plivoApiRequest.call(this, 'POST', '/Call', body);
}
} else if (resource === 'mms') {
// *********************************************************************
// mms
// *********************************************************************
if (operation === 'send') {
// ----------------------------------
// mss: send
// ----------------------------------
// https://www.plivo.com/docs/sms/api/message#send-a-message
const body = {
src: this.getNodeParameter('from', i) as string,
dst: this.getNodeParameter('to', i) as string,
text: this.getNodeParameter('message', i) as string,
type: 'mms',
media_urls: this.getNodeParameter('media_urls', i) as string,
} as IDataObject;
responseData = await plivoApiRequest.call(this, 'POST', '/Message', body);
}
}
Array.isArray(responseData)
? returnData.push(...(responseData as IDataObject[]))
: returnData.push(responseData as IDataObject);
}
return [this.helpers.returnJsonArray(returnData)];
}
}
@@ -0,0 +1,74 @@
import type { INodeProperties } from 'n8n-workflow';
export const smsOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['sms'],
},
},
options: [
{
name: 'Send',
value: 'send',
description: 'Send an SMS message',
action: 'Send an SMS',
},
],
default: 'send',
},
];
export const smsFields: INodeProperties[] = [
// ----------------------------------
// sms: send
// ----------------------------------
{
displayName: 'From',
name: 'from',
type: 'string',
default: '',
description: 'Plivo Number to send the SMS from',
placeholder: '+14156667777',
required: true,
displayOptions: {
show: {
resource: ['sms'],
operation: ['send'],
},
},
},
{
displayName: 'To',
name: 'to',
type: 'string',
default: '',
description: 'Phone number to send the message to',
placeholder: '+14156667778',
required: true,
displayOptions: {
show: {
resource: ['sms'],
operation: ['send'],
},
},
},
{
displayName: 'Message',
name: 'message',
type: 'string',
default: '',
description: 'Message to send',
required: true,
displayOptions: {
show: {
operation: ['send'],
resource: ['sms'],
},
},
},
];
@@ -0,0 +1,15 @@
{
"type": "object",
"properties": {
"api_id": {
"type": "string"
},
"message": {
"type": "string"
},
"request_uuid": {
"type": "string"
}
},
"version": 1
}
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="40 30 170 170"><defs><path id="a" d="M0 .549h152V119H0z"/></defs><g fill="none" fill-rule="evenodd"><path fill="#FFF" fill-opacity=".01" d="M0 0h250v218H0z"/><g transform="translate(49 49.451)"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><path fill="#43A046" d="M75.735.548C62.831.594 50.927 4.841 41.311 11.99c-9.616 7.15-16.943 17.202-20.695 28.853a4.3 4.3 0 0 1-.684 1.3 4.4 4.4 0 0 1-1.08.997 41.64 41.64 0 0 0-14.14 15.496C1.402 64.93-.328 72.182.052 79.872c.548 11.117 5.601 20.919 13.3 27.93 7.697 7.014 18.041 11.236 29.173 11.198h67.233a42.94 42.94 0 0 0 29.096-11.513c7.65-7.122 12.635-17.015 13.108-28.137.326-7.693-1.454-14.932-4.807-21.203a41.64 41.64 0 0 0-14.244-15.4 4.4 4.4 0 0 1-1.089-.988 4.3 4.3 0 0 1-.692-1.296c-3.832-11.625-11.228-21.626-20.894-28.71C100.572 4.672 88.64.506 75.736.549m.05 14.778c9.526-.032 18.572 3.124 25.92 8.568 7.347 5.444 12.998 13.175 15.734 22.293l.592 1.973.593 1.974a4.25 4.25 0 0 0 1.913 2.441l1.776 1.047 1.775 1.046c4.261 2.513 7.634 6.024 9.894 10.143s3.408 8.847 3.22 13.794c-.277 7.18-3.503 13.548-8.458 18.128a27.9 27.9 0 0 1-18.824 7.392l-33.83.116-33.83.117a27.9 27.9 0 0 1-18.874-7.263c-4.986-4.545-8.257-10.891-8.58-18.07-.225-4.945.89-9.68 3.122-13.815 2.233-4.135 5.582-7.67 9.826-10.211l1.768-1.058 1.767-1.06a4.25 4.25 0 0 0 1.898-2.454l.578-1.978.58-1.977c2.673-9.136 8.27-16.906 15.58-22.401 7.31-5.493 16.333-8.711 25.86-8.745" mask="url(#b)"/></g><path fill="#43A046" d="M113.281 100.651c0 .87-.35 1.658-.918 2.229a3.15 3.15 0 0 1-2.224.934l-3.174.012-3.175.011a3.15 3.15 0 0 1-2.229-.919 3.16 3.16 0 0 1-.934-2.223l-.01-3.175-.01-3.175a3.16 3.16 0 0 1 3.141-3.163l3.174-.01 3.174-.011c.87 0 1.658.35 2.23.918a3.15 3.15 0 0 1 .933 2.223l.011 3.175zm17.961 0c0 .87-.35 1.658-.918 2.229a3.15 3.15 0 0 1-2.223.934l-3.175.012-3.174.011c-.87 0-1.658-.351-2.23-.919a3.15 3.15 0 0 1-.933-2.223l-.012-3.175-.01-3.175a3.16 3.16 0 0 1 3.141-3.163l3.175-.01 3.174-.011c.87 0 1.658.35 2.23.918s.928 1.354.934 2.223l.01 3.175zm17.962.002c0 .869-.35 1.657-.918 2.229a3.16 3.16 0 0 1-2.225.934l-3.174.011-3.174.011a3.15 3.15 0 0 1-2.232-.916 3.15 3.15 0 0 1-.931-2.226l-.012-3.175-.01-3.175a3.13 3.13 0 0 1 .916-2.231 3.15 3.15 0 0 1 2.226-.931l3.175-.011 3.173-.011a3.15 3.15 0 0 1 2.26.867c.587.557.96 1.338.984 2.21v.064l-.03 3.175-.029 3.175zm-35.915 17.955c0 .869-.35 1.657-.918 2.229a3.16 3.16 0 0 1-2.224.934l-3.174.011-3.175.011a3.15 3.15 0 0 1-2.23-.918 3.16 3.16 0 0 1-.933-2.224l-.011-3.175-.01-3.174c-.001-.87.35-1.658.918-2.229a3.15 3.15 0 0 1 2.223-.934l3.175-.01 3.174-.012c.87 0 1.658.35 2.229.919.573.567.929 1.353.934 2.222l.01 3.175zm17.96 0c0 .869-.35 1.657-.917 2.229a3.16 3.16 0 0 1-2.223.934l-3.175.011-3.174.011a3.15 3.15 0 0 1-2.23-.918 3.15 3.15 0 0 1-.933-2.224l-.012-3.175-.01-3.174c-.001-.87.35-1.658.918-2.229a3.15 3.15 0 0 1 2.223-.934l3.175-.01 3.174-.012c.87 0 1.658.35 2.23.919a3.15 3.15 0 0 1 .934 2.222l.01 3.175zm17.962 0c0 .869-.35 1.657-.918 2.229a3.16 3.16 0 0 1-2.224.934l-3.174.011-3.175.011a3.14 3.14 0 0 1-2.232-.916 3.15 3.15 0 0 1-.93-2.226l-.012-3.175-.01-3.174a3.13 3.13 0 0 1 .915-2.232 3.15 3.15 0 0 1 2.226-.931l3.175-.01 3.174-.012c.87 0 1.658.35 2.23.919.572.567.928 1.353.933 2.222l.011 3.175zm-35.914 17.95a3.14 3.14 0 0 1-.916 2.232 3.14 3.14 0 0 1-2.226.931l-3.174.011-3.175.011a3.15 3.15 0 0 1-2.232-.915 3.15 3.15 0 0 1-.931-2.226l-.011-3.175-.01-3.175a3.15 3.15 0 0 1 .918-2.229 3.16 3.16 0 0 1 2.223-.934l3.175-.01 3.174-.01a3.14 3.14 0 0 1 2.229.917c.573.568.929 1.353.934 2.222l.01 3.175zm17.96 0a3.14 3.14 0 0 1-.915 2.232 3.14 3.14 0 0 1-2.225.931l-3.175.011-3.174.011a3.146 3.146 0 0 1-3.163-3.14l-.012-3.176-.01-3.175a3.15 3.15 0 0 1 .918-2.229 3.16 3.16 0 0 1 2.223-.934l3.175-.01 3.174-.01a3.15 3.15 0 0 1 2.23.917c.572.568.928 1.353.934 2.222l.01 3.175zm17.962 0a3.14 3.14 0 0 1-.916 2.232 3.14 3.14 0 0 1-2.226.931l-3.174.011-3.175.011a3.15 3.15 0 0 1-2.232-.915 3.15 3.15 0 0 1-.93-2.226l-.012-3.175-.01-3.175c-.004-.87.346-1.66.915-2.232a3.15 3.15 0 0 1 2.226-.93l3.175-.01 3.174-.012a3.14 3.14 0 0 1 2.23.918c.572.568.928 1.353.933 2.222l.011 3.175z"/></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB