Skip to main content
Drupal is a registered trademark of Dries Buytaert
Release: Drupal 11.4.6 Update released for Drupal core (11.4.6)! Release: Drupal 10.6.16 Update released for Drupal core (10.6.16)! Release: Drupal 12.0.0-alpha1 First alpha version released for Drupal core (12.0.0-alpha1). Release: AI (Artificial Intelligence) 1.5.0-rc3 New release candidate for module ai (1.5.0-rc3). Release: Smart Image Optimizer 1.0.1 Minor update available for module smart_image_optimizer (1.0.1). Release: EzContent API - Enhanced De-coupled CMS Experience 2.3.10 Minor update available for module ezcontent_api (2.3.10). Release: Collector Systems Gallery 1.0.11 Minor update available for module collector_systems (1.0.11). Release: Sector 10.3.2 Minor update available for module sector (10.3.2). Module Revived: EzContent API - Enhanced De-coupled CMS Experience 2.3.9 Module ezcontent_api updated after 15 months of inactivity (2.3.9). Security Coverage: Analyze PostHog Module analyze_posthog now has official Drupal security advisory coverage.

Email Attachment Helper

1,052 sites Security covered Drupal 10–11
View on drupal.org

This module allows developers to programmatically attach files to emails sent from Drupal. It intercepts emails and adds attachments based on specific parameters provided in the email settings.

This is a module for developers who want to attach files programmatically to emails sent from Drupal 8+. This module doesn't send emails but rather intercepts emails from other modules.

If an 'attachment' or an 'attachments' key is present in the $params array, it will be converted into an actual MIME attachment. Otherwise, this module doesn't touch the mail.

This module has no configuration options.

Requirements

This module requires Drupal core ^10.1, ^11, or ^12. No additional PHP extensions or contributed modules are needed.

This module hooks into Drupal core's default MailManager via hook_mail_alter(). This module is not compatible with Symfony Mailer, Mailer Plus, DSM+.

Installation

Install the module as you would normally install a contributed Drupal module.

Single attachment

Example code to put into your module:

      $params = [
        'attachment' => [
          'filecontent' =>
            'Your attachment contents. ' .
            'You could use file_get_contents() instead of ' .
            'this string.',
          'filename' => 'filename_how_' .
            'recipients_see_it.txt',
          'filemime' => 'text/plain',
        ],
        // further params as needed by your hook_mail
      ];
      $mail_manager = \Drupal::service('plugin.manager.mail');
      $result = $mail_manager->mail($your_module, $your_key, $to, $lang, $params);

Multiple attachments

If you need to attach more than one file, use the array key 'attachments' instead, and nest your files in an array:

      $params = [
        'attachments' => [
          [
            'filecontent' =>
              'Your attachment contents. ' .
              'You could use file_get_contents() instead of this string.',
            'filename' => 'attached_filename_how_recipients_see_it.txt',
            'filemime' => 'text/plain',
          ],
          [
            'filecontent' => file_get_contents('temporary://test.pdf'),
            'filename' => 'Invoice.pdf',
            'filemime' => 'application/pdf',
          ],
        ],
        // further params as needed by your hook_mail
      ];
      $mail_manager = \Drupal::service('plugin.manager.mail');
      $result = $mail_manager->mail($your_module, $your_key, $to, $lang, $params);

Files can be binary, too.

The 'filemime' key is optional. If it is missing then Drupal's ExtensionMimeTypeGuesser will be used.

The 'filecontent' key is optional, if 'filename' points to an existing file on the webserver.

Inline attachments (embedding images in the HTML body)

To reference an attachment from within the HTML message body itself, for example to embed a QR code or logo as <img src="cid:..."> instead of (or in addition to) offering it as a downloadable attachment, add a 'cid' key and set 'disposition' to 'inline':

      $cid = '[email protected]';
      $params = [
        'attachment' => [
          'filecontent' => MymoduleElement::getFileString($submission),
          'filename' => 'qr-code.png',
          'filemime' => 'image/png',
          'disposition' => 'inline',
          'cid' => $cid,
        ],
        // further params as needed by your hook_mail
      ];

Then reference the same $cid in the HTML body, without angle brackets:

      $body = '<img alt="QR code" src="cid:' . $cid . '">';

The 'disposition' key is optional and defaults to 'attachment'. The 'cid' key is optional; without it, no Content-ID header is added and the attachment can't be referenced from the body.

Using hook_mail_alter()

You can also use the mail_alter hook to insert attachments. The following example is for a hypothetical module called “mymodule”:

// attach a file to submission emails sent by the webform module
function mymodule_mail_alter(array &$message): void {
  if (isset($message['module']) && $message['module'] == 'webform') {
      $message['params']['attachments'][] = [
        'filecontent' => MymoduleElement::getFileString($message['params']['webform_submission']),
        'filename' => t('QR code') . '.png',
        'filemime' => 'image/png',
      ];
  }
}

Examples

For working examples, see the email_attachment_demo sub-module and the webform_qr_code_element contrib module.

Maintainer

Christian “Gogowitsch” Bläul.

Support

To submit bug reports and feature suggestions, or to track changes, use the issue queue.

To say “thank you” or financially support development of this module, you can send a few Euros via PayPal: [email protected] or various other means.

Depends on

Dependencies of the latest stable release

No dependencies recorded for this project.

Required by

Tracked projects that depend on this one

No tracked projects depend on this one yet.

Activity

Tracked releases
2
Tracked since
Jul 2026
Latest release
3 weeks ago
Releases (12 mo)
2 ▲ from 0
Maintenance
Active

Releases

Version Type Core Release date
8.x-1.7 Stable 10–11 Aug 9, 2026
8.x-1.6 Stable 10–11 Jul 19, 2026