n8n-nodes-wuzapi
Version:
n8n community nodes for Wuzapi - WhatsApp Multi-Device REST API
582 lines • 25.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WuzapiGroup = void 0;
const GenericFunctions_1 = require("../GenericFunctions");
class WuzapiGroup {
constructor() {
this.description = {
displayName: 'Wuzapi Group',
name: 'wuzapiGroup',
icon: 'file:wuzapi.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"]}}',
description: 'Manage WhatsApp groups with Wuzapi API',
defaults: {
name: 'Wuzapi Group',
},
inputs: ["main" /* NodeConnectionType.Main */],
outputs: ["main" /* NodeConnectionType.Main */],
credentials: [
{
name: 'wuzapiApi',
required: true,
},
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new group',
action: 'Create group',
},
{
name: 'Get Info',
value: 'info',
description: 'Get group information',
action: 'Get group info',
},
{
name: 'Get Invite Link',
value: 'inviteLink',
description: 'Get group invite link',
action: 'Get invite link',
},
{
name: 'Get Invite Info',
value: 'inviteInfo',
description: 'Get info about an invite code',
action: 'Get invite info',
},
{
name: 'Join',
value: 'join',
description: 'Join a group via invite',
action: 'Join group',
},
{
name: 'Leave',
value: 'leave',
description: 'Leave a group',
action: 'Leave group',
},
{
name: 'List',
value: 'list',
description: 'List all groups',
action: 'List groups',
},
{
name: 'Set Announce',
value: 'announce',
description: 'Set announce mode',
action: 'Set announce mode',
},
{
name: 'Set Description',
value: 'topic',
description: 'Set group description/topic',
action: 'Set group description',
},
{
name: 'Set Ephemeral',
value: 'ephemeral',
description: 'Set disappearing messages',
action: 'Set ephemeral messages',
},
{
name: 'Set Locked',
value: 'locked',
description: 'Lock/unlock group info',
action: 'Set locked status',
},
{
name: 'Set Name',
value: 'name',
description: 'Change group name',
action: 'Set group name',
},
{
name: 'Set Photo',
value: 'photo',
description: 'Set group photo',
action: 'Set group photo',
},
{
name: 'Remove Photo',
value: 'removePhoto',
description: 'Remove group photo',
action: 'Remove group photo',
},
{
name: 'Update Participants',
value: 'updateParticipants',
description: 'Add/remove/promote/demote participants',
action: 'Update participants',
},
],
default: 'list',
},
// Create Group
{
displayName: 'Group Name',
name: 'groupName',
type: 'string',
default: '',
placeholder: 'My New Group',
description: 'Name for the new group',
required: true,
displayOptions: {
show: {
operation: ['create'],
},
},
},
{
displayName: 'Participants',
name: 'participants',
type: 'string',
default: '',
placeholder: 'e.g. 5491112345678,5491123456789',
description: 'Comma-separated list of phone numbers to add',
required: true,
displayOptions: {
show: {
operation: ['create'],
},
},
},
// Group JID for operations
{
displayName: 'Group JID',
name: 'groupJid',
type: 'string',
default: '',
placeholder: 'e.g. 120363312246943103@g.us',
description: 'JID of the group',
required: true,
displayOptions: {
show: {
operation: ['info', 'inviteLink', 'leave', 'announce', 'topic', 'ephemeral', 'locked', 'name', 'photo', 'removePhoto', 'updateParticipants'],
},
},
},
// Get Invite Link
{
displayName: 'Reset Link',
name: 'reset',
type: 'boolean',
default: false,
description: 'Whether to revoke the old link and generate a new one',
displayOptions: {
show: {
operation: ['inviteLink'],
},
},
},
// Join Group
{
displayName: 'Invite Code',
name: 'inviteCode',
type: 'string',
default: '',
placeholder: 'e.g. HffXhYmzzyJGec61oqMXiz',
description: 'Group invite code or link',
required: true,
displayOptions: {
show: {
operation: ['join', 'inviteInfo'],
},
},
},
// Set Name
{
displayName: 'New Name',
name: 'newName',
type: 'string',
default: '',
placeholder: 'New Group Name',
description: 'New name for the group',
required: true,
displayOptions: {
show: {
operation: ['name'],
},
},
},
// Set Topic
{
displayName: 'Description',
name: 'topic',
type: 'string',
default: '',
placeholder: 'Welcome to our group!',
description: 'Group description/topic',
required: true,
displayOptions: {
show: {
operation: ['topic'],
},
},
},
// Set Announce
{
displayName: 'Announce Mode',
name: 'announceMode',
type: 'boolean',
default: true,
description: 'Whether only admins can send messages',
displayOptions: {
show: {
operation: ['announce'],
},
},
},
// Set Locked
{
displayName: 'Locked Status',
name: 'lockedStatus',
type: 'boolean',
default: true,
description: 'Whether only admins can modify group info',
displayOptions: {
show: {
operation: ['locked'],
},
},
},
// Set Ephemeral
{
displayName: 'Duration',
name: 'duration',
type: 'options',
default: 'off',
options: [
{
name: 'Off',
value: 'off',
description: 'Disable disappearing messages',
},
{
name: '24 Hours',
value: '24h',
description: 'Messages disappear after 24 hours',
},
{
name: '7 Days',
value: '7d',
description: 'Messages disappear after 7 days',
},
{
name: '90 Days',
value: '90d',
description: 'Messages disappear after 90 days',
},
],
description: 'Duration for disappearing messages',
displayOptions: {
show: {
operation: ['ephemeral'],
},
},
},
// Set Photo
{
displayName: 'Photo Source',
name: 'photoSource',
type: 'options',
default: 'binary',
options: [
{
name: 'Binary Data',
value: 'binary',
description: 'Use binary data from previous node',
},
{
name: 'Base64',
value: 'base64',
description: 'Provide base64 encoded image',
},
{
name: 'URL',
value: 'url',
description: 'Provide URL to image file',
},
],
displayOptions: {
show: {
operation: ['photo'],
},
},
},
{
displayName: 'Binary Property',
name: 'photoBinaryProperty',
type: 'string',
default: 'data',
description: 'Name of the binary property containing the image',
displayOptions: {
show: {
operation: ['photo'],
photoSource: ['binary'],
},
},
},
{
displayName: 'Base64 Image',
name: 'photoBase64',
type: 'string',
default: '',
placeholder: 'data:image/jpeg;base64,iVBORw0...',
description: 'Base64 encoded JPEG image with data URL prefix',
displayOptions: {
show: {
operation: ['photo'],
photoSource: ['base64'],
},
},
},
{
displayName: 'Photo URL',
name: 'photoUrl',
type: 'string',
default: '',
placeholder: 'https://example.com/photo.jpg',
description: 'URL to the photo file',
displayOptions: {
show: {
operation: ['photo'],
photoSource: ['url'],
},
},
},
// Update Participants
{
displayName: 'Action',
name: 'participantAction',
type: 'options',
default: 'add',
options: [
{
name: 'Add',
value: 'add',
description: 'Add participants to group',
},
{
name: 'Remove',
value: 'remove',
description: 'Remove participants from group',
},
{
name: 'Promote',
value: 'promote',
description: 'Promote participants to admin',
},
{
name: 'Demote',
value: 'demote',
description: 'Demote admins to regular participants',
},
],
displayOptions: {
show: {
operation: ['updateParticipants'],
},
},
},
{
displayName: 'Phone Numbers',
name: 'participantPhones',
type: 'string',
default: '',
placeholder: 'e.g. 5491112345678,5491123456789@s.whatsapp.net',
description: 'Comma-separated list of phone numbers or JIDs',
required: true,
displayOptions: {
show: {
operation: ['updateParticipants'],
},
},
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
for (let i = 0; i < items.length; i++) {
try {
const operation = this.getNodeParameter('operation', i);
let responseData;
if (operation === 'create') {
const name = this.getNodeParameter('groupName', i);
const participants = this.getNodeParameter('participants', i);
const phones = participants.split(',').map(phone => (0, GenericFunctions_1.validatePhoneNumber)(phone.trim()));
const body = {
Name: name,
Participants: phones,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/create', body);
}
else if (operation === 'list') {
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'GET', '/group/list');
}
else if (operation === 'info') {
const groupJid = this.getNodeParameter('groupJid', i);
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'GET', '/group/info', {}, { groupJID: groupJid });
}
else if (operation === 'inviteLink') {
const groupJid = this.getNodeParameter('groupJid', i);
const reset = this.getNodeParameter('reset', i);
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'GET', '/group/invitelink', {}, {
groupJID: groupJid,
reset: reset,
});
}
else if (operation === 'join') {
const inviteCode = this.getNodeParameter('inviteCode', i);
// Extract code from URL if provided
const code = inviteCode.includes('chat.whatsapp.com/')
? inviteCode.split('/').pop() || inviteCode
: inviteCode;
const body = {
Code: code,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/join', body);
}
else if (operation === 'inviteInfo') {
const inviteCode = this.getNodeParameter('inviteCode', i);
// Extract code from URL if provided
const code = inviteCode.includes('chat.whatsapp.com/')
? inviteCode.split('/').pop() || inviteCode
: inviteCode;
const body = {
Code: code,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/inviteinfo', body);
}
else if (operation === 'leave') {
const groupJid = this.getNodeParameter('groupJid', i);
const body = {
GroupJID: groupJid,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/leave', body);
}
else if (operation === 'name') {
const groupJid = this.getNodeParameter('groupJid', i);
const newName = this.getNodeParameter('newName', i);
const body = {
GroupJID: groupJid,
Name: newName,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/name', body);
}
else if (operation === 'topic') {
const groupJid = this.getNodeParameter('groupJid', i);
const topic = this.getNodeParameter('topic', i);
const body = {
GroupJID: groupJid,
Topic: topic,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/topic', body);
}
else if (operation === 'announce') {
const groupJid = this.getNodeParameter('groupJid', i);
const announce = this.getNodeParameter('announceMode', i);
const body = {
GroupJID: groupJid,
Announce: announce,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/announce', body);
}
else if (operation === 'locked') {
const groupJid = this.getNodeParameter('groupJid', i);
const locked = this.getNodeParameter('lockedStatus', i);
const body = {
GroupJID: groupJid,
Locked: locked,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/locked', body);
}
else if (operation === 'ephemeral') {
const groupJid = this.getNodeParameter('groupJid', i);
const duration = this.getNodeParameter('duration', i);
const body = {
GroupJID: groupJid,
Duration: duration,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/ephemeral', body);
}
else if (operation === 'photo') {
const groupJid = this.getNodeParameter('groupJid', i);
const photoSource = this.getNodeParameter('photoSource', i);
const body = {
GroupJID: groupJid,
};
if (photoSource === 'binary') {
const binaryProperty = this.getNodeParameter('photoBinaryProperty', i);
const binaryData = items[i].binary?.[binaryProperty];
if (!binaryData) {
throw new Error(`Binary property "${binaryProperty}" not found`);
}
const buffer = Buffer.from(binaryData.data, 'base64');
body.Image = (0, GenericFunctions_1.prepareMediaData)(buffer, binaryData.mimeType || 'image/jpeg');
}
else if (photoSource === 'base64') {
body.Image = this.getNodeParameter('photoBase64', i);
}
else if (photoSource === 'url') {
body.Image = this.getNodeParameter('photoUrl', i);
}
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/photo', body);
}
else if (operation === 'removePhoto') {
const groupJid = this.getNodeParameter('groupJid', i);
const body = {
GroupJID: groupJid,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/photo/remove', body);
}
else if (operation === 'updateParticipants') {
const groupJid = this.getNodeParameter('groupJid', i);
const action = this.getNodeParameter('participantAction', i);
const participantPhones = this.getNodeParameter('participantPhones', i);
const phones = participantPhones.split(',').map(phone => {
const trimmed = phone.trim();
// If it already has @s.whatsapp.net, keep it as is
if (trimmed.includes('@')) {
return trimmed;
}
// Otherwise, validate and format it
return (0, GenericFunctions_1.validatePhoneNumber)(trimmed);
});
const body = {
GroupJID: groupJid,
Action: action,
Phone: phones,
};
responseData = await GenericFunctions_1.wuzapiApiRequest.call(this, 'POST', '/group/updateparticipants', body);
}
const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { 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];
}
}
exports.WuzapiGroup = WuzapiGroup;
//# sourceMappingURL=WuzapiGroup.node.js.map