How to send Email with FileAttachment from local disk - node.js

I am using node-ews for sending Email through MicroSoft Exchange using my corporate credendials.
But I cannot figure out how to attach .xlsx files to an email from local disk storage. It seems that there is no simple Path tag.
This is what i have
const ewsArgs = {
attributes: {
MessageDisposition: 'SendAndSaveCopy',
},
SavedItemFolderId: {
DistinguishedFolderId: {
attributes: {
Id: 'sentitems',
},
},
},
Items: {
Message: {
ItemClass: 'IPM.Note',
Subject: 'Subject',
Body: {
attributes: {
BodyType: 'Text',
},
$value: 'Bodytext',
},
ToRecipients: {
Mailbox: {
EmailAddress: 'email#email.ru',
},
},
IsRead: 'false',
Attachments: {
FileAttachment: [{
Name: 'filename.xlsx',
IsInline: false,
ContentType: 'text/xlsx',
ContentLocation: 'filename.xlsx',
}]
}
},
},
};
What am I doing wrong?

Check your contentLocation. You need to give the correct path of the file you want to attach. But you just provided the filename.
Content-Type: application/vnd.ms-excel

Related

node-ews Update email to mark as read

I'm using "node-ews" library version 3.5.0, but when I try to update any property I get the following error:
{
"ResponseMessages":{
"UpdateItemResponseMessage":{
"attributes":{
"ResponseClass":"Error"
},
"MessageText":"An internal server error occurred. The operation failed., Object reference not set to an instance of an object.",
"ResponseCode":"ErrorInternalServerError",
"DescriptiveLinkKey":0,
"Items":null
}
}
}
I'm trying to mark email as read using the following code:
const markFolderAsRead = async (ews, id, changeKey) => {
const args = {
attributes: {
MessageDisposition: "SaveOnly",
},
ItemChanges: {
ItemChange: {
ItemId: {
attributes: {
Id: id,
ChangeKey: changeKey,
},
},
Updates: {
SetItemField: {
FieldURI: {
attributes: {
FieldURI: "message:IsRead",
},
Message: {
IsRead: true,
},
},
},
},
},
},
};
await ews.run("UpdateItem", args).then((result) => {
console.log("email read:", JSON.stringify(result));
});
};
I tried several modifications, including trying to update another fields, but none of it worked.
I followed this documentation: https://learn.microsoft.com/pt-br/exchange/client-developer/web-service-reference/updateitem-operation
And the lib doesn't show any example of it, but when I change the json to a wrong "soap" construction the error show different messages, or even if I do not pass any of the parameters required as "ChangeKey".
So, maybe this error is something relate to microsoft ews soap construction that I'm missing parameters, or so.
Got it working!
My JSON was wrong. The FieldURI was finishing after the message attribute, it should be before.
Correct JSON:
const args = {
attributes: {
MessageDisposition: "SaveOnly",
ConflictResolution: "AlwaysOverwrite",
SendMeetingInvitationsOrCancellations: "SendToNone",
},
ItemChanges: {
ItemChange: {
ItemId: {
attributes: {
Id: id,
ChangeKey: changeKey,
},
},
Updates: {
SetItemField: {
FieldURI: {
attributes: {
FieldURI: "message:IsRead",
},
},
Message: {
IsRead: "true",
},
},
},
},
},
};

aws nodejs sdk putObjectAcl correct syntax

I need to assign public read access and in the same time to allow owner to operate an object with full access after I process the object within the sharp() lib. So, I replace the old object with a new one and thus I need to set new ACL. The ACL allows to have only one type of access and I need kind of to combine
"public-read" and "bucket-owner-full-controll"
According to the interface and documentation this is enough
await s3Bucket.putObjectAcl({
Bucket: s3EventMessage.bucket.name,
Key: key,
AccessControlPolicy: {},
GrantFullControl: 'canonical_id',
GrantRead: 'http://acs.amazonaws.com/groups/global/AllUsers'
}).promise();
Also, I tried this, it should be enough according to the interface, but I'm getting errors:
Bucket: s3EventMessage.bucket.name,
Key: key,
AccessControlPolicy: {
Grants: [
{
Grantee: {
Type: "CanonicalUser"
},
},
],
},
GrantRead: 'http://acs.amazonaws.com/groups/global/AllUsers'
Also I tried this way, I get an error that my XML has wrong format
await s3Bucket.putObjectAcl({
Bucket: s3EventMessage.bucket.name,
Key: key,
AccessControlPolicy: {
Grants: [
{
Grantee: {
Type: "CanonicalUser",
DisplayName: 'Owner',
ID: 'canonical_id',
},
Permission: "FULL_CONTROL"
},
{
Grantee: {
Type: "Group",
URI: 'http://acs.amazonaws.com/groups/global/AllUsers',
},
Permission: "READ",
}
],
},
}).promise();
The error:
MalformedACLError: The XML you provided was not well-formed or did not validate against our published schema
This syntax with a precise owner:
await s3Bucket.putObjectAcl({
Bucket: s3EventMessage.bucket.name,
Key: key,
AccessControlPolicy: {
Owner: {
DisplayName: 'Owner',
ID: 'canonical_id',
},
Grants: [
{
Grantee: {
Type: "CanonicalUser",
DisplayName: 'Owner',
ID: 'canonical_id',
},
Permission: "FULL_CONTROL"
},
{
Grantee: {
Type: "Group",
URI: 'http://acs.amazonaws.com/groups/global/AllUsers',
},
Permission: "READ",
}
],
},
}).promise();
gives an error :
AccessDenied: Access Denied
also, I found a solution in PHP, but that didn't work for me - I'm getting access denied
this is the solution
this is the doc Nodejs example
Thanks in advance!
After some investigation and playing around I figured out what I need:
The lambda had to have a permission related to the bucket: s3:PutObject*
This snippet works perfectly for my task:
await s3Bucket.putObjectAcl({
Bucket: bucket.name,
Key: key,
AccessControlPolicy: {
Owner: {
DisplayName: 'Owner',
ID: 'canonical_id',
},
Grants: [
{
Grantee: {
Type: "CanonicalUser",
DisplayName: 'Owner',
ID: 'canonical_id',
},
Permission: "FULL_CONTROL"
},
{
Grantee: {
Type: "Group",
URI: 'http://acs.amazonaws.com/groups/global/AllUsers',
},
Permission: "READ",
}
],
},
}).promise();

How does admin. messaging. AndroidNotification need to be configured for localization?

In the firebase documentation I found that admin. messaging. AndroidNotification has properties to provide localization to your notifications. Or at least that is what I understand from it.
https://firebase.google.com/docs/reference/admin/node/admin.messaging.AndroidNotification
In the docs they have bodyLocArgs and bodyLocKey to localize the body and titleLocArgs and titleLocKey. How do these need to be configured in order to localize my notification?
So let's say my client (the android device) is using en_US as his current language. Is my clients locale used to localize the notification?
This is what my current message
const translator = deviceData.language !== 'nl' ? languages.en : languages.nl;
const title = `${translator['messageTitle' as keyof typeof translator]} ${group.displayName}`;
const body = `${sender.displayName} ${translator[type as keyof typeof translator]}`;
const systemTrayNotification: TokenMessage = {
token: deviceData.cloudMessagingToken,
notification: {
title: title,
body: body,
},
data: {
title: title,
body: body,
senderId: sender.id,
senderDisplayName: sender.displayName,
groupId: group.id,
type: 'groupMessage',
messageType: type,
sentAt: new Date().toISOString(),
},
android: {
priority: 'high',
notification: {
priority: 'max',
channelId: '59054',
clickAction: 'FLUTTER_NOTIFICATION_CLICK',
tag: 'groupMessage',
defaultSound: true,
defaultVibrateTimings: true,
bodyLocArgs: //what do I do here?,
bodyLocKey: //what do I do here?
titleLocArgs: //what do I do here?,
titleLocKey: //what do I do here?
}
},
apns: {
payload: {
aps: {
category: 'groupMessage',
headers:{
"apns-priority":"10"
},
alert: {
title: title,
body: body,
},
aps: {
sound: 'default',
},
customData: {
title: title,
body: body,
senderId: sender.id,
senderDisplayName: sender.displayName,
groupId: group.id,
type: 'groupMessage',
messageType: type,
sentAt: new Date().toISOString(),
}
}
},
}
}
Use like this.
body: jsonEncode({
'notification': <String, dynamic>{
'title_loc_key': 'BOOKING_RECEIVED_PUSH_SUBTITLE',
'title_loc_args': [booking.shopName],
'body_loc_key': 'BOOKING_RECEIVED_PUSH_BODY',
'body_loc_args': [
customerName,
'',
bookingStart
], //, bookingDate, bookingStart]),
'sound': 'true',
'mutable_content': 'true',
'content_available': 'true'
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done'
},
'to': customerFCMToken
})).whenComplete(() {
print('sendBookingReceived(): message sent');
}).catchError((e) {
print('sendBookingReceived() error: $e');
});
try this and let me know if it is working or not.

node.js odata-server mongodb unable to post related entity

I have been working on a node.js odata server based on this example: How to set up a nodejs OData endpoint with odata-server
I have everything working... I can read, update, insert, delete. But I am trying to associate a Journal with a Tasks and I am having problems.
I have tried several different ways outlined here: Operations (OData Version 2.0)
Here is my code:
/* global $data */
require('odata-server');
$data.Class.define("Task", $data.Entity, null, {
Id: { type: "id", key: true, computed: true, nullable: false },
Title: { type: "string", required: true, maxLength: 200 },
Journals: { type: "array", elementType: "Journal"
, inverseProperty: "Task" }
});
$data.Class.define("Journal", $data.Entity, null, {
Id: { type: "id", key: true, computed: true, nullable: false },
Entry: { type: "string" },
DateInserted: { type: "string" },
Task: { type: "object", elementType: "Task" , inverseProperty: "Journals" }
});
$data.EntityContext.extend("obb", {
Tasks: { type: $data.EntitySet, elementType: Task },
Journals: { type: $data.EntitySet, elementType: Journal }
});
$data.createODataServer(obb, '/api-v0.1', 2046, 'localhost');
Question:
Is this feature even available from odata-server what would the post look like to link a Journal to a Task?
I am using fiddler2 and composing a POST I have tried these urls:
//localhost:2046/api-v0.1/Tasks('the-id-of-a-task')/Journals
//localhost:2046/api-v0.1/Tasks('the-id-of-a-task')/Journals/$link
post body's I have tried:
{"Entry":"This is a test"}
{"url":"http://localhost:2046/api-v0.1/Journals('id-of-a-journal-in-the-db')"}
I have even tried to build out and post a Task with journals together and that didn't work.
Any help would be greatly appreciated. Thanks.

Sending images in Mandrill

Trying to send QR codes via email with mandrill. Here's what I've got so far:
db.get(id, function (err, doc) {
if (err) { fail('Couch', [err, doc]) }
db.attachment.get(id, 'qr-code.png', function (error, image) {
// Base64 encode the image.
var base64 = 'data:image/png;base64,' + new Buffer(image).toString('base64');
Up to this point, I'm good. base64 can be used in an html img tag to render the qr code, woohoo! The bit I'm having trouble with is next...
// Email Tickets to client
mandrill('/messages/send-template', {
template_name: 'qr-confirm',
template_content: [],
template_content is supposed to be empty if I'm just using merge_vars right?
message: {
to: [{email: doc.email, name: doc.name}],
from_email: 'events#example.com',
from_name: 'The Team',
subject: "QR codes attached",
tags: ['qr'],
merge_vars: [{
rcpt: doc.email,
vars: [
{ name: "name", content: doc.name },
{ name: "attendee", content: doc.id },
{ name: "purchaser", content: doc.purchaser }
]
}],
Okay, do I need both attachments and images or if I use images will it automatically attach them?
attachments: [
{type: "image/png", name: "qr-code.png", content: base64}
],
images: [
{type: "image/png", name: "qr-code.png", content: base64}
],
}
}, function(error, manReply) { console.log(error || manReply) }); // manReply, haha
});
});
Okay, so with all that, I still get a broken attachment. There's an attachment, it's just broken 1kb, and not rendering inline either.
Any help would rock!!
Okay, problem solved, just don't include data:image/png;base64, in the content parameter : )

Resources