Mailjet e-mail is empty when attaching a file to it - node.js

I have this bit of code that creates a calendar for a specific delivery, and then attaches it to an e-mail to be send. The problem is, when I attach the .ics file, the template breaks (no text, no pictures... nothing). Only the calendar file gets send (even though it does get send to the right e-mail).
const event = await this.calendarService.getEventForDelivery(deliveryId);
await this.sendMailjetTemplate('4069368', d.email, [{contentType: 'text/calendar', content: event}], {
ASN: d.identifier,
});

I fixed my issue by specifying a "text" attribute to my mail.

Related

Can i attach an object to an email with nodemailer?

I need to send a email with nodemailer, but in the email i need to attach an pdf that i generate using jspdf, the thing is that i cannot attach an object to an email, i can attach a file getting it's path, a string, and a lot of other things, but an object i cannot.
I tought of saving the pdf and using it's path, but this is all working on an VM, so i dont want to use too much cpu power or ram space.
I also tried using JSON.stringify() in the pdf, but it didn't work, and the file attached to the email was empty.
You can attach your pdf file by using content property of attachments object. It support many formats - string, path to file, buffer, fs read stream, etc.
See this docs.
In case with jspdf you can use output() method
const message = {
// ...
attachments: [
{
filename: "mypdf.pdf",
content: pdfObject.output('arraybuffer')
}
]
};

DocuSign "delete envelope lock" not working

I'm using the DocuSign REST API to automate document signing. I use the sender view to allow my clients to place signing tabs on their documents and ultimately send them.
However, I'm running into a problem where the client, for whatever reason, needs to start over in our workflow, and so abandons the embed without saving it and contacting us to restart the process.
Normally, we'd call Update to mark the Envelope as voided and then create a new one, but because the client didn't exit the embed properly, the Envelope is still marked as locked.
I thought the Delete Lock endpoint would allow us to remove the lock so that we could edit the envelope, but it's returning an error message saying that we can't delete the lock as we weren't the ones who put it there.
Given that the same credentials were used for both the embed window and the delete lock call, why does DocuSign treat us like two different users? And is there a way to get around the lock?
This might help some folks in the future.
"by appending a lockToken parameter to the view URL, you can give your
integration control over the envelope lock, enabling it to make
changes to the envelope without having to wait for the DocuSign token
to expire."
http://m.mmffs.com/the-trenches-whos-locking-my-envelopes.html
The article shows how to accomplish this using the API directly. In the code snippet below, this is how you would do it going against the DocuSign Nuget package.
var lockInfo = envelopesApi.CreateLock(accountID, envelopeID, new LockRequest()
{
LockedByApp = "[Your App]",
LockType = "edit"
});
existingViewUrl += "&lockToken={lockInfo.LockToken}";
Note, the third LockRequest parameter is required for this to work even though it is not required by the CreateLock method. Credit to Inbar Gazit - Error trying to add a document to envelope and getting a user lock error message
Now, the normal DeleteLock method will work.
try
{
var lockInfo = envelopesApi.GetLock(accountId, envelopeID);
if (lockInfo?.LockDurationInSeconds?.Length > 0)
{
envelopesApi.ApiClient.Configuration.AddDefaultHeader("X-DocuSign-Edit", $"{{\"lockToken\":\"{lockInfo.LockToken}\"}}");
envelopesApi.DeleteLock(accountId, envelopeID);
}
}
catch(ApiException e)
{
// Not locked.
}
Lock is done by NDSE not your credentials, solution is to wait for sometime and lock will be released by NDSE or you have to redirect user to same screen again and the user needs to select Save and Close instead of Discard Changes. Once user selects Discard Changes then envelope is moved to Deleted folder.
You can try code below:
var config = new Configuration(new ApiClient(basePath));
config.AddDefaultHeader("Authorization", "Bearer " + accessToken);
var envelopesApi = new EnvelopesApi(config);
try
{
// this line will throw error if envelope is not locked, so handle it using try & catch block
LockInformation lockInfo = envelopesApi.GetLock(accountId, envelopeId);
// check if this app locked it
if (lockInfo?.LockDurationInSeconds?.Length > 0)
{
// add a header with the LockToken to ensure this app has the right to unlock
string LockHeader = $"{{\"lockToken\":\"{lockInfo.LockToken}\"}}";
envelopesApi.Configuration.AddDefaultHeader("X-DocuSign-Edit", LockHeader);
envelopesApi.DeleteLock(accountId, envelopeId);
}
}
catch (ApiException exp)
{
// Do Whatever you want to do
}

Update a bot message after responding to a slack dialog

I'm having some issues to update an interactive message after responding to a slack dialog. I'm using botkit on a node.js server.
Here is my workflow:
User trigger an interactive message via a slash command
User click a button on that message
A dialog pops up, user fill the form and validate
Something is done on the server side
The first message should update
Now, here is the logic I'm using:
User trigger an interactive message via a slash command
Nothing fancy, I use:
controller.on('slash_command', function (bot, message)
Then I parse the command, and send the appropriate message, with the appropriate attachments (buttons)
User click a button on that message
Same, I use the event sent by botkit:
controller.on('interactive_message_callback', function (bot, message)
Then I create a dialog:
var dialog = bot.createDialog(
'Which book?',
JSON.stringify(callback),
'Ok'
)
Here I'm doing something really (really) dirty, and should not be done. But that's the only way I found to update the initial message after the dialog is filled.
The callback_id actually contains an object, with the response_urlof the initial message (and something to identify the form).
A dialog pops up, user fill the form and validate
Something is done on the server side
Here, I use once more the event provided by botkit:
controller.on('dialog_submission', function (bot, message)
then I parse the message.submission.callback_id and detect the response_url. With this, I can create an object I call originalMessage.
The first message should update
At the moment I use :
bot.replyInteractive(originalMessage, 'DONE, everything is saved.');
with originalMessagecontaining the response_url of the first message.
It does work. The first message is being replaced by the new one.
But I'm really not happy with that solution, and was wondering if I was missing something somewhere. I've seen couple apps having that type of workflow, so there must be a way.
Thank you for your help :)
I wrote to Slack to ask about this situation and got a great suggestion from Mark P:
Use the state dialog field to pass the original response_url to the dialog. Then when you receive the dialog data, you can use state instead of response_url.
I just tried it and it worked great. No need to store any state on your own server.
I don't know how that would work exactly with Node and botkit, since that's not what I use.
To flesh this out a bit more:
Someone clicks a button and Slack POSTs about that interaction to your configured "Request URL".
From Slack's payload, get the "response_url" value.
When you call dialog.open in the Slack API, pass along this response_url as the "state" value.
When the dialog is submitted, Slack again POSTs to your "Request URL".
From Slack's payload, get the "state" value and use it as a response_url.
Profit!
This only works if you hold the original message object somewhere on your server for future reference.
So on creating the interactive dialog store it somewhere and add a reference. I use uuids.
let newId = uuid();
messageStore[newId] = message;
var dialog = bot.createDialog(
'My Dialog',
'idPrefix_' + newId,
'Submit'
).addText('Sample Input', 'input', '');
bot.replyWithDialog(message, dialog.asObject());
Then once you get your interactive dialog response back disassemble the prefix and the uuid and get your original message object back from the servers memory. Then use ´replayInteractive` there.
controller.on('dialog_submission', function handler(bot, message) {
if (message.callback_id.indexOf('idPrefix') === 0) {
let id = message.callback_id.substr('idPrefix_'.length);
bot.dialogOk();
let originalMessage = messageStore[id];
bot.replyInteractive(originalMessage, {
text: 'replacing the original message with this.'
});
}
});
Be careful that you do not create a memory leak here. You have to find a way to clean up your messageStore over time.

Getting just email body using mail-listener-2

I am using mail-listener-2 and node.js to receive emails. I have it all setup doing what I want except for one thing.
I can not figure out how to get just the text of the current message. This is what I mean.
1. Send an email in my application with a unique id in the subject.
2. User receives email in inbox and replies.
3. Mail-Listener-2 grabs the email reply and saves it under the unique id.
Code:
mailListener.on("mail", function(mail, seqno, attributes){
var body = mail.text
});
Now when step 3 occurs, it's grabbing the entire thread message. Instead of just the message the user sent. Meaning, my original message plus the users new message is included in the reply.
Is there a way to grab just the users reply? Or do I just need to do something like putting a line in the message and then parse everything before the line?
Try this one:
mailListener.on("mail", function(mail, seqno, attributes){
text:mail.text
});

Sign MimeBodyPart which has attachments in it (with Bouncycastle)

I am working with OpenAS2Server-1.3.3 library.
There sending a single document is working fine..
Now I wanted to modify it to send document with attachments, like we do with emails. In this scenario, all the decription work well, but signature verification failed (MIC is not matched)
This is how I am tring to send attachments with main doc:
Create a MimeMultipart and add two MimeBodyPart into it. (main document and the attachment)
Finally wrap the MimeMultipart within a MimeBodyPart (I am not sure this is the way to do this, but anyway Bouncycastle do not have API to sign MimeMultipart )
Could anyone tell me the correct way to sign a message with attachment ?
MimeBodyPart mainBody = new MimeBodyPart();
mainBody.setDataHandler(new DataHandler(byteSource));
MimeBodyPart attachemt1 = new MimeBodyPart();
attachemt1.attachFile("/home/user/Desktop/Test1.txt");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mainBody);
multipart.addBodyPart(attachemt1);
MimeBodyPart body = new MimeBodyPart();
body.setContent(multipart);
body.setHeader("Content-Type", multipart.getContentType());
logger.info("--------------Attaching the file... Done");
I was able to get the issue and solution. I am just putting it here for anyone else who will try to do this kind of work.
I just dump the data that use for calculating MIC, at both sending side and receiving side. So the attached image will show the problem clearly.
So I added those header fields manually for all the attachments and main doc, at the sending side, as bellow.
mainBody.setHeader("Content-Type", "application/EDI-X12");
mainBody.setHeader("Content-Transfer-Encoding", "7bit");
Now it solved and "MIC is matched".

Resources