added email bounces processing, fixes #44
This commit is contained in:
parent
4aa530b274
commit
a0172b1e10
@ -173,4 +173,12 @@
|
||||
sql("ALTER TABLE `cache_reports` ADD INDEX `userid` (`userid`)");
|
||||
}
|
||||
|
||||
function dbv_108() // automatic email-bounce processiong
|
||||
{
|
||||
if (!sql_field_exists('user','last_email_problem'))
|
||||
sql("ALTER TABLE `user` ADD COLUMN `last_email_problem` datetime default NULL AFTER `email_problems`");
|
||||
if (!sql_field_exists('user','mailing_problems'))
|
||||
sql("ALTER TABLE `user` ADD COLUMN `mailing_problems` int(10) unsigned NOT NULL default '0' AFTER `last_email_problem`");
|
||||
}
|
||||
|
||||
?>
|
@ -111,6 +111,14 @@
|
||||
// date format
|
||||
$opt['db']['dateformat'] = 'Y-m-d H:i:s';
|
||||
|
||||
// email delivery processing from syslog-ng eventlog DB
|
||||
$opt['system']['maillog']['syslog_db_host'] = '';
|
||||
$opt['system']['maillog']['syslog_db_name'] = '';
|
||||
$opt['system']['maillog']['syslog_db_user'] = '';
|
||||
$opt['system']['maillog']['syslog_db_password'] = '';
|
||||
$opt['system']['maillog']['syslog_oc_host'] = ''; // 'host_name' column in syslog DB
|
||||
$opt['system']['maillog']['syslog_mta'] = 'postfix/smtp'; // 'program' column in syslog DB
|
||||
|
||||
/* cookie or session
|
||||
*
|
||||
* SAVE_COOKIE = only use cookies
|
||||
|
@ -2488,6 +2488,7 @@ INSERT INTO `sys_trans` (`id`, `text`, `last_modified`) VALUES ('2066', 'Open ch
|
||||
INSERT INTO `sys_trans` (`id`, `text`, `last_modified`) VALUES ('2067', 'Status', '2013-05-28 16:51:40');
|
||||
INSERT INTO `sys_trans` (`id`, `text`, `last_modified`) VALUES ('2068', 'since June 2013', '2013-05-28 16:51:40');
|
||||
INSERT INTO `sys_trans` (`id`, `text`, `last_modified`) VALUES ('2069', 'since February 2012', '2013-05-28 16:51:40');
|
||||
INSERT INTO `sys_trans` (`id`, `text`, `last_modified`) VALUES ('2070', 'One ore more emails to this user could not be delivered. It might be a good idea to additionally log comments on the user\'s geocaches, and/or trying to contact him/her through other channels like a message board account or another geocaching platform.', '2013-05-28 16:51:40');
|
||||
|
||||
-- Table sys_trans_ref
|
||||
SET NAMES 'utf8';
|
||||
@ -6428,6 +6429,7 @@ INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUE
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2067', 'DE', 'Status', '2013-04-25 23:00:00');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2068', 'DE', 'seit Juni 2013', '2013-04-25 23:00:00');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2069', 'DE', 'seit Februar 2012', '2013-04-25 23:00:00');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2070', 'DE', 'Eine oder mehrere Emails an diesen Benutzer konnten nicht zugestellt werden. Es könnte ratsam sein, Hinweise zu seinen Caches zusätzlich zu loggen, und ihn ggf. über weitere Adressen wie z.B. Forenaccounts oder andere Geocaching-Plattformen zu kontaktieren.', '2013-04-25 23:00:00');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('1', 'EN', 'Reorder IDs \r', '2010-09-02 00:15:30');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2', 'EN', 'The database could not be reconnected.', '2010-08-28 11:48:07');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('3', 'EN', 'Testing – please do not login', '2010-08-28 11:48:07');
|
||||
@ -7988,6 +7990,7 @@ INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUE
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2067', 'EN', 'Status', '2013-04-25 23:00:00');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2068', 'EN', 'since June 2013', '2013-04-25 23:00:00');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2069', 'EN', 'since February 2012', '2013-04-25 23:00:00');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2070', 'EN', 'One ore more emails to this user could not be delivered. It might be a good idea to additionally log comments on the user\'s geocaches, and/or trying to contact him/her through other channels like a message board account or another geocaching platform.', '2013-04-25 23:00:00');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('1', 'ES', 'Reordenar ID', '2010-12-09 00:17:55');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('2', 'ES', 'La base de datos no se pudo conectar.', '2010-12-09 00:17:55');
|
||||
INSERT INTO `sys_trans_text` (`trans_id`, `lang`, `text`, `last_modified`) VALUES ('3', 'ES', 'En pruebas - por favor, no entre.', '2010-12-09 00:17:55');
|
||||
|
@ -522,7 +522,13 @@
|
||||
INSERT IGNORE INTO `notify_waiting` (`id`, `cache_id`, `user_id`, `type`)
|
||||
SELECT NULL, nCacheId, `user`.`user_id`, 1 /* notify_new_cache */
|
||||
FROM `user`
|
||||
WHERE NOT ISNULL(`user`.`latitude`)
|
||||
/* After reaching the 5-bounces limit, we try to send new cache notifications
|
||||
in larger intervals for some more time, and at least on per year.
|
||||
See also runwatch.php. */
|
||||
WHERE (`email_problems` < 5
|
||||
OR (`email_problems` < 10 AND NOW() > IFNULL(`last_email_problem`,'2013-03-01') + INTERVAL 30 DAY)
|
||||
OR NOW() > IFNULL(`last_email_problem`,'2013-03-01') + INTERVAL 365 DAY)
|
||||
AND NOT ISNULL(`user`.`latitude`)
|
||||
AND NOT ISNULL(`user`.`longitude`)
|
||||
AND `user`.`notify_radius`>0
|
||||
AND (acos(cos((90-nLatitude) * 3.14159 / 180) * cos((90-`user`.`latitude`) * 3.14159 / 180) + sin((90-nLatitude) * 3.14159 / 180) * sin((90-`user`.`latitude`) * 3.14159 / 180) * cos((nLongitude-`user`.`longitude`) * 3.14159 / 180)) * 6370) <= `user`.`notify_radius`;
|
||||
|
@ -11,6 +11,8 @@ CREATE TABLE `user` (
|
||||
`password` varchar(32) default NULL,
|
||||
`email` varchar(60) default NULL,
|
||||
`email_problems` int(10) NOT NULL default '0',
|
||||
`last_email_problem` datetime default NULL,
|
||||
`mailing_problems` int(10) unsigned NOT NULL default '0',
|
||||
`latitude` double NOT NULL,
|
||||
`longitude` double NOT NULL,
|
||||
`is_active_flag` tinyint(1) NOT NULL,
|
||||
|
@ -51,6 +51,8 @@ class user
|
||||
$this->reUser->addString('password', null, true);
|
||||
$this->reUser->addString('email', null, true);
|
||||
$this->reUser->addString('email_problems', 0, false);
|
||||
$this->reUser->addDate('last_email_problem', null, true);
|
||||
$this->reUser->addInt('mailing_problems', 0, false);
|
||||
$this->reUser->addFloat('latitude', 0, false);
|
||||
$this->reUser->addFloat('longitude', 0, false);
|
||||
$this->reUser->addDate('last_modified', time(), true, RE_INSERT_IGNORE);
|
||||
@ -1173,16 +1175,20 @@ class user
|
||||
// email bounce processing
|
||||
function addEmailProblem($licensemail=false)
|
||||
{
|
||||
// mailing_problems is a bit-flag field to remember nondelivered, important mailings
|
||||
if ($licensemail)
|
||||
return $this->reUser->setValue('email_problems', 1000001) && $this->save();
|
||||
else
|
||||
return $this->reUser->setValue('email_problems', $this->getEmailProblems() + 1) && $this->save();
|
||||
if (!$this->reUser->setValue('mailing_problems', $this->reUser->getValue('mailing_problems') | 1))
|
||||
return false;
|
||||
|
||||
return $this->reUser->setValue('email_problems', $this->getEmailProblems() + 1) &&
|
||||
$this->reUser->setValue('last_email_problem', date('Y-m-d H:i:s')) &&
|
||||
$this->save();
|
||||
}
|
||||
|
||||
function getEmailProblems()
|
||||
{
|
||||
// see also common.inc.php "SELECT `email_problems`"
|
||||
return $this->reUser->getValue('email_problems') % 1000000;
|
||||
return $this->reUser->getValue('email_problems');
|
||||
}
|
||||
|
||||
function getDataLicense()
|
||||
@ -1198,7 +1204,7 @@ class user
|
||||
|
||||
function missedDataLicenseMail()
|
||||
{
|
||||
return $this->reUser->getValue('email_problems') > 1000000;
|
||||
return $this->reUser->getValue('mailing_problems') & 1;
|
||||
}
|
||||
|
||||
function confirmEmailAddress()
|
||||
|
@ -56,6 +56,7 @@
|
||||
$tpl->assign('subject', $subject);
|
||||
$tpl->assign('text', $text);
|
||||
$tpl->assign('emailaddress', $bEmailaddress);
|
||||
$tpl->assign('email_problems', $user->getEmailProblems());
|
||||
|
||||
$tpl->assign('userid', $user->getUserId());
|
||||
$tpl->assign('username', $user->getUsername());
|
||||
|
@ -10,7 +10,7 @@
|
||||
{if $success==true}
|
||||
<div class="content2-pagetitle">
|
||||
<img src="resource2/{$opt.template.style}/images/misc/22x22-email.png" style="align: left; margin-right: 10px;" width="32" height="32" alt="" />
|
||||
<b>{t 1=$smarty.capture.userlink}E-Mail to %1 was sent{/t}</b>
|
||||
{t 1=$smarty.capture.userlink}E-Mail to %1 was sent{/t}
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
@ -33,10 +33,18 @@
|
||||
<input type="hidden" name="userid" value="{$userid}"/>
|
||||
<div class="content2-pagetitle">
|
||||
<img src="resource2/{$opt.template.style}/images/misc/22x22-email.png" style="align: left; margin-right: 10px;" width="32" height="32" alt="" />
|
||||
<b>{t 1=$smarty.capture.userlink}Send E-Mail to %1{/t}</b>
|
||||
{t 1=$smarty.capture.userlink}Send E-Mail to %1{/t}
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
{if $email_problems > 0}
|
||||
<tr>
|
||||
<td colspan="2" class="errormsg">
|
||||
<p>{t}One ore more emails to this user could not be delivered. It might be a good idea to additionally log comments on the user's geocaches, and/or trying to contact him/her through other channels like a message board account or another geocaching platform.{/t}</p>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
|
||||
<tr>
|
||||
<td colspan="2">{t}Subject:{/t} <input type="text" name="subject" value="{$subject|escape}" class="input400"></td>
|
||||
</tr>
|
||||
|
@ -60,6 +60,7 @@
|
||||
// Benachrichtigung speichern
|
||||
sql("INSERT IGNORE INTO `watches_notified` (`user_id`, `object_id`, `object_type`, `date_created`) VALUES ('&1', '&2', 1, NOW())", $rNewLog['user_id'], $rNewLog['log_id']);
|
||||
|
||||
// Owner notifications are always sent, independent of user.email_problems counter.
|
||||
process_owner_log($rNewLog['user_id'], $rNewLog['log_id']);
|
||||
}
|
||||
mysql_free_result($rsNotified);
|
||||
@ -77,7 +78,11 @@
|
||||
{
|
||||
// Benachrichtigung speichern
|
||||
sql("INSERT IGNORE INTO `watches_notified` (`user_id`, `object_id`, `object_type`, `date_created`) VALUES ('&1', '&2', 1, NOW())", $rcw['user_id'], $rcw['log_id']);
|
||||
process_log_watch($rcw['user_id'], $rcw['log_id']);
|
||||
|
||||
// Watch notifications are discarded if the user had some undeliverable emails.
|
||||
// See also stored procedure sp_notify_new_cache().
|
||||
if (sqlValue("SELECT `email_problems` FROM `user` WHERE `user_id`='" . sql_escape($rcw['user_id']) . "'", 0) < 5)
|
||||
process_log_watch($rcw['user_id'], $rcw['log_id']);
|
||||
|
||||
sql("DELETE FROM `watches_logqueue` WHERE `log_id`='&1' AND `user_id`='&2'", $rcw['log_id'], $rcw['user_id']);
|
||||
}
|
||||
|
105
htdocs/util2/cron/modules/maillog.class.php
Normal file
105
htdocs/util2/cron/modules/maillog.class.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/***************************************************************************
|
||||
* For license information see doc/license.txt
|
||||
*
|
||||
* Unicode Reminder メモ
|
||||
*
|
||||
* Process system maillog to detect email delivery problems
|
||||
***************************************************************************/
|
||||
|
||||
checkJob(new maillog());
|
||||
|
||||
|
||||
class maillog
|
||||
{
|
||||
var $name = 'maillog';
|
||||
var $interval = 600; // every 10 minutes
|
||||
|
||||
|
||||
function run()
|
||||
{
|
||||
global $opt;
|
||||
if ($opt['system']['maillog']['syslog_db_host'] != '')
|
||||
if ($opt['system']['maillog']['syslog_mta'] != 'postfix/smtp')
|
||||
{
|
||||
echo $this->name.": unknown MTA '".$opt['system']['maillog']['syslog_mta']."'\n";
|
||||
return;
|
||||
}
|
||||
else
|
||||
$this->process_syslog();
|
||||
}
|
||||
|
||||
|
||||
function process_syslog()
|
||||
{
|
||||
global $opt;
|
||||
|
||||
$dbc = @mysql_connect($opt['system']['maillog']['syslog_db_host'],
|
||||
$opt['system']['maillog']['syslog_db_user'],
|
||||
$opt['system']['maillog']['syslog_db_password']);
|
||||
if ($dbc === FALSE)
|
||||
{
|
||||
echo $this->name.": could not connect to syslog database\n";
|
||||
return;
|
||||
}
|
||||
if (@mysql_query("USE ".$opt['system']['maillog']['syslog_db_name']) === FALSE)
|
||||
{
|
||||
echo $this->name.": could not open syslog database: ".mysql_error()."\n";
|
||||
return;
|
||||
}
|
||||
|
||||
$last_id = sql_value("SELECT `value` FROM `sysconfig` WHERE `name`='syslog_maillog_lastid'", 0);
|
||||
$last_date = sql_value("SELECT `value` FROM `sysconfig` WHERE `name`='syslog_maillog_lastdate'", "");
|
||||
|
||||
// We check for both, new IDs and new creation dates, so that it still works
|
||||
// if the syslog DB is re-setup and IDs restarted from 1 (dates are not unique).
|
||||
$rs = @mysql_query(
|
||||
"SELECT `id`, `message`, `created`
|
||||
FROM `event`
|
||||
WHERE (`id`>'" . mysql_real_escape_string($last_id) . "' OR `created`>'" . mysql_real_escape_string($last_date) . "')
|
||||
AND `host_name`='" . mysql_real_escape_string($opt['system']['maillog']['syslog_oc_host']) . "'
|
||||
AND `program`='" . mysql_real_escape_string($opt['system']['maillog']['syslog_mta']) . "'
|
||||
ORDER BY `id`");
|
||||
if ($rs === FALSE)
|
||||
{
|
||||
echo $this->name.": syslog query error (".mysql_errno()."): ".mysql_error()."\n";
|
||||
return;
|
||||
}
|
||||
|
||||
while ($logentry = mysql_fetch_assoc($rs))
|
||||
{
|
||||
$message = $logentry['message']; // latin-1 charset
|
||||
$delivered = strpos($message, 'status=sent') > 0;
|
||||
$bounced = strpos($message, 'status=bounced') > 0;
|
||||
if ($delivered || $bounced)
|
||||
{
|
||||
if (preg_match('/ to=<(.+)>,/U',$message,$matches))
|
||||
{
|
||||
$emailadr = $matches[1];
|
||||
if ($delivered)
|
||||
sql("UPDATE `user` SET `email_problems`=0
|
||||
WHERE `email`='" . mysql_real_escape_string($emailadr) . "'");
|
||||
else if ($bounced)
|
||||
// maximum one bounce per day is counted, to filter out temporary problems
|
||||
sql("UPDATE `user` SET `email_problems`=`email_problems`+1, `last_email_problem`='" . mysql_real_escape_string($logentry['created']) . "'
|
||||
WHERE `email`='" . mysql_real_escape_string($emailadr) . "'
|
||||
AND IFNULL(`last_email_problem`,'') < '" . mysql_real_escape_string(substr($logentry['created'],0,10)) . "'");
|
||||
}
|
||||
else
|
||||
echo $this->name.": no email address found for record ID ".$logentry['id']."\n";
|
||||
}
|
||||
$last_id = $logentry['id'];
|
||||
$last_date = $logentry['created'];
|
||||
}
|
||||
mysql_free_result($rs);
|
||||
|
||||
sql("INSERT INTO `sysconfig` (`name`, `value`) VALUES ('syslog_maillog_lastid','&1')
|
||||
ON DUPLICATE KEY UPDATE `value`='&1'",
|
||||
$last_id);
|
||||
sql("INSERT INTO `sysconfig` (`name`, `value`) VALUES ('syslog_maillog_lastdate','&1')
|
||||
ON DUPLICATE KEY UPDATE `value`='&1'",
|
||||
$last_date);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user