module.exports = function(RED) { var https = require('https'); var http = require('http'); var url = require('url'); var OPERATIONS = { 'account:list': { method: 'GET', path: '/ocs/v2.php/apps/mail/account/list' }, 'message:get': { method: 'GET', path: '/ocs/v2.php/apps/mail/message/{id}' }, 'message:getRaw': { method: 'GET', path: '/ocs/v2.php/apps/mail/message/{id}/raw' }, 'message:attachment': { method: 'GET', path: '/ocs/v2.php/apps/mail/message/{id}/attachment/{attachmentId}' }, 'mailbox:list': { method: 'GET', path: '/ocs/v2.php/apps/mail/ocs/mailboxes', query: ['accountId'] }, 'mailbox:messages': { method: 'GET', path: '/ocs/v2.php/apps/mail/ocs/mailboxes/{mailboxId}/messages', query: ['cursor','filter','limit','view'] }, 'message:send': { method: 'POST', path: '/ocs/v2.php/apps/mail/message/send', body: ['accountId','fromEmail','subject','body','isHtml','to','cc','bcc','references'] } }; function MailNode(config) { RED.nodes.createNode(this, config); var node = this; this.configNode = RED.nodes.getNode(config.nextcloud); this.operation = config.operation || 'account:list'; this.messageId = config.messageId; this.attachmentId = config.attachmentId; this.mailboxId = config.mailboxId; this.bodyAccountId = config.bodyAccountId; this.bodyFromEmail = config.bodyFromEmail; this.bodySubject = config.bodySubject; this.bodyBody = config.bodyBody; this.bodyIsHtml = config.bodyIsHtml; this.bodyTo = config.bodyTo; this.bodyCc = config.bodyCc; this.bodyBcc = config.bodyBcc; this.bodyReferences = config.bodyReferences; if (!this.configNode) { node.error("No Nextcloud configuration node selected"); return; } node.on('input', function(msg) { var op = OPERATIONS[msg.operation || node.operation]; if (!op) { node.error("Unknown operation: " + (msg.operation || node.operation), msg); return; } var baseUrl = (node.configNode.baseUrl || '').replace(/\/+$/, ''); var username = node.configNode.credentials.username; var password = node.configNode.credentials.password; var path = op.path .replace('{id}', msg.messageId || node.messageId || '') .replace('{attachmentId}', msg.attachmentId || node.attachmentId || '') .replace('{mailboxId}', msg.mailboxId || node.mailboxId || ''); var queryParts = []; if (op.query) { op.query.forEach(function(q) { var v = msg[q] !== undefined ? msg[q] : getField(node, q); if (v !== undefined && v !== '') queryParts.push(encodeURIComponent(q) + '=' + encodeURIComponent(v)); }); } var fullUrl = baseUrl + path + (queryParts.length ? '?' + queryParts.join('&') : ''); var parsedUrl = url.parse(fullUrl); var headers = { 'OCS-APIRequest': 'true', 'Accept': 'application/json', 'Authorization': 'Basic ' + Buffer.from(username + ':' + password).toString('base64') }; var bodyObj = {}; if (op.body) { op.body.forEach(function(b) { var v = msg[b] !== undefined ? msg[b] : getField(node, b); if (v !== undefined && v !== '') bodyObj[b] = v; }); } // Handle complex send fields: to/cc/bcc can be msg arrays if (msg.to && Array.isArray(msg.to)) bodyObj.to = msg.to; if (msg.cc && Array.isArray(msg.cc)) bodyObj.cc = msg.cc; if (msg.bcc && Array.isArray(msg.bcc)) bodyObj.bcc = msg.bcc; var bodyStr = null; if (Object.keys(bodyObj).length > 0) { headers['Content-Type'] = 'application/json'; bodyStr = JSON.stringify(bodyObj); } var opts = { hostname: parsedUrl.hostname, port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80), path: parsedUrl.path, method: op.method, headers: headers, rejectUnauthorized: false }; node.log(op.method + ' ' + fullUrl); var transport = parsedUrl.protocol === 'https:' ? https : http; var req = transport.request(opts, function(res) { var body = ''; res.on('data', function(chunk) { body += chunk; }); res.on('end', function() { msg.statusCode = res.statusCode; msg.operation = msg.operation || node.operation; try { msg.payload = JSON.parse(body); } catch(e) { msg.payload = body; } node.send(msg); }); }); req.on('error', function(err) { msg.error = err.message; node.error(op.method + ' ' + fullUrl + ' — ' + err.message, msg); }); if (bodyStr) req.write(bodyStr); req.end(); }); } function getField(node, name) { var m = { 'accountId': node.bodyAccountId, 'fromEmail': node.bodyFromEmail, 'subject': node.bodySubject, 'body': node.bodyBody, 'isHtml': node.bodyIsHtml, 'references': node.bodyReferences, 'cursor': node.bodyCursor, 'filter': node.bodyFilter, 'limit': node.bodyLimit, 'view': node.bodyView }; return m[name]; } RED.nodes.registerType("mail", MailNode); };