|
| 1 | +import axios from 'axios'; |
| 2 | +import { replaceMailVaribles } from '../../../../Utils.js'; |
| 3 | + |
| 4 | +export default async function resendMail(request, response) { |
| 5 | + try { |
| 6 | + const reqToken = request.headers['x-api-token']; |
| 7 | + const docId = request.body.document_id; |
| 8 | + const userMail = request.body.email; |
| 9 | + const email_subject = request.body.email_subject; |
| 10 | + const email_body = request.body.email_body; |
| 11 | + const baseUrl = new URL(process.env.SERVER_URL); |
| 12 | + |
| 13 | + if (!reqToken) { |
| 14 | + return response.status(400).json({ error: 'Please Provide API Token' }); |
| 15 | + } |
| 16 | + const tokenQuery = new Parse.Query('appToken'); |
| 17 | + tokenQuery.equalTo('token', reqToken); |
| 18 | + tokenQuery.include('userId'); |
| 19 | + const token = await tokenQuery.first({ useMasterKey: true }); |
| 20 | + if (token !== undefined) { |
| 21 | + // Valid Token then proceed request |
| 22 | + const parseUser = JSON.parse(JSON.stringify(token)); |
| 23 | + const userPtr = { |
| 24 | + __type: 'Pointer', |
| 25 | + className: '_User', |
| 26 | + objectId: parseUser.userId.objectId, |
| 27 | + }; |
| 28 | + |
| 29 | + const docQuery = new Parse.Query('contracts_Document'); |
| 30 | + docQuery.equalTo('objectId', docId); |
| 31 | + docQuery.equalTo('CreatedBy', userPtr); |
| 32 | + docQuery.include('Signers,ExtUserPtr'); |
| 33 | + docQuery.notEqualTo('IsCompleted', true); |
| 34 | + docQuery.notEqualTo('IsDeclined', true); |
| 35 | + docQuery.notEqualTo('IsArchive', true); |
| 36 | + docQuery.lessThanOrEqualTo('ExpiryDate', new Date()); |
| 37 | + docQuery.exists('SignedUrl'); |
| 38 | + |
| 39 | + const resDoc = await docQuery.first({ useMasterKey: true }); |
| 40 | + if (resDoc) { |
| 41 | + const _resDoc = resDoc.toJSON(); |
| 42 | + const contact = _resDoc.Signers.find(x => x.Email === userMail); |
| 43 | + if (contact) { |
| 44 | + try { |
| 45 | + const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png'; |
| 46 | + let url = `${process.env.SERVER_URL}/functions/sendmailv3/`; |
| 47 | + const headers = { |
| 48 | + 'Content-Type': 'application/json', |
| 49 | + 'X-Parse-Application-Id': process.env.APP_ID, |
| 50 | + 'X-Parse-Master-Key': process.env.MASTER_KEY, |
| 51 | + }; |
| 52 | + |
| 53 | + const objectId = contact.objectId; |
| 54 | + const hostUrl = baseUrl.origin; |
| 55 | + const title = _resDoc.Name; |
| 56 | + const receiverMail = contact.Email; |
| 57 | + //encode this url value `${response.id}/${receiverMail}/${objectId}` to base64 using `btoa` function |
| 58 | + const encodeBase64 = btoa(`${_resDoc.objectId}/${receiverMail}/${objectId}`); |
| 59 | + let signPdf = `${hostUrl}/login/${encodeBase64}`; |
| 60 | + const openSignUrl = 'https://www.opensignlabs.com/contact-us'; |
| 61 | + const orgName = _resDoc.ExtUserPtr.Company ? _resDoc.ExtUserPtr.Company : ''; |
| 62 | + const newDate = new Date(_resDoc.ExpiryDate.iso); |
| 63 | + newDate.setDate(newDate.getDate() + 15); |
| 64 | + const sender = _resDoc.ExtUserPtr.Email; |
| 65 | + const localExpireDate = newDate.toLocaleDateString('en-US', { |
| 66 | + day: 'numeric', |
| 67 | + month: 'long', |
| 68 | + year: 'numeric', |
| 69 | + }); |
| 70 | + |
| 71 | + const themeBGcolor = '#47a3ad'; |
| 72 | + const email_html = |
| 73 | + "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /> </head> <body> <div style='background-color: #f5f5f5; padding: 20px'> <div style=' box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background: white;padding-bottom: 20px;'> <div style='padding:10px 10px 0 10px'><img src=" + |
| 74 | + imgPng + |
| 75 | + " height='50' style='padding:20px; width:170px; height:40px;' /></div> <div style='padding:2px; font-family: system-ui;background-color:" + |
| 76 | + themeBGcolor + |
| 77 | + ";'><p style='font-size: 20px;font-weight: 400;color: white;padding-left: 20px;' > Digital Signature Request</p></div><div><p style='padding: 20px;font-family: system-ui;font-size: 14px; margin-bottom: 10px;'> " + |
| 78 | + _resDoc.ExtUserPtr.Name + |
| 79 | + ' has requested you to review and sign <strong> ' + |
| 80 | + title + |
| 81 | + "</strong>.</p><div style='padding: 5px 0px 5px 25px;display: flex;flex-direction: row;justify-content: space-around;'><table> <tr> <td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Sender</td> <td> </td> <td style='color:#626363;font-weight:bold'>" + |
| 82 | + sender + |
| 83 | + "</td></tr><tr><td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Organization</td> <td> </td><td style='color:#626363;font-weight:bold'> " + |
| 84 | + orgName + |
| 85 | + "</td></tr> <tr> <td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Expires on</td><td> </td> <td style='color:#626363;font-weight:bold'>" + |
| 86 | + localExpireDate + |
| 87 | + "</td></tr><tr> <td></td> <td> </td></tr></table> </div> <div style='margin-left:70px'><a href=" + |
| 88 | + signPdf + |
| 89 | + "> <button style='padding: 12px 12px 12px 12px;background-color: #d46b0f;color: white; border: 0px;box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px,rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;font-weight:bold;margin-top:30px'>Sign here</button></a> </div> <div style='display: flex; justify-content: center;margin-top: 10px;'> </div></div></div><div><p> This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender " + |
| 90 | + sender + |
| 91 | + ' directly.If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ <a href=' + |
| 92 | + openSignUrl + |
| 93 | + ' target=_blank>here</a>.</p> </div></div></body> </html>'; |
| 94 | + let replaceVar; |
| 95 | + const variables = { |
| 96 | + document_title: title, |
| 97 | + sender_name: _resDoc.ExtUserPtr.Name, |
| 98 | + sender_mail: _resDoc.ExtUserPtr.Email, |
| 99 | + sender_phone: _resDoc.ExtUserPtr.Phone, |
| 100 | + receiver_name: contact.Name, |
| 101 | + receiver_email: contact.Email, |
| 102 | + receiver_phone: contact.Phone, |
| 103 | + expiry_date: localExpireDate, |
| 104 | + company_name: orgName, |
| 105 | + signing_url: signPdf, |
| 106 | + }; |
| 107 | + if (email_subject && email_body) { |
| 108 | + replaceVar = replaceMailVaribles(email_subject, email_body, variables); |
| 109 | + } else if (email_subject) { |
| 110 | + replaceVar = replaceMailVaribles(email_subject, '', variables); |
| 111 | + replaceVar = { subject: replaceVar.subject, body: email_html }; |
| 112 | + } else if (email_body) { |
| 113 | + replaceVar = replaceMailVaribles( |
| 114 | + `${_resDoc.ExtUserPtr.Name} has requested you to sign "${title}"`, |
| 115 | + email_body, |
| 116 | + variables |
| 117 | + ); |
| 118 | + } else { |
| 119 | + replaceVar = { |
| 120 | + subject: `${_resDoc.ExtUserPtr.Name} has requested you to sign "${title}"`, |
| 121 | + body: email_html, |
| 122 | + }; |
| 123 | + } |
| 124 | + const subject = replaceVar.subject; |
| 125 | + const html = replaceVar.body; |
| 126 | + |
| 127 | + let params = { |
| 128 | + recipient: contact.Email, |
| 129 | + subject: subject, |
| 130 | + from: sender, |
| 131 | + html: html, |
| 132 | + extUserId: _resDoc.ExtUserPtr.objectId, |
| 133 | + }; |
| 134 | + |
| 135 | + const res = await axios.post(url, params, { headers: headers }); |
| 136 | + if (res.data.result && res.data.result.status === 'success') { |
| 137 | + return response.json({ result: 'mail sent successfully.' }); |
| 138 | + } |
| 139 | + } catch (error) { |
| 140 | + console.log('error', error); |
| 141 | + return response.status(400).json({ error: error.message }); |
| 142 | + } |
| 143 | + } else { |
| 144 | + return response.status(404).json({ error: 'user not found.' }); |
| 145 | + } |
| 146 | + } else { |
| 147 | + return response.status(404).json({ error: 'document not found.' }); |
| 148 | + } |
| 149 | + } else { |
| 150 | + return response.status(405).json({ error: 'Invalid API Token.' }); |
| 151 | + } |
| 152 | + } catch (err) { |
| 153 | + console.log('err in resendmail', err); |
| 154 | + return response.status(400).json({ error: err.message || 'Something went wrong.' }); |
| 155 | + } |
| 156 | +} |
0 commit comments