mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
feat(Twilio Node): Add ability to make a voice call using TTS (#3467)
* Add ability to make a voice call on Twilio using TTS
* ⚡ Small improvement
Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
This commit is contained in:
parent
b8e3bcc052
commit
eff97e8d67
|
@ -59,3 +59,17 @@ export async function twilioApiRequest(this: IHookFunctions | IExecuteFunctions,
|
||||||
throw new NodeApiError(this.getNode(), error);
|
throw new NodeApiError(this.getNode(), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const XML_CHAR_MAP: { [key: string]: string } = {
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'&': '&',
|
||||||
|
'"': '"',
|
||||||
|
"'": '''
|
||||||
|
};
|
||||||
|
|
||||||
|
export function escapeXml(str: string) {
|
||||||
|
return str.replace(/[<>&"']/g, function (ch: string) {
|
||||||
|
return XML_CHAR_MAP[ch];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -61,6 +61,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"alias": [
|
"alias": [
|
||||||
"SMS"
|
"SMS",
|
||||||
|
"Phone",
|
||||||
|
"Voice"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
|
|
||||||
import {
|
import {
|
||||||
twilioApiRequest,
|
twilioApiRequest,
|
||||||
|
escapeXml,
|
||||||
} from './GenericFunctions';
|
} from './GenericFunctions';
|
||||||
|
|
||||||
export class Twilio implements INodeType {
|
export class Twilio implements INodeType {
|
||||||
|
@ -44,6 +45,11 @@ export class Twilio implements INodeType {
|
||||||
name: 'SMS',
|
name: 'SMS',
|
||||||
value: 'sms',
|
value: 'sms',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// eslint-disable-next-line n8n-nodes-base/node-param-resource-with-plural-option
|
||||||
|
name: 'Call',
|
||||||
|
value: 'call',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
default: 'sms',
|
default: 'sms',
|
||||||
},
|
},
|
||||||
|
@ -70,13 +76,34 @@ export class Twilio implements INodeType {
|
||||||
default: 'send',
|
default: 'send',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
noDataExpression: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'call',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Make',
|
||||||
|
value: 'make',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'make',
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// sms
|
// sms / call
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// sms:send
|
// sms:send / call:make
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
{
|
{
|
||||||
displayName: 'From',
|
displayName: 'From',
|
||||||
|
@ -89,9 +116,11 @@ export class Twilio implements INodeType {
|
||||||
show: {
|
show: {
|
||||||
operation: [
|
operation: [
|
||||||
'send',
|
'send',
|
||||||
|
'make',
|
||||||
],
|
],
|
||||||
resource: [
|
resource: [
|
||||||
'sms',
|
'sms',
|
||||||
|
'call',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -108,9 +137,11 @@ export class Twilio implements INodeType {
|
||||||
show: {
|
show: {
|
||||||
operation: [
|
operation: [
|
||||||
'send',
|
'send',
|
||||||
|
'make',
|
||||||
],
|
],
|
||||||
resource: [
|
resource: [
|
||||||
'sms',
|
'sms',
|
||||||
|
'call',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -151,6 +182,40 @@ export class Twilio implements INodeType {
|
||||||
},
|
},
|
||||||
description: 'The message to send',
|
description: 'The message to send',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Use TwiML',
|
||||||
|
name: 'twiml',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'make',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'call',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Whether to use the <a href="https://www.twilio.com/docs/voice/twiml">Twilio Markup Language</a> in the message',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'make',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'call',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Options',
|
displayName: 'Options',
|
||||||
name: 'options',
|
name: 'options',
|
||||||
|
@ -218,6 +283,30 @@ export class Twilio implements INodeType {
|
||||||
} else {
|
} else {
|
||||||
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`);
|
||||||
}
|
}
|
||||||
|
} else if (resource === 'call') {
|
||||||
|
if (operation === 'make') {
|
||||||
|
// ----------------------------------
|
||||||
|
// call:make
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
requestMethod = 'POST';
|
||||||
|
endpoint = '/Calls.json';
|
||||||
|
|
||||||
|
const message = this.getNodeParameter('message', i) as string;
|
||||||
|
const useTwiml = this.getNodeParameter('twiml', i) as boolean;
|
||||||
|
body.From = this.getNodeParameter('from', i) as string;
|
||||||
|
body.To = this.getNodeParameter('to', i) as string;
|
||||||
|
|
||||||
|
if (useTwiml) {
|
||||||
|
body.Twiml = message;
|
||||||
|
} else {
|
||||||
|
body.Twiml = `<Response><Say>${escapeXml(message)}</Say></Response>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.StatusCallback = this.getNodeParameter('options.statusCallback', i, '') as string;
|
||||||
|
} else {
|
||||||
|
throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`);
|
throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue