Hello All,

I'm currently working on a module that will essentially act as a newsletter for our company that I'll call 'Tips of the Week'. Along with creating the message, it keeps track of how many times a user has received the newsletter and triggers various things based on that number. But none of that is really important at that point...

I'm having a LOT of problems trying to send mail from within my module. I'm using the SMTP Authentication module to send mail through our server - and if I use the 'Send Test E-mail' from within the SMTP module's page it works perfectly. But when I call drupal_mail from within my module, it isn't working.

I call drupal_mail with the following parameters:

drupal_mail('totw', 'tipOfTheWeek', 'xxx@xxx.com', language_default(), $params, $from, TRUE)

I submit my form with an ajax call, I echo $message['results'] from my php method, and I alert the results in my Javascript function and the text reads 'Message Body Empty.' It also logs two errors, one says 'Error Sending Email' and the other says 'Error Sending Email from xxx to xxx: Message Body Empty'.

I've read through both drupal_mail and hook_mail and I believe that I'm calling and using them correctly in my module, but I'm unable to get it to actually send. I've tried searching through the forums and I can't come up with anything that would really apply to my situation. Absolutely any help or thoughts that anyone could provide would be a big help.

Comments

lorinpda’s picture

Hi,
What values are storing in $params ? Are you storing the body?

Are you implementing hook_mail()? E.G. totw_mail()?

Do you have any special handling for for message key (tipOfTheWeek)?

Are you sending plain text or html? Email is plain text by default. If you are trying to send html, you will need the content type.

Please elaborate and folks can help you out.

dwatty1’s picture

Currently I only store some information on the user that is pulled from a database query in the $params variable. I've been setting the message body explicitly in totw_mail() until I got some results. I've tried the following two ways, both in totw_mail itself:

$message['body'][] = t("Testing Testing"); or $message['body'] = t("Testing Testing");

And I got nothing for either of those. I'm using a switch to handle the message key - per most of the examples that I saw online. As far as content type goes, eventually I'd like it to be in HTML but for now I've just been trying to get plain text working and then I thought I'd worry about getting the content type correct.

Are there are problems explicitly setting the message body in hook_mail? Do I have to pass all information into hook_mail() via $params?

lorinpda’s picture

Hi,
Yes you can override (I.E. set explicit test values in your hook_mail (totw_mail() ) function.
....
So you are setting a valid "from", "to", "subject" and "body"? The "from" is a valid account on your mail server?

Set "SMTP Authentication Support -- Enable debugging" (SMTP module) and see what the detailed exception is.

Is your Drupal installation running any other mail modules?

dwatty1’s picture

I am setting a valid to, from, subject, and body - I'm actually hard coding those in now to make sure they are set.

I've got 'Enable debugging' checked in the SMTP module and I get no output whatsoever from that when my function is called. When I use the 'Send Test Email' function of the SMTP module I can see the output from the debugger, but I see nothing when I mail from my module. Do I have to do anything in particular to use the SMTP module from within my module? Or does calling drupal_mail() take care of that?

And no, it's a pretty stripped down sandbox with only a few modules enabled - none of those being anything mail related.

lorinpda’s picture

Hi,
Can we assume that you've verified your hook_mail function is being called? Can you isolate the issue by removing the "ajax" processing? You seem really sure that the problem is in the mail call, nothing else. Please test and verify your "ajax" processing isn't the issue (just comment it out for debugging purposes).
....
Can you post your code?
....
The "from" email address (set in the SMTP module admin email options") matches the "from" email address used in your hook_mail implementation?

dwatty1’s picture

So I did away with the ajax call, and stripped the functions down to bare bones version and just visited the URL that does the processing directly. The function that is called when I visit the URL is:

function totw_process_form(){

	$from = "xxx@xxx.com";
		
	$ret = drupal_mail('totw', 'tipOfTheWeek', 'xxx@xxx.com', language_default(), $params, $from, TRUE);
	
	if($ret['result'])
		echo "Yes";
	else
		echo "No";
		
	exit();
}

I placed an echo in the totw_mail function that it does echo - so I'm convinced that hook_mail is being called. Do I need to return something from hook_mail()? Because currently I don't return anything - as you can see below:

function totw_mail($key, $message, $params){
	
	echo "TOTW MAIL ";
	$message['subject'] = t('Tip of The Week by Strategic Marketing & Mailing');
	$message['body'][] = t('Testing Testing');
	$message['to'] = t('xxx@xxx.com');
	
}

So when I visit this at http://localhost/admin/totw-send I get "TOTW MAIL Message body empty No" displayed in my browser.

lorinpda’s picture

Hi,
Thank you for posting the code. No, you don't need to return anything from totw_mail() -- hook_mail,
.....
Where is the "From" email address?

You said you were explicitly setting the "From" email address. Where is it??
......
Pseudo code

function mymodulename_mail($key, &$message, $params) {

    switch ($key) {
        case 'tipOfTheWeek':
            print ('<p>Process tip of the Week email message</p>);
            $message['subject'] = 'Test Message';
            $message['body'] = 'Test Body';

            $message['to'] = 'trijump3540@yourdomain.com';
            $site_mail = variable_get('site_mail', '');
            print ('<p>Debug: site_mail = ' .$site_mail' </p>);
            $message['from'] = $site_mail;
          
        break;
    }

}

Note:
Please correct the $message['body'] , see example above.
.....
Please post the result of what "site mail" is set to. Let's see what happens using that as the from?
,,,,,
Have you checked your Drupal installation Admin reports? Are there any details in "Recent Log Entries"?

jaypan’s picture

This:

function totw_mail($key, $message, $params){

Should be this:

function totw_mail($key, &$message, $params){

Contact me to contract me for D7 -> D10/11 migrations.

dwatty1’s picture

Wow, it was such a small thing but just adding that ampersand seems to have cured the issue that I was having. Many many thanks to you spotting that.

killua99’s picture

IF i have PHP 5.3.x this code work ?

<?php
function totw_mail($key, $message, $params){ 
?>

But if I have PHP 5.2.x I should use this one ....

<?php
function totw_mail($key, &$message, $params){ 
?>

that's correct ?

[at]Killua99 ~~

vomitHatSteve’s picture

...regardless of your PHP version.

The ampersand (&) says that $message needs to be passed by reference. Without it, a copy of the $message variable is passed in to your function, so any changes you make to it are lost when the function ends. With the ampersand, you're modifying the original version of $message, so when you change $message['body'], it changes everywhere that uses $message from then on out.

killua99’s picture

I was looking that style of explanation about the ampersand (&) use. That means without & the $message is the same of hook_mail() and don't override the original version.

I was a little confuse about the & for the issue with date and calendar module #549884: PHP 5.3 issue - Attempt to modify property of non-object (Date module).

[at]Killua99 ~~