shopwareshopware6shopware6-apishopware6-app

Use PDF mediaId in Email Attachment


I am using the "api/_action/mail-template/send" action in a Shopware App to send an email to the customer and I want to add a document which was created before. If I understand it correct, I only have to give the mediaId as parameter to the request. The problem is, that the file can not be found ('detail' => 'File not found at path: media/29/50/18/1660063117/invoice_2544.pdf'),because the PDF files are in the files directory.

What am I doing wrong? Are PDFs a special case?

Thanks Danny


Solution

  • Unfortunately you are correct with your assumption. The primary keys you provide with mediaIds may only refer to files stored in the public filesystem. There's already a feature flag in place that will allow to provide documentIds specifically instead, but since you're developing an app I doubt you'll be able to activate said feature flag for this purpose and the feature flag is only to be removed with the upcoming major release 6.5.0.0.

    What you can do however is provide raw binary data for your attachments with the request payload key binAttachments. You can find how this data is handled in the MailFactory service.

    There's the endpoint POST /api/_action/order/document/download you can request with a payload documentIds that will give you the files binary content (You essentially download the file). You can provide multiple ids but it will merge all documents into one, so you might want to do one request per document if you want to keep the files separated as attachments.

    You can then use the binary data you retrieved as content of your binAttachments.

    PHP example with GuzzleHttp\Client:

    $response = $client->post($host . '/api/_action/order/document/download', [
        'json' => [
            'documentIds' => ['b0b3ac0ca218473babaffc7f0a800f36'],
        ],
        'headers' => [
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer ' . $accessToken,
        ],
    ]);
    
    $client->post($host . '/api/_action/mail-template/send', [
        'form_params' => [
            'recipients' => [
                'test1@example.com' => 'Test user 1',
            ],
            'salesChannelId' => '6923fd0d41e04521a2a259ba13f20bc3',
            'contentHtml' => 'officia Lorem non aute',
            'contentPlain' => 'eu veniam m',
            'subject' => 'sed adipisicing',
            'senderName' => 'enim occaecat aliquip veniam',
            'senderEmail' => 'test@example.com',
            'binAttachments' => [
                [
                    'content' => $response->getBody()->getContents(),
                    'fileName' => 'test.pdf',
                    'mimeType' => 'application/pdf',
                ],
            ],
        ],
        'headers' => [
            'Authorization' => 'Bearer ' . $accessToken,
        ],
    ]);
    

    While this is certainly a workaround, as of now this might be your best bet to achieve this purely with an app.