diff --git a/src/Plugin/WebformScheduledTasks/Task/EmailedExport.php b/src/Plugin/WebformScheduledTasks/Task/EmailedExport.php
index a278593..06cea6a 100644
--- a/src/Plugin/WebformScheduledTasks/Task/EmailedExport.php
+++ b/src/Plugin/WebformScheduledTasks/Task/EmailedExport.php
@@ -144,6 +144,16 @@ class EmailedExport extends TaskPluginBase implements ContainerFactoryPluginInte
       '#required' => TRUE,
       '#description' => $this->t('Select how the resulting file will be delivered to the configured users. Saving the file to the file system will generate a private file which only privileged roles will have access to.'),
     ];
+    $form['attachment_storage_type_warning'] = [
+      '#type' => 'webform_message',
+      '#message_type' => 'warning',
+      '#message_message' => $this->t('<strong>Warning:</strong> Sending email file attachments requires webform to have already been configured for attachments. See <a target="_blank" href=":help">this help topic for more information</a>.', [':help' => 'https://www.drupal.org/node/3021480']),
+      '#states' => [
+        'visible' => [
+          ':input[name="task_settings[storage_type]"]' => ['value' => 'email'],
+        ],
+      ],
+    ];
     $form['delete_submissions'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Delete submissions after export'),
@@ -235,44 +245,49 @@ class EmailedExport extends TaskPluginBase implements ContainerFactoryPluginInte
       throw new HaltScheduledTaskException('An invalid archive file was generated.');
     }
 
-    // @todo, build this option.
-    // https://www.drupal.org/project/webform_scheduled_tasks/issues/3031237.
-    if ($this->configuration['storage_type'] === static::STORAGE_TYPE_EMAIL) {
-      throw new HaltScheduledTaskException('The email storage type has not been implemented yet.');
+    $target_directory = static::DESTINATION_DIRECTORY;
+    if (!$this->fileSystem->prepareDirectory($target_directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) {
+      throw new HaltScheduledTaskException('Could not create a directory for the exported files to be written to.');
+    }
+    $attempted_file_destination_uri = sprintf('%s/%s', static::DESTINATION_DIRECTORY, $this->getExportFileOrArchiveName($exporter));
+    if (!$unique_destination_file_uri = $this->fileSystem->copy($this->getExportFileOrArchivePath($exporter), $attempted_file_destination_uri)) {
+      throw new HaltScheduledTaskException('Could not write the generated file to the private file system.');
     }
 
-    // If we have chosen to store the submissions on the file system, copy the
-    // generated temp file into the private file system.
-    if ($this->configuration['storage_type'] === static::STORAGE_TYPE_FILESYSTEM) {
-      $target_directory = static::DESTINATION_DIRECTORY;
-      if (!$this->fileSystem->prepareDirectory($target_directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) {
-        throw new HaltScheduledTaskException('Could not create a directory for the exported files to be written to.');
-      }
-      $attempted_file_destination_uri = sprintf('%s/%s', static::DESTINATION_DIRECTORY, $this->getExportFileOrArchiveName($exporter));
-      if (!$unique_destination_file_uri = $this->fileSystem->copy($this->getExportFileOrArchivePath($exporter), $attempted_file_destination_uri)) {
-        throw new HaltScheduledTaskException('Could not write the generated file to the private file system.');
-      }
-
-      // Save a file entity with the data so the file can be deleted from the UI
-      // if it has been downloaded.
-      $file = File::create([
-        'uri' => $unique_destination_file_uri,
-        'filename' => $this->getExportFileOrArchiveName($exporter),
-        'status' => FILE_STATUS_PERMANENT,
-      ]);
-      $file->save();
-      // Register a file usage that tells Drupal the file URI was sent in an
-      // email, to prevent the make_unused_managed_files_temporary setting from
-      // deleting it. This will ensure the file sticks around until the user
-      // explicitly decides to delete the export.
-      $this->fileUsage->add($file, 'webform_scheduled_tasks', 'email_uri', $this->getScheduledTask()->id());
-
-      $this->emailRecipients('export_summary_filesystem', [
-        'file_url' => file_create_url($unique_destination_file_uri),
-        'task_id' => $this->getScheduledTask()->id(),
-      ]);
+    // Save a file entity with the data so the file can be deleted from the UI
+    // if it has been downloaded.
+    $file = File::create([
+      'uri' => $unique_destination_file_uri,
+      'filename' => $this->getExportFileOrArchiveName($exporter),
+      'status' => FILE_STATUS_PERMANENT,
+    ]);
+    $file->save();
+    // Register a file usage that tells Drupal the file URI was sent in an
+    // email, to prevent the make_unused_managed_files_temporary setting from
+    // deleting it. This will ensure the file sticks around until the user
+    // explicitly decides to delete the export.
+    $this->fileUsage->add($file, 'webform_scheduled_tasks', 'email_uri', $this->getScheduledTask()->id());
+
+    // Add the export as an email attachment if the task is configured as such.
+    // Note, the file is still written to the private file system regardless, to
+    // ensure no data is lost in the case of dropped, rejected or undelivered
+    // mail.
+    $email_attachments = [];
+    if ($this->configuration['storage_type'] === static::STORAGE_TYPE_EMAIL) {
+      $email_attachments[] = [
+        'filecontent' => file_get_contents($file->getFileUri()),
+        'filename' => $file->getFilename(),
+        'filemime' => $file->getMimeType(),
+        'filepath' => $this->fileSystem->realpath($file->getFileUri()),
+      ];
     }
 
+    $this->emailRecipients('export_summary_filesystem', [
+      'file_url' => file_create_url($unique_destination_file_uri),
+      'task_id' => $this->getScheduledTask()->id(),
+      'attachments' => $email_attachments,
+    ]);
+
     if ($this->configuration['delete_submissions']) {
       foreach ($processed_submission_ids as $submission_delete_id) {
         WebformSubmission::load($submission_delete_id)->delete();
diff --git a/tests/src/Kernel/EmailedExportTest.php b/tests/src/Kernel/EmailedExportTest.php
index f01fbf0..5e2cc49 100644
--- a/tests/src/Kernel/EmailedExportTest.php
+++ b/tests/src/Kernel/EmailedExportTest.php
@@ -339,6 +339,38 @@ class EmailedExportTest extends FileTestBase {
     $this->assertContains('BAR SUBMISSION CONTENT', $archive->extractInString('foo.webform_scheduled_task.foo/foo.webform_scheduled_task.foo.csv'));
   }
 
+  /**
+   * Test the task when emails are sent as attachments.
+   */
+  public function testSendExportAsEmailAttachment() {
+    $this->createTestTask([
+      'email_addresses' => 'foo@example.com, bar@example.com',
+      'storage_type' => EmailedExport::STORAGE_TYPE_EMAIL,
+      'exporter' => 'delimited_text',
+      'exporter_settings' => [
+        'delimiter' => '|',
+        'excel' => TRUE,
+      ],
+      'include_attachments' => FALSE,
+      'delete_submissions' => FALSE,
+    ]);
+    $this->createTestSubmissions();
+    webform_scheduled_tasks_cron();
+
+    $mail = $this->getMails();
+    $this->assertCount(2, $mail);
+
+    // Ensure the attachment information was included in the email params.
+    $this->assertEquals('foo.webform_scheduled_task.foo.csv', $mail[0]['params']['attachments'][0]['filename']);
+    $this->assertEquals('text/csv', $mail[0]['params']['attachments'][0]['filemime']);
+    $this->assertContains('scheduled-exports/foo.webform_scheduled_task.foo.csv', $mail[0]['params']['attachments'][0]['filepath']);
+    $this->assertContains('FOO SUBMISSION CONTENT', $mail[0]['params']['attachments'][0]['filecontent']);
+    $this->assertContains('BAR SUBMISSION CONTENT', $mail[0]['params']['attachments'][0]['filecontent']);
+
+    // The file should still be saved to the private filesystem as a backup.
+    $this->assertFileExists('private://scheduled-exports/foo.webform_scheduled_task.foo.csv');
+  }
+
   /**
    * Create test submissions.
    */
