I'm using aws-php-sdk to save Outlook email attachments to S3. I'm able to upload the file to S3 but when I download the file and open it I only see the content byte data. I don't know how to store the content of the file using contentbytes.
I've tried $attachment->getContentBytes()->getContents()
but that always uploads a 0kb file and $attachment->getContentBytes()
displays the content bytes when I open the file.
The FileAttachment is from msgraph-sdk-php which I'm using to get the Outlook email attachments.
private function saveToS3(string $s3_directory, \Microsoft\Graph\Model\FileAttachment $attachment)
{
$aws_s3_key = 'XXXXXXX';
$aws_s3_secret = 'XXXXXXXX';
$aws_s3_region = 'us-west-1';
$aws_bucket = 'test-storage';
$s3Client = new S3Client([
'version' => 'latest',
'region' => $aws_s3_region,
'credentials' => [
'key' => $aws_s3_key,
'secret' => $aws_s3_secret,
],
]);
return $s3Client->putObject([
'Bucket' => $aws_bucket,
'Key' => $s3_directory,
'Body' => $attachment->getContentBytes(),
'ContentType' => $attachment->getContentType(),
]);
}
A sample FileAttachment:
{
"@odata.type": "#microsoft.graph.fileAttachment",
"@odata.mediaContentType": "application/octet-stream",
"id": "AAMkAGQyMzYyNXXXXXXXXXXXXXXXxLjl14fH8FdpE=",
"lastModifiedDateTime": "2023-07-31T22:43:52Z",
"name": "README.md",
"contentType": "application/octet-stream",
"size": 1708,
"isInline": false,
"contentId": "f_leudosmi0",
"contentLocation": null,
"contentBytes": "IyBDUk0gaW5XXXXXXXXXXXXXXXXXXXXXgZnJhbWV3b3JrIAo="
}
How do I upload the file contents and not the content bytes to S3?
You can base64_decode
the content bytes and send it to S3.
return $s3Client->putObject([
'Bucket' => $aws_bucket,
'Key' => $s3_directory,
'Body' => base64_decode($attachment->getContentBytes()->getContents(), true),
'ContentType' => $attachment->getContentType(),
]);
Another solution could be, create and save the file from the content bytes.
$content = base64_decode($attachment->getContentBytes()->getContents(), true);
file_put_contents($attachment->getname(), $content);
Then, you can pass the file to S3.
return $s3Client->putObject([
'Bucket' => $aws_bucket,
'Key' => $s3_directory,
'SourceFile' => $attachment->getname(),
'ContentType' => $attachment->getContentType(),
]);