Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm running a webserver with a contact form which triggers a php script to sendmail the message to a local account on the server, and I want to be notified on my regular email account when I got new messages.

I could have a notification per email or just send the emails directly to my account but that'd be too much: I just want a "you have new mail" notification sent to my email every time the inbox turns from 0 unread messages to 1.

Google is burying me in sendmail documentation, and still can't find anything about it.

Any ideas?

share|improve this question
add comment

4 Answers

up vote 1 down vote accepted

I make use of the .forward file to accomplish this.

PROS: dead simple.

CONS: 1 "ping" email for every email received. So if I receive 5 emails before checking, then I'll get 5 pings in my other mailbox. This could be solved by using a script such as your send_notification_if_no_new_mails().

.forward file:

\username
|"echo 'New email just arrived.' | mailx -s 'new message on the server' primary.email@example.com"

The first line is your local account preceeded by a backslash to prevent a loop. This ensures local delivery. The second line executes a script. In this case it directly calls mailx to fire off a ping email. You could instead run a script similar to your send_notification_if_no_new_mails() to limit the pings sent.

share|improve this answer
add comment

You probably want to write a cron task of some sort.

eg. you could write something in Python or PHP that runs every min, logs into the mailbox using IMAP, checks if the waiting message size has changed and if so, sends you a notification email.

To have Sendmail do this natively is going to be a lot more trouble.

As an aside> why don't you just have the email from the contact form go to both the local account and your real account?

share|improve this answer
    
The reason is I don't want a burst of emails coming to my account (I'm using a shared relay server for outbound email and the admin told me not to abuse it, so I want to keep the messages local on the web server but I still want unread email notifications to my gmail account), so I want just a simple notification that I have something unread. A cron task was also my first thought when I couldn't find how to config sendmail to do it, but I'm an efficiency freak and curious to know if it's possible to just add a line to my sendmail.mc (it should be) and what to put on it. –  elcodedocle Apr 12 '12 at 9:20
1  
fair enough. If you want to do it natively in Sendmail, I'd say you'd need to write a custom milter to do a similar check and fire a notification to you as required. I don't know enough about Sendmail to be of much help. Sorry –  Andre Lackmann Apr 12 '12 at 12:19
    
You cannot do that with one line in your sendmail.mc. You could do that by implementing your own message delivery agent (instead of procmail or mail.local) but it would be overkill. I would not be surprised if a procmail hacker can offer such a recipe. –  adamo Apr 12 '12 at 15:56
add comment

You need to write a biff-like program like xbiff or xbiff2. You should record the following states: all-read, unread-mail-not-sent, unread-mail-sent.

So now you have to write a script run by cron every say 30 minutes that checks your mailbox (via POP3, IMAP or even directly) and asks for new mail. If new mail exists you have to know whether you have sent notification mail or not. If you have new mail and have not sent a notification, sent the notification and record the fact in a "flag" file. If you have new mail and the file exists, do not sent email. If no email is new and the file exists erase it.

share|improve this answer
    
Again, a solution checking every X minutes for an event doesn't seem as effective/efficient as a solution triggered when the event occurs, but after doing my research I take your word on that needing a true sendmail hacker to work, not just 1 line on a config file, which I'm surprised of because it doesn't seem such an unusual requirement... Anyway, definetly out of my reach. –  elcodedocle Apr 12 '12 at 16:19
add comment

In case anybody is interested, here's a basic example with the code I've included on my .php contact form script which, by calling mail -f /var/mail/www-data -e, does what I want. Not exactly the kind of solution I was looking for, but the same results:

Basic contact form and mail script:

<?php
require_once 'send_notification_if_no_new_mails.php';
if (isset($_POST['subject'])&&isset($_POST['message'])){
    send_notification_if_no_new_mails();
    mail("www-data",$_POST['subject'],$_POST['message']);
}
?>
<!doctype html><html>
<head><title>contact form</title></head>
<body><form method='post'>Subject:<input name='subject' type='text' /><br />
<textarea name='message'>Type here your message.</textarea>
<input type='submit' value='send'/></form></body>
</html>

The function to check and send the notification if necessary:

<?php
function send_notification_if_no_new_mails(){
    exec('mail -f /var/mail/www-data -e',$output,$return_var);
    if ($return_var=='0') { 
        /* There's already new mail. Do not send notification. */
        return 0; 
    }

    /* There is no new mail but there is going to be now -> Send notification */ 

    $email="myemail@gmail.com";

    $subject="New message from your webapp";

    $msg  = "You have a new message from your webapp's contact form";
    $msg .= PHP_EOL.PHP_EOL;

    /* Common Headers */
    $time = time(); 
    $now = (int)(date('Y',$time).date('m',$time).date('j',$time));
    $headers = 'From: SYNAPP mailer <noreply@mywebapp.com>'.PHP_EOL;
    $headers .= 'Reply-To: noreply <noreply@mywebapp.com>'.PHP_EOL;
    $headers .= 'Return-Path: noreply <noreply@mywebapp.com>'.PHP_EOL;
    $headers .= "Message-ID:<".$now." admin@".$_SERVER['SERVER_NAME'].">".PHP_EOL;
    $headers .= "X-Mailer: PHP v".phpversion().PHP_EOL;
    $headers .= 'MIME-Version: 1.0'.PHP_EOL;
    $headers .= "Content-Type: text/plain; charset=\"utf-8\"".PHP_EOL;

    mail($email, $subject, $msg, $headers);

    return 1;
}
?>
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.