I am running a PHP/MySQL server and am using cron jobs to periodically update my customers as well as send automated newsletters, invoices, etc. However, it does not appear to be working, as emails are not getting sent.
The cron jobs are running (checked the logs).
Invoking the script via the browser results in the emails being sent.
Using SSMTP for email transport.
SPF and DKIM records are in place and correct.
I cannot figure out what is going wrong. Here is pseudocode of the email script:
$override_authentication = true;
require_once('../services/shared/connect.php');
$query = "SELECT * FROM `organizations`";
$orgs = mysqli_query($database,$query);
while ($org = mysqli_fetch_array($orgs)) {
// GENERATE EMAIL CONTENT HERE
// Send email to all users
$query = "SELECT `id`, `email`, `avatar`, `gender`, `phone`, `option_textalerts` FROM `users` WHERE `organization` = " . $org['id'] . " AND `option_scheduling` = 'enabled'";
$users = mysqli_query($database, $query);
while($user = mysqli_fetch_array($users)) {
$message = emailGetHeader("Submit Availability for ".date('F Y', mktime(0,0,0,date('n')+1,1,date('Y'))), $user) . $body . emailGetFooter();
$to = $user['email'];
mail($to,"Submit Availability for ".date('F Y', mktime(0,0,0,date('n')+1,1,date('Y'))),$message,emailGetMeta('Leadsheet <email#leadsheet.us>', 'Leadsheet Automailer <no-reply#leadsheet.us>'));
// If enabled, sent a text alert to the phone number on their account
if ($user['option_textalerts'] == 'availability') {
$phone = preg_replace("/[^0-9]/", "", $user['phone']);
$domains = array('txt.att.net', 'myboostmobile.com', 'sms.mycricket.com', 'tmomail.net', 'vtext.com');
foreach ($domains as $domain) {
mail($phone.'#'.$domain, "Availability Reminder",'Please submit your availability for '.date('F Y', mktime(0,0,0,date('n')+1,1,date('Y'))).' on Leadsheet', emailGetMeta('Leadsheet <txt#leadsheet.us>', 'Leadsheet Automailer <no-reply#leadsheet.us>'));
}
}
}
}
mysqli_close($database);
It looks like you are missing an environment variable. look at phpinfo() and compare with your local environment. Alternatively you can just use wget to emulate a browser loading the page.
After consulting a friend, I discovered the answer. The cron engine was executing the script from the root directory, so the relative file name in the require_once wasn't resolving. Adding a cd command before executing the script solved the issue.
Related
I have a script that periodically (every ~5 minutes) requests a bunch of data from an API and possibly sends a email.
However I recently got contacted by the server administrator that there a huge amount of queued mails which will never be sent because of the Cron.
However as it stands right now it should never send the emails because it should never pass the if-statements in which the mailing code is placed.
Script more or less does the same thing twice, but with some different emails:
/* Paging - Every ~15 minutes, during non-working-times, for all dashboards that have pagerservice enabled. */
$queryPagerservice = mysqli_query($dbcon, "SELECT `id`, `text` FROM `dashboard` WHERE `pagerservice`=true AND (`last_pager` < NOW() - INTERVAL ".PAGER_INTERVAL." MINUTE OR `last_pager` IS NULL)");
$timeNow = date("Gi");
while ($pagerservice = mysqli_fetch_array($queryPagerservice, MYSQLI_ASSOC)) {
echo '1.'; //Does the script hit this code?
$issues = new Issues($pagerservice['id'], 'all', $dbcon);
$array = $issues->getIssues();
if ((count($array['aaData']) > 0) && ($timeNow > WORK_START && $timeNow < WORK_END)) {
mysqli_query($dbcon, "UPDATE `dashboard` SET `last_pager`=NOW() WHERE `id`='".$pagerservice['id']."'");
$date = date('d-m-Y H:i:s');
$message = "There are ".count($array['aaData'])." problems in '".$pagerservice['text']."'.";
echo '2.'; //Does the script hit this code?
require_once('phpmailer/PHPMailerAutoload.php');
$pagerMail = new PHPMailer;
$pagerMail->isSMTP();
$pagerMail->Host = MAILSERVER_ADDRESS;
$pagerMail->Port = MAILSERVER_PORT;
$pagerMail->setFrom('pagerservice#example.com', 'EXAMPLE Pager');
$pagerMail->addReplyTo('noreply#example.com', 'No Reply');
$pagerMail->addAddress(PAGE_EMAIL, 'pagerservice');
$pagerMail->addAddress(PAGER_PHONE.'#'.PAGER_PROVIDER, 'pagerservice');
$pagerMail->Subject = 'pagerservice';
$pagerMail->Body = $message;
$pagerMail->AltBody = $message;
$pagerMail->send();
}
}
/* Notifications - Every ~15 minutes, during working hours, for all dashboards that have notifications enabled. */
$queryNotification = mysqli_query($dbcon, "SELECT `id`, `text` FROM `dashboard` WHERE `notification`=true AND (`last_notification` < NOW() - INTERVAL ".NOTIF_INTERVAL." MINUTE OR `last_notification` IS NULL)");
$timeNow = date("Gi");
while ($notifications = mysqli_fetch_array($queryNotification, MYSQLI_ASSOC)) {
echo '3.'; //Does the script hit this code?
$issues = new Issues($notifications['id'], 'all', $dbcon);
$array = $issues->getIssues();
if ((count($array['aaData']) > 0) && ($timeNow > WORK_START && $timeNow < WORK_END)) {
mysqli_query($dbcon, "UPDATE `dashboard` SET `last_notification`=NOW() WHERE `id`='".$notifications['id']."'");
$date = date('d-m-Y H:i:s');
$message = "(Notif) There are ".count($array['aaData'])." problems in '".$pagerservice['text']."'.";
echo '4.'; //Does the script hit this code?
require_once('phpmailer/PHPMailerAutoload.php');
$notifMail = new PHPMailer;
$notifMail->isSMTP();
$notifMail->Host = MAILSERVER_ADDRESS;
$notifMail->Port = MAILSERVER_PORT;
$notifMail->setFrom('notifications#example.com', 'EXMAPLE Notificator');
$notifMail->addReplyTo('noreply#example.com', 'No Reply');
$notifMail->addAddress(NOTIF_EMAIL, 'notifications');
$notifMail->Subject = 'notification';
$notifMail->Body = $message;
$notifMail->AltBody = $message;
$notifMail->send();
}
}
Attempted fix: I moved the require_once() call to within the if-statement. This didn't fix it.
There is no other code in the script that is in any way related to sending email's. And the code that is e-mail related isn't executed (as shown by the fact that neither 1., 2., 3. nor 1. is echoed).
I am looking for any tips as to what can cause the cron script to queue an email that is never sent by the SMTP server.
Cron jobs have no user interface, so if the script outputs anything to the stderror or stdoutput it will cause the cron system to generate an email, to contain that output. This is how you would know your cron is having problems, or how you monitor things like "I did 10 things this run" type of stuff.
It looks to me as if your script has some kind of output either reporting errors or doing your echo '1.' debugging code or something similiar.
First I would check all the code you say it is running for anything like echo or print etc etc, anything that would normally write info to the terminal, and remove/rethink it.
Then change the cron's config to send these emails to a valid email address that you actually monitor, so you know when your script is trying to tell you something.
I have issue with email in my table when I try to send mails for birthdays..
Here is the printscreen, if you see the table in the right, there are 2 users with birthdays but in the input below of div error is empty... and say "there is not birthday for today":
<?php
$sql = $conn->prepare("SELECT email FROM USERS WHERE f_nac >= CURDATE() AND f_nac < CURDATE() + INTERVAL 1 DAY ORDER BY f_nac ASC");
$sql->execute();
while($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$email = ($row['email'].", ");
}
$largo=strlen($email);
if ($largo>2)
$email=substr($email,0,$largo-2);
} else {
echo '<div class="alert alert-danger">No hay cumpleaƱeros!</div>';
};
?>
<input type="text" id="email" name="email" value="<?php echo $email; ?>" />
How can I show the emails to send the mail to them?
the two users have emails and the row in the table is "f_nac" with type "date"
CUR_DATE() is in 2014, the birthdays are in 1975 and 1978. You have to ignore the year when you're comparing.
SELECT email
FROM USERS
WHERE MONTH(f_nac) = MONTH(NOW()) AND DAY(f_nac) = DAY(NOW())
In your while loop you're overwriting $email, not appending to it. It should be:
$email = '';
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$email .= ($row['email'].", ");
}
What you are doing currently is extracting the data from SQL (daily) and composing and email to send the wish manually daily. What if I suggest you a better approach ?
There is an application called Wishing Application which can send birthday and work anniversary mailer with a breeze.
At minimal it just need two things excel file with wish details (Date, name, email) and a configuration file (application.properties) and that is it, you are good to go.
Further there various options to run the application locally (Command line, foreground, background, docker, windows scheduler, unix cron etc) Cloud.
Application is highly configurable , you can configure various details like:
Workbook loading options
Image options to send with wishes.
SMTP Configurations
Other application level configurations like, when to send wish, belated wish, logging etc.
Disclaimer : I am the owner of the application
So, Writing this script, and now I do get the correct email, with the old IP address from the database, and the new address from the script. My problem now, is that wether the old ip address and the current are the same or different, the email sends. This script will run every minute to check for dynamic ip address changes, so I don't really want an email every minute. My goal is to have it send the email ONLY if the last posted IP is DIFFERENT from the one discovered. Now, the email is sending wether the IPs are different or not. Everything else works. The email sends fine, and everything else works perfectly. The only problem is using logic to decide when to send the email. (When the new and old IPs are different.)
When the script gets there ip from the database, it looks like 123.123.123.123. The IP from the http://www.ipaddresscheck.comlu.com/ip.php also looks like 123.123.123.123. (***Example) But if the database says 123.123.123.123, and the current is 134.134.134.134, it should send the email.
In the comparison, I've tried !=, ==, and I've tried putting the mail block in the then and else sections. Could the problem be caused by different data types? Is the $new_ip a string while $old_ip is an integer? Im only 14, so... Yea.
<?php
//Get IP
$new_ip = file_get_contents('http://www.ipaddresscheck.comlu.com/ip.php');
//Connect to SQL
mysql_connect('localhost','root','root');
//Select database
mysql_select_db("ip_changes") or die(mysql_error());
//Get Date Info
$date = date("D M Y");
$time = date("H:i:s");
//Get last inserted IP
$sql = mysql_query('SELECT * FROM ip ORDER BY id DESC LIMIT 1');
$row = mysql_fetch_array( $sql );
$old_ip = $row['current_ip'];
echo $old_ip;
//Generate SQL query
$sql="INSERT INTO ip (date, time, current_ip) VALUES ('$date', '$time', '$new_ip')";
//Execute SQL
mysql_query($sql);
//Get latest IP
//$lastip = mysql_query(SELECT $selected FROM ip ORDER BY id DESC LIMIT 1);
if ($old_ip == $current_ip)
{
}
else {
//Set Mail Settings
$to = "justinmarmorato#gmail.com";
$subject = "IP Address Change";
$from = "no-reply#http://mar-remote-net.dns2.us";
$headers = array (
"From:" . $from,
"Content-Type: Text/HTML"
);
//Create email
$finalmessage = <<< EOT
Hello! This is an automated message from the IPMS. An IP address change has been detected.
<html>
<style>
table, th, td
{
border: 2px solid black;
border-color:grey;
}
</style>
<table class='table'>
<tr>
<td>Old IP</td><td>New IP</td><td>Time Detected</td>
</tr>
<tr>
<td>$old_ip</td><td>$new_ip</td><td>$date $time</td>
</tr>
</table>
</html>
EOT;
mail($to,$subject,$finalmessage, implode("\r\n", $headers));
mail('justinmarmorato#gmail.com', 'Hello!', implode("\r\n", $headers));
}
?>
Did you mean to say $new_ip instead of $current_ip in your if statement?
$current_ip doesn't appear to be set anywhere -- if that is the case $current_ip will always be unset and will never be equal to $old_ip.
I just made a php script that will send email reminders to admins of a website 2 days before an appointment begins. I was going to automate the script to run through a cron job, only to realise who I am hosting with (crazy domains) does NOT appear to have Cron Jobs
Is there ANY way of doing this without cron-jobs? I do not mind going to a different service provider if that is the case; I have done quite a bit of searching around, and my understanding so far is that I need Cron Jobs for these types of things?
Here is the script I did so far:
<?php include "../connect-to-database.php"; ?>
<?php
$date = date("Y-m-d");
$mod_date = strtotime($date."+ 2days");
$newDate = date("m/d/Y",$mod_date);
$sqlCommand = "SELECT * FROM eventcalender WHERE eventDate='$newDate'" ;
$query = mysql_query($sqlCommand) or die(mysql_error());
$count = mysql_num_rows($query);
if ($count >= 1){
while($row = mysql_fetch_array($query)){
$ID = $row["ID"];
$schedule_title = $row["Title"];
$schedule_description = $row["Detail"];
$importance_level = $row["importance_level"];
$meeting_datetime = $row["eventDate"];
$contacts_involved = $row["contacts_involved"];
$meeting_occurred = $row["meeting_occurred"];
$mid = mysql_insert_id();
$search_output .= "<ul>
<li>
<h4>".$schedule_title."</h4>
<p><b>Time: ".$meeting_datetime."</b></p>
<p>People/Persons involved: ".$contacts_involved."</p>
<p>Meeting Occurred?: ".$meeting_occurred."</p>
<a href='uniqueMeeting.php?ID=".$ID."'>View more details of this meeting</a>
<p><a href='editschedulePage.php?mid=$ID'>Edit This Meeting</a></p>
<p><a href='scheduleList.php?deleteid=$ID'>Delete this meeting</a></p>
</li><br/>
</ul>";
$sendMail = true;
}
}
if($sendMail){
$admin = "SELECT * FROM admin" ;
$queryAdmin = mysql_query($admin) or die(mysql_error());
$adminCount = mysql_num_rows($queryAdmin);
$recipients = array();
if ($count >= 1){
while($row = mysql_fetch_array($queryAdmin)){
$subject ='A-CRM; UpComing Activities';
$msg = $search_output;
$to = $row['email_address'];
mail($to, $subject, $msg);
}
}
}
?>
Yes I do realise I am an absolute horrible person for NOT using mysqli, and I will start to as soon as I finish this website
If the site you're building is visited frequently, you can keep a timestamp (or datetime or whatever) in your database holding the next time the script has to run. Then include the script in your website (every page or just a selection them).
If the current time is equal or greater than the time in the database, run the script and set the time in the database to the value the script has to run next. In this way, the script will be executed by one of the visitors of the site, without them knowing.
Replace
php include "../connect-to-database.php";
with
php include dirname(__DIR__) . "/connect-to-database.php";
Try to add some Observer which will check whether there is a need to send mails.
For example - add into your init file (maybe index.php)
<?php include DIR ."send_mail.php" ?> // your file that you describe in the question.
It will add an additional query to DB since the check will be executed every time the user comes on the page.
I hope it will help you to resolve your issue.
Very simply and effective way using crons. The crons are very simple you will set up date and time cron automatically runs your file. This is guide to using crontab: http://www.adminschoice.com/crontab-quick-reference/
The following script was supposed to send email if all conditions are met and echo "success". The problem here is it is returning "success" but email is not being sent. I tried my best to figure out the problem but can't figure out as I am new to PHP. So I am looking for any possible help. Any help will be appreciated. Thank you in advance
$sql = "SELECT id, username FROM user WHERE email='$e' AND activated='1' LIMIT 1";
$query = mysqli_query($db_conx, $sql);
$numrows = mysqli_num_rows($query);
if($numrows > 0){
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){
$id = $row["id"];
$u = $row["username"];
$emailcut = substr($e, 0, 4);
$randNum = rand(10000,99999);
$tempPass = "$emailcut$randNum";
$hashTempPass = md5($tempPass);
$sql = "UPDATE useroptions SET temp_pass='$hashTempPass' WHERE username='$u' LIMIT 1";
$query = mysqli_query($db_conx, $sql);
$to = "$e";
$from = "auto_responder#geniusfree.net";
$headers ="From: $from\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-type: text/html; charset=iso-8859-1 \n";
$subject ="GeniusFree Password Reset";
$msg = '<h2>Hello '.$u.'</h2><p>This is an automated message from GeniusFree. If you did not recently initiate the Forgot Password process, please disregard this email.</p><p>You indicated that you forgot your login password. We can generate a temporary password for you to log in with, then once logged in you can change your password to anything you like.</p><br /><p>Click here now to apply the temporary password shown below to your account</p><p>If you do not click the link in this email, no changes will be made to your account. In order to set your login password to the temporary password you must click the link above.</p>';
if(mail($to,$subject,$msg,$headers)) {
echo "success";
exit();
} else {
echo "email_send_failed";
exit();
}}
Check the MX entry settings. Highest priority is 0. If you are using your mail server in your host. The first entry should be something like this priority number 0 ---> mail.yoursite.com.
Another way to debug this is to use email trace route. You can do it in cpanel.
Hope this helps.
First you need to configure php to send emails from your server ,if you are running code on your local host machine then you have to configure your php.ini file for sending emails and if code is running on web hosting server then contact them for this issue ,
for configuration details you can refer send mail using xampp in php
if you are using another local server like wamp then you have to separately (download) install sendmail utility on your server.
Hope this works for you
do you run it on the local host? if so , it may does not work there , please test it on the Web Host and let me know the result.