tags:

views:

78

answers:

3

Hi,

I have a (PHP) script which runs on a new row in MySQL. However, it will continually send the emails, even if they've already been sent...causing mass emails into the users Inbox.

The script is quite big, so I cant paste it here - http://pastebin.com/6v75F4Gv

Is there anyway I can somehow check if this script has already sent 'xx' email, but if a new row containing 'zz' and the user has specified they wish to receive content containing 'zz' it sends the 'zz' row?

ie. It stops duplicate/etc. emails.

Note: MySQL table is in the following format:
Table: feed
Rows in pager: id, title, description, date

Table: recipients
Rows in recipients: id, email, suburb

Thanks :)

+1  A: 

Neither of your tables has a column to log if the email has been sent, which is what I'd expect to see happen here:

if (sendMail($subject, $to, $body, $from, $cc))
{
   echo 'Mail for ' . $to . ' has been sent.<br />';

   //Update database so only one email is sent...
   $sql = "INSERT INTO TRACKING_TABLE 
              (feed_id, recipient_id, isSent)
           VALUES
              ($feed_id, $recip_id, 'Y')";
   $query = mysql_query($sql);
} else
{  ...

...which would mean updating:

$feed_sql = "SELECT id, title, description, rssDate 
               FROM feed 
              WHERE MATCH (title) AGAINST ('" . $rows['suburb'] . "') 
                AND NOT EXISTS(SELECT NULL
                                 FROM TRACKING_TABLE tt
                                WHERE tt.feed_id = feed.id
                                  AND tt.recipient_id = $Recipient_id
                                  AND tt.issent = 'Y')
           GROUP BY pubDate 
           ORDER BY pubDate DESC 
              LIMIT 1";

...to be sure that your query isn't picking up those that have been successfully sent.

DROP TABLE IF EXISTS `example`.`tracking_table`;
CREATE TABLE  `example`.`tracking_table` (
  `feed_id` int(10) unsigned NOT NULL default '0',
  `recipient_id` int(10) unsigned NOT NULL default '0',
  `issent` char(1) NOT NULL default '',
  PRIMARY KEY  (`feed_id`,`recipient_id`),
  FOREIGN KEY (feed_id) REFERENCES pager(id),
  FOREIGN KEY (recipient_id) REFERENCES recipients(id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
OMG Ponies
Ok, but as Brad suggested. I'm sending the message to several recipients. This will mark it as sent if it sends to only 1 address, am I right?
Dean
@Dean: Not if the `TRACKING` table contains two columns - `feed_id` and `recipient_id`. These two columns should be the primary key, or at least a unique constraint to ensure the pair of values are unique but still allowing for a recipient_id to be associated to multiple feeds and vice versa.
OMG Ponies
Ok, great. I'll try it out :)
Dean
You've confused me with the `WHERE tt.feed_id = feed.id)` bit. What does tt mean? I have the table named log, so I assume you meant TRACKING_TABLE = tt?Error is `Unknown column 'tt.id' in 'where clause'`
Dean
@Dean: I've added the CREATE TABLE statement for the table you'd need to create. You can name it whatever you like, but have to update the name references in the code I provided to suit. What's throwing me off is you posted this question calling the table "pager" but the link to the source code uses a table called "feed"...
OMG Ponies
Yeah, error on my behalf. The database is "pager", the table is "feed".Once again, thanks. Will give her a shot.
Dean
@Dean: I see - I updated the answer to properly reference the TRACKING table to stop those which've already been sent.
OMG Ponies
Ok thanks. However "feed" is in MyISAM because of fulltext. This will require InnoDB wont it? This is because of the error (errno: 150), which suggests the foreign tables.
Dean
@Dean: Foreign keys are only for data validation - it's nice to have, but not entirely necessary.
OMG Ponies
Ok, well created it in MyISAM. Will have a look and see if it works :)Thanks
Dean
Am I right in saying I'll have to define each of the $recipient_id etc statements?
Dean
@Dean: Sorry, I don't understand. You'll need the recipient_id in order to check if the email has already been sent...
OMG Ponies
Well using your code returns various errors, which are empty strings. So I have to add to my code, somehow `$Recipient_id = $rows['id']` ?Those errors: http://pastebin.com/raw.php?i=6pWK8Zp9
Dean
@Dean: Have you updated the first query from the `recipients` table to select the `id`?
OMG Ponies
I have it exactly as you've put it, it just wont detect the variables - http://pastebin.com/MVd6fuyPDo i need to edit the `tt` bit? Also, in PHPMyAdmin, there's nothing in the table "tracking_table"
Dean
Problem sorted:http://pastebin.com/1YSmkFt7
Dean
A: 

Well, there is no generic way, which means you'll have to implement it yourself.

Either create a sent flag column in your recipients table, unsetting it in all records before the sending process starts, and setting it to "yes" once E-Mail for that specific recipient has been sent.

Or, more complex but more flexible, create a new table "deliveries" containing all the addresses that already received a certain mailing (identified by the current date, a string [e.g. "Newsletter Q3"] or whatever). This method may be a bit database-heavy, but a great way of keeping track of multiple mailings.

Pekka
Hmm, well I currently have the third table as Brad suggested. With fields: message_id, recipient_id, time, isSent. Id prefer it be a simple solution, but it can be database heavy if required.
Dean
A: 

You need to keep track of this in your database. You don't have any fields currently in your tables to support this, so you first need to revise your schema.

By quickly scanning your program, I get the impression that your pager table contains messages, and recipients contains those that receive the messages. The messages are one-to-many, so each message MAY be sent to several recipients. Correct?

That being the case, you will want to have a 3rd table where you keep track of what you sent. Perhaps with fields such as recipient_id, message_id, timestamp, and maybe a field for the success or failure of the message, which you can populate later if the message bounces.

Brad
You're 100% correct, thanks :)
Dean