How to tackle emails failed to send after commit database php - php

The case is I am calling a function which makes changes in DB and return list of users to whom I have to send emails.
If my db have made changes and selected users and due to some reason emails were not send and users are not informed from changes.
How to make sure that emails were sent after making changes in DB and if emails were failed to send what action should be taken.

You can use mysqli transaction commit & rollback when fails
here is another thread that may help you
Mysql transaction : commit and rollback

You should restructure your code in order to SELECT the users you wanted to update, try to email, and update the successfully emailed contacts. Maybe add a flag to denote contacts that had a successful email.
This way on your next SELECT you will have the left over ones that failed to email and were not updated.

Related

Laravel email conditional send - checking when last email of this type was sent to a user

I run a scheduled task each day to send emails to customers who have outstanding invoice and need to add a condition to check whether the email has been sent to this customer within the last 72 hours.
I guess I would need to:
Send the mail.
Log the message type and user to the database
Check the database for when the last mail was sent.
I have done a fair bit of reading and wonder if anything like this is already included in Laravel? I have not been able to find much so far.
This isn't built in to the platform, but it should be fairly straightforward to add. Sending an email using Laravel's mail functions triggers a MessageSent event. Attach a listener to that event and you can do whatever you like with it. The event will include the message object as well as any data passed to it.

How to handle Send Email Limit using Cron in Cpanel?

I have developed a custom newsletter sending module using php in which admin can send newsletter to subscribers. Newsletter can be designed within the module and can be send by selecting the category of subscribers that contain thousands of emails with one click. Now issue is i have a restriction of sending 500 emails per hour. Using sleep() cause expiry of max execution script time.
After some research it came to me that this can be done via cron job. I created a cron job in cpanel that is set to every 5 minutes but i am not able to figure out that how this cron job will be triggered when admin click on send newsletter button in administrative panel. I am using swiftmailer library and querying subscriber table on some category id.
Any Help will be greatly appreciated.
This is what I would do:
Have two tables. One for the email being sent and one for the emails that the newsletter is going to with what newsletter the email is receiving.
Structure examples
table newsletter :
id - Auto INC
email_subject - Subject of newsletter
email_html - HTML version of the email
email_plain_text - Plain text version of email
created_datetime - datetime newsletter was created
table newsletter_recipients:
id - Auto INC
newsletter_id - ID of what newsletter is being sent out (create a foreign key referring to the id field on the newsletter table
email - HTML version of the email
name - Name of client
sent - Whether the email was sent off or not (this isn't required, see below)
When the administrator sends the email create the newsletter row with the html/plain text version (you can use only one column, just better to have a html and plain text version of email) and also add the recipients to the newsletter_recipients table referring the newsletter_id to the id of the newsletter you added.
Now you have your PHP cron job file run every hour. This file will check if any clients need a newsletter sent out and if so send it out. Once sent out you can either delete the recipient row or mark it as sent. Personally I would delete them to keep data from backing up. Only run the php job up till 500 or whatever amount of emails you want to send out then have the script end. Next hour it will run and pick up the next 500.
With this system the newsletter wont be sent out immediately, it will be done when the cron job runs. But this is the best solution I can quickly think up for you. That or get a mail server that lets you send out all the emails you want and use something like gearman to handle load balancing.
NOTE: Storing the newsletter in a database can be handy so the admin can look back and see when they sent out their newsletter. Also you can step it up another level and create a sent_date column on the newsletter_recipient table that stores when the email was sent (if you are simply marking the recipient as sent or not instead of deleting) that way you know when the emails finished sending, who received the emails at what time, etc. This is totally up to you).

PHP / MySQL Ticket Response - Store E-mail repsonse in database?

I am building a basic support request system where the customer can log in and ask a question and an admin can go in and reply and it will set the status to "Responded" and e-mail the customer to let them know someone has responded.
My question is.. I have a "comments" section which is a log of the interaction between the admin and the customer. If I e-mail the customer the initial response from the admin, then I have a feeling they will just hit "Reply" from their email and start communicating through there, and the logs won't be stored.
I could either e-mail the customer and say "Log in to view the response", or maybe if the customer does hit reply I can somehow track it and insert that in the comments table like they did it from the website. If that is even possible?
Just wondering if there is a standard way to do this and any suggestions you may have.
Thanks!
When sending the email to the user you can have it sent from an email address created for that specific ticket. Something that can identify it with your email system to help you route it back to the php ticketing system.
support(ticketnumber)#domain
support12345#mydomain.com
Then it depends on your email server how to go from there.
There are several useful tips at this question that may help or get your started.
How to get email and their attachments from PHP
If you want their reply to be automatically inserted into the DB, you'll have a assign a cron job in your server to run a php script to detect whether there's a reply from a customer (you need a table listing the customers' email and names.
Each time a customer uses the ticket system their email and name goes into this table).
You'll need to connect to your Inbox too via imap or SMTP, and there are scripts to do this (phpmailer, swiftmailer, etc) and "walk" through each email and see if the sender email matches any in your customers table. Then so an INSERT to the comments table.
Anther way is to read through the emails each time the comments page is loaded, but this will cause the page to take longer to load. However, the data will always be more "real-time" compared to cron jobs.
You could use email piping (if your server supports it).
In the subject, you'd have a unique identifier which contains the ticket ID or something unique to the ticket. Example: "How do I eat food [Question: #1234]", where 1234 is the ticket ID.
In your control panel, you would set up an email forwarder to your email piping script.
This tutorial offers the basics to email piping, and I used it as the base for my piping script: http://www.damnsemicolon.com/php/parse-emails-in-php-with-email-piping-part-1

How can I make email transactional in PHP and MySQL?

I want to send email to my app users ensuring that every email is sent only once.
I will be recording the email transmission in a database.
If I use this order of operations:
Insert into database
Send email
Commit
There is a chance that script times out just after sending the email (step #2) and before doing the commit (step #3). In that case the change in step #1 will not be committed and email sending job won't be able to know that the email was successfully sent last time so the same email will be sent again.
Is there a way out or do I have to live with occasional duplicate emails?
To make a long story short: you can't make email transactional.
At best you know that your smtp server recieved your request to sent the message. You have however no way of knowing whether it got sent, was received or bounced.
So your best bet, as you already suggested, is to live occasional duplicate emails. It will be a very rare event anyway.
You can use MySQL transactions for this, basically it prepares all your queries and executes them when you tell it to do so.
So you prepare the queries before sending the mail, then commit it after sending it.
More info
http://dev.mysql.com/doc/refman/5.0/en/commit.html
Alternatively you could set the mail as pending, and afterwards update it as completed. Then run a cron job that kills pending jobs that have been running for a certain amount of time, or try to reprocess them.
well you can make a column status which can be enum or int with values representing sending, failed, sent_successfully
Now, you do this:
Insert the data before sending the mail. And set status to sending
Send the mail
based on the result in step (2), update the row either failed or sent_successfully.
You might also like to have a column tries and a batch process that sends failed mails at every 30 minutes, if tries < TRY_THRESHOLD. And then, set status to failed_permanently or sent_successfully and log the error.
Just got some time to think over my own question. Here is what I think now:
The email sending steps in question were:
Insert into database
Send email
Commit
Email cannot be made transactional because the step #2 (above) is not part of the transaction even though it is done while the transaction is active.
These steps can help ensure that any failed email-sending attempts is retried but cannot guarantee that an email is not sent more than once. This situation could only be improved if the email sending engine is transaction-aware. Such an engine would (atleast) do the following:
Accept email job submission but don't send the email until the commit is performed
Make the commit fail if the email is not sent.
Cancel the submitted job if the transaction is rolled-back
I am not aware of any such email server.
Nishant, in his answer suggested following steps:
Insert the data before sending the mail. And set status to sending
Send the mail
based on the result in step (2), update the row either failed or sent_successfully.
These steps also cannot ensure duplicate sending of email due to script timeout for the same reason as noted above.
So far, I think, I will just have to live with occasional duplicate emails.

Email notificiation on different actions

I'm creating email notification system on my site to send email to the users who has subscribed the article for new comments... I would like to know what is the best way to handle with this situation in php. Should I use the mail function just after the database insertion or there is some better ways. Will it slow down the process of adding new comments if there are too many subscribers?
I would create a new database table and add the subscribers that needs notifications to that table. Then run a crontab every 5 minutes that sends the emails to those whose article has been commented. That way you don't have to send it directly thus clogging the user experience with longer loading times.
You can send an email as soon as a comment is inserted into the database or when admin/mod approves from admin side if you such mechanism.
Will it slow down the process of
adding new comments if there are too
many subscribers?
It will because you will be sending the email to more and more subscribers. However, you might want to consider optimizing your insertion query as well as your code if you can.

Categories