SpamAssassin sa-learn scan emails from the database - php

I have been working on getting SpamAssassin up and running for a while now and I am pretty close to being finished. However, I need some help with this. I'm storing the source emails in a database after I have fetching the emails from imap server. I'm running the cron job in every 24 hours to monitor for spam emails in the spam folder so the Bayes database can get update.
Here is what I am using right now to run on cron job:
/usr/local/cpanel/3rdparty/bin/sa-learn -p ~/.spamassassin/user_prefs --spam ~/mail/mydomain.com/myaccount/.spam/{cur,new
As I'm using to store the emails in a database, can I be able to run PHP script on cron job to get the Bayes database update if I create a txt file to get the sa-learn to scan my emails and learn from it?
Example:
/usr/local/cpanel/3rdparty/bin/sa-learn -p ~/.spamassassin/user_prefs --spam ~/public_html/username/myfolder/update_bayes.php
update_bayes.php:
<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
require_once('../Spamassassin/Client.php');
require_once('../Spamassassin/Client/Exception.php');
require_once('../Spamassassin/Client/Result.php');
$spam_mailbox = $link->prepare("SELECT count(*) FROM `Spam` WHERE readtype = ?");
$spam_mailbox->execute([$unread]);
$row = spam_mailbox->fetch(PDO::FETCH_ASSOC);
$header = $row['header'];
$fp = fopen('/home/user/myfolder/spam.txt', 'w');
fwrite($fp, $header);
fclose($fp);
$message = #file_get_contents('spam.txt');
$params = array(
"hostname" => "localhost",
"port" => "783",
"user" => "root");
$sa = new Spamassassin\Client($params);
if ($isSpam == 'Spam') {
$sa->report($email_content);
}
else if ($isSpam == 'Not Spam') {
$sa->revoke($email_content);
}
?>
Would it work to get the Bayes database update if I run PHP script on cron job so the sa-learn could scan my emails and learn from it??
I have been told that sa-learn don't have any way to scan the database, only mail directories or mbox files. I hope he is wrong.

Related

cURL request in PHP script works via browser but not CRON

I know there's questions about this but so far none has helped me solve my problem.
I have a PHP script whose job is to send scheduled e-mails. It does this by calling a web service, which I control, via cURL.
Run in the browser, it works fine. Run via CRON, the cURL response is empty. It never reaches the web service; I know this because I had the WS write a text file when it's contacted. It does if you access via browser, not via CRON.
I know CRON runs in a different environment and I'm not relying on any environmental vars e.g. $_SERVER. The path to require() isn't the problem, either, as it's successfully getting data out of that file to connect to the DB.
This question suggested adding the following cURL opts, which I've done, but no dice:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
Here's my PHP script:
//prep
define('WS_URL', 'http://mywebservicedomain.com/index.php/web_service');
require '../application/config/database.php';
$db = new mysqli($db['default']['hostname'], $db['default']['username'], $db['default']['password'], $db['default']['database']) or die('failed to connect to DB');
//get scheduled e-mails
$res = $db->query('SELECT * FROM _cron_emails WHERE send_when < NOW()');
//process each...
while ($email_arr = $res->fetch_assoc()) {
//...get API connection info
$api_accnt = $db->query($sql = 'SELECT id, secret FROM _api_accounts WHERE project = "'.$email_arr['project'].'"');
$api_accnt = $api_accnt->fetch_assoc();
//...recreate $_POST env
$tmp = json_decode($email_arr['post_vars'], 1);
$_POST = array();
foreach($tmp as $key => $val) $_POST[$key] = !is_array($val) ? $val : implode(',', $val);
//...call API to send e-mail
$ch = curl_init($url = WS_URL.'/send_scheduled_email/'.$email_arr['email_id'].'/'.$email_arr['store_id'].'/'.$email_arr['item_id']);
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_SAFE_UPLOAD => true,
CURLOPT_SSL_VERIFYHOST => 1, //<-- tried adding this
CURLOPT_SSL_VERIFYPEER => 1, //<-- ditto
CURLOPT_POSTFIELDS => array_merge($_POST, array(
'api_key' => $api_accnt['id'],
'api_secret' => $api_accnt['secret'],
))
));
$resp = curl_exec($ch); //<-- empty when CRON
//if e-mail was sent OK, or decider script said it was ineligible, delete it from the queue
if (($resp == 'ok' || $resp == 'ineligible'))
$db->query('DELETE FROM _cron_emails WHERE id = '.$email_arr['id'].' LIMIT 1');
}
Does anyone have any idea why it fails to connect to my web service via cURL only when run in CRON?
Here's the CRON job:
/usr/bin/php /home/desyn/public_html/cron/send_scheduled_emails.php
In the end this turned out to be a very particular, and I imagine uncommon, problem. I doubt it'll prove too much help to others, but I leave it here in case.
Essentially, my server didn't like cURL'ing itself, via a domain.
The server being called by cURL in the CRON script was the same server that the CRON task was running on (but a different account and website.)
This has not proved to be a problem via a browser; only via CRON.
Changing the cURL request to use the server's local IP, rather than using the domain, solved this.

Creating cPanel email accounts with fopen

I'm using the following code to create an email account and a email forward at the same time. I'm consfused as the email forward works every time (f2) and the email creation is only working roughly half the time (f1). I'm a PHP newbie and can't understand what could cause this. Any help is appreciated!
$f = fopen ("https://$cpuser:$cppass#$cpdomain:2083/frontend/$cpskin/mail/doaddpop.html?email=$username&domain=$cpdomain&password=$password&quota=0", "r");
fclose($f);
$f2 = fopen ("https://$cpuser:$cppass#$cpdomain:2083/frontend/$cpskin/mail/doaddfwd.html?email=all&domain=$cpdomain&fwdemail=$email&fwdopt=fwd&submit=Add Forwarder", "r");
fclose($f2);
Yahoo is closing down Yahoo Mail Classic so I'm having to implement my own email. I currently use JustHost. I've made an effort to make the variables as easy to understand. If you don't understand what they mean then FIRST contact your host because (presuming you get a competent tech on the line) they'll understand what you'll need.
<?php
//exampledot.com for domain
$cpuser = 'exampled';////////////e.g. exampled, your cPanel main domain usually
$cppass = 'CPANEL-PASSWORD';/////Your cPanel password.
$cpdomain = 'exampledot.com';////The cPanel domain
$cpskin = 'justhost';////////////listed on cPanel as 'theme'
$emailname = 'john1';/////////////The username, e.g. john1#exampledot.com
$emaildomain = 'exampledot.com';////The domain name in email, #exampledot.com
$emailpass = 'EMAIL_PASSWORD';////The password for the email account
$quota = '25';///////////////////Megabytes of space, 0 for unlimited
$homepage = file_get_contents("https://$cpuser:$cppass#$cpdomain:2083/frontend/$cpskin/mail/doaddpop.html?email=$emailname&domain=$emaildomain&password=$emailpass&quota=$quota");
echo $homepage;
?>
I used just that code and then checked cPanel and the email account was created.
So your URL does work, it was just that file_get_contents function is what you want to use.
with fopen
$fopen ("http://$cp_user:$cp_pass#$cp_domain:2082/frontend/$cp_skin/mail/doaddpop.html?email=$user&domain=$e_domain&password=$e_pass"a=$e_quota", "r");
for full plugin..
1.http://tobbynews.com/create-e-mail-account-in-c-panel-using-php.html
2.http://forums.cpanel.net/f42/xmlapi-php-class-111897.html
you can ask for support in cpanel's support for assistance..

SMPP connection

I'm establishing an SMPP connection via PHP using this free library. To receive a message, I'm using the following code, given in the example:
<?php
$GLOBALS['SMPP_ROOT'] = dirname(__FILE__); // assumes this file is in the root
require_once $GLOBALS['SMPP_ROOT'].'/protocol/smppclient.class.php';
require_once $GLOBALS['SMPP_ROOT'].'/transport/tsocket.class.php';
// Construct transport and client
$transport = new TSocket('your.smsc.com',2775);
$transport->setRecvTimeout(60000); // for this example wait up to 60 seconds for data
$smpp = new SmppClient($transport);
// Activate binary hex-output of server interaction
$smpp->debug = true;
// Open the connection
$transport->open();
$smpp->bindReceiver("USERNAME","PASSWORD");
// Read SMS and output
$sms = $smpp->readSMS();
echo "SMS:\n";
var_dump($sms);
// Close connection
$smpp->close();
?>
It works perfectly well, when I run the script in the browser window and send the SMS from my phone within given 60 seconds, but I don't quite understand how to make it work for a long time. I mean, like in real-life situation, when it should run on the background and trigger some events when receiving an SMS. How do I do that? Because now, I need to refresh the page every time to get an SMS, and it only works once. Thanks in advance.
If your solution needs to run within a browser, you shouldn't connect to the SMPP server directly from your script. It would lead to a single user scenario.
You should put a endless loop around the readSMS call and make it a console application which runs as a daemon. Then you write the result of readSMS into a database and read this from your web application. With this you could use html refresh or some fancy ajax querying the database and presenting the incoming sms.
Usually SMPP receiver connections run in blocking mode on the socket (no timeout), because either you receive either a SMS, or an enquire_link (which needs to be answered by a enquire_link_resp - your library does this automatically). Whenever you read a SMS, process it (put it in the database) and call readSMS again - it will block until the next SMS comes in.
You can try this.
<?php
set_time_limit(0);
$GLOBALS['SMPP_ROOT'] = dirname(__FILE__); // assumes this file is in the root
require_once $GLOBALS['SMPP_ROOT'].'/protocol/smppclient.class.php';
require_once $GLOBALS['SMPP_ROOT'].'/transport/tsocket.class.php';
// Construct transport and client
$transport = new TSocket('your.smsc.com',2775);
$transport->setRecvTimeout(60000); // for this example wait up to 60 seconds for data
$smpp = new SmppClient($transport);
// Activate binary hex-output of server interaction
$smpp->debug = true;
// Open the connection
$transport->open();
$smpp->bindReceiver("USERNAME","PASSWORD");
while(1) {
// Read SMS and output
$sms = $smpp->readSMS();
echo "SMS:\n";
var_dump($sms);
}
// Close connection
$smpp->close();
?>
Try to use another library
composer require glushkovds/php-smpp
To receive sms:
<?php
require_once 'vendor/autoload.php';
$service = new \PhpSmpp\Service\Listener(['your.smsc.com'], 'login', 'pass');
$service->listen(function (\PhpSmpp\SMPP\Unit\Sm $sm) {
if ($sm instanceof \PhpSmpp\Pdu\DeliverSm) {
var_dump($sm->message);
}
});

Connect to port using php_serial_class every minute

If I have a script which will send sms every minute using crontab :
$sql = "SELECT * FROM table WHERE Status = '0' LIMIT 0,6";
$query = mysql_query($sql);
$serial = new Sms_Serial;
$serial->deviceSet("/dev/ttyUSB0");
$serial->confBaudRate(115200);
$serial->confParity('none');
$serial->confCharacterLength(8);
while ($row = mysql_fetch_array($query))
{
$serial->deviceOpen();
//sending....
$serial->deviceClose();
}
Which means it will detect the port and set BaudRate to send few sms every minute.Will it bring any damage to the port or modem?Some of my ports will not able to detect SIM card anymore after some days,I'm not sure whether is the modem quality problem or my script problem.
Thank you.
Have you tried checking to see what happens if it doesn't send the message? Mainly I see that the modem does not support so many traffic/connection and then there might be a bug in your code where if the message is not sent will try to send it again and so on and on instead of reporting it and "pause" the process until you see what is happening, that causes a lot of traffic and if your modem doesn't take it, it will get fried eventually .

smtp callback on new email

I have a custom app that i built which relies on a cron job to check for new email every 5 minutes. If there is a new email it then performs an action. What I would like to do is have a callback fired off when a new email arrives and then perform the action.
I could set the cron job to 1min intervals ( currently it is set to 5min ) but this seems like a waste of resources. The app is built in php and any help would be appreciated, i am just not sure what direction i should be looking at them moment.
M
You could use something like MailGun or SendGrid's Parse API which will receive your email for you and callback to an endpoint you specify.
very basic mail pipe script:
#!/usr/bin/php -q
<?php
// read from stdin
$fd = fopen("php://stdin","r");
$email = "";
while ( !feof($fd) ){
$email .= fread($fd,1024);
}
fclose($fd);
?>
what you do with $email, depends on what you need

Categories