n8n-nodes-meetbot
Version:
n8n community node for Meetbot booking API
323 lines (322 loc) • 14.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Meetbot = void 0;
const n8n_workflow_1 = require("n8n-workflow");
class Meetbot {
constructor() {
this.description = {
displayName: 'Meetbot',
name: 'meetbot',
icon: 'file:meetbot128.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"]}}',
description: 'Book meetings with the Meetbot API',
defaults: {
name: 'Meetbot',
},
inputs: ["main"],
outputs: ["main"],
credentials: [
{
name: 'meetbotApi',
required: true,
},
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Get Slots',
value: 'getSlots',
description: 'Get available slots',
action: 'Get available slots',
},
{
name: 'Make Booking',
value: 'makeBooking',
description: 'Book a meeting',
action: 'Book a meeting',
},
],
default: 'getSlots',
},
{
displayName: 'Page',
name: 'page',
type: 'string',
displayOptions: {
show: {
operation: ['getSlots'],
},
},
default: '',
required: true,
description: 'The booking page identifier (e.g., zsoldosp/meet)',
},
{
displayName: 'Day',
name: 'day',
type: 'dateTime',
displayOptions: {
show: {
operation: ['getSlots'],
},
},
default: '',
required: false,
description: 'The day to get slots for (YYYY-MM-DD format). If not provided, will get slots for all available days.',
},
{
displayName: 'Start Date',
name: 'start',
type: 'dateTime',
displayOptions: {
show: {
operation: ['getSlots'],
},
},
default: '',
required: false,
description: 'The start date boundary for getting slots (YYYY-MM-DD format). If not provided, no lower boundary will be applied.',
},
{
displayName: 'End Date',
name: 'end',
type: 'dateTime',
displayOptions: {
show: {
operation: ['getSlots'],
},
},
default: '',
required: false,
description: 'The end date boundary for getting slots (YYYY-MM-DD format). If not provided, no upper boundary will be applied.',
},
{
displayName: 'Page',
name: 'bookingPage',
type: 'string',
displayOptions: {
show: {
operation: ['makeBooking'],
},
},
default: '',
required: true,
description: 'The booking page identifier',
},
{
displayName: 'Slot',
name: 'slot',
type: 'json',
displayOptions: {
show: {
operation: ['makeBooking'],
},
},
default: '{}',
required: true,
description: 'The slot object from Get Slots response',
},
{
displayName: 'Guest Name',
name: 'guestName',
type: 'string',
displayOptions: {
show: {
operation: ['makeBooking'],
},
},
default: '',
required: true,
description: 'Name of the person making the booking',
},
{
displayName: 'Guest Email',
name: 'guestEmail',
type: 'string',
displayOptions: {
show: {
operation: ['makeBooking'],
},
},
default: '',
required: true,
description: 'Email of the person making the booking',
},
],
};
}
async execute() {
var _a, _b, _c, _d;
const items = this.getInputData();
const returnData = [];
const operation = this.getNodeParameter('operation', 0);
for (let i = 0; i < items.length; i++) {
try {
if (operation === 'getSlots') {
const page = this.getNodeParameter('page', i);
const dayDateTime = this.getNodeParameter('day', i);
const startDateTime = this.getNodeParameter('start', i);
const endDateTime = this.getNodeParameter('end', i);
const credentials = await this.getCredentials('meetbotApi');
const encodedPage = encodeURIComponent(page);
let fullUrl = `https://meet.bot/v1/slots?page=${encodedPage}`;
if (dayDateTime) {
const day = dayDateTime.slice(0, 10);
fullUrl += `&day=${day}`;
}
if (startDateTime) {
const start = startDateTime.slice(0, 10);
fullUrl += `&start=${start}`;
}
if (endDateTime) {
const end = endDateTime.slice(0, 10);
fullUrl += `&end=${end}`;
}
try {
new URL(fullUrl);
}
catch (urlError) {
console.log('=== URL VALIDATION ERROR ===');
console.log('Invalid URL:', fullUrl);
console.log('Page parameter:', page);
console.log('Encoded page parameter:', encodedPage);
console.log('Day parameter:', dayDateTime || 'Not provided');
console.log('Start parameter:', startDateTime || 'Not provided');
console.log('End parameter:', endDateTime || 'Not provided');
console.log('URL Error:', urlError.message);
console.log('============================');
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid URL: ${fullUrl}`, { itemIndex: i });
}
console.log('=== GET SLOTS REQUEST DETAILS ===');
console.log('Full URL:', fullUrl);
console.log('Method: GET');
console.log('Page parameter:', page);
console.log('Encoded page parameter:', encodedPage);
console.log('Day parameter:', dayDateTime || 'Not provided');
console.log('Start parameter:', startDateTime || 'Not provided');
console.log('End parameter:', endDateTime || 'Not provided');
console.log('Authorization header present:', !!credentials.apiToken);
console.log('=====================================');
const apiToken = credentials.apiToken;
console.log('=== HTTP REQUEST DETAILS ===');
console.log('Request URL:', fullUrl);
console.log('API Token present:', !!apiToken);
console.log('============================');
const response = await this.helpers.httpRequest({
method: 'GET',
url: fullUrl,
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json',
},
});
returnData.push({
json: response,
pairedItem: { item: i },
});
}
else if (operation === 'makeBooking') {
const bookingPage = this.getNodeParameter('bookingPage', i);
const slot = this.getNodeParameter('slot', i);
const guestName = this.getNodeParameter('guestName', i);
const guestEmail = this.getNodeParameter('guestEmail', i);
const payload = {
booking_page: bookingPage,
slot: slot,
guest_name: guestName,
guest_email: guestEmail,
};
const credentials = await this.getCredentials('meetbotApi');
const fullUrl = `https://meet.bot/v1/book`;
try {
new URL(fullUrl);
}
catch (urlError) {
console.log('=== URL VALIDATION ERROR ===');
console.log('Invalid URL:', fullUrl);
console.log('URL Error:', urlError.message);
console.log('============================');
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid URL: ${fullUrl}`, { itemIndex: i });
}
console.log('=== MAKE BOOKING REQUEST DETAILS ===');
console.log('Full URL:', fullUrl);
console.log('Method: POST');
console.log('Payload:', JSON.stringify(payload, null, 2));
console.log('Authorization header present:', !!credentials.apiToken);
console.log('========================================');
const apiToken = credentials.apiToken;
const response = await this.helpers.httpRequest({
method: 'POST',
url: fullUrl,
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json',
},
body: payload,
json: true,
});
returnData.push({
json: response,
pairedItem: { item: i },
});
}
}
catch (error) {
console.log('=== REQUEST ERROR ===');
console.log('Operation:', operation);
console.log('Error message:', error.message);
console.log('Error stack:', error.stack);
console.log('====================');
let serverErrorMessage = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || error.message;
if (error && typeof error === 'object' && 'response' in error) {
const axiosError = error;
const responseData = (_c = axiosError.response) === null || _c === void 0 ? void 0 : _c.data;
if (responseData) {
if (responseData.__all__ && Array.isArray(responseData.__all__) && responseData.__all__.length > 0) {
serverErrorMessage = responseData.__all__[0];
}
else if (responseData.errors && typeof responseData.errors === 'object') {
const errorMessages = [];
for (const messages of Object.values(responseData.errors)) {
if (Array.isArray(messages)) {
errorMessages.push(...messages);
}
}
if (errorMessages.length > 0) {
serverErrorMessage = errorMessages[0];
}
}
else if (typeof responseData === 'string') {
serverErrorMessage = responseData;
}
else if (responseData.message) {
serverErrorMessage = responseData.message;
}
}
}
if (this.continueOnFail()) {
returnData.push({
json: { error: serverErrorMessage },
pairedItem: { item: i },
});
continue;
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), serverErrorMessage, {
itemIndex: i,
description: error && typeof error === 'object' && 'response' in error
? JSON.stringify((_d = error.response) === null || _d === void 0 ? void 0 : _d.data)
: "",
});
}
}
return [returnData];
}
}
exports.Meetbot = Meetbot;