/* eslint-disable @typescript-eslint/camelcase */ import Mail from 'nodemailer/lib/mailer'; import { Match } from 'meteor/check'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import { callbacks } from '../../../lib/callbacks'; import { IEmailInbox } from '../../../definition/IEmailInbox'; import { IUser } from '../../../definition/IUser'; import { FileUpload } from '../../../app/file-upload/server'; import { slashCommands } from '../../../app/utils/server'; import { Messages, Rooms, Users } from '../../../app/models/server'; import { Uploads } from '../../../app/models/server/raw'; import { Inbox, inboxes } from './EmailInbox'; import { sendMessage } from '../../../app/lib/server/functions/sendMessage'; import { settings } from '../../../app/settings/server'; import { IMessage } from '../../../definition/IMessage'; const livechatQuoteRegExp = /^\[\s\]\(https?:\/\/.+\/live\/.+\?msg=(?.+?)\)\s(?.+)/s; const user: IUser = Users.findOneById('rocket.cat'); const language = settings.get('Language') || 'en'; const t = (s: string): string => TAPi18n.__(s, { lng: language }); const sendErrorReplyMessage = (error: string, options: any): void => { if (!options?.rid || !options?.msgId) { return; } const message = { groupable: false, msg: `@${options.sender} something went wrong when replying email, sorry. **Error:**: ${error}`, _id: String(Date.now()), rid: options.rid, ts: new Date(), }; sendMessage(user, message, { _id: options.rid }); }; function sendEmail(inbox: Inbox, mail: Mail.Options, options?: any): void { inbox.smtp .sendMail({ from: inbox.config.senderInfo ? { name: inbox.config.senderInfo, address: inbox.config.email, } : inbox.config.email, ...mail, }) .then((info) => { console.log('Message sent: %s', info.messageId); }) .catch((error) => { console.log('Error sending Email reply: %s', error.message); if (!options?.msgId) { return; } sendErrorReplyMessage(error.message, options); }); } slashCommands.add( 'sendEmailAttachment', (command: any, params: string) => { if (command !== 'sendEmailAttachment' || !Match.test(params, String)) { return; } const message = Messages.findOneById(params.trim()); if (!message || !message.file) { return; } const room = Rooms.findOneById(message.rid); const inbox = inboxes.get(room.email.inbox); if (!inbox) { return sendErrorReplyMessage(`Email inbox ${room.email.inbox} not found or disabled.`, { msgId: message._id, sender: message.u.username, rid: room._id, }); } const file = Promise.await(Uploads.findOneById(message.file._id)); if (!file) { return; } FileUpload.getBuffer(file, (_err?: Error, buffer?: Buffer) => { !_err && buffer && sendEmail( inbox, { to: room.email.replyTo, subject: room.email.subject, text: message.attachments[0].description || '', attachments: [ { content: buffer, contentType: file.type, filename: file.name, }, ], inReplyTo: room.email.thread, references: [room.email.thread], }, { msgId: message._id, sender: message.u.username, rid: message.rid, }, ); }); Messages.update( { _id: message._id }, { $set: { blocks: [ { type: 'context', elements: [ { type: 'mrkdwn', text: `**${t('To')}:** ${room.email.replyTo}\n**${t('Subject')}:** ${room.email.subject}`, }, ], }, ], }, $pull: { attachments: { 'actions.0.type': 'button' }, }, }, ); }, { description: 'Send attachment as email', params: 'msg_id', }, undefined, false, undefined, undefined, ); callbacks.add( 'beforeSaveMessage', function (message: IMessage, room: any) { if (!room?.email?.inbox) { return message; } if (message.file) { message.attachments = message.attachments || []; message.attachments.push({ actions: [ { type: 'button', text: t('Send_via_Email_as_attachment'), msg: `/sendEmailAttachment ${message._id}`, msg_in_chat_window: true, msg_processing_type: 'sendMessage', }, ], }); return message; } const { msg } = message; // Try to identify a quote in a livechat room const match = msg.match(livechatQuoteRegExp); if (!match?.groups) { return message; } const inbox = inboxes.get(room.email.inbox); if (!inbox) { sendErrorReplyMessage(`Email inbox ${room.email.inbox} not found or disabled.`, { msgId: message._id, sender: message.u.username, rid: room._id, }); return message; } if (!inbox) { return message; } const replyToMessage = Messages.findOneById(match.groups.id); if (!replyToMessage?.email?.messageId) { return message; } sendEmail( inbox, { text: match.groups.text, inReplyTo: replyToMessage.email.messageId, references: [...(replyToMessage.email.references ?? []), replyToMessage.email.messageId], to: room.email.replyTo, subject: room.email.subject, }, { msgId: message._id, sender: message.u.username, rid: room._id, }, ); message.msg = match.groups.text; message.groupable = false; message.blocks = [ { type: 'context', elements: [ { type: 'mrkdwn', text: `**${t('To')}:** ${room.email.replyTo}\n**${t('Subject')}:** ${room.email.subject}`, }, ], }, { type: 'section', text: { type: 'mrkdwn', text: message.msg, }, }, { type: 'section', text: { type: 'mrkdwn', text: `> ---\n${replyToMessage.msg.replace(/^/gm, '> ')}`, }, }, ]; delete message.urls; return message; }, callbacks.priority.LOW, 'ReplyEmail', ); export async function sendTestEmailToInbox(emailInboxRecord: IEmailInbox, user: IUser): Promise { const inbox = inboxes.get(emailInboxRecord.email); if (!inbox) { throw new Error('inbox-not-found'); } const address = user.emails?.find((email) => email.verified)?.address; if (!address) { throw new Error('user-without-verified-email'); } console.log(`Sending testing email to ${address}`); sendEmail(inbox, { to: address, subject: 'Test of inbox configuration', text: 'Test of inbox configuration successful', }); }