n8n/packages/nodes-base/nodes/WhatsApp/MessagesDescription.ts
Valya f63710a892
feat(WhatsApp Business node): WhatsApp node (#3659)
* feat: base structure for whatsapp node with credentials

* feat: messages operation

* feat: create generic api call with credentials and test first operation

* fix: add missing template params

* fix: language code for template

* feat: media type and start of template components

* fix: remove provider name from media type

* lintfix

* fix: format

* feat: media operations w/o upload media type

* ♻️ Convert WhatsApp Business node to declarative style

* 🐛 form data not being sent with boundary in header

*  add media operations to WhatsApp

*  add credentials test to WhatsApp credentials

* ♻️ move preview url to optional collection in whatsapp message

* ♻️ renamed media operations in whatsapp node

* :refactor: move media file name to optional fields in whatsapp node

*  add upload from n8n for whatsapp node message resource

* 🔥 remove other template component types in whatsapp node

* :speech_bubble: add specialised text for media types in WhatsApp node

*  Load dinamically phone number and template name

*  Add action property to all operations

* 🔥 Remove unnecessary imports

*  Use getBinaryDataBuffer helper

*  Add components property

*  send components for whatsapp templates and template language

* 🏷️ fix WhatsApp node message function types

* 🏷️ fix any in whatsapp message functions

* 🔥 remove unused import

*  Improvements

*  Add send location

*  Add send contact

*  Small improvement

* ♻️ changes for review

* 🐛 fix presend error

* ♻️ change lat/long to numbers with proper clamping

* fix: bad merge

* refactor: changes for review

* update package-lock.json

* update package.-lock.json

* update

Co-authored-by: cxgarcia <schlaubitzcristobal@gmail.com>
Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
2022-09-29 20:17:46 -04:00

1509 lines
30 KiB
TypeScript

import { INodeProperties } from 'n8n-workflow';
import {
cleanPhoneNumber,
componentsRequest,
mediaUploadFromItem,
sendErrorPostReceive,
setType,
templateInfo,
} from './MessageFunctions';
export const mediaTypes = ['image', 'video', 'audio', 'sticker', 'document'];
let currencies = require('currency-codes/data');
currencies = currencies.map(({ code, currency }: { code: string; currency: string }) => ({
name: `${code} - ${currency}`,
value: code,
}));
export const messageFields: INodeProperties[] = [
{
displayName: 'Operation',
noDataExpression: true,
name: 'operation',
type: 'options',
placeholder: '',
options: [
{
name: 'Send',
value: 'send',
action: 'Send message',
},
{
name: 'Send Template',
value: 'sendTemplate',
action: 'Send template',
},
],
default: 'sendTemplate',
routing: {
request: {
ignoreHttpStatusErrors: true,
},
send: {
preSend: [setType],
},
output: { postReceive: [sendErrorPostReceive] },
},
displayOptions: {
show: {
resource: ['message'],
},
},
},
{
displayName: 'Messaging Product',
name: 'messagingProduct',
default: 'whatsapp',
type: 'hidden',
routing: {
send: {
type: 'body',
property: 'messaging_product',
},
},
displayOptions: {
show: {
resource: ['message'],
},
},
},
{
displayName: 'Sender Phone Number (or ID)',
name: 'phoneNumberId',
type: 'options',
typeOptions: {
loadOptions: {
routing: {
request: {
url: '={{$credentials.businessAccountId}}/phone_numbers',
method: 'GET',
},
output: {
postReceive: [
{
type: 'rootProperty',
properties: {
property: 'data',
},
},
{
type: 'setKeyValue',
properties: {
name: '={{$responseItem.display_phone_number}} - {{$responseItem.verified_name}}',
value: '={{$responseItem.id}}',
},
},
{
type: 'sort',
properties: {
key: 'name',
},
},
],
},
},
},
},
default: '',
placeholder: '',
required: true,
description:
"The ID of the business account's phone number from which the message will be sent from",
routing: {
request: {
method: 'POST',
url: '={{$value}}/messages',
},
},
displayOptions: {
show: {
resource: ['message'],
},
},
},
{
displayName: "Recipient's Phone Number",
name: 'recipientPhoneNumber',
type: 'string',
default: '',
required: true,
description: 'Phone number of the recipient of the message',
hint: 'When entering a phone number, make sure to include the country code',
routing: {
send: {
type: 'body',
preSend: [cleanPhoneNumber],
},
},
displayOptions: {
show: {
resource: ['message'],
},
},
},
{
displayName: 'MessageType',
noDataExpression: true,
name: 'messageType',
type: 'options',
placeholder: '',
options: [
{
name: 'Audio',
value: 'audio',
},
{
name: 'Contacts',
value: 'contacts',
},
{
name: 'Document',
value: 'document',
},
{
name: 'Image',
value: 'image',
},
{
name: 'Location',
value: 'location',
},
{
name: 'Text',
value: 'text',
},
{
name: 'Video',
value: 'video',
},
],
default: 'text',
description: 'The type of the message',
displayOptions: {
show: {
resource: ['message'],
operation: ['send'],
},
},
},
];
export const messageTypeFields: INodeProperties[] = [
// ----------------------------------
// type: contact
// ----------------------------------
{
displayName: 'Name',
name: 'name',
type: 'fixedCollection',
typeOptions: {
multipleValues: false,
},
displayOptions: {
show: {
operation: ['send'],
messageType: ['contacts'],
},
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'Name',
name: 'data',
values: [
{
displayName: 'Formatted Name',
name: 'formatted_name',
type: 'string',
required: true,
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].name.formatted_name',
},
},
},
{
displayName: 'First Name',
name: 'first_name',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].name.first_name',
},
},
},
{
displayName: 'Last Name',
name: 'last_name',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].name.last_name',
},
},
},
{
displayName: 'Middle Name',
name: 'middle_name',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].name.middle_name',
},
},
},
{
displayName: 'Suffix',
name: 'suffix',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].name.suffix',
},
},
},
{
displayName: 'Prefix',
name: 'prefix',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].name.prefix',
},
},
},
],
},
],
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
operation: ['send'],
messageType: ['contacts'],
},
},
options: [
{
displayName: 'Addresses',
name: 'addresses',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'Address',
name: 'address',
values: [
{
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Home',
value: 'HOME',
},
{
name: 'Work',
value: 'WORK',
},
],
default: 'HOME',
routing: {
send: {
property: '=contacts[0].addresses[{{$index}}].type',
type: 'body',
},
},
},
{
displayName: 'Street',
name: 'street',
type: 'string',
default: '',
routing: {
send: {
property: '=contacts[0].addresses[{{$index}}].street',
type: 'body',
},
},
},
{
displayName: 'City',
name: 'city',
type: 'string',
default: '',
routing: {
send: {
property: '=contacts[0].addresses[{{$index}}].city',
type: 'body',
},
},
},
{
displayName: 'State',
name: 'state',
type: 'string',
default: '',
routing: {
send: {
property: '=contacts[0].addresses[{{$index}}].state',
type: 'body',
},
},
},
{
displayName: 'Zip',
name: 'zip',
type: 'string',
default: '',
routing: {
send: {
property: '=contacts[0].addresses[{{$index}}].zip',
type: 'body',
},
},
},
{
displayName: 'Country',
name: 'country',
type: 'string',
default: '',
routing: {
send: {
property: '=contacts[0].addresses[{{$index}}].country',
type: 'body',
},
},
},
{
displayName: 'Country Code',
name: 'country_code',
type: 'string',
default: '',
routing: {
send: {
property: '=contacts[0].addresses[{{$index}}].country_code',
type: 'body',
},
},
},
],
},
],
},
{
displayName: 'Birthday',
name: 'birthday',
type: 'string',
default: '',
routing: {
send: {
property: 'contacts[0].birthday',
type: 'body',
},
},
placeholder: 'YYYY-MM-DD',
},
{
displayName: 'Emails',
name: 'emails',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'Email',
name: 'data',
values: [
{
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Home',
value: 'HOME',
},
{
name: 'Work',
value: 'WORK',
},
],
default: 'HOME',
routing: {
send: {
property: '=contacts[0].emails[{{$index}}].type',
type: 'body',
},
},
},
{
displayName: 'Email',
name: 'email',
type: 'string',
placeholder: 'name@email.com',
default: '',
routing: {
send: {
property: '=contacts[0].emails[{{$index}}].email',
type: 'body',
},
},
},
],
},
],
},
{
displayName: 'Organization',
name: 'organization',
type: 'fixedCollection',
typeOptions: {
multipleValues: false,
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'Organization',
name: 'data',
values: [
{
displayName: 'Company',
name: 'company',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].org.company',
},
},
},
{
displayName: 'Department',
name: 'department',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].org.department',
},
},
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'contacts[0].org.title',
},
},
},
],
},
],
},
{
displayName: 'Phones',
name: 'phones',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'Phone',
name: 'data',
values: [
{
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Cell',
value: 'CELL',
},
{
name: 'Home',
value: 'HOME',
},
{
name: 'Iphone',
value: 'IPHONE',
},
{
name: 'Main',
value: 'MAIN',
},
{
name: 'WhatsApp ID',
value: 'wa_id',
},
{
name: 'Work',
value: 'WORK',
},
],
default: 'CELL',
routing: {
send: {
property: '=contacts[0].phones[{{$index}}].type',
type: 'body',
},
},
},
{
displayName: 'Phone',
name: 'phone',
type: 'string',
default: '',
routing: {
send: {
property: '=contacts[0].phones[{{$index}}].phone',
type: 'body',
},
},
},
],
},
],
},
{
displayName: 'URLs',
name: 'urls',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'URL',
name: 'url',
values: [
{
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Home',
value: 'HOME',
},
{
name: 'Work',
value: 'WORK',
},
],
default: 'HOME',
routing: {
send: {
property: '=contacts[0].urls[{{$index}}].type',
type: 'body',
},
},
},
{
displayName: 'URL',
name: 'url',
type: 'string',
default: '',
routing: {
send: {
property: '=contacts[0].urls[{{$index}}].url',
type: 'body',
},
},
},
],
},
],
},
],
},
// ----------------------------------
// type: location
// ----------------------------------
{
displayName: 'Longitude',
name: 'longitude',
type: 'number',
required: true,
default: '',
typeOptions: {
minValue: -180,
maxValue: 180,
},
displayOptions: {
show: {
resource: ['message'],
operation: ['send'],
messageType: ['location'],
},
},
routing: {
send: {
type: 'body',
property: 'location.longitude',
},
},
},
{
displayName: 'Latitude',
name: 'latitude',
type: 'number',
default: '',
required: true,
typeOptions: {
minValue: -90,
maxValue: 90,
},
displayOptions: {
show: {
resource: ['message'],
operation: ['send'],
messageType: ['location'],
},
},
routing: {
send: {
type: 'body',
property: 'location.latitude',
},
},
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'fixedCollection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['message'],
operation: ['send'],
messageType: ['location'],
},
},
options: [
{
displayName: 'Name and Address',
name: 'nameAndAddress',
values: [
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'location.name',
},
},
},
{
displayName: 'Address',
name: 'address',
type: 'string',
default: '',
routing: {
send: {
type: 'body',
property: 'location.address',
},
},
},
],
},
],
},
// ----------------------------------
// type: text
// ----------------------------------
{
displayName: 'Text Body',
name: 'textBody',
type: 'string',
required: true,
default: '',
description: 'The body of the message (max 4096 characters)',
displayOptions: {
show: {
resource: ['message'],
operation: ['send'],
messageType: ['text'],
},
},
routing: {
send: {
type: 'body',
property: 'text.body',
},
},
},
// ----------------------------------
// type: media
// ----------------------------------
{
displayName: 'Take Audio From',
name: 'mediaPath',
type: 'options',
default: 'useMediaLink',
description: 'Use a link, an ID, or n8n to upload an audio file',
options: [
{
name: 'Link',
value: 'useMediaLink',
description:
'WhatsApp will download the audio, saving you the step of uploading audio yourself',
},
{
name: 'WhatsApp Media',
value: 'useMediaId',
description: 'If you have already uploaded the audio to WhatsApp',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'n8n',
value: 'useMedian8n',
description: 'Use binary data passed into this node',
},
],
displayOptions: {
show: {
operation: ['send'],
messageType: ['audio'],
},
},
},
{
displayName: 'Take Document From',
name: 'mediaPath',
type: 'options',
default: 'useMediaLink',
description: 'Use a link, an ID, or n8n to upload a document',
options: [
{
name: 'Link',
value: 'useMediaLink',
description:
'When using a link, WhatsApp will download the document, saving you the step of uploading document yourself',
},
{
name: 'WhatsApp Media',
value: 'useMediaId',
description: 'You can use an ID if you have already uploaded the document to WhatsApp',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'n8n',
value: 'useMedian8n',
description: 'Upload a binary file on the item being processed in n8n',
},
],
displayOptions: {
show: {
operation: ['send'],
messageType: ['document'],
},
},
},
{
displayName: 'Take Image From',
name: 'mediaPath',
type: 'options',
default: 'useMediaLink',
description: 'Use a link, an ID, or n8n to upload an image',
options: [
{
name: 'Link',
value: 'useMediaLink',
description:
'When using a link, WhatsApp will download the image, saving you the step of uploading image yourself',
},
{
name: 'WhatsApp Media',
value: 'useMediaId',
description: 'You can use an ID if you have already uploaded the image to WhatsApp',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'n8n',
value: 'useMedian8n',
description: 'Upload a binary file on the item being processed in n8n',
},
],
displayOptions: {
show: {
operation: ['send'],
messageType: ['image'],
},
},
},
{
displayName: 'Take Video From',
name: 'mediaPath',
type: 'options',
default: 'useMediaLink',
description: 'Use a link, an ID, or n8n to upload a video',
options: [
{
name: 'Link',
value: 'useMediaLink',
description:
'When using a link, WhatsApp will download the video, saving you the step of uploading video yourself',
},
{
name: 'WhatsApp Media',
value: 'useMediaId',
description: 'You can use an ID if you have already uploaded the video to WhatsApp',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'n8n',
value: 'useMedian8n',
description: 'Upload a binary file on the item being processed in n8n',
},
],
displayOptions: {
show: {
operation: ['send'],
messageType: ['video'],
},
},
},
{
displayName: 'Link',
name: 'mediaLink',
type: 'string',
default: '',
description: 'Link of the media to be sent',
displayOptions: {
show: {
operation: ['send'],
messageType: mediaTypes,
mediaPath: ['useMediaLink'],
},
},
routing: {
send: {
type: 'body',
property: '={{$parameter["messageType"]}}.link',
},
},
},
{
displayName: 'ID',
name: 'mediaId',
type: 'string',
default: '',
description: 'ID of the media to be sent',
displayOptions: {
show: {
operation: ['send'],
messageType: mediaTypes,
mediaPath: ['useMediaId'],
},
},
routing: {
send: {
type: 'body',
property: '={{$parameter["messageType"]}}.id',
},
},
},
{
displayName: 'Input Data Field Name',
name: 'mediaPropertyName',
type: 'string',
default: 'data',
description: 'The name of the input field containing the binary file data to be uploaded',
required: true,
displayOptions: {
show: {
operation: ['send'],
messageType: mediaTypes,
mediaPath: ['useMedian8n'],
},
},
routing: {
send: {
preSend: [mediaUploadFromItem],
},
},
},
{
displayName: 'Filename',
name: 'mediaFilename',
type: 'string',
default: '',
description: 'The name of the file (required when using a file ID)',
required: true,
displayOptions: {
show: {
operation: ['send'],
messageType: ['document'],
mediaPath: ['useMediaId'],
},
},
routing: {
send: {
type: 'body',
property: '={{$parameter["messageType"]}}.filename',
},
},
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['message'],
operation: ['send'],
messageType: mediaTypes,
},
},
options: [
{
displayName: 'Filename',
name: 'mediaFilename',
type: 'string',
default: '',
description: 'The name of the file',
routing: {
send: {
type: 'body',
property: '={{$parameter["messageType"]}}.filename',
},
},
displayOptions: {
show: {
'/messageType': ['document'],
},
},
},
{
displayName: 'Caption',
name: 'mediaCaption',
type: 'string',
default: '',
description: 'The caption of the media',
routing: {
send: {
type: 'body',
property: '={{$parameter["messageType"]}}.caption',
},
},
},
],
},
// ----------------------------------
// type: template
// ----------------------------------
{
displayName: 'Template',
name: 'template',
default: '',
type: 'options',
displayOptions: {
show: {
operation: ['sendTemplate'],
resource: ['message'],
},
},
typeOptions: {
loadOptions: {
routing: {
request: {
url: '={{$credentials.businessAccountId}}/message_templates',
method: 'GET',
},
output: {
postReceive: [
{
type: 'rootProperty',
properties: {
property: 'data',
},
},
{
type: 'setKeyValue',
properties: {
name: '={{$responseItem.name}} - {{$responseItem.language}}',
value: '={{$responseItem.name}}|{{$responseItem.language}}',
},
},
{
type: 'sort',
properties: {
key: 'name',
},
},
],
},
},
},
},
required: true,
description: 'Name of the template',
routing: {
send: {
type: 'body',
// property: 'template.name',
preSend: [templateInfo],
},
},
},
//{
// // Search for ISO6391.getCode(language) in the Twitter node. Pehaps, we can use the same library?
// //TODO: would be nice to change this to a searchable dropdown with all the possible language codes
// displayName: 'Language Code',
// name: 'templateLanguageCode',
// type: 'string',
// default: 'en_US',
// displayOptions: {
// show: {
// operation: ['sendTemplate'],
// resource: ['message'],
// },
// },
// description:
// 'The code of the language or locale to use. Accepts both language and language_locale formats (e.g., en and en_US).',
// routing: {
// send: {
// type: 'body',
// property: 'template.language.code',
// },
// },
//},
{
displayName: 'Components',
name: 'components',
type: 'fixedCollection',
default: {},
typeOptions: {
multipleValues: true,
},
placeholder: 'Add Component',
displayOptions: {
show: {
operation: ['sendTemplate'],
resource: ['message'],
},
},
routing: {
send: {
preSend: [componentsRequest],
},
},
options: [
{
name: 'component',
displayName: 'Component',
values: [
{
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Body',
value: 'body',
},
{
name: 'Button',
value: 'button',
},
{
name: 'Header',
value: 'header',
},
],
default: 'body',
},
{
displayName: 'Parameters',
name: 'bodyParameters',
type: 'fixedCollection',
typeOptions: {
sortable: true,
multipleValues: true,
},
displayOptions: {
show: {
type: ['body'],
},
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'Parameter',
name: 'parameter',
values: [
{
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Text',
value: 'text',
},
{
name: 'Currency',
value: 'currency',
},
{
name: 'Date Time',
value: 'date_time',
},
],
default: 'text',
},
{
displayName: 'Text',
name: 'text',
type: 'string',
displayOptions: {
show: {
type: ['text'],
},
},
default: '',
},
{
displayName: 'Currency Code',
name: 'code',
type: 'options',
options: currencies,
displayOptions: {
show: {
type: ['currency'],
},
},
default: '',
placeholder: 'USD',
},
{
displayName: 'Amount',
name: 'amount_1000',
type: 'number',
displayOptions: {
show: {
type: ['currency'],
},
},
default: '',
placeholder: '',
},
{
displayName: 'Date Time',
name: 'date_time',
type: 'dateTime',
displayOptions: {
show: {
type: ['date_time'],
},
},
default: '',
placeholder: '',
},
{
displayName: 'Fallback Value',
name: 'fallback_value',
type: 'string',
displayOptions: {
show: {
type: ['currency'],
},
},
default: '',
},
],
},
],
},
{
displayName: 'Sub Type',
name: 'sub_type',
type: 'options',
displayOptions: {
show: {
type: ['button'],
},
},
options: [
{
name: 'Quick Reply',
value: 'quick_reply',
description: 'Allows your customer to call a phone number and visit a website',
},
{
name: 'URL',
value: 'url',
},
],
default: 'quick_reply',
},
{
displayName: 'Index',
name: 'index',
type: 'number',
typeOptions: {
maxValue: 2,
minValue: 0,
},
displayOptions: {
show: {
type: ['button'],
},
},
default: 0,
},
{
displayName: 'Parameters',
name: 'buttonParameters',
type: 'fixedCollection',
typeOptions: {
multipleValues: false,
},
displayOptions: {
show: {
type: ['button'],
},
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'Parameter',
name: 'parameter',
values: [
{
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Payload',
value: 'payload',
},
{
name: 'Text',
value: 'text',
},
],
default: 'payload',
},
{
displayName: 'Payload',
name: 'payload',
type: 'string',
displayOptions: {
show: {
type: ['payload'],
},
},
default: '',
},
{
displayName: 'Text',
name: 'text',
type: 'string',
displayOptions: {
show: {
type: ['text'],
},
},
default: '',
},
],
},
],
},
{
displayName: 'Parameters',
name: 'headerParameters',
type: 'fixedCollection',
typeOptions: {
sortable: true,
multipleValues: true,
},
displayOptions: {
show: {
type: ['header'],
},
},
placeholder: 'Add Parameter',
default: {},
options: [
{
displayName: 'Parameter',
name: 'parameter',
values: [
{
displayName: 'Type',
name: 'type',
type: 'options',
options: [
{
name: 'Text',
value: 'text',
},
{
name: 'Currency',
value: 'currency',
},
{
name: 'Date Time',
value: 'date_time',
},
{
name: 'Image',
value: 'image',
},
],
default: 'text',
},
{
displayName: 'Text',
name: 'text',
type: 'string',
displayOptions: {
show: {
type: ['text'],
},
},
default: '',
},
{
displayName: 'Currency Code',
name: 'code',
type: 'options',
options: currencies,
displayOptions: {
show: {
type: ['currency'],
},
},
default: '',
placeholder: 'USD',
},
{
displayName: 'Amount',
name: 'amount_1000',
type: 'number',
displayOptions: {
show: {
type: ['currency'],
},
},
default: '',
placeholder: '',
},
{
displayName: 'Date Time',
name: 'date_time',
type: 'dateTime',
displayOptions: {
show: {
type: ['date_time'],
},
},
default: '',
placeholder: '',
},
{
displayName: 'Image Link',
name: 'imageLink',
type: 'string',
displayOptions: {
show: {
type: ['image'],
},
},
default: '',
},
],
},
],
},
],
},
],
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['message'],
operation: ['send'],
messageType: ['text'],
},
},
options: [
{
displayName: 'Show URL Previews',
name: 'previewUrl',
type: 'boolean',
default: false,
description: 'Whether to display URL previews in text messages',
routing: {
send: {
type: 'body',
property: 'text.preview_url',
},
},
},
],
},
];