Error when Sending Mail with Attachments Using PEAR - php

My page continues to error out (Error 324 - Chrome) when attempting to send e-mails with attachments using PHP's PEAR Mail extension. Although the page error's out - I do receive one of the approximately 800 e-mails. Here's what I'm working with:
function email_statements($type) {
switch($type) {
// Determine the type of statement to be e-mailed
case 'monthly':
// Array holding all unique AP e-mail addresses
$ap_email_addresses = array();
include('../path/to/db/connection/params.php');
// Grab the unique AP e-mail address set to receive statements
$stmt = $mysqli->prepare("SELECT email FROM statements GROUP BY email ORDER BY email ASC");
$stmt->execute();
$stmt->bind_result($ap_email_address);
// Add unique e-mail address to AP E-mail Addresses array
while($row = $stmt->fetch()) $ap_email_addresses[] = $ap_email_address;
$stmt->close();
$mysqli->close();
// Verify we grabbed the e-mail addresses
if(count($ap_email_addresses) == 0) {
// Exit and return error code if unable to grab e-mail addresses
$return_message = 1;
exit;
}
// E-mail addresses grabbed - proceed
else {
// PDF formatted date
date_default_timezone_set('America/New_York');
$formatted_date = date('m_d_Y');
// Now we have the unique e-mail addresses - associate those with the account numbers
include('../path/to/db/connection/params.php');
foreach($ap_email_addresses as $email_address) {
$file_names = array();
$stmt = $mysqli->prepare("SELECT customer_number FROM statements WHERE email = ?");
$stmt->bind_param("s", $email_address);
$stmt->execute();
$stmt->bind_result($ap_account_number);
// Constructs the name of the statement (PDF) file to be sent
while($output = $stmt->fetch()) $file_names[] = $ap_account_number . '_' . $formatted_date . '.pdf';
// Send e-mails
include('Mail.php');
include('Mail/mime.php');
// Include SMTP authentication parameters
include('../path/to/email/info.php');
// Set the e-mail recipients
$recipients = 'example#example.com';
// Set the e-mail subject
$subject = 'Monthly Account Statement';
// Create the e-mail body
$html =
'<html>
<body>
<p>Test E-mail</p>
</body>
</html>';
// Construct the message headers
$headers = array(
'From' => $from,
'Subject' => $subject,
'Content-Type' => 'text/html; charset=UTF-8',
'MIME-Version' => '1.0'
);
$mimeparams = array();
$mimeparams['text_encoding'] = '8bit';
$mimeparams['text_charset'] = 'UTF-8';
$mimeparams['html_charset'] = 'UTF-8';
$mimeparams['head_charset'] = 'UTF-8';
// Create a new instance
$mime = new Mail_mime();
// Specify the e-mail body
$mime->setHTMLBody($html);
// Attach the statements (PDF)
foreach($file_names as $attached_file) {
$file = '../path/to/the/pdf/file/' . $attached_file;
$file_name = $attached_file;
$content_type = "Application/pdf";
$mime->addAttachment ($file, $content_type, $file_name, 1);
}
// Create the body
$body = $mime->get($mimeparams);
// Add the headers
$headers = $mime->headers($headers);
// Create SMTP connect array to be passed
$smtp = Mail::factory('smtp', array ('host' => $host, 'port' => $port, 'auth' => true, 'username' => $username, 'password' => $password));
// Send the message
$mail = $smtp->send($recipients, $headers, $body);
if(PEAR::isError($mail)) echo 'Error';
else echo 'Sent';
// Close this account and cycle through the rest
$stmt->close();
}
$mysqli->close();
}
break;
}
}
Now I thought maybe I wasn't giving the script enough time to execute - so I set it ridiculously high set_time_limit(99999999) to ensure it had plenty of time, although it normally times out within 10-15 seconds. So basically it works like this, I have an internal DB that stores customer account numbers and e-mail addresses. Accounts can have the same e-mail address (It's sent to their company's AP department) - aka one e-mail address receives statements for multiple branches. From their each statement is already constructed with the format being ACCOUNTNUMBER_MM_DD_YYYY.pdf.
So I'm simply trying to have a short message in the body, and attach the monthly statements. Again, not sure why it's failing, and even though the script halts, I do receive ONE of the e-mails (I'm sending them all to myself at the moment just to test). Can anyone see where I may have an issue?

I discovered the issue. As of PHP 5.0+ you cannot have multiple instances of the same include file - aka Mail.php was included as it looped. Once it was moved outside of the loop, the issue was resolved.

Related

how to handle twilio error status when sending whatsapp message

when I try to send a whatsapp message to a mobile number that isn't registered on whatsapp, how do I know that it failed? because I want to send the message using regular SMS instead. but my code below doesn't give any different result between success and failed process:
public function sendMessage($to, $msg, $params=[])
{
$client = new Client($this->sid, $this->token);
$from = $this->from_number; // my twilio number e.g. +1786xxxx
if ( ! empty($params['via']) && $params['via'] == 'whatsapp') {
$to = 'whatsapp:'.$to;
$from = 'whatsapp:'.$from;
}
$options = [
// A Twilio phone number you purchased at twilio.com/console
'from' => $from,
// the body of the text message you'd like to send
'body' => $msg,
];
// Use the client to do fun stuff like send text messages!
$response = $client->messages->create(
$to,
$options,
);
return $response;
}
// end public function sendMessage
public function do_send_msg()
{
$to = '+628123456789';
// this message already uses the same format as the approved message template
$msg = "Your otp code for Login Process is 123456";
$params = [
'via' => 'whatsapp',
];
$send = $this->twilio->sendMessage('+628123456789', $msg, $params);
var_dump($send->status);
}
I wanted to make the code like this instead but this code is unable to differentiate the value of $send->status whether it's successful or failed:
public function do_send_msg()
{
$to = '+628123456789';
// this message already uses the same format as the approved message template
$msg = "Your otp code for Login Process is 123456";
$params = [
'via' => 'whatsapp',
];
$send = $this->sendMessage($to, $msg, $params);
// if sending via whatsapp failed, try sending via regular SMS instead
if ( ! $send->status ) {
$params['via'] = 'SMS';
$send = $this->sendMessage($to, $msg, $params);
}
}
I'm afraid Meta/WhatsApp doesn't expose this information at this point in time. Therefore, I'd recommend that you let the users choose whether they want to receive a WhatsApp message or a regular SMS.

How to send custom message before, proxy session send actual message

When Customer replies to proxy service reserved number then proxy hit an OutOfSessionCallbackUrl(if a session is not active).
That URL will come to my code below.
public function response()
{
$to = $_POST['To'];
$from = $_POST['From'];
$from = substr($from, 2);
$body = $_POST['Body'];
$twilio = new Client($this->sid, $this->token);
$response=$this->db->get_where('contact_management as cm
,proxy_service as ps',
array('mobile'=>$from,'company_mobile'=>$to,'sc.sms_template_id<>'=>0))
->row_array();
$number = trim($response['country_code'].$response['mobile_number']);
//Here I'm sending a response
header("content-type:application/json");
?>
{
"uniqueName": "<?php echo rand();?>",
"ttl":"64800",
"mode": "voice-and-message",
"participantIdentifier":"<?php echo $number;?>"
}
<?php
}
This will create a session between SMS sender and returned number(company) and send the message of the sender to the company. I want to send a custom message before Twilio proxy send actual message to the company.
Thanks.
Twilio developer evangelist here.
Currently you are using the out of session callback in order to create a session, but you want to send a message before you forward on the incoming message.
To do this, you won't be able to respond with the JSON to create a session. Instead, you should create the session manually using the session API. Once you have created a session you can then send your initial message by creating an interaction on the participant you want to send the message to. You can then follow up by using the same API to forward the original message. And finally you still need to respond to the webhook. Since you handled all the message sending manually, you can return an empty TwiML <Response/> to signify that you need Twilio to take no further part.
Let me know if that helps at all.
Here Are the complete Description.
I have add Twilio number as reserved in proxy service and set the proxy service OutOfSessionCallbackUrl.When this URL reach my code then the magic happens,
public function response()
{
$to = $_POST['To'];
$from = $_POST['From'];
$twilio = new Client($this->sid, $this->token);
$response=$this->db->get_where('contact_management ,proxy_service,
array('mobile'=>$from,'company_mobile'=>$to))->row_array();
$service_sid=$response['service_sid'];
$session = $twilio->proxy->v1->services($service_sid)->sessions
->create(array("uniqueName" => rand(),"ttl"=>"64800"));
$session_sid = $session->sid;
$participant1 = $twilio->proxy->v1->services($service_sid)
->sessions($session_sid)->participants->create($_POST['From'], // identifier
array("friendlyName" => $response['f_name'],"proxyIdentifier"=>$to));
$from_id = $participant1->proxyIdentifier;
$participant2 = $twilio->proxy->v1->services($service_sid)
->sessions($session_sid)->participants
->create($response['country_code'].$response['mobile_number'], // identifier
array("friendlyName" => $response['first_name']));
$to_id = $participant2->proxyIdentifier;
$to_sid = $participant2->sid;
$body = $response['campaign_name']."\n";
$body .= $_POST['Body'];
$message_interaction = $twilio->proxy->v1->services($service_sid)
->sessions($session_sid)
->participants($to_sid)
->messageInteractions
->create(array("body" => $body));
header("content-type:text/xml");
?>
<Response />
<?php
}

How to implement a Spamword filter in php contact form and reCaptcha

I 've a contact form with a working reCaptcha on it, but some spam gets through.
I've tried adding a spamword filter I've found in here Spam Filter in Contact Form
. But it doesn't work, any ideas?
EDIT: ( further explanation, noob mistake) The filter scans through the words in the message field and blocks the mail sending If a word is present.
Nowadays I almost have no spam thanks to recaptcha, but there's like 10 mails a
day advertising Prednisone or Viagra. so, Id like to filter those words ir order to avoid receiving that spam
I've tried inserting the solution I've mentioned before but I receive those mails anyways
Here's my code
I've tried putting the code from the previous post in several different places with no luck.
Thanks in advance.
<?php
// require ReCaptcha class
require '../recaptcha-master/src/autoload.php';
//require($_SERVER['DOCUMENT_ROOT'].'/recaptcha-master/src/autoload.php');
// configure
// an email address that will be in the From field of the email.
$from = 'Formulario de contacto <blehblehbleh#somethingsomething.com>';
// an email address that will receive the email with the output of the form
$sendTo = 'InfoPapelCosido <blablabla#somethingsomething.com>';
// subject of the email
$subject = 'Mensaje Nuevo desde la web de PapelCosido';
// form field names and their translations.
// array variable name => Text to appear in the email
$fields = array('name' => 'Name', 'surname' => 'Surname', 'phone' => 'Phone', 'email' => 'Email', 'message' => 'Message');
// message that will be displayed when everything is OK :)
$okMessage = 'Mensaje enviado, a la brevedad nos comunicaremos con usted.';
// If something goes wrong, we will display this message.
$errorMessage = 'Hubo un error al enviar el mensaje, por favor intente mas tarde';
// ReCaptch Secret
$recaptchaSecret = '#######################';
// let's do the sending
// if you are not debugging and don't need error reporting, turn this off by error_reporting(0);
error_reporting(E_ALL & ~E_NOTICE);
try {
if (!empty($_POST)) {
// validate the ReCaptcha, if something is wrong, we throw an Exception,
// i.e. code stops executing and goes to catch() block
if (!isset($_POST['g-recaptcha-response'])) {
throw new \Exception('ReCaptcha is not set.');
}
// do not forget to enter your secret key from https://www.google.com/recaptcha/admin
$recaptcha = new \ReCaptcha\ReCaptcha($recaptchaSecret, new \ReCaptcha\RequestMethod\CurlPost());
// we validate the ReCaptcha field together with the user's IP address
$response = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
if (!$response->isSuccess()) {
throw new \Exception('ReCaptcha was not validated.');
}
// everything went well, we can compose the message, as usually
$emailText = "Mensaje desde la web\n=============================\n";
foreach ($_POST as $key => $value) {
// If the field exists in the $fields array, include it in the email
if (isset($fields[$key])) {
$emailText .= "$fields[$key]: $value\n";
}
}
// All the neccessary headers for the email.
$headers = array('Content-Type: text/plain; charset="UTF-8";',
'From: ' . $from,
'Reply-To: ' . $from,
'Return-Path: ' . $from,
);
// THIS IS THE CODE FROM THE POST I'VE CITED BEFORE
//TEST SPAM FILTER
// Prevent spammers from using contact form
//Create an array containing the words in the message
$MessageArray = explode(" ", $emailText );
//Get SPAM words from file and store them in an array
$SpamWords = file_get_contents('spamwords.txt');
$SpamArray = explode("\r\n", $SpamWords);
//Cycle through all the words in the message
foreach($MessageArray as $word){
//Check the word for SPAM words, if it is don't send the email
if(in_array($word, $SpamArray)){
echo '<h1>Spam Guard</h1>';
echo '<p>Here in European Community, the Privacy and Electronic Communications Regulations 2003 cover the sending of email marketing. This legislation says that organisations must only send marketing emails to anyone if they have agreed to receive them, except where there is a clearly defined customer relationship.</p>';
echo '<p>It appears that you are attempting to send an unsolicited message (e.g. a marketing message).</p>';
echo '<p>We as an organisation do not send unsolicited messages and we request that you do the same for us.</p>';
echo '<p>If you are not attempting to send an unsolicited message, there may be an error in the system so please accept our apologies.</p>';
die();
}
}
//If we've made it to this point, our message doesn't contain any obvious SPAM words
//END SPAM FILTER
// Send email
mail($sendTo, $subject, $emailText, implode("\n", $headers));
$responseArray = array('type' => 'success', 'message' => $okMessage);
}
}
catch (\Exception $e) {
$responseArray = array('type' => 'danger', 'message' => $e->getMessage());
}
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$encoded = json_encode($responseArray);
header('Content-Type: application/json');
echo $encoded;
} else {
echo $responseArray['message'];
}

Gmail API with PHP mailer can't send multiple attachments

I am using PHPmailer with Gmail API to send out mail. This process has worked very well for me for sending just standard emails, however, I want to also have the ability to send out an email with attachments using the Gmail API. When I tried using $mail->addAttachment($urlString, $name); Gmail would come back with the error Request Entity Too Large Error 413 (The size of the attachments never goes above 20MB so it should be well within the 35MB limits of Gmail API).
After some searching, I found out it was because I wasn't using "/Upload URI" for sending large Gmail Attachments (Anything above 5mb and below 35mb). Problem is, I am not very knowledgeable on how to work the Gmail API and only got what I have now from basically copying code from somewhere else and slightly modifying it for my uses and as such, I have no idea how to change the URI like that.
Here is what I have so far, that works with standard emails:
function($agent, $assistantName='', $assistantEmail='', $subject, $body, $attachments=''){
$key = realpath(dirname(__FILE__).'/Services/Google/Gmail.json');
$useremail = 'myuseremail#example.com';
$toAddress = $agent->email;
$agentFirst = $agent->first_name;
$client = new Google_Client();
putenv('GOOGLE_APPLICATION_CREDENTIALS='.$key);
$client->useApplicationDefaultCredentials();
$user_to_impersonate = $useremail;
$client->setSubject($user_to_impersonate);
$client->addScope('https://www.googleapis.com/auth/gmail.compose');
if ($client->isAccessTokenExpired()) {
$client->refreshTokenWithAssertion();
}
//prepare the mail with PHPMailer
$mail = new PHPMailer();
$mail->CharSet = "UTF-8";
$mail->Encoding = "base64";
$subject = $subject;
$msg = $body;
$from = $useremail;
$fname = "My Name";
$mail->From = $from;
$mail->FromName = $fname;
$mail->AddAddress($toAddress, $agentFirst);
$mail->AddCC($assistantEmail, $assistantName);
$mail->AddReplyTo($from,$fname);
if ($attachments != '') {
foreach ($attachments as $name => $urlString) {
$mail->addAttachment($urlString, $name);
}
}
$mail->Subject = $subject;
$mail->Body = $msg;
$mail->IsHTML(true);
$mail->preSend();
$mime = $mail->getSentMIMEMessage();
$m = new Google_Service_Gmail_Message();
$data = base64_encode($mime);
$data = str_replace(array('+','/','='),array('-','_',''),$data); // url safe
$m->setRaw($data);
$service = new Google_Service_Gmail($client);
$email = $service->users_messages->send($useremail, $m);
return json_encode($email);
}
I don't really know where to go from here, so any help would be appreciated.
use EZCMail and build the email structure yourself... it is very pickey! I can post some details after.
you may also have to send the email in chunks.
If the email is over 4MB then you are going to have to send in chunks using Google_Http_MediaFileUpload
Your code using this should be something similar to this, there is examples for using Google_Http_MediaFileUpload elsewhere on the web which might be more complete:
$client->setDefer(true);
// Call the API with the media upload, defer so it doesn't immediately return.
$arrRequestParams = $arrRequestParams+['uploadType' => 'multipart'];
$result = $this->TransportPrepSwitch($strAction, $objGMessage, $arrRequestParams); // Make draft or message $service->users_messages->send('me', $objGMessage, $arrRequestParams);
$mailMessage = base64url_decode($strRaw);
// create mediafile upload
$chunkSizeBytes = 1*1024*1024; // send to google in 1MB chunks
$media = new Google_Http_MediaFileUpload($client,$result,'message/rfc822',$mailMessage,true,$chunkSizeBytes);
$media->setFileSize(strlen($mailMessage));
// Upload chunks. Status will contain the completed $result.
$status = false;
set_time_limit(300);
while(!$status)
$status = $media->nextChunk();
// Reset to the client to execute requests immediately in the future.
$client->setDefer(false);
$objResponce = $status;
Also the structure of the email parts MUST be as follows:
multipart/mixed => [
multipart/related => [
multipart/alternative => [
plain,
html
],
inline images,
],
attachments,
]
The only way I could achieve this was using EZCMail to build the email part by part.

Error sending more than 300 emails with PHP Swift Mailer showing Internal Server Error

Error sending more than 300 emails with PHP Swift Mailer showing Internal Server Error getting only 200 mails out of 300
i am using ftp surfer
another problem is after sending 200 mails upto one hour mails are not going it showing us as send but i am not getting any mails after one hour again they are getting
mail ids are getting from mysql database
using for each loop mails are sending
<?php // Create the message
// Create the message
$message = Swift_Message::newInstance();
$sql=mysql_query("select * from test_email where status=''");
while($row=mysql_fetch_array($sql))
{
// Usually you want to replace the following static array
// with a dynamic one built retrieving users from the database
$users = array(
array(
"fullname" => "Aurelio De Rosa",
"operations" => $row['sno'],
"email" => $row['email']
)
);
// Create the replacements array
$replacements = array();
foreach ($users as $user) {
$replacements[$user["email"]] = array (
"{fullname}" => $user["fullname"],
"{transactions}" => $user["operations"]
);
}
// Create the mail transport configuration
$transport = Swift_MailTransport::newInstance();
// Create an instance of the plugin and register it
$plugin = new Swift_Plugins_DecoratorPlugin($replacements);
$mailer = Swift_Mailer::newInstance($transport);
$mailer->registerPlugin($plugin);
// Create the message
$message = Swift_Message::newInstance();
$message->setSubject("This email is sent using Swift Mailer");
// Create your file contents in the normal way, but don't write them to disk
// Create your file contents in the normal way, but don't write
//them to disk
$type = $message->getHeaders()->get('Content-Type');
$type->setValue('text/html');
$type->setParameter('charset', 'utf-8');
// Use AntiFlood to re-connect after 100 emails
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100));
// And specify a time in seconds to pause for (30 secs)
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100, 30));
// Create the message
$message = Swift_Message::newInstance('My subject');
// Set the body
$message->setBody(
'<html>' .
' <head></head>' .
' <body>' .
' Here is an image <img src="http://www.graymatter8.info/Developer1/swiftm/x.php?ts={transactions}&&ip='.$ip.'" alt="" width="1" height="1" border="0"/>' .
' Rest of message' .
' </body>' .
'</html>',
'text/html' // Mark the content-type as HTML
);
$message->setFrom("account#bank.com", "Testing");
$failedRecipients = array();
$numSent = 0;
// Send the email
foreach($users as $user)
{
$message->setTo($user["email"], $user["fullname"]);
$mailer->send($message);
}
?>
You should send it out in packets, like 10-20 at once. As soon as a package is done, you can go to the next 10-20, and so on...

Categories