Skip to content

MailgunPayloadConverter causes an ErrorException when parsing valid "accepted" webhook calls from Mailgun #53862

Closed
@boodle

Description

@boodle

Symfony version(s) affected

7.0.2

Description

PHP 8.2

The payload sent by MailGun for "accepted" events does not contain 'delivery-status'. This causes the following error:

Uncaught PHP Exception ErrorException: "Warning: Undefined array key "delivery-status"" at MailgunPayloadConverter.php line 79

Here is a redacted example payload from MailGun:

{
   "signature":{
      "token":"##REDACTED##",
      "timestamp":"##REDACTED##",
      "signature":"##REDACTED##"
   },
   "event-data":{
      "event":"accepted",
      "id":"4o7-z86dSkSI54c6IudeuA",
      "timestamp":1707402341.91242,
      "api-key-id":"##REDACTED##",
      "envelope":{
         "sender":"postmaster@mg.herehaveth.is",
         "targets":"ben@##REDACTED##",
         "transport":"smtp"
      },
      "flags":{
         "is-authenticated":true,
         "is-test-mode":false
      },
      "message":{
         "headers":{
            "message-id":"##REDACTED##",
            "from":"\"Here, have this\" <hello@herehaveth.is>",
            "to":"ben@##REDACTED##",
            "subject":"Please verify your email address."
         },
         "size":2411
      },
      "storage":{
         "key":"##REDACTED##",
         "url":"https:\/\/storage-us-east4.api.mailgun.net\/v3\/domains\/##REDACTED##"
      },
      "method":"HTTP",
      "log-level":"info",
      "recipient":"ben@##REDACTED##",
      "recipient-domain":"##REDACTED##",
      "tags":null,
      "user-variables":{
         "email-identifier":"ce167b2e-f2b6-4e8d-a79c-637930bc982b",
         "email-type":"EMAIL_TYPE_VERIFY_EMAIL",
         "recipient-user":15
      }
   }
}

How to reproduce

framework.yml has to be configured to have a webhook available:

framework:
    webhook:
        routing:
            mailer_mailgun:
                service: 'mailer.webhook.request_parser.mailgun'
                secret: '%env(MAILER_MAILGUN_SECRET)%'

With a listener attached - this can effectively be blank as the error prevents the webhook request getting this far:

<?php

namespace App\Webhook;

use Symfony\Component\RemoteEvent\Attribute\AsRemoteEventConsumer;
use Symfony\Component\RemoteEvent\Consumer\ConsumerInterface;
use Symfony\Component\RemoteEvent\RemoteEvent;

#[AsRemoteEventConsumer('mailer_mailgun')]
class MailgunListener implements ConsumerInterface
{
    public function consume(RemoteEvent $event): void
    {
        return
    }
}

In Mailgun attach your webhook to the Acceepted event and trigger the event from the webhook test page of MailGun:
image

NB:

Possible Solution

Update lines 78 to 86 from this:

        if ('' !== $payload['delivery-status']['description']) {
            return $payload['delivery-status']['description'];
        }
        if ('' !== $payload['delivery-status']['message']) {
            return $payload['delivery-status']['message'];
        }
        if ('' !== $payload['reason']) {
            return $payload['reason'];
        }

to this:

        if ('' !== ($payload['delivery-status']['description'] ?? '')) {
            return $payload['delivery-status']['description'];
        }
        if ('' !== ($payload['delivery-status']['message'] ?? '')) {
            return $payload['delivery-status']['message'];
        }
        if ('' !== ($payload['reason'] ?? '')) {
            return $payload['reason'];
        }

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions