n8n-nodes-magic-inbox
Version:
Magic Inbox P2P - Revolutionary workflow teleportation system for n8n
323 lines (303 loc) • 14.9 kB
JavaScript
class MagicInboxSend {
constructor() {
this.description = {
displayName: '📤 Magic Inbox Send',
name: 'magicInboxSend',
icon: 'fa:paper-plane',
group: ['transform'],
version: 12,
subtitle: '={{$parameter["contentType"] === "workflow_with_message" ? "🔄 Workflow + Message" : "💬 Message Only"}}',
description: '📤 Send messages and workflows P2P to any Magic Inbox – direct recipient or fun public forums!',
defaults: {
name: '📤 Magic Inbox Send',
},
inputs: ['main'],
outputs: ['main'],
properties: [
// New: Toggle for forums!
{
displayName: '✨ Send to a forum',
name: 'sendToForum',
type: 'boolean',
default: false,
description: 'Enable to send your message or workflow directly to a public forum instead of a private URL. Super useful for communities! 🚀'
},
{
displayName: '🌐 Magic Inbox Destination URL',
name: 'destinationUrl',
type: 'string',
required: false,
default: '',
placeholder: 'https://target-instance.com/webhook/magic-inbox',
description: 'Direct Magic Inbox URL of your recipient. Leave empty to use a forum. 🔒',
displayOptions: { show: { sendToForum: [false] } }
},
{
displayName: '🗣️ Forum',
name: 'forum',
type: 'options',
options: [
{ name: '💬 General', value: 'general', description: 'General friendly chat and cool workflows' },
{ name: '💼 Job', value: 'job', description: 'Share offers, find teammates, post job requests!' },
{ name: '🆘 Help', value: 'help', description: 'Ask for help, propose solutions, share tips' },
{ name: '🤝 Business', value: 'business', description: 'Partnerships, commercial, collaboration' }
],
default: '',
description: 'Pick a forum. Your message will be sent to everyone reading the theme. Fun & open! 🥳',
displayOptions: { show: { sendToForum: [true] } }
},
{
displayName: '🔑 Destination API Key (Optional)',
name: 'destinationApiKey',
type: 'string',
typeOptions: { password: true },
default: '',
placeholder: 'api-key-if-required-by-recipient',
description: 'API key if the destination requires authentication 🔐'
},
{
displayName: '👤 Your Identity',
name: 'senderId',
type: 'string',
required: true,
default: '',
placeholder: 'your@email.com or fun-nickname',
description: 'Show how you want to be displayed to the recipient or the forum (be cool 😉)'
},
{
displayName: '✉️ Message',
name: 'message',
type: 'string',
typeOptions: { rows: 4 },
required: true,
default: '',
placeholder: 'Hello everyone! Here is a nice workflow for you...',
description: 'A personal (or public) message! Attach a workflow for extra awesomeness! 🎁'
},
{
displayName: '📦 Content Type',
name: 'contentType',
type: 'options',
options: [
{
name: '💬 Message Only',
value: 'message_only',
description: 'Send only your message'
},
{
name: '🔄 Message + Workflow',
value: 'workflow_with_message',
description: 'Send a message AND a ready-to-import workflow'
}
],
default: 'message_only',
description: 'What do you want to send? You can keep it simple or really wow people with a shared workflow! ✨'
},
{
displayName: '🏷️ Workflow Name',
name: 'workflowName',
type: 'string',
displayOptions: { show: { contentType: ['workflow_with_message'] } },
required: true,
default: '',
placeholder: 'My_Awesome_Scraper_v2',
description: 'Name your workflow so people can tell what it does! 🚀'
},
{
displayName: '🗂️ Workflow JSON',
name: 'workflowJson',
type: 'string',
typeOptions: { rows: 8 },
displayOptions: { show: { contentType: ['workflow_with_message'] } },
required: true,
default: '',
placeholder: '{"nodes": [...], "connections": {...}, "settings": {...}}',
description: 'Paste the full JSON export from n8n here (File > Export).'
},
{
displayName: '📒 P2P Address Book',
name: 'addressBook',
type: 'string',
typeOptions: { rows: 6 },
default: '',
placeholder: 'Your Magic Inbox contacts:\n- Alice: https://alice-n8n.com/webhook/magic-inbox\n- Bob: https://bob-automation.net/webhook/magic-inbox\n- Team: https://team-workflows.org/webhook/magic-inbox',
description: 'Copy-paste your favorite Magic Inbox links or forum links for easy access. 📝'
},
{
displayName: '⏱️ Timeout (seconds)',
name: 'timeout',
type: 'number',
default: 30,
typeOptions: { minValue: 5, maxValue: 300 },
description: 'Wait this long (in seconds) for a response before giving up. ⏳'
},
{
displayName: '🔄 Retry on Failure',
name: 'retryOnFailure',
type: 'boolean',
default: true,
description: 'Retry automatically if it fails? (Network issues can disappear!)'
},
{
displayName: '🔢 Max Retries',
name: 'maxRetries',
type: 'number',
displayOptions: { show: { retryOnFailure: [true] } },
default: 3,
typeOptions: { minValue: 1, maxValue: 10 },
description: 'Try this many times before giving up (just in case)'
},
{
displayName: '🔍 Debug Mode',
name: 'debugMode',
type: 'boolean',
default: false,
description: 'Enable to see all logs in your console (for advanced users) 🪛'
}
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
const forumUrls = {
general: 'https://n8n.srv740722.hstgr.cloud/webhook/magic-inbox/general',
job: 'https://n8n.srv740722.hstgr.cloud/webhook/magic-inbox/job',
help: 'https://n8n.srv740722.hstgr.cloud/webhook/magic-inbox/help',
business: 'https://n8n.srv740722.hstgr.cloud/webhook/magic-inbox/business'
};
for (let i = 0; i < items.length; i++) {
try {
const sendToForum = this.getNodeParameter('sendToForum', i, false);
let destinationUrl = this.getNodeParameter('destinationUrl', i, '').trim();
let forum = '';
if (sendToForum) {
forum = this.getNodeParameter('forum', i, '');
if (forum && forumUrls[forum]) {
destinationUrl = forumUrls[forum];
} else {
throw new Error('Please select a forum to send your message.');
}
}
if (!destinationUrl) {
throw new Error('Please provide a destination URL or enable "Send to a forum" and choose one.');
}
const destinationApiKey = this.getNodeParameter('destinationApiKey', i);
const senderId = this.getNodeParameter('senderId', i);
const message = this.getNodeParameter('message', i);
const contentType = this.getNodeParameter('contentType', i);
const timeout = this.getNodeParameter('timeout', i);
const retryOnFailure = this.getNodeParameter('retryOnFailure', i);
const maxRetries = this.getNodeParameter('maxRetries', i);
const debugMode = this.getNodeParameter('debugMode', i);
if (debugMode) {
console.log('📤 Magic Inbox Send v12');
console.log(`🌟 Destination: ${destinationUrl}`);
if (forum) { console.log(`🗣️ Forum: ${forum}`); }
console.log(`👤 Sender: ${senderId}`);
}
let payload = {
from: senderId,
message: message,
timestamp: new Date().toISOString(),
magicInboxVersion: 'v12.0.0',
transmissionMeta: {
sentAt: new Date().toISOString(),
protocol: 'magic-inbox-p2p-v12'
}
};
if (contentType === 'workflow_with_message') {
const workflowName = this.getNodeParameter('workflowName', i);
const workflowJsonString = this.getNodeParameter('workflowJson', i);
try {
const workflowJson = JSON.parse(workflowJsonString);
payload.workflowName = workflowName;
payload.workflowJson = workflowJson;
if (debugMode) {
console.log(`🔄 Workflow attached: ${workflowName} (${workflowJson.nodes?.length || 0} nodes)`);
}
} catch (parseError) {
throw new Error(`Invalid Workflow JSON: ${parseError instanceof Error ? parseError.message : parseError}`);
}
}
const requestOptions = {
method: 'POST',
url: destinationUrl,
headers: {
'Content-Type': 'application/json',
'User-Agent': 'n8n-magic-inbox-send/12.0.0',
'X-Magic-Inbox-Version': 'v12.0.0'
},
body: payload,
json: true,
timeout: timeout * 1000
};
if (destinationApiKey) {
requestOptions.headers['X-Magic-Inbox-Auth'] = destinationApiKey;
}
let response;
let attempt = 1;
while (attempt <= (retryOnFailure ? maxRetries : 1)) {
try {
if (debugMode && attempt > 1) {
console.log(`🔄 Attempt ${attempt}/${maxRetries}`);
}
response = await this.helpers.request(requestOptions);
break;
} catch (error) {
if (debugMode) {
console.log(`❌ Attempt ${attempt} failed: ${error instanceof Error ? error.message : error}`);
}
if (attempt < maxRetries && retryOnFailure) {
await new Promise(resolve => setTimeout(resolve, attempt * 1000));
attempt++;
} else {
throw error;
}
}
}
const transmissionResult = {
action: 'magic_inbox_p2p_sent',
success: true,
destination: destinationUrl,
forum: forum || null,
from: senderId,
contentType: contentType,
sentAt: new Date().toISOString(),
attempts: attempt,
originalPayload: {
messageLength: message.length,
hasWorkflow: contentType === 'workflow_with_message',
workflowName: payload.workflowName || null
},
response: response,
responseTime: new Date().toISOString(),
magicInboxProtocol: 'v12.0.0',
debugMode: debugMode
};
if (debugMode) {
console.log('🎉 Magic Inbox P2P - Transmission successful!');
}
returnData.push({
json: transmissionResult,
});
} catch (error) {
const errorResult = {
action: 'magic_inbox_p2p_send_failed',
success: false,
error: error instanceof Error ? error.message : String(error),
errorType: 'transmission_error',
failedAt: new Date().toISOString()
};
if (typeof console !== 'undefined') {
console.log('❌ Magic Inbox Send - Transmission failed:', errorResult.error);
}
returnData.push({
json: errorResult,
});
}
}
return [returnData];
}
}
module.exports = { MagicInboxSend };