Jump to content

Mail with attachments doesn't get past 'sent' - PHP 8.0

Jonathan_bdlf
Go to solution Solved by Jonathan_bdlf,
On 11/25/2023 at 9:07 AM, C2dan88 said:

Try using PHPMailer. It provides alot more flexibility over the simple mail function.

https://github.com/PHPMailer/PHPMailer

 

No need to memorize mail headers/formatting which is probably why your email is sent incorrectly.

 

Worked like a charm, thanks 🫶

 

My mails are getting a 9/10 score on https://www.mail-tester.com/ 🙂
I have to sign the message with DKIM to receive a 10/10

 

Here's some information I've gathered while debugging that may help some people :

  1. Install PHPMailer
    1. Run at the base directory of your web server (e.g. /opt/bitnami/apache/htdocs) : 
      composer require phpmailer/phpmailer
    2. RTFM, it's well documented !
  2. Check if your mail address isn't flagged as spam
    • Due to extensive testing, my (OVH) mail have been flagged as spam.
      • The resulting logs were "SASL authentication failed."
      • The result behavior was simple : No mail received nor sent
      • I had to change the password. Now everything's fine ! (Don't forget to flush postfix queue 😉) 
        sudo postqueue -f
  3. (Re)configure postfix -> https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-as-a-send-only-smtp-server-on-ubuntu-18-04-fr 
  4. Write PHP to send mail using postfix :
$to = $user['usr_mail'];
$from = 'contact@mydomain.fr';
$fromName = 'Jonathan Bdlf Photographie ';
if ($bc_type == 1){ // Si couple
    $subject = 'Votre bon cadeau pour une séance photo en couple ';
} else if ($bc_type == 2){ // Si famille
    $subject = 'Votre bon cadeau pour une séance photo en famille ';
}
$prenom = $user['usr_prenom'];
$nomcomplet = $user['usr_prenom'].$user['usr_nom'];

//Import PHPMailer classes into the global namespace
//These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP; // Not sure if useful
use PHPMailer\PHPMailer\Exception;

//Load Composer's autoloader
require '/opt/bitnami/apache2/htdocs/vendor/autoload.php';

//Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true);

try {
    //To load the French version
    $mail->setLanguage('fr', '/opt/bitnami/apache2/htdocs/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php'); // Because I'm french ! Lots of language come with the package
    //Server settings
    $mail->SMTPDebug = SMTP::DEBUG_SERVER;                      //Enable verbose debug output
    $mail->isMail();                                            //Send using Postfix
    $mail->CharSet = "UTF-8";


    //Recipients
    $mail->setFrom($from, $fromName);
    $mail->addAddress( $to,$nomcomplet );     //Add a recipient
    $mail->addReplyTo($from, $fromName);

    //Attachments
    $mail->addAttachment($outputPDF);    //Optional name

    //Content
    $mail->isHTML(true);                                  //Set email format to HTML
    $mail->Subject = $subject;
    $mail->Body = '<p>Merci pour votre achat</p>';
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

    $mail->send();
    echo 'Message has been sent';
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

 

Voila 🎉

I hope this may help some one over on the internet.

Thanks again @C2dan88 for your help 😉

Hey there 👋

 

I've finally decided to give up on this, and ask the community some help...
It has given me so many headaches 😭

Here are the basics :
1. A file is generated using PDFtk

2. An automated email is sent with the file attached

 

I'm using postfix through an SMTP relay 😉

 

I've gathered some code around the internet and tried to learn to use it the best as I could and here's what I came up with :

$to = $user['usr_mail'];
$from = 'contact@mydomain.fr';
$fromName = 'Jonathan Bdlf Photographie ';
if ($bc_type == 1){ // Si couple
    $subject = 'Votre bon cadeau pour une séance photo en couple ';
} else if ($bc_type == 2){ // Si famille
    $subject = 'Votre bon cadeau pour une séance photo en famille ';
}
$prenom = $user['usr_prenom'];
$html_content = "<h1>Voici votre bon cadeau </h1>
<p>Je vous remercie pour votre achat</p>";

$plaintext = "Voici votre bon cadeau. Je vous remercie pour votre achat.";

$boundary = uniqid();

// attachment
$attachment = chunk_split(base64_encode(file_get_contents($outputPDF)));

// message with attachment
$message = "--".$boundary."\r\n";
$message .= "Content-Type: text/html; charset=UTF-8\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n\r\n";
$message .= chunk_split(base64_encode($html_content))."\r\n";
$message .= "--" . $boundary . "\r\n";
$message .= "Content-Type: text/plain; charset=UTF-8\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n\r\n";
$message .= chunk_split(base64_encode($plaintext))."\r\n";
$message .= "--".$boundary."\r\n";
$message .= "Content-Type: application/octet-stream; name=\"$outputPDFname\"\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n";
$message .= "Content-Disposition: attachment; filename=\"$outputPDFname\"\r\n\r\n";
$message .= $attachment."\r\n";
$message .= "--".$boundary."--";



// header information
$headers = "From: $from\r\n";
$headers .= "Reply-To: contact@mydomain.fr\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";

// send email
if (mail($to, $subject, $message, $headers)) {
    echo "Email with attachment sent successfully.";
} else {
    echo "Failed to send email with attachment.";
}

The email went through once with the attachment 😳

 

Then I had this weird email :

This is a sample email with attachement--655feab3a6c7f
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64

VGhpcyBpcyBhIHNhbXBsZSBlbWFpbCB3aXRoIGF0dGFjaGVtZW50LS02NTVmZWFiM2E2YzdmDQpD
b250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9VVRGLTgNCkNvbnRlbnQtVHJhbnNmZXIt
RW5jb2Rpbmc6IGJhc2U2NA0KDQo=
--655feab3a6c7f
Content-Type: application/octet-stream; name="bon-cadeau-couple-1700784819.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="bon-cadeau-couple-1700784819.pdf"

 

Then nothing

 

The logs aren't showing any error

Here's what I have :

Nov 24 00:31:13 ip-172-26-0-118 postfix/pickup[1435549]: A2A3780437: uid=1 from=<daemon>
Nov 24 00:31:13 ip-172-26-0-118 postfix/cleanup[1435594]: A2A3780437: message-id=<20231124003113.A2A3780437@mydomain.fr>
Nov 24 00:31:13 ip-172-26-0-118 postfix/qmgr[1208021]: A2A3780437: from=<daemon@mydomain.fr>, size=681, nrcpt=1 (queue active)
Nov 24 00:31:14 ip-172-26-0-118 postfix/smtp[1435596]: A2A3780437: to=<personnal-mail@hotmail.fr>, relay=ssl0.ovh.net[193.70.18.144]:587, delay=0.81, delays=0.02/0/0.57/0.23, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 52EEE1FE06)
Nov 24 00:31:14 ip-172-26-0-118 postfix/qmgr[1208021]: A2A3780437: removed

 

I can't seem to figure out why the heck this doesn't work 😭

The only thing I'm 99% sure is that the mail isn't received because of the code I'm trying to pass in mail() 😕
I'm 100% sure that my mail is sent. I'm 99,99% sure that it's delivered (at mx.outlook.com) since I don't receive back any "undelivered" message 🙂

 

 

👉 Do any of you know how mails work deep from the inside ?
👉 Somebody knows more headers I should fill to ensure high delivering ?
👉 Has anyone an idea on what can possibly be wrong in my code ?

 

 

Let's get over the basic questions :

  • Yes, all my variables are right and work
  • Yes emails can be sent from my server (tested from postfix using command line)

 

Thanks a lot to you all 🫶

Link to comment
Share on other sites

Link to post
Share on other sites

just curious are you receiving the "email Successfully Sent or Not Successful messages you have echoed in the last "if" of the code?  if not then it is likely quitting before that point.

wish I could help further.

Link to comment
Share on other sites

Link to post
Share on other sites

12 hours ago, Bryce_NZ101 said:

just curious are you receiving the "email Successfully Sent or Not Successful messages you have echoed in the last "if" of the code?  if not then it is likely quitting before that point.

wish I could help further.

Yeup I receive the message 🙂

Link to comment
Share on other sites

Link to post
Share on other sites

11 hours ago, C2dan88 said:

Try using PHPMailer. It provides alot more flexibility over the simple mail function.

https://github.com/PHPMailer/PHPMailer

 

No need to memorize mail headers/formatting which is probably why your email is sent incorrectly.

Okay I'll check it thanks !

I hope it's well documented 🙂

I keep you posted^^

Link to comment
Share on other sites

Link to post
Share on other sites

On 11/25/2023 at 9:07 AM, C2dan88 said:

Try using PHPMailer. It provides alot more flexibility over the simple mail function.

https://github.com/PHPMailer/PHPMailer

 

No need to memorize mail headers/formatting which is probably why your email is sent incorrectly.

 

Worked like a charm, thanks 🫶

 

My mails are getting a 9/10 score on https://www.mail-tester.com/ 🙂
I have to sign the message with DKIM to receive a 10/10

 

Here's some information I've gathered while debugging that may help some people :

  1. Install PHPMailer
    1. Run at the base directory of your web server (e.g. /opt/bitnami/apache/htdocs) : 
      composer require phpmailer/phpmailer
    2. RTFM, it's well documented !
  2. Check if your mail address isn't flagged as spam
    • Due to extensive testing, my (OVH) mail have been flagged as spam.
      • The resulting logs were "SASL authentication failed."
      • The result behavior was simple : No mail received nor sent
      • I had to change the password. Now everything's fine ! (Don't forget to flush postfix queue 😉) 
        sudo postqueue -f
  3. (Re)configure postfix -> https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-as-a-send-only-smtp-server-on-ubuntu-18-04-fr 
  4. Write PHP to send mail using postfix :
$to = $user['usr_mail'];
$from = 'contact@mydomain.fr';
$fromName = 'Jonathan Bdlf Photographie ';
if ($bc_type == 1){ // Si couple
    $subject = 'Votre bon cadeau pour une séance photo en couple ';
} else if ($bc_type == 2){ // Si famille
    $subject = 'Votre bon cadeau pour une séance photo en famille ';
}
$prenom = $user['usr_prenom'];
$nomcomplet = $user['usr_prenom'].$user['usr_nom'];

//Import PHPMailer classes into the global namespace
//These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP; // Not sure if useful
use PHPMailer\PHPMailer\Exception;

//Load Composer's autoloader
require '/opt/bitnami/apache2/htdocs/vendor/autoload.php';

//Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true);

try {
    //To load the French version
    $mail->setLanguage('fr', '/opt/bitnami/apache2/htdocs/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php'); // Because I'm french ! Lots of language come with the package
    //Server settings
    $mail->SMTPDebug = SMTP::DEBUG_SERVER;                      //Enable verbose debug output
    $mail->isMail();                                            //Send using Postfix
    $mail->CharSet = "UTF-8";


    //Recipients
    $mail->setFrom($from, $fromName);
    $mail->addAddress( $to,$nomcomplet );     //Add a recipient
    $mail->addReplyTo($from, $fromName);

    //Attachments
    $mail->addAttachment($outputPDF);    //Optional name

    //Content
    $mail->isHTML(true);                                  //Set email format to HTML
    $mail->Subject = $subject;
    $mail->Body = '<p>Merci pour votre achat</p>';
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

    $mail->send();
    echo 'Message has been sent';
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

 

Voila 🎉

I hope this may help some one over on the internet.

Thanks again @C2dan88 for your help 😉

Edited by Jonathan_bdlf
Precisions added
Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×