I'm trying to send an html email from my module.
I have SMTP module installed to send via our smtp server. Sending emails work but cant get html emails to work...
SMTP module uses the phpmailer class which I've used before by itself to send html emails (just need a header 'content-type' set to 'text/html')...
Do you need additional modules to make it work like mimemail or htmlmail? (hoping not, as they arent compatible totally it seems reading some posts unless apply patch ).

I tried setting $params to send into drupal_mail by itself...
like....
$params['headers'] = 'Content-type: text/html';
$params['headers'] = array('Content-type'=>'text/html');
$params['Content-type'] = 'text/html');

None work frustratingly, anyone have html emails working just using drupal_mail() func (and SMTP module)?

Comments

searchmax’s picture

I have not used SMTP module, but I have used html mail and it worked fine for me. Below is the code on how i got this done.

$headers = array(
'MIME-Version' => '1.0',
'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
'Content-Transfer-Encoding' => '8Bit',
'X-Mailer' => 'Drupal'
);

drupal_mail("contactus(any string identifier)",$to(to email address),$re(subject),$msg(html formatted msg),$from(from email address),$headers);

Hope this helps you

comterkumar’s picture

I think you can use mimemail module

armyofda12mnkeys’s picture

Drupal6 adds the $module parameter,... Wonder what goes there if no module should add things to the email (with its hook_mail). aka just want to send standalone email in a php input page for example.

More importantly the $headers were a param in D5, but in D6 you just see $params, and these dont seem to be header values (but rather values you can pass onto your module's hook_mail function).

Wish the function was as clear as D5 on how to send headers.

mattyoung’s picture

>Wonder what goes there if no module should add things to the email (with its hook_mail)

Looking at the source: http://api.drupal.org/api/function/drupal_mail/6

  if (function_exists($function = $module .'_mail')) {
    $function($key, $message, $params);
  }

So, if there is no hook_mail() defined, no call is made.

>just want to send standalone email in a php input page for example

call drupal_send_mail() directly? http://api.drupal.org/api/function/drupal_mail_send/6

phpdiva’s picture

You can implement hook_mail_alter() like so...
I had to only use HTML for the user welcome message, but you can modify this to your liking:

/**
 * hook_mail_alter()
**/
function mymodule_mail_alter(&$message) {
  
  if ($message['id'] == 'user_register_no_approval_required') {

  	require_once $_SERVER['DOCUMENT_ROOT'] . '/lib/Swift.php';
  	require_once $_SERVER['DOCUMENT_ROOT'] . '/lib/Swift/Connection/SMTP.php';
  	
	$html_message = nl2br($message['body'][0]);
	
	// get the contents of the html email and replace placeholders.
	$html_container = file_get_contents('URL of the HTML template');
	$html_container = str_replace('%%title%%', 'Some title', $html_container);
	$html_container = str_replace('%%content%%', $html_message, $html_container);
	
	$message['body'][0] = $html_container;
  
  	$swift = new Swift (new Swift_Connection_SMTP('127.0.0.1', 25));
  	$email = new Swift_Message ($message['subject'], $message['body'][0], 'text/html');

	$swift->send ($email, $message['to'], $message['from']); 
  	$swift->disconnect();
	
        // set message here and redirect to homepage so you don't send the email twice.
	drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
	drupal_goto('home');
  }
}

---
Threshold Interactive :: www.thresholdinteractive.com
---
http://phpdiva.wordpress.com

incaic’s picture

I use the hook_mail_alter() function for Drupal5 as follows:
(I also replace tokens used in the subject and body)

function mymodule_mail_alter($mailkey, &$to, &$subject, &$body, &$from, &$headers = array()) {
  switch ($mailkey) {
    case 'user-pass':
    case 'user-register-welcome':
      $headers['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
      $subject = token_replace_multiple($subject);
      $body    = token_replace_multiple($body);
      break;
  }
}
roychri’s picture

<?php
// $Id$

/**
 * @file This is sites/all/modules/somemodule/somemodule.module
 */

/**
 * Implements hook_mail().
 */
function somemodule_mail($key, &$message, $params) {
  $headers = array(
    'MIME-Version' => '1.0',
    'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
    'Content-Transfer-Encoding' => '8Bit',
    'X-Mailer' => 'Drupal'
  );
  foreach ($headers as $key => $value) {
    $message['headers'][$key] = $value;
  }
  $message['subject'] = $params['subject'];
  $message['body'] = $params['body'];
}

Then in your code to send email, you do:

$params = array(
  'body' => $body,
  'subject' => 'This is a subject',
);
$message = drupal_mail('somemodule', 'some_mail_key', $to, language_default(), $params, $from, TRUE);
AdrianSmithUK’s picture

Hi

I am trying to write a Drupal 6 snippet to append to http://drupal.org/node/197122.

I have written the following code by modifying Christian Roy's posting above and combining it with the Drupal 5 example in http://drupal.org/node/197122.

It works but I can't understand why?

Below is a function called 'somemodule_mail'. This was Christian's sample name.

In my example I was sure I should need to change it to 'my_form_mail'. If I do it stops working.

If I leave it as 'somemodule_mail' it works.

Can anybody help and explain why?

Kind Regards,

Adrian Smith


<?php

/**
* Create a block and insert this code. 
* I placed the block in the rh column.
*/

function my_form() {

  $form['email'] = array(
    '#type' => 'textfield',
    '#title' => '',
    '#size' => '20',
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Subscribe',
  );
  return $form;
}

function my_form_validate($form, &$form_state) {
  $valid_email = $form_state['values']['email'];
  if (!valid_email_address($valid_email)) {
  form_set_error('email', 'Your email address -- ' . $valid_email . ' -- appears malformed');
  } 
}

function somemodule_mail($key, &$message, $params) {
  $headers = array(
    'MIME-Version' => '1.0',
    'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
    'Content-Transfer-Encoding' => '8Bit',
    'X-Mailer' => 'Drupal'
  );
  foreach ($headers as $key => $value) {
    $message['headers'][$key] = $value;
  }
  $message['subject'] = $params['subject'];
  $message['body'] = $params['body'];
}

function my_form_submit($form, &$form_state) {

	$valid_email = $form_state['values']['email'];
	$from = 'test@example.com';
	$body = 'New Email Sent = ' . $valid_email;
	
	$params = array(
	'body' => $body,
	'subject' => 'This is a subject',
	);
	
	if (drupal_mail('somemodule', 'some_mail_key', $valid_email, language_default(), $params, $from, TRUE))
	{
		drupal_set_message('An email has been sent to ' . $valid_email);		
	} else {
		drupal_set_message('There was an error sending your email');
	}
}

return drupal_get_form('my_form');

?>

roychri’s picture

@AdrianSmithUK:

In my example, I had presumed that you would create a module and give it a name. I put 'somemodule' to represent whatever module name you would choose.

When you call drupal_mail(), the first argument is the module name. Both this first argument and the name of the xxxx_mail() function have to match.

So if you create a new module located in sites/all/modules/codesnippet_htmlmaild6/codesnippet_htmlmaild6.module then I suggest you call the function codesnippet_htmlmaild6_mail() and that you change the line in your submit function liike this:

...
if (drupal_mail('codesnippet_htmlmaild6', 'some_mail_key', $valid_email, language_default(), $params, $from, TRUE))
...

HOWEVER, unlike most hooks, the module parameter does not have to be a real module that is enable. You can put anything you want as the first parameter ti drupal_mail() as long as 1) it's not in conflict with any other functions 2) you have a function called xxx_mail() where 'xxx' match your first parameter.

Feel free to read http://api.drupal.org/api/function/drupal_mail/6 and http://api.drupal.org/api/function/hook_mail/6 for more information.

I hope this answers your question.

AdrianSmithUK’s picture

Many thanks for the fast reply Christian.

I added a drupal 6 solution to http://drupal.org/node/197122 and thanked you for your support.

Kind Regards,

Adrian Smith

Tom Van Schoor’s picture

Good solution, here's the same with an alternative use of array_merge():

/**
* Implements hook_mail().
*/
function somemodule_mail($key, &$message, $params) {
  $message['headers'] = array_merge(
    $message['headers'],  
    array(
      'MIME-Version' => '1.0',
      'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
      'Content-Transfer-Encoding' => '8Bit',
      'X-Mailer' => 'Drupal'
    )
  );
  $message['subject'] = $params['subject'];
  $message['body'] = $params['body'];
}

For people who really dislike the foreach loop...

tmsimont’s picture

@roychri:

why the foreach loop and array replacement? why not just put the values directly into the m-d array?


$message['headers']=array(
'MIME-Version' => '1.0',
'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
'Content-Transfer-Encoding' => '8Bit',
);

works for me :)

roychri’s picture

@tmsimont:
Because if another module adds additional headers, I do not want my code to trash them.
The way you propose it would completly override existing headers.

An alternative to the loop would be:

$message['headers']['MIME-Version'] = '1.0';
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
$message['headers']['Content-Transfer-Encoding'] = '8Bit';

What do you think?

asmdec’s picture

$message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';

JoshuaKissoon’s picture

Hey, here is the link to a tutorial i did on sending mail using drupal_mail and hook_mail: Sending HTML and Plain text Mail with Drupal 6. Hope this helps

jerilcjs’s picture

function asset_form_submit($form, &$form_state) 
{
   $body = '<html>
               <body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0" bgcolor="#ffffff" >
               <p>Hello</p>
               </body></html>';
     
               $my_module = 'foo';
	       $my_mail_token = 'bar';
	       $from = 'john@gmail.com';
	       
               $message = array(
		 'to' => '"'.addslashes(mime_header_encode('Winnie Pooh')) .'"<james@gmail.com>',
		 'subject' => t('Example subject'),
		 'body' => $body,
		 'headers' => array(
		 'From' => 'john@gmail.com',
		 'MIME-Version' => '1.0',
		 'Content-Type' => 'text/html;charset=utf-8',),
	       );
	      
               $system = drupal_mail_system($my_module, $my_mail_token);
	       if ($system->mail($message)) {
	        	// Success.
	       }
	       else {
		 // Failure.
		}
}
cutcopypaste’s picture

I'm trying to do something similar in a mymodule_mail hook, but it's all the html is being removed despite that I have

	$message['headers'] = array(
		'MIME-Version' => '1.0',
		'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
		'Content-Transfer-Encoding' => '8Bit',
		'X-Mailer' => 'Drupal'
	);
bloke_zero’s picture

Works for me too, but it's worth noting that there are a number of modules that enable this in a much more complete and systematic way based around http://drupal.org/project/htmlmail allowing theming etc. of emails.

webfaqtory’s picture

To get this to work you need the HTML Mail & Mail System (and the SMTP module if required).

Leave the HTML Mail module alone, nothing needs to be configured.

In the Mail System module, expand New Setting and select your module name from the Module dropdown and then the key for your email (I used html which you define in mymodule_mail hook). Click Save Settings and now your class appears in the list of Mail Settings. Select HTMLMailSytem from the dropdown under your class name and click Save Settings again. Below is a snippet for the mymodule_mail hook:

  case 'html':
      $headers = array(
        'MIME-Version' => '1.0',
        'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
        'Content-Transfer-Encoding' => '8Bit',
        'X-Mailer' => 'Drupal'
      );
      foreach ($headers as $key => $value) {
        $message['headers'][$key] = $value;
      }
      $message['subject'] = $params['subject'];
      $message['body'][] = $params['body'];
      break;

Send mail as normal eg.

drupal_mail('mymodule', 'html', $account->mail, 'en', $params);

Replace all occurrences of 'mymodule' with your module name.

The SMTP module works fine with these settings and sends HTML mail via a SMTP server and requires no further setup.

suresh.gju’s picture

Above method works great