Import from URL Email Adjuster

Created on 10 April 2025, 15 days ago

Problem/Motivation

It would be nice to include an "Import from URL" email body adjuster. This would allow people to design the content of their emails in an email builder like Mailchimp or Beefree and easily import the body of the email.

Proposed resolution

Most of this is taken from BodyEmailAdjuster.php, but it works.

<?php

namespace Drupal\your_module\Plugin\EmailAdjuster;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\symfony_mailer\EmailInterface;
use Drupal\symfony_mailer\Processor\EmailAdjusterBase;

/**
 * Defines the Body Email Adjuster.
 *
 * @EmailAdjuster(
 *   id = "remote_body",
 *   label = @Translation("Import from URL"),
 *   description = @Translation("Sets the email body by importing from a URL."),
 * )
 */
class RemoteBodyEmailAdjuster extends EmailAdjusterBase implements TrustedCallbackInterface {

  /**
   * {@inheritdoc}
   */
  public function build(EmailInterface $email) {
    $url = $this->configuration['remote_url'] ?? NULL;

    $content = [
      'value' => $email->getBody(),
      'format' => 'email_html'
    ];

    $httpClient = \Drupal::service('http_client');

    if ($url) {
      try {
        $response = $httpClient->get($url);
        $html = (string) $response->getBody();
        $content['value'] = $html;
      }
      catch (\Exception $e) {
        \Drupal::logger('your_module')->error('Failed to fetch email HTML from @url: @message', [
          '@url' => $url,
          '@message' => $e->getMessage(),
        ]);
      }
    }

    $body = [
      '#type' => 'processed_text',
      '#text' => $content['value'],
      '#format' => $content['format'] ?? filter_default_format(),
    ];

    $variables = $email->getVariables();
    if ($existing_body = $email->getBody()) {
      $variables['body'] = $existing_body;
    }

    if ($variables) {
      $body += [
        '#pre_render' => [
          // Preserve the default pre_render from the element.
          [$this, 'preRenderVariables'],
          ['Drupal\filter\Element\ProcessedText', 'preRenderText'],
        ],
        '#context' => $variables,
      ];
    }

    $email->setBody($body);
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $form['remote_url'] = [
      '#title' => $this->t('Remote HTML Template URL'),
      '#type' => 'textfield',
      '#default_value' => $this->configuration['remote_url'] ?? '',
      '#description' => $this->t('Enter the URL of a remote HTML email template (e.g. from BeeFree or another email builder).'),
      '#required' => TRUE,
    ];

    return $form;
  }  

  /**
   * Pre-render callback for replacing twig variables.
   */
  public function preRenderVariables(array $body) {
    $twig_service = \Drupal::service('twig');
    $body['#text'] = $twig_service->renderInline($body['#text'], $body['#context']);
    return $body;
  }

  /**
   * {@inheritdoc}
   */
  public static function trustedCallbacks() {
    return ['preRenderVariables'];
  }

}

Remaining tasks

User interface changes

API changes

Data model changes

Feature request
Status

Active

Version

1.5

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024