Fix email notification reply to (#603)
This commit is contained in:
parent
6bdce23967
commit
08837e6a29
|
|
@ -19,7 +19,6 @@ class FormEmailNotification extends Notification implements ShouldQueue
|
||||||
|
|
||||||
public FormSubmitted $event;
|
public FormSubmitted $event;
|
||||||
public string $mailer;
|
public string $mailer;
|
||||||
private array $formattedData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new notification instance.
|
* Create a new notification instance.
|
||||||
|
|
@ -30,7 +29,6 @@ class FormEmailNotification extends Notification implements ShouldQueue
|
||||||
{
|
{
|
||||||
$this->event = $event;
|
$this->event = $event;
|
||||||
$this->mailer = $mailer;
|
$this->mailer = $mailer;
|
||||||
$this->formattedData = $this->formatSubmissionData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -54,7 +52,7 @@ class FormEmailNotification extends Notification implements ShouldQueue
|
||||||
{
|
{
|
||||||
return (new MailMessage())
|
return (new MailMessage())
|
||||||
->mailer($this->mailer)
|
->mailer($this->mailer)
|
||||||
->replyTo($this->getReplyToEmail($notifiable->routes['mail']))
|
->replyTo($this->getReplyToEmail($this->event->form->creator->email))
|
||||||
->from($this->getFromEmail(), $this->getSenderName())
|
->from($this->getFromEmail(), $this->getSenderName())
|
||||||
->subject($this->getSubject())
|
->subject($this->getSubject())
|
||||||
->withSymfonyMessage(function (Email $message) {
|
->withSymfonyMessage(function (Email $message) {
|
||||||
|
|
@ -63,13 +61,15 @@ class FormEmailNotification extends Notification implements ShouldQueue
|
||||||
->markdown('mail.form.email-notification', $this->getMailData());
|
->markdown('mail.form.email-notification', $this->getMailData());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function formatSubmissionData(): array
|
private function formatSubmissionData($createLinks = true): array
|
||||||
{
|
{
|
||||||
$formatter = (new FormSubmissionFormatter($this->event->form, $this->event->data))
|
$formatter = (new FormSubmissionFormatter($this->event->form, $this->event->data))
|
||||||
->createLinks()
|
|
||||||
->outputStringsOnly()
|
->outputStringsOnly()
|
||||||
->useSignedUrlForFiles();
|
->useSignedUrlForFiles();
|
||||||
|
|
||||||
|
if ($createLinks) {
|
||||||
|
$formatter->createLinks();
|
||||||
|
}
|
||||||
if ($this->integrationData->include_hidden_fields_submission_data ?? false) {
|
if ($this->integrationData->include_hidden_fields_submission_data ?? false) {
|
||||||
$formatter->showHiddenFields();
|
$formatter->showHiddenFields();
|
||||||
}
|
}
|
||||||
|
|
@ -98,27 +98,25 @@ class FormEmailNotification extends Notification implements ShouldQueue
|
||||||
private function getReplyToEmail($default): string
|
private function getReplyToEmail($default): string
|
||||||
{
|
{
|
||||||
$replyTo = $this->integrationData->reply_to ?? null;
|
$replyTo = $this->integrationData->reply_to ?? null;
|
||||||
|
|
||||||
if ($replyTo) {
|
if ($replyTo) {
|
||||||
$parsedReplyTo = $this->parseReplyTo($replyTo);
|
$parsedReplyTo = $this->parseReplyTo($replyTo);
|
||||||
if ($parsedReplyTo && $this->validateEmail($parsedReplyTo)) {
|
if ($parsedReplyTo && $this->validateEmail($parsedReplyTo)) {
|
||||||
return $parsedReplyTo;
|
return $parsedReplyTo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $default;
|
||||||
return $this->getRespondentEmail() ?? $default;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseReplyTo(string $replyTo): ?string
|
private function parseReplyTo(string $replyTo): ?string
|
||||||
{
|
{
|
||||||
$parser = new MentionParser($replyTo, $this->formattedData);
|
$parser = new MentionParser($replyTo, $this->formatSubmissionData(false));
|
||||||
return $parser->parse();
|
return $parser->parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getSubject(): string
|
private function getSubject(): string
|
||||||
{
|
{
|
||||||
$defaultSubject = 'New form submission';
|
$defaultSubject = 'New form submission';
|
||||||
$parser = new MentionParser($this->integrationData->subject ?? $defaultSubject, $this->formattedData);
|
$parser = new MentionParser($this->integrationData->subject ?? $defaultSubject, $this->formatSubmissionData(false));
|
||||||
return $parser->parse();
|
return $parser->parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,7 +148,7 @@ class FormEmailNotification extends Notification implements ShouldQueue
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'emailContent' => $this->getEmailContent(),
|
'emailContent' => $this->getEmailContent(),
|
||||||
'fields' => $this->formattedData,
|
'fields' => $this->formatSubmissionData(),
|
||||||
'form' => $this->event->form,
|
'form' => $this->event->form,
|
||||||
'integrationData' => $this->integrationData,
|
'integrationData' => $this->integrationData,
|
||||||
'noBranding' => $this->event->form->no_branding,
|
'noBranding' => $this->event->form->no_branding,
|
||||||
|
|
@ -160,7 +158,7 @@ class FormEmailNotification extends Notification implements ShouldQueue
|
||||||
|
|
||||||
private function getEmailContent(): string
|
private function getEmailContent(): string
|
||||||
{
|
{
|
||||||
$parser = new MentionParser($this->integrationData->email_content ?? '', $this->formattedData);
|
$parser = new MentionParser($this->integrationData->email_content ?? '', $this->formatSubmissionData());
|
||||||
return $parser->parse();
|
return $parser->parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,26 +168,6 @@ class FormEmailNotification extends Notification implements ShouldQueue
|
||||||
return $submissionId ? Hashids::encode($submissionId) : null;
|
return $submissionId ? Hashids::encode($submissionId) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRespondentEmail(): ?string
|
|
||||||
{
|
|
||||||
$emailFields = ['email', 'e-mail', 'mail'];
|
|
||||||
|
|
||||||
foreach ($this->formattedData as $field => $value) {
|
|
||||||
if (in_array(strtolower($field), $emailFields) && $this->validateEmail($value)) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no email field found, search for any field containing a valid email
|
|
||||||
foreach ($this->formattedData as $value) {
|
|
||||||
if ($this->validateEmail($value)) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateEmail($email): bool
|
public static function validateEmail($email): bool
|
||||||
{
|
{
|
||||||
return (bool)filter_var($email, FILTER_VALIDATE_EMAIL);
|
return (bool)filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ it('send email with the submitted data', function () {
|
||||||
$notifiable->route('mail', 'test@test.com');
|
$notifiable->route('mail', 'test@test.com');
|
||||||
$renderedMail = $mailable->toMail($notifiable);
|
$renderedMail = $mailable->toMail($notifiable);
|
||||||
expect($renderedMail->subject)->toBe('New form submission');
|
expect($renderedMail->subject)->toBe('New form submission');
|
||||||
|
expect($renderedMail->replyTo[0][0])->toBe('reply@example.com');
|
||||||
expect(trim($renderedMail->render()))->toContain('Test body');
|
expect(trim($renderedMail->render()))->toContain('Test body');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -163,3 +164,65 @@ it('does not use custom sender email in non-self-hosted mode', function () {
|
||||||
expect($renderedMail->subject)->toBe('Custom Subject');
|
expect($renderedMail->subject)->toBe('Custom Subject');
|
||||||
expect(trim($renderedMail->render()))->toContain('Custom content');
|
expect(trim($renderedMail->render()))->toContain('Custom content');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('send email with mention as reply to', function () {
|
||||||
|
$user = $this->actingAsUser();
|
||||||
|
$workspace = $this->createUserWorkspace($user);
|
||||||
|
$form = $this->createForm($user, $workspace);
|
||||||
|
|
||||||
|
$emailProperty = collect($form->properties)->first(function ($property) {
|
||||||
|
return $property['type'] == 'email';
|
||||||
|
});
|
||||||
|
|
||||||
|
$integrationData = $this->createFormIntegration('email', $form->id, [
|
||||||
|
'send_to' => 'test@test.com',
|
||||||
|
'sender_name' => 'OpnForm',
|
||||||
|
'subject' => 'New form submission',
|
||||||
|
'email_content' => 'Hello there 👋 <br>Test body',
|
||||||
|
'include_submission_data' => true,
|
||||||
|
'include_hidden_fields_submission_data' => false,
|
||||||
|
'reply_to' => '<span mention-field-id="' . $emailProperty['id'] . '" mention-field-name="' . $emailProperty['name'] . '" mention-fallback="" contenteditable="false" mention="true">' . $emailProperty['name'] . '</span>'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$formData = [
|
||||||
|
$emailProperty['id'] => 'reply@example.com',
|
||||||
|
];
|
||||||
|
|
||||||
|
$event = new \App\Events\Forms\FormSubmitted($form, $formData);
|
||||||
|
$mailable = new FormEmailNotification($event, $integrationData, 'mail');
|
||||||
|
$notifiable = new AnonymousNotifiable();
|
||||||
|
$notifiable->route('mail', 'test@test.com');
|
||||||
|
$renderedMail = $mailable->toMail($notifiable);
|
||||||
|
expect($renderedMail->replyTo[0][0])->toBe('reply@example.com');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('send email with empty reply to', function () {
|
||||||
|
$user = $this->actingAsUser();
|
||||||
|
$workspace = $this->createUserWorkspace($user);
|
||||||
|
$form = $this->createForm($user, $workspace);
|
||||||
|
|
||||||
|
$emailProperty = collect($form->properties)->first(function ($property) {
|
||||||
|
return $property['type'] == 'email';
|
||||||
|
});
|
||||||
|
|
||||||
|
$integrationData = $this->createFormIntegration('email', $form->id, [
|
||||||
|
'send_to' => 'test@test.com',
|
||||||
|
'sender_name' => 'OpnForm',
|
||||||
|
'subject' => 'New form submission',
|
||||||
|
'email_content' => 'Hello there 👋 <br>Test body',
|
||||||
|
'include_submission_data' => true,
|
||||||
|
'include_hidden_fields_submission_data' => false,
|
||||||
|
'reply_to' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$formData = [
|
||||||
|
$emailProperty['id'] => 'reply@example.com',
|
||||||
|
];
|
||||||
|
|
||||||
|
$event = new \App\Events\Forms\FormSubmitted($form, $formData);
|
||||||
|
$mailable = new FormEmailNotification($event, $integrationData, 'mail');
|
||||||
|
$notifiable = new AnonymousNotifiable();
|
||||||
|
$notifiable->route('mail', 'test@test.com');
|
||||||
|
$renderedMail = $mailable->toMail($notifiable);
|
||||||
|
expect($renderedMail->replyTo[0][0])->toBe($form->creator->email);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue