cli-microsoft365 icon indicating copy to clipboard operation
cli-microsoft365 copied to clipboard

Extends `outlook mail send` command with support for attachments

Open milanholemans opened this issue 3 years ago • 8 comments

Extends outlook mail send command with support for attachments. Closes #3422

Remarks

  • Make a small refactor for option bodyContentType, comment https://github.com/pnp/cli-microsoft365/issues/3422#issuecomment-1179266954
  • Changed e-mail to email in the docs. Both forms are correct, but the one without hypen is more accepted.
  • Right now I've set a specific size for the total size of all files to 3 100 000 bytes. Although I'm having some problems here, theoretically I can increase the size if a single file is sent. However the more files are sent, the larger the request gets, and you will therefore receive a request too large faster. So it's pretty hard to set a fixed size here. I can determine the fixed size for 1 file but when you have 2 attachments of half the size, the request will still fail.

milanholemans avatar Jul 26 '22 19:07 milanholemans

Thanks @milanholemans, we'll review ASAP!

martinlingstuyl avatar Jul 26 '22 21:07 martinlingstuyl

Right now I've set a specific size for the total size of all files to 3 100 000 bytes. Although I'm having some problems here, theoretically I can increase the size if a single file is sent. However the more files are sent, the larger the request gets, and you will therefore receive a request too large faster. So it's pretty hard to set a fixed size here. I can determine the fixed size for 1 file but when you have 2 attachments of half the size, the request will still fail.

@milanholemans what's the limit of the total request? Since we're pointing to files on disk, we should be able to get the total request size before executing the request, right?

waldekmastykarz avatar Sep 02 '22 15:09 waldekmastykarz

@milanholemans what's the limit of the total request? Since we're pointing to files on disk, we should be able to get the total request size before executing the request, right?

Yeah maybe I could try to figure out what the max size of the request body is. But I guess this has to be done in the commandAction where I have to check the length of the request body and thus not in the option validation method.

Maybe another approach is to just execute the call and if it fails, it returns a request too large response (if I remember it correctly). Maybe we could catch this error and print a user friendly error like "attachments are too large".

milanholemans avatar Sep 03 '22 00:09 milanholemans

Yeah maybe I could try to figure out what the max size of the request body is. But I guess this has to be done in the commandAction where I have to check the length of the request body and thus not in the option validation method.

@milanholemans why couldn't we run it as a part of validation? We've got paths to all the files to upload so we should be able to do it during validation, right?

waldekmastykarz avatar Sep 03 '22 17:09 waldekmastykarz

Yeah maybe I could try to figure out what the max size of the request body is. But I guess this has to be done in the commandAction where I have to check the length of the request body and thus not in the option validation method.

@milanholemans why couldn't we run it as a part of validation? We've got paths to all the files to upload so we should be able to do it during validation, right?

Because consider the following example:

I have one file called 3MB.docx which is 3MB in size. When we send and API request, the body would look something like this:

{
 "attachments": [
   {
      "@odata.type": "#microsoft.graph.fileAttachment",
      "name": "3MB.docx"
      "contentBytes": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ="
   }
 ]
}

The request will work with no problem since it's just below the max request size.

If we now send another message with 2 files of 1,5MB (1.5MBa.docx & 1.5MBb.docx), the request would look something like this:

{
 "attachments": [
   {
      "@odata.type": "#microsoft.graph.fileAttachment",
      "name": "1.5MBa.docx"
      "contentBytes": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ="
   },
  {
      "@odata.type": "#microsoft.graph.fileAttachment",
      "name": "1.5MBb.docx"
      "contentBytes": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ="
   },
 ]
}

This request will fail because the body is now too large (there's an extra attachment object with odata and name properties). So the only way to kind of validate this is by finding the max size a request can be. Since the request is built in the commandAction, this should be checked there. So the more attachments you have, the smaller they can be. The bigger your email body text is, the smaller your attachments can be. At least that's what my findings are. The only proper way is by uploading files in chunks to the mail, but I haven't gotten this to work yet (https://github.com/pnp/cli-microsoft365/issues/3422#issuecomment-1195647659).

milanholemans avatar Sep 03 '22 18:09 milanholemans

So the more attachments you have, the smaller they can be. The bigger your email body text is, the smaller your attachments can be.

But in the validate method you do have all the info you need to calculate the eventual size, right? Just count the file bytes and the extra size needed for the message object.

martinlingstuyl avatar Sep 03 '22 20:09 martinlingstuyl

But in the validate method you do have all the info you need to calculate the eventual size, right? Just count the file bytes and the extra size needed for the message object.

That's exactly what I've been thinking @milanholemans: before we construct the body, we've got all the information to determine the total size of the body. To avoid doing the work twice, we could see if we can build the body during the validation stage and reuse for command execution, but that's an extra.

waldekmastykarz avatar Sep 04 '22 12:09 waldekmastykarz

But in the validate method you do have all the info you need to calculate the eventual size, right? Just count the file bytes and the extra size needed for the message object.

That's exactly what I've been thinking @milanholemans: before we construct the body, we've got all the information to determine the total size of the body. To avoid doing the work twice, we could see if we can build the body during the validation stage and reuse for command execution, but that's an extra.

That can indeed work I guess. I'll see if I can make it work. Thanks for the feedback!

milanholemans avatar Sep 08 '22 15:09 milanholemans

@milanholemans seems like you have some merge conflicts, could you resolve them please?

Jwaegebaert avatar Oct 02 '22 17:10 Jwaegebaert

@milanholemans seems like you have some merge conflicts, could you resolve them please?

PR is in draft so is still WIP 😃 Will prob make a new PR, will be easier than solving the merge conflicts 😄

milanholemans avatar Oct 02 '22 20:10 milanholemans

Going to pick this one up again (finally). I'm going to create a new PR to make my life a bit easier 😊

milanholemans avatar Oct 15 '22 18:10 milanholemans