Showing posts with label email. Show all posts
Showing posts with label email. Show all posts

Monday, July 30, 2018

Laravel mail with g suites and XOAUTH2

Leave a Comment

I have a g suites account and applications associated with my e-mails. I was looking at the Laravel mail functions but I do not see any option to log in to gmail smtp with xoauth auth type.

I was using PHPMailer with codeigniter and I had to use clientId, clientSecret and refreshToken to send emails via smtp.gmail.com

Is there any chance I can authenticate using xoauth with native laravel swiftmailer?

1 Answers

Answers 1

Since Laravel doesn't have available configuration to set AuthMode then we need to tweak it a little bit.

  1. Register a new Mail service provider in config/app.php:

    // ... 'providers' => [     // ...      // Illuminate\Mail\MailServiceProvider::class,     App\MyMailer\MyMailServiceProvider::class,      // ... 
  2. app/MyMailer/MyMailServiceProvider.php should create your own TransportManager class:

```

namespace App\MyMailer;  class MyMailServiceProvider extends \Illuminate\Mail\MailServiceProvider {     public function registerSwiftTransport()     {         $this->app['swift.transport'] = $this->app->share(function ($app) {              return new MyTransportManager($app);         });     } } 

```

  1. In the app/MyMailer/MyTransportManager.php we can provide additional configuration to the SwiftMailer:

```

<?php  namespace App\MyMailer;   class MyTransportManager extends \Illuminate\Mail\TransportManager {     /**      * Create an instance of the SMTP Swift Transport driver.      *      * @return \Swift_SmtpTransport      */     protected function createSmtpDriver()     {         $transport = parent::createSmtpDriver();         $config = $this->app->make('config')->get('mail');           if (isset($config['authmode'])) {             $transport->setAuthMode($config['authmode']);         }          return $transport;     } } 

```

  1. Last thing to do is to provide mail configuration with authmode set to XOAUTH2 and password to your access token:

```

<?php  return array(  /* |-------------------------------------------------------------------------- | Mail Driver |-------------------------------------------------------------------------- | | Laravel supports both SMTP and PHP's "mail" function as drivers for the | sending of e-mail. You may specify which one you're using throughout | your application here. By default, Laravel is setup for SMTP mail. | | Supported: "smtp", "mail", "sendmail" | */  'driver' => 'smtp',  /* |-------------------------------------------------------------------------- | SMTP Host Address |-------------------------------------------------------------------------- | | Here you may provide the host address of the SMTP server used by your | applications. A default option is provided that is compatible with | the Postmark mail service, which will provide reliable delivery. | */  'host' => 'smtp.gmail.com',  /* |-------------------------------------------------------------------------- | SMTP Host Port |-------------------------------------------------------------------------- | | This is the SMTP port used by your application to delivery e-mails to | users of your application. Like the host we have set this value to | stay compatible with the Postmark e-mail application by default. | */  'port' => 587,  /* |-------------------------------------------------------------------------- | Global "From" Address |-------------------------------------------------------------------------- | | You may wish for all e-mails sent by your application to be sent from | the same address. Here, you may specify a name and address that is | used globally for all e-mails that are sent by your application. | */  'from' => array('address' => 'user@gmail.com', 'name' => 'user'),  /* |-------------------------------------------------------------------------- | E-Mail Encryption Protocol |-------------------------------------------------------------------------- | | Here you may specify the encryption protocol that should be used when | the application send e-mail messages. A sensible default using the | transport layer security protocol should provide great security. | */  'encryption' => 'tls',  /* |-------------------------------------------------------------------------- | SMTP Server Username |-------------------------------------------------------------------------- | | If your SMTP server requires a username for authentication, you should | set it here. This will get used to authenticate with your server on | connection. You may also set the "password" value below this one. | */  'username' => 'user@gmail.com',  /* |-------------------------------------------------------------------------- | SMTP Server Password |-------------------------------------------------------------------------- | | Here you may set the password required by your SMTP server to send out | messages from your application. This will be given to the server on | connection so that the application will be able to send messages. | */  'password' => 'YOUR ACCESS TOKEN',  /* |-------------------------------------------------------------------------- | Sendmail System Path |-------------------------------------------------------------------------- | | When using the "sendmail" driver to send e-mails, we will need to know | the path to where Sendmail lives on this server. A default path has | been provided here, which will work well on most of your systems. | */  'sendmail' => '/usr/sbin/sendmail -bs',  /* |-------------------------------------------------------------------------- | Mail "Pretend" |-------------------------------------------------------------------------- | | When this option is enabled, e-mail will not actually be sent over the | web and will instead be written to your application's logs files so | you may inspect the message. This is great for local development. | */  'pretend' => false,  'authmode' => 'XOAUTH2',  ); 

```

Read More

Friday, July 6, 2018

ActionMailer - Create new mail with attachments from original RFC822 message

Leave a Comment

I use an email delivery service to send emails (Sparkpost), and everytime one of these emails is replied, I receive a JSON that contains: the reply mail body as HTML (body_html), the reply mail body as text (body_text) and the original RFC822 (email_rfc822) for the reply message.

After receiving this JSON, I need to forward this email to another recipient. Currently, I use the following mailer to achieve that:

class ReplyMailer < ApplicationMailer   def reply(body_html, body_text, options = {})     mail(to: options[:to], from: options[:from], reply_to: options[:reply_to], subject: options[:subject], skip_premailer: true) do |format|       format.html { render html: body_html.html_safe } if body_html.present?       format.text { render plain: body_text } if body_text.present?     end   end end  

The problem with this approach is that it does not forward the attachments of the original message.

How could change this mailer to also forward all the attachments from the original message (including inline images that are referenced on the html body)?

2 Answers

Answers 1

The following snippet might help you

options[:attachments].each do |attachment|     attachments[attachment.original_filename] = File.read(attachment.tempfile) end 

Answers 2

You can use something like this to handle inline attachments

 context "Inline Attachments" do it "accepts an inline attachment" do   test_email = Mailer.test_email inline_attachments: 1   @delivery_method.deliver!(test_email)    images = @delivery_method.data[:content][:inline_images]   expect(images.length).to eq(1)   image = images[0]   expect(image).to include(:name, :type=>"image/png; filename=image_0.png", :data=>"iVBORw0KGgoAAAANSUhEUgAAAfIAAACCCAMAAACKGrqXAAAAY1BMVEX////6ZCNVVVr6ZCP6ZCNVVVr6ZCNVVVr6ZCP6ZCNVVVpVVVr6ZCNVVVpVVVr6ZCNVVVpVVVr6ZCNVVVpVVVpVVVpVVVr6ZCP6ZCNVVVr6ZCP6ZCP6ZCP6ZCNVVVpVVVr6ZCO+CfRXAAAAH3RSTlMAgMBAEPBgoDAg4NBwkIDAUBDwQLBgMOCgIFCQ0LBwPgQxPgAADDFJREFUeF7s2kGLnEAYhOFqbERhSROHZFzXWer//8rAJo172jklhK73OXsrKItP9Q/hmBQGZ1EWLD6roqB4W5QEdbNnJUFxWOaoTssce1rmOGznbTia3VtVDJy27aYYePjDi1KgOLPaidy7whC5V4Uh8l1hiNxVEdDcvSgCTnenIsCXVQEw+TIrBOstarPjtKNe5lj9mbLQ6/ak4eEeFjkOf+ai0aGFRY7JYZGjhUWOyWGRo4VFjsNhkeMeFjmKsyLHurnLuL7h4dTI2W4Zv8Wg3t1drHHhzV3iLxLc3bqmLNS6i6JQ6/asKNS6vSgKtW5raNQ6641a95uGRa2z3qj1rPXGbb3TiFA3+9l6WzQQPOwn662ehyJQ6z7+JO6qBNR6/1jefNc4sNtP1luJuMhwhLnW2+qIyDnCXOutBUTOEaYrvQY2DQKLvzT1d72rxoD2NPLqD4eGgNlfux7ZNTQurd11mts0NLZbJ2nz/9Hs328/vv32fnvV3/N6u/zUaH61d4bLjatIFLZJCL4owsKScEgm8n3/p9zazexi6yC6Wz2pqbo752diLBUfNN3QtP/6m9LdZ85tHkv40jB+B4fUd7cHmVB/Tm+2FQJnrPjbnYjPz6apPsyJ17RGx61fn/FcF5Yxynw3RP5OX1QanX/A4d0Q18iMSI8dFRd/q8i6CnVza8u7oU1xeGgQ2sjDjda0ZLppjfjtUV3kPrfrk2DfDRMkjlQx17nKY4VjvIn00Hi22wDnCMhJ+VAaUWPGKpAXTaMc+bwe4EnyXL9E7iTHNKi39n3EwW/hMOMvQR7bEO0CxGjZ7cmbVw1mDfIik4TI0xpiEj7XLsJJXmb2uXVvJbryCPMfPUDPeuTJkgN6BOS0uoKAMKc65EVBhDxbGHrQ2IW1jDEWuh8mOaHLc0GOv5oWu5+47xbvOPYdLoU5VOTKi6+UgXhLfQTkpGx9+kZ43qhDXuQigRw7tqiH5269WRx6X9YCnOS0Pq6rHXckbmFBzcHiSEONZJdmK5izNHLaZC9ISosc/S8a+QQv0UCOGn+2tyNMcpFwmk9l9K4Vg8WRJkfeia2m4SMYqhEaKOuQIzgaeYDBQiAHjR30Pj3J6VuoS9O/if3XShtJ5Poe7eSGvT4ah8Zw0iO/LQzk6KxjHyJylMOmb3uQX2HZWxpEPXSrDHm0InY0ctI1m24o++uQ28xBniwMTS5yHDgBNt6kelk91hwaigZsgAj5Ipo8cuTwdpn4lBb5zRHIYaADWkBOzfOM9d1Q53PjfwWIZ2xIDgcNcg+7Sss4DsGt/m4Oe5H7FcG+2sCokRdlGnkHI24n8ugfff1r1T17ezn9NALvX6466PSwVzAdCGmQpxXw8sm8dGAta8h9uJPrkMDMWkgSE3l4VF95YCCROwjPJMixf30rdf38vori3loXURfoMgVyyq7j6EoOHG9EbiB2bK7mM2GOxbumcYEHUk0XeLYMOZrJtOm8nZ+wyV+faAgenpq+CTmaWQtea55gKBDIK7u3GXqopshEjooTPLDZdIDwTIM83BuWy5rka73RO+RQvN/37eGbkCM9txF82ihAjj75zDoHCHuRo6Eemk2ThfBMg3wsPQd2/cdpM2/mB+y6/xbkYaPLh4MMefSwUlZHw6NPwEVOR5qh1TR2EJ6pkB/uOuFjRbyRvvr8Bpa9dFD+VuTABhUPEuS4YJuNCM1HMAZ7kCNb12pqiPBMg/wKxPn3Uk/sp+qR0xNNjDxuhWn942R0+EVy5Bjsm0ZTB/GEFrn5Qg77MFcg3rTtr3euZf/dyIsWBfLG124Y4LwKERMbOYqLfCbCMxXyF5i2giLtnxD0fSfyohC/DTl0+LTeEnEK5B0PeYLwTI/c/g/5h7Bg52ttMSe22PXIAyb3aJGj+ayDGWHSxf3IPQt5tkR4plvLz2DWCZ0r9dkd+JR65NTOyDTHb5jlEKF5tPTL9xp2dNbjQY98LOuDuMjXU+VXGDLGEXrk9CGHWZIOuYdjMpj7C/7J70aeWEHaBOGZDnnxSOe193aV/4b98fGlgxI5hQ9lpzmzkdMONP41Vv427EXu0AvFpgHSNzTI8eTrSV688QWQFyR+/ibkszBXG5GTBKYaAEd8lwh52gi1A3Wqq0c+l/d+lVfye64coJb1x4esRi7Pg+qWKEee6kftFrDAkMty5LihZjeaorOuRx5tGT1HsOsiB+5cOzTolqRFTvFBWZeFyLOvnovO9dMuCxykyEcLMGnk00GLvHSFh/QI9hXiY71282Lvl9hlVCJH00QpRD5yJOBr5mQmzvL4yAfwRgYG8i6qkZcVbIQd1OOe2nB4eaHI9EMUItcx9yMbORLoy4sAWnDgFgq5eVRXTcOhkdukRV4MsEMj/bSnbhSZeLAkJfKiwZLQZ1ZWTG/sZl6S2zLgE/DSJULNrKZdVCMfffkmRC7335CLQ+pRgRyGK5+5EWYf4mROm0nOgxa5YTY1SuRpKmOHjRxFFG8ew6qzbYgq5EWjYTGXI7exAs4Qm6UK5DZzmzoF8rx0aC30yOsaF+fh7qMcOSo7S/elHPlQ4zo3mGYd8sRvOjOQLyMoBOOrWSVvO5CfmIFdHO6wm6hEjmtHXWYPcldzEW3rdL0XI+cOJkfcfpQ/16SNgOtV7r7RhR4T3n2UI0eVK62oJEfu5E1s3I/cplbT2MHHVcjNDDG2+MdyXgF5U7MBk6tDjjakPv+MmHiSTNTdyE17tOAd2y7uRu77JJ+xqDdWLI/lPjol8rp7AvJS5AtsunPkdyL3M0GtMvKmPci96efcWJcldTqvvONW3F0OauSo3MPCnkXIuwSrNU/jHuTdTFKDXSddIhTqIuZ3gpMYLnMb9chRMQALPnI/73a6pz3IF94hnLsp0h0lZyRiu37hc7H44nrk9Sz/hY18GiDyFijvQG6Zh3BdI6rTIn+FtCZB4c9PPpYZJoYYOfcqcmAh7+AEYL7J1De4lfh4Bc/wkEcLY0WBHMy0jOCRnTmFUa1VIXdD68uLAnnzdBgTmXlDy7IKvqS6aaeaJnTbtcirV42fOIU/5Q5fARAVyF3Di6GRG3p5uEk108jR4tvEQo42Z/plyF9lKa5nuJPGVI9Q5eflXWIgX/Yhd2LknoEc1+WOhxyLGvR65HguRkM8Qn4rV0GHfGzdWki0x24YDqZYIwM5pqUHHnJcaGYtcvTA6V3XF6gc8s3I0Sn3M7UK513Il5tcjoMcvzrxkEePbrseOd5KeyGIwyQXGfa8E3nsGldVosM0QjlyT6+baKUzAznO146HHF04G5XI6zXAjhRx+SQvAHR30oqmkmyTFw9TT4ocMyCY6ViBgxxNe08gh5cCtx2Qq35i4/N542MfX6gxil96ZpDWEchFnpUxLjjj8ehbjBwjOu6Sb1nI0bSPPOS4v+O0yOsFgi7v1SPTK1R3LAPf8bZi+n3IZ6kbLUeO2Yy84TdzkKOZ8pGHHAsOBhXyok+yPtDTeV1f5NFd7iKn8FgSIkcctGYxcgQZ2eF7t7PCds9EHjtw2+vI9b98ef043Tl4rz+gGlQx6xYrAaMcdLtklltZZU458og3E5h+xUhwI0w72RRduKRBXnS6/A26nD+O/9b58jfqhC/VRyoHfeQhRyXPTzgRIUcg0nx6x0KOpt1GHnJ04WxUIS/MxfVbi3K3KmUP6sGYSYM0JzHrcuReUovGQpxGI0fTPjGR44ZBFzXIi17kxBGIr0LPBt6UQo4aPJu4HPkguuvZoz9FI0d0AxM5xitOhbzo6SInjhdJLORaJQdjk4kcK/kTssNhH/IJDCffu7cUN9q0Y1PChQsK5Lie07qc2pbXTmEY4xfIufdgjZrINdBNPuxDnhuhL81u5iJH0y5cE4oGFfKi5zOH+I+NRIpkqJ+50Sc1x7mjU5rkyHtyI5suEYjcaNO+sO8po5eqRE5XZmelPo+O/J00fVZMCh2R0iRGHi1EeYQ8jBHkxjHtmYkcN6N81CEvOhET/do+SolLR/4AoD4RKg7hfp/Vbl1qnsOdGj5ZDvfivMRQaTGGexFPKi2ZTZeATe8a54NCL9fGKn7k8Hi4ytu5GXBsdkbe86vDB63+6Pl42QLOz3tKXzjyHwC/TfqZfgXg/yj90dPb6kD1/Q+Af77e/0v98vny/zLB/+j0+vl5PP1uAP8CV/GqdTJ4tWwAAAAASUVORK5CYII=")   expect(image[:name]).to match(/.*@.*/) end 
Read More

Tuesday, May 1, 2018

How to send a batch with emails in android?

Leave a Comment

I want to send several emails to different recipients, but the text of the letters may differ. And I also want to authorize the user and send mail on his behalf, by Intent and the built-in mail client app. And is there any way to do this with one button click, rather than calling up a new email window (activity) for each of these letters and forcing the user to confirms the sending of each letter?

And is there any way to not call the new e-mail window for each of these letters, so that the user confirms the sending of each letter, and do this at the touch of a button?

Maybe are there any third-party libraries or free mail services for this purpose?

1 Answers

Answers 1

You can use simple-java-mail to achieve that.

public static void SendMail(String recipientName,String recipientAddress,String subject,String message,File file,String myAdress,String password) throws IOException{               System.out.println("File size "+file.length());   Email email = new Email();  email.setFromAddress(myAdress.split("@")[0], myAdress);  email.addRecipient(recipientName, recipientAddress, Message.RecipientType.TO);  email.setSubject(subject);  email.setText(message);  if(file!=null)  email.addAttachment(file.getName(),  FileUtils.readFileToByteArray(file),"application/pdf");   String host = myAdress.split("@")[1];   new Mailer(     new ServerConfig("smtp."+host, 587, myAdress, password),     TransportStrategy.SMTP_TLS,     new ProxyConfig("socksproxy."+host, 1080, "proxy user", "proxy password")  ).sendMail(email);   } 

If your client is using Gmail, they have to allow third parties to send mail in their settings

Read More

Sunday, February 25, 2018

php mail and SMTP while using cloudflare

Leave a Comment

I am using cloudflare on my website and I want to keep my server's IP (the ORIGIN IP) private, to avoid DDoS attacks being sent directly to my server's IP. My server uses Apache, PHP, MySQL.

When using php mail to send emails (even if I use phpmailer library to send the emails through external SMTP) the IP of my server is added to the mail headers. It happens with Google SMTP, Mailgun and others, because probably it is in their policy to write in the header the IP from which the mail came.

At the moment, the only solution that I have in mind and requires a lot of effort, which is to create my own REST API and send emails through another server, something like this:

ORIGIN SERVER IP sends email data in text format via my REST API to MY MAIL SERVER IP and then MY MAIL SERVER IP uses php mail function with phpmailer to send the email via SMTP to the user. This way, the IP of MY MAIL SERVER will appear in the email headers and not the IP of the ORIGIN SERVER.

Is there a much more elegant way to do this? Is there a mail service that offers a rest API and if I use their API, they won't display my server's IP in the email headers? Or maybe there is an already developed REST API / library for sending emails remotely as I requested, so I won't have to develop and test my own from scratch?

5 Answers

Answers 1

You should send emails through mailgun (or sendgrid, or jetmail, or SES, or ...) through their API and not the SMTP protocol and your IP won't be disclosed.

For instance for Mailgun SDK: https://github.com/mailgun/mailgun-php

$mg = Mailgun::create('key-example');  # Now, compose and send your message. # $mg->messages()->send($domain, $params); $mg->messages()->send('example.com', [   'from'    => 'bob@example.com',   'to'      => 'sally@example.com',   'subject' => 'The PHP SDK is awesome!',   'text'    => 'It is so simple to send a message.' ]); 

But there are SDK for most providers:

Moreover, I would recommend using SwiftMailer which is powerful library to handle email. One of the cool thing is that it abstract the transport and you would be able to switch from SMTP or any provider API using packages.

Answers 2

You can use e.g. mailchimp, amazon SES, or other mail service provider, they should not add your ip. But that services are paid.

Answers 3

Long time ago, at college, I can not use php mail command because of firewall rules so write my own SMTP autentication class. Some time latter I start using PHPMailer class and I never had another problem, even using Gmail as sender. Give a look at https://github.com/PHPMailer/PHPMailer .

This is a simple example:

<?php // 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\Exception;  //Load composer's autoloader require 'vendor/autoload.php';  $mail = new PHPMailer(true);                              // Passing `true` enables exceptions try {     //Server settings     $mail->SMTPDebug = 2;                                 // Enable verbose debug output     $mail->isSMTP();                                      // Set mailer to use SMTP     $mail->Host = 'smtp1.example.com;smtp2.example.com';  // Specify main and backup SMTP servers     $mail->SMTPAuth = true;                               // Enable SMTP authentication     $mail->Username = 'user@example.com';                 // SMTP username     $mail->Password = 'secret';                           // SMTP password     $mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted     $mail->Port = 587;                                    // TCP port to connect to      //Recipients     $mail->setFrom('from@example.com', 'Mailer');     $mail->addAddress('joe@example.net', 'Joe User');     // Add a recipient     $mail->addAddress('ellen@example.com');               // Name is optional     $mail->addReplyTo('info@example.com', 'Information');     $mail->addCC('cc@example.com');     $mail->addBCC('bcc@example.com');      //Attachments     $mail->addAttachment('/var/tmp/file.tar.gz');         // Add attachments     $mail->addAttachment('/tmp/image.jpg', 'new.jpg');    // Optional name      //Content     $mail->isHTML(true);                                  // Set email format to HTML     $mail->Subject = 'Here is the subject';     $mail->Body    = 'This is the HTML message body <b>in bold!</b>';     $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; } 

Answers 4

get an instance from any cloud provider, send REST request to that instance or whatever you prefer, then your original web server's ip will be totally invisible.

Answers 5

There is no API or elegant way to hide your IP from emails that you're sending. Any SMTP provider who offers this is worthy of blacklisting and would be immediately overcome by spammers signing up to abuse this privacy.

You must use your idea of creating an internal Web relay system to send to other IPs before initiating SMTP. But the hassle of setting that up should be more of a hassle than rebuilding your current site with another IP.

This sounds like a classic case of treating your server like a pet instead of like cattle. If rebuilding your current site on a new IP is less attractive than building and maintaining a custom Web API to hide your IP from exposure, you need to investigate automation tools.

Read More

Saturday, December 30, 2017

PHP imap_fetchbody can't get HTML a tag link url

Leave a Comment

I'm building a email read script, it read emails via imap, when i try to read email body using imap_fetchbody it only show texts, but email body have one link it seems not show,

This is my code

    $hostname = '{mail.test.com/notls}INBOX';     $username = 'info@test.com';     $password = 'testopw';      /* try to connect */     $inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Email Server: ' . imap_last_error());     /* grab emails */     $emails = imap_search($inbox,'SEEN FROM "noreply@test.com"'); if($emails) {      /* put the newest emails on top */     rsort($emails);     /* for every email... */     foreach($emails as $email_number) {         /* get information specific to this email */                        echo $message = imap_fetchbody($inbox,$email_number,1); } } 

The email contents is like below

 We do our utmost to arrive to you on time. There may, however,  be unexpected circumstances, causing our driver to be delayed.  You can follow the current status of your assignment here. 

When i read the email from mail client text here has a link, but when read that using php it only shows a text,

Email screen shot here enter image description here someone know what is the reason for this issue or is there need to change some parameters for get the link with url. Thank You

1 Answers

Answers 1

You have to check the multiple sections of the email. You can actually read the source code of an email. It is quite easy to follow and you will identify the different sections.

imap_fetchbody($inbox,$email_number,$section); 

http://php.net/manual/en/function.imap-fetchbody.php

(empty) - Entire message 0 - Message header 1 - MULTIPART/ALTERNATIVE 1.1 - TEXT/PLAIN 1.2 - TEXT/HTML 2 - file.ext 

The section you mention on the comments it is a PNG file. Some sections can be encoded in base64 as the email it is a text based protocol.

https://www.base64decode.org/

Example of an email:

 From: Nathaniel Borenstein <nsb@bellcore.com>   To:  Ned Freed <ned@innosoft.com>   Subject: Sample message   MIME-Version: 1.0   Content-type: multipart/mixed; boundary="simple   boundary"    This is the preamble.  It is to be ignored, though it   is a handy place for mail composers to include an   explanatory note to non-MIME compliant readers.   --simple boundary    This is implicitly typed plain ASCII text.   It does NOT end with a linebreak.   --simple boundary   Content-type: text/plain; charset=us-ascii    This is explicitly typed plain ASCII text.   It DOES end with a linebreak.    --simple boundary--   This is the epilogue.  It is also to be ignored. 

https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html

Read More

Saturday, December 23, 2017

Accessing Gmail (or a secure website) without getting a PKIX certification path error

Leave a Comment

Sending an e-mail via gmail resulted in getting a PKIX certification path error. The same applied to sending an e-mail from Tomcat.

After solving the issue, I hope you find this post useful. This post provides you with a step by step diagnosis for these kinds of errors.

Step 1: I tried to solve the problem using this post and another post, but that did not help me. In most cases this will be sufficient. You can use the keytool to list the certificates via 'keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"'

I added the certificate by clicking the lock-icon of the gmail URL and exporting/importing the certificate to the cacert file of my used JDK version. I could see with keytool -list that the certificate was added. This process is described well in the (linked) posts.

Step 2A: Was I using the right truststore? I added the JVM arguments to direct the certificate search, like -Djavax.net.ssl.trustStore="..../jre/lib/security/cacerts" -Djavax.net.ssl.trustStorePassword="changeit".

Step 2B: When I change the value of the cacerts file to cacertsXYZ I get the error. So, this proofed that the 'cacert' was used.

Caused by: javax.mail.MessagingException: Can't send command to SMTP host; nested exception is: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

Step 2C: Was this also the case for my Tomcat webserver? I verified that in the cacerts of my JRE_HOME that the certificate was there. In Tomcat my JRE_HOME is "C:\Program Files\Java\jdk1.8.0_144\jre". My JAVA_HOME = C:\Program Files\Java\jdk1.8.0_144.

Step 3: I tried with publicly available 'SSLPoke' Java class to see whether I could connect with Google and or smtp.gmail.com. The results are in the listing: I could connect with SSL to google.com AND mail.google.com via port 443.

try {             SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();             // **Fail** TLS - SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("smtp.gmail.com", 587);             // **Fail** SSL - SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("smtp.gmail.com", 465);             // **OK**             SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("google.com", 443);             // OK             SSLSocket sslsocket2 = (SSLSocket) sslsocketfactory.createSocket("mail.google.com", 443);              InputStream in = sslsocket.getInputStream();             OutputStream out = sslsocket.getOutputStream();             out.write(1); // write test byte to get reaction.             while (in.available() > 0) {                 System.out.print(in.read());             }             System.out.println("Successfully connected");         } catch (Exception exception) {             exception.printStackTrace();         } 

Step 4: The trusted store could be corrupt? I installed a newer version of the JDK1.8 being v152. I restarted the application without any success. Had this to do with the difference between JDK and JRE? Only the JRE has a lib\security\cacerts file. I tried both the SSL (465) and TLS (587) ports. Nope.

Step 5: Running openssl (with s_client -connect smtp.gmail.com:587 -starttls smtp) showed that my virus scanner (Avast) was prohibiting the sending of secure mail. So, for a moment I disabled this email-shield. That gave the following error:

java.lang.RuntimeException: javax.mail.AuthenticationFailedException

Step 6: After releasing the virusscanner web shield, using the openssl gave the following error: CN = Google Internet Authority G3 verify error:num=20:unable to get local issuer certificate.

OpenSSL> s_client -connect smtp.gmail.com:587 -starttls smtp CONNECTED(00000280) depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3 verify error:num=20:unable to get local issuer certificate ....

Allowing the 'gmail account to be accessable from weakly authenticated apps', a setting in your google account, that finally yielded in correctly sending the e-mail. This is the link to the security settings of your Google account.

Step 7: Sending e-mail from another server may be a problem. Authentication errors are (still) the result. To overcome these errors, you can do:

Notice: The mkyong example is the base of my simple test application.

1 Answers

Answers 1

Finally I found the answer.

1 - Of course the google/gmail certifcates were ok ;-) Step 1 was performing these kinds of checks. Trying to add the certificate CA by hand, etc. See above.

2 - Step 2 was checking whether the known 'SSLPoke' Java class Java class could get contact with the secure website.

3 - After checking all above checks, executing 'openssl' showed that my virus scanner email-shield blocked the traffic. Stopping this defence for some time was step 3.

4 - Then I got the 'not authenticated' error from Gmail. Allowing the 'gmail account accessable from weakly authenticated apps', that finally gave a correctly sent e-mail. This is an Google account security setting

Read More

Friday, September 8, 2017

PEAR Mail unable to connect to Gmail SMTP, failed to connect to socket

Leave a Comment

Facts

I am using PEAR Mail, I want to use gmail SMTP to send a mail. I have Apache/2.4.27 (Win64) PHP/7.2.0beta3, PEAR 1.10.15, Mail 1.4.1, Net_SMTP 1.8.0, Net_Socket 1.2.2.

I went to php.ini and added extension = php_openssl.dll. The error.log gives no ssl-related errors.

Here is the code

require_once "Mail.php";  $from = '<slevin@gmail.com>'; $to = '<slevinkelevra@gmal.com>'; $subject = 'Hi!'; $body = "Hi,\n\nHow are you?";  $headers = array(     'From' => $from,     'To' => $to,     'Subject' => $subject );  $smtp = Mail::factory('smtp', array(         'host' => 'ssl://smtp.gmail.com',         'port' => '465',         'auth' => true,         'username' => 'slevinmail@gmail.com',         'password' => 'mypassword'     ));  $mail = $smtp->send($to, $headers, $body);  if (PEAR::isError($mail)) {     echo('<p>' . $mail->getMessage() . '</p>'); } else {     echo('<p>Message successfully sent!</p>'); } 

The problem

I get this error

Failed to connect to ssl://smtp.gmail.com:465 [SMTP: Failed to connect socket: fsockopen(): unable to connect to ssl://smtp.gmail.com:465 (Unknown error) (code: -1, response: )]

and I have no clue what to do, I Googled but I got more confused.

Please advice on how to fix this. Thank you

Update

Following symcbean's instructions I got the following results :

bool(true)   array(5) {  [0]=> string(31) "alt3.gmail-smtp-in.l.google.com"  [1]=> string(26) "gmail-smtp-in.l.google.com"  [2]=> string(31) "alt4.gmail-smtp-in.l.google.com"  [3]=> string(31) "alt1.gmail-smtp-in.l.google.com"  [4]=> string(31) "alt2.gmail-smtp-in.l.google.com" }  IPV4 address = 64.233.188.27  If you've got this far without errors then problem is with your SSL config  Check you've got your cacerts deployed in one of the following locations default_cert_file = C:\Program Files\Common Files\SSL/cert.pem default_cert_file_env = SSL_CERT_FILE default_cert_dir = C:\Program Files\Common Files\SSL/certs default_cert_dir_env = SSL_CERT_DIR default_private_dir = C:\Program Files\Common Files\SSL/private default_default_cert_area = C:\Program Files\Common Files\SSL ini_cafile =  ini_capath =   If all good so far, then this bit should work.... fsockopen  Warning: fsockopen(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in C:\Apache24\htdocs\phptest2.php on line 28  Warning: fsockopen(): Failed to enable crypto in C:\Apache24\htdocs\phptest2.php on line 28  Warning: fsockopen(): unable to connect to ssl://smtp.gmail.com:465 (Unknown error) in C:\Apache24\htdocs\phptest2.php on line 28 bool(false) int(0) string(0) ""  

Line 28 is this line var_dump(fsockopen("ssl://smtp.gmail.com", 465, $errno, $errstr, 3.0));

Thanks again

Update #2

I googled just "fsockopen(): SSL operation failed with code 1." of the first warning.

End up here . I changed the mail port of the AVG, like the answer. symcbean's code run with no errors, but my code replied with mail error : authentication failure [SMTP: Invalid response code received from server (code: 534, response: 5.7.14 Please log in via your web browser and 5.7.14 then try again. 5.7.14 Learn more at 5.7.14 https://support.google.com/mail/answer/78754 c1sm1243434wre.84 - gsmtp)]

So I googled code: 534, response: 5.7.14 and end-up here, followed the instructions of the first answer by emgh3i, enabled less secured connections and allowed access to my google account

And its working perfectly now.

7 Answers

Answers 1

Few debugging steps :

1. check phpinfo

I recommend checking phpinfo() to check whether all modules are enabled. Check for mail, fsocketopen.

2. Enable debug flag

Enable debug flag to check exactly what's the problem. Like below.

$smtp = Mail::factory('smtp', array(         'host' => 'ssl://smtp.gmail.com',         'port' => '465',         'auth' => true,         'debug' => true,         'pipelining' => true,         'username' => 'xxx@gmail.com',         'password' => 'xxx'     )); 

After running above code on my machine I got follow response. Issue can be different from yours. But debug helped me. As I have 2FA enabled, it gave me error. And I got a mail also, that my login has been blocked.

DEBUG: Recv: 220 smtp.gmail.com ESMTP s65sm4891344pfi.36 - gsmtp DEBUG: Send: EHLO localhost DEBUG: Recv: 250-smtp.gmail.com at your service, [110.227.210.84] DEBUG: Recv: 250-SIZE 35882577 DEBUG: Recv: 250-8BITMIME DEBUG: Recv: 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH DEBUG: Recv: 250-ENHANCEDSTATUSCODES DEBUG: Recv: 250-PIPELINING DEBUG: Recv: 250-CHUNKING DEBUG: Recv: 250 SMTPUTF8 DEBUG: Send: AUTH LOGIN DEBUG: Recv: 334 VsadfSFcm5hbWU6 DEBUG: Send: cGF0ZWwuZ29wYhkafdaASFnbWFpbC5jb20= DEBUG: Recv: 334 UGFzc3dvcmQ6 DEBUG: Send: OWwzMy5zaHlAbTE4 DEBUG: Recv: 534-5.7.14 Please log in via your web browser and DEBUG: Recv: 534-5.7.14 then try again. DEBUG: Recv: 534-5.7.14 Learn more at DEBUG: Recv: 534 5.7.14 https://support.google.com/mail/answer/78754 s65sm4891344pfi.36 - gsmtp DEBUG: Send: RSET DEBUG: Send: QUIT DEBUG: Recv: 250 2.1.5 Flushed s65sm4891344pfi.36 - gsmtp DEBUG: Recv: 221 2.0.0 closing connection s65sm4891344pfi.36 - gsmtp authentication failure [SMTP: Invalid response code received from server (code: 534, response: 5.7.14 Please log in via your web browser and 5.7.14 then try again. 5.7.14 Learn more at 5.7.14 https://support.google.com/mail/answer/78754 s65sm4891344pfi.36 - gsmtp)] 

Update:

Your issue looks like PHP is not even able to connect to gmail server.

Answers 2

Your host configuration shouldn't contain the protocol. The reason it's failing is because it's probably trying to perform a DNS Lookup on ssl://smtp.gmail.com and failing.

Change

'host' => 'ssl://smtp.gmail.com', 

to

'host' => 'smtp.gmail.com', 

Answers 3

Your code is correct

I tried to test my gmail account. Mail sending was successful.

Check your socket connection

<?php  error_reporting(E_ALL);  var_dump(fsockopen("ssl://smtp.gmail.com", 465, $errno, $errstr)); var_dump($errno); var_dump($errstr); 

resource(4) of type (stream)

int(0)

string(0) ""

Answers 4

Been Kyung-yoong is the only person to have made a meaningful contribution to solving the problem so far (+1 Been!). I can confirm his result. And I would recommend you try the same. You are currently trying to debug a rather complex stack of components:

Been is doing your job for you - as the person posting the question - should be creating a Minimal, Complete, and Verifiable example

This will hopefully also provide more meaningful diagnostic information.

The most likely reasons for this to be failing are:

  • the host you are running this on cannot route outgoing connections to the internet (but since you seem to be using a desktop PC, I would think you might have noticed this by now)
  • the code is running within a security sandbox (but MSWindows doesn't really have such things)
  • the host is unable to resolve the hostname (see first point about routing)
  • the host is able to connect but unable to verify the certificate

Hence you might consider this more elaborate implementation of a test script:

 <?php   error_reporting(E_ALL);   print "DNS\n";  var_dump(getmxrr('gmail.com',$result));  var_dump($result);  $use_ip=gethostbyname($result[0]);  print "IPV4 address = $use_ip\n";   print "\nIf you've got this far without errors then problem is with your SSL config\n";  $calocns=openssl_get_cert_locations();  if (count($calocns)) {      print "Check you've got your cacerts deployed in one of the following locations\n";      foreach ($calocns as $k=>$v) print "$k = $v\n";  } else {      print "You've not configured your openssl installation on this host\n";  }   print "\nIf all good so far, then this bit should work....\n";  print "fsockopen\n";  var_dump(fsockopen("ssl://smtp.gmail.com", 465, $errno, $errstr, 3.0));  var_dump($errno);  var_dump($errstr); 

Which should give you a response like this:

 DNS  bool(true)  array(5) {    [0]=>    string(31) "alt1.gmail-smtp-in.l.google.com"    [1]=>    string(31) "alt2.gmail-smtp-in.l.google.com"    [2]=>    string(31) "alt4.gmail-smtp-in.l.google.com"    [3]=>    string(26) "gmail-smtp-in.l.google.com"    [4]=>    string(31) "alt3.gmail-smtp-in.l.google.com"  }  IPV4 address = 74.125.131.26   If you've got this far without errors then problem is with your SSL config  Check you've got your cacerts deployed in one of the following locations  default_cert_file = /usr/lib/ssl/cert.pem  default_cert_file_env = SSL_CERT_FILE  default_cert_dir = /usr/lib/ssl/certs  default_cert_dir_env = SSL_CERT_DIR  default_private_dir = /usr/lib/ssl/private  default_default_cert_area = /usr/lib/ssl  ini_cafile =  ini_capath =   If all good so far, then this bit should work....  fsockopen  resource(4) of type (stream)  int(0)  string(0) "" 

Given that we can't replicate your error we can't give a definitive answer what the problem is - but my guess would be that you haven't configure openSSL.

Answers 5

Before I begin, let me preface this that there are many possibly solutions and outcomes between your server and the google server, so these may or may not work for different people.

1) SMTP is not very secure, so Google may be rejecting your request. I had this problem 6 months ago and the solution was enabling insecure apps under 'myaccount.google.com'

enter image description here

2) If that doesn't work for you then you may consider switching protocols.

from

'host' => 'ssl://smtp.gmail.com',

to

'host' => 'tls://smtp.gmail.com:587';

Answers 6

  • The "Use the Gmail SMTP Server" section of this guide says you need to enable "Less secure apps".

  • I notice that the from address you are using for the message is not the same as the Gmail account you are using to send. I would guess that is a problem. Try using $from = '<slevinmail@gmail.com>';, so that address is the same one you are using in the 'username' => 'slevinmail@gmail.com', field.

Answers 7

When something fail and we don't know the cause we have to do debugging. So here instead of putting an answer I am requesting you to execute some tests

  1. confirm system connectivity with internet: Open cmd terminal and type

    ping smtp.gmail.com 
  2. confirm firewall: Enter following in cmd terminal

    telnet smtp.gmail.com 465 
  3. confirm php setup: enter php -a at cmd terminal and on php prompt execute (copy / paste and then press enter) following code.

    $result = fsockopen('ssl://smtp.gmail.com', 465, $error_no, $error_message, 5); if ($result === false) {   echo "error no: $error_no error message: $error_message";   echo print_r($result, true); } else {   echo 'success'; } 
  4. confirm Pear Mail library and Gmail SMTP access: again on cmd and php prompt php -a execute your own code (as you posted in this thread)

And lets know where it breaks, and what is the error. Only after that we can help

Read More

Saturday, September 2, 2017

Laravel 5 SwiftMailer's Send: how to get error code

Leave a Comment

Good day guys,

I am sending email similar to this: Laravel 5: Sending Email. This is how I do it:

$mail_status = Mail::send( 'emails.followup', $data, function( $message ) use ($data) {                  $message->to( $data['email'] )                          ->from( $data['email_from'], $data['email_name'] )                          ->subject( $data['subject'] );                     });  if($mail_status) {     $ret_status = 'sent'; } else     $ret_status = 'sent_failed'; 

Now, if the $ret_status is 'sent_failed', I want to know what happened. How do I do it? How can I see the message from the mail server?

Here is my .env file:

MAIL_DRIVER=smtp MAIL_HOST=mail.mydomain.com MAIL_PORT=465 MAIL_USERNAME=noreply@mydomain.com MAIL_PASSWORD=thepassword MAIL_ENCRYPTION=ssl 

UPDATE:

Looks like the approach above is Laravel 4. If you know how to get the error code using Laravel 5+, I can consider it as the correct answer.

3 Answers

Answers 1

You can use try catch for that, also you mistaken that use $email, $email_from, $email_name, $subject without passing into function scope.

try{     $mail_status = Mail::send( 'emails.followup', $data, function( $message ) use ($data, $email, $email_from, $email_name, $subject) {                         $message->to( $email )                         ->from( $email_from, $email_name )                         ->subject( $subject );                     });     //If error from Mail::send     if($mail_status->failures() > 0){         //Fail for which email address...         foreach(Mail::failures as $address) {             print $address . ', ';         }         exit;     }   } catch(\Exception $e){     // Get error here     print $e->getMessage();     exit; } 

Added failure printing for email address to check email fail for which address.

Answers 2

Checking Mail::failures() immediately after Mail::send() will return an array of failed email addresses you tried to send an email to.

However, as far as I know you cannot get the exact error on failure using Mail facade. For that, you need to set the debug true on your .env and check on Laravel log.

Answers 3

  1. To get dev version of errors (on screen), set in your .env file APP_DEBUG=true
  2. To get the exact message, do do the try catch, but catch Swift_TransportException https://stackoverflow.com/a/42221501/2119863
  3. You may also, if needed, get the mailer instance via app('mailer') and do some research there.

here is a working example:

try{     $mail_status = Mail::send( 'emails.followup', $data, function( $message ) use ($data) {         $message->to( $data['email'] )         ->from( $data['email_from'], $data['email_name'] )         ->subject( $data['subject'] );     }); }catch(\Swift_TransportException $e){     dd($e, app('mailer')); } 

and the dd() result:

Swift_TransportException {#237 ▼   #message: """     Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required\r\n     "     """   #code: 530   #file: ... 
Read More

Monday, August 14, 2017

Laravel 5.4 using Mail fake with Mail::queue, Mail::assertSent not working

Leave a Comment

I am writing unit test for a code that sends email with Mail::queue function, like the one in the documentation: https://laravel.com/docs/5.4/mocking#mail-fake

My Test:

/** @test */ public function send_reminder() {      Mail::fake();       $response = $this->actingAs($this->existing_account)->json('POST', '/timeline-send-reminder', []);      $response->assertStatus(302);       Mail::assertSent(ClientEmail::class, function ($mail) use ($approver) {           return $mail->approver->id === $approver->id;      }); } 

Code being Tested:

Mail::to($email, $name)->queue(new ClientEmail(Auth::user())); 

Error Message:

The expected [App\Mail\ClientEmail] mailable was not sent. Failed asserting that false is true. 

The email is sent when I manually test it, but not from Unit Test. I'm thinking it might be because I am using Mail::queue instead of Mail::send function.

In .env file, I have

QUEUE_DRIVER=sync and MAIL_DRIVER=log 

How can I test Mail::queue for Laravel?

1 Answers

Answers 1

I have searched around this issue I found this

https://stackoverflow.com/a/44354201/5853931

I hope it helps you

Read More

Monday, June 26, 2017

SMTP Friendly Name in 3 different places — still doesn't show

Leave a Comment

I have specified the SMTP friendly name in my code and in my web.config file, but once the email gets sent, the friendly name is not there. Please see my setup below. In all these instances, I've tried both "Friendly Name" <email@email.com> (with quotes) as well as Friendly Name <email@email.com> (without quotes), but neither makes a difference; both show up in inbox as being from the email address, no friendly name.

Here's IIS: enter image description here

Here's web.config: enter image description here

And here's my code:

var message = new MailMessage {     From = new MailAddress(fromAddress, fromFriendly),     Sender = new MailAddress(fromAddress, fromFriendly),     Body = messageBody,     Subject = subject,     IsBodyHtml = true };    

UPDATE: I moved my code to a different server, and it started working. Turns out my code was fine

(ノಠ益ಠ)ノ彡┻━┻ So what would cause this to happen??

3 Answers

Answers 1

Assuming information is being correctly retrieved from your configuration file, this works with no need for any additional settings:

    protected void Page_Load(object sender, EventArgs e)     {         var message = new MailMessage         {             From = new MailAddress(fromAddress, "Friendly Name"),             Subject = "Test Friendly Name",             Body = "Friendly name works !"         };          message.To.Add(recipient);          var client = new SmtpClient         {             Host = "smtp.gmail.com",             Port = 587,             EnableSsl = true,             UseDefaultCredentials = false,             Credentials = new NetworkCredential             {                 UserName = username,                 Password = password             }         };          client.Send(message);     } 

enter image description here


EDIT: I just tried the very same code using account / host information from our domain and it works just as good:

enter image description here

Answers 2

Use the overload constructor of the MailAddress like you have in your code.

I would remove the Friendly Name specified in the Configuration. The configuration setting should just have the Email Address listed.

UPDATE:

I wrote a sample code with the exact same settings and sent email through our internal mail relay. The email was sent fine and did display the friendly name in the sent email.

The one thing I would check is any network policy if any is in place within your network to trim the friendly name display while sending mail internally/externally.

Answers 3

You could try an encoded markup in your from attribute.

<smtp deliveryMethod="Network" from="Friendly Displayname &lt;your.mail@domain.com&gt;"> 

I know this still does not explain why it works on another server without this format.

Read More

Wednesday, April 26, 2017

Populating Quick Type Bar Options on IOS Devices

Leave a Comment

I have an input type email.

<form>   E-mail:   <input type="email" name="email"> </form> 

As soon as the user start typing, I would like to give them the option of most popular emails. Ex. @gmail.com ...

See the image below for details.

enter image description here

How would one go about and implement something like this? Is there any plug-in or framework that help me achieve this kind of task?

Will HTML/CSS/JS have the ability to do that or only swift2 can ?

2 Answers

Answers 1

QuickType is part of the built-in iOS keyboard, and here is no way to access and/or modify it with JavaScript from a simple website. Unfortunately, you can't even detect the keyboard's height, and position some fake QuickType-like buttons over the keyboard, because the keyboard animates up from the bottom, over the current application without resizing or moving anything.

I'm afraid your only option is to add these as small buttons under the input, or maybe you can create something similar to the iOS copy/paste menu, that becomes visible, when the user starts typing in the input, and append the email endings on a click/touch.

Answers 2

I agree with @frzsombor, but I can think of a different workaround. It would take a lot of code though, so it might not be worth it. Anyway, what you could do is periodically take a screenshot and check for one of the colors on the keyboard in a certain position, maybe #ACB3BB (the return button color). If it is there, you could display another Quick Type Bar above the built-in one. The only problem would be if an update to iOS changes what the bar looks like, but you could always update your website. Another possible way to detect the keyboard is here. I think you need jQuery for that, though...

Read More

Thursday, April 20, 2017

SMTP email message with SSL not working with GoDaddy email address in ASP.NET

Leave a Comment

When I try to send STMP email in ASP.NET using SSL on my new GoDaddy email address, it does not work. I receive an error message saying Unable to read data from the transport connection: net_io_connectionclosed.

Here are the email settings for the server:

enter image description here

Here's the snippet from my web.config with the email server information:

<system.net>   <mailSettings>     <smtp from="no-reply@mysite.com" >       <network host="smtpout.secureserver.net" port="465" userName="no-reply@mysite.com" password="password123" enableSsl="true" />     </smtp>   </mailSettings> </system.net> 

And here's the C# code that sends the email.

MailMessage message = new MailMessage(); message.To.Add(new MailAddress(to)); message.Subject = "Message from " + inputModel.Name; message.Body = body; message.IsBodyHtml = true;  using (var smtp = new SmtpClient()) {     smtp.Send(message); } 

Ports 80, 3535, and 25 work fine without SSL, but none of the four work with SSL. I even tried port 587 with SSL, and after quite a long time it just times out.

How can I get these emails to send using SSL?

2 Answers

Answers 1

Much about this in this older question, including the description of the problem - that SmtpClient only supports "explicit SSL", and you need to do "implicit SSL" to just talk SSL on port 465 directly.

A better and more modern approach than those options discussed there, is to use a well maintained library that has implicit SSL support. MailKit would be a good way to go for this.

Alternatively, consider using a third-party email relay service, such as SendGrid, Mandrill, Mailgun, and others. Doing so will greatly improve your odds of users to actually receive your mail in their inbox rather than a spam/junk folder.

Answers 2

From your Screenshot i'm assuming your site is hosted outside the godaddy so then you can use "smtpout.secureserver.net" .

if your site hosted on godaddy then you need to change config as follows:

 <system.net>       <mailSettings>        <smtp from="no-reply@mysite.com">         <network host="relay-hosting.secureserver.net"/>        </smtp>       </mailSettings>     </system.net> 

If you want to use Explicit ssl Try to change the Port From 465 to 587

For Implicit SSL we used netimplicitssl :

here is the sample taken from this answer

var mailMessage = new MimeMailMessage(); mailMessage.Subject = "test mail"; mailMessage.Body = "hi dude!"; mailMessage.Sender = new MimeMailAddress("you@gmail.com", "your name"); mailMessage.IsBodyHtml = true; mailMessage.To.Add(new MimeMailAddress("yourfriend@gmail.com", "your friendd's name"));  mailMessage.Attachments.Add(new MimeAttachment("your file address")); var emailer = new SmtpSocketClient(); emailer.Host = "your mail server address"; emailer.Port = 465; emailer.EnableSsl = true; emailer.User = "mail sever user name"; emailer.Password = "mail sever password" ; emailer.AuthenticationMode = AuthenticationType.PlainText; emailer.MailMessage = mailMessage; emailer.OnMailSent += new SendCompletedEventHandler(OnMailSent); //Send email emailer.SendMessageAsync();  // A simple call back function: private void OnMailSent(object sender, AsyncCompletedEventArgs asynccompletedeventargs) {     Console.Out.WriteLine(asynccompletedeventargs.UserState.ToString()); } 
Read More

Sunday, April 9, 2017

Expected response code 220 but got code “” with message “”

Leave a Comment

Every time I submit the contact form on my Laravel application I receive the error message in the title. I've followed the recommendation in this discussion, but it has had no effect even after php artisan cache:clear and php artisan config:cache. Here's the relevant code:

.env

MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=username@gmail.com MAIL_PASSWORD=password MAIL_ENCRYPTION=ssl 

config/mail.php

<?php  return [     'driver' => env('MAIL_DRIVER', 'smtp'),     'host' => env('MAIL_HOST', 'smtp.gmail.org'),     'port' => env('MAIL_PORT', 587),     'from' => [         'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),         'name' => env('MAIL_FROM_NAME', 'Example'),     ],     'encryption' => env('MAIL_ENCRYPTION', 'tls'),         'username' => env('MAIL_USERNAME'),     'password' => env('MAIL_PASSWORD'),     'sendmail' => '/usr/sbin/sendmail -bs',     'markdown' => [         'theme' => 'default',          'paths' => [             resource_path('views/vendor/mail'),         ],     ],  ]; 

I was under the impression from the documentation that the global 'from' wouldn't fire unless no other from address was provided, but in my controller for the mail, I specified the address supplied to the contact form as the 'from,' is that a conflict point somehow? It doesn't seem to be from the error message details.

Because the contact form is not a distinct view but the bottom of the mainpage view, the Controller function lives in PageController

public function postContact(Request $request) {     $this->validate($request, [        'email' => 'required|email',       'subject' => 'required|min:3',       'message' => 'required|min:10'     ]);      $data = array(       'email' => $request->email,       'subject' => $request->subject,       'mailbody' => $request->message     );      Mail::send('emails.contact', $data, function($message) use ($data) {       $message->from($data['email']);       $message->to('username@gmail.com');       $message->subject($data['subject']);     });   } 

2 Answers

Answers 1

I think you should define mail sender (MAIL_FROM_ADDRESS) as your gmail which you want to use send emails with.

for example, if your MAIL_USERNAME at .env is example@gmail.com you should define your MAIL_FROM_ADDRESS (or of course $mail->from()) as example@gmail.com.

I don't think gmail allows you send emails as another user (another address).

Answers 2

Similar problem 587 port

MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=username@gmail.com MAIL_PASSWORD=mypassword 
Read More

Sunday, April 2, 2017

ANDROID: email client receiver email id empty in android-parse

Leave a Comment

I'm using android- parse server in app. below is parse db screenshot of email column . the email column is after the hidden password column in database .

parse database screenshot

my problem is


when i retrieve email ids to email client, email is null even if the email column has emails .


note : in the app in another place (another table) i'm pulling email ids to email client in same manner, but there mail is showing well .. only here the problem occurs.

if anyone knows please help ?

this is email column in parse database

 try{                         JSONObject jsonObject = parseObjectToJson(object);                         Log.d("Object", jsonObject.toString());                         Log.d("Email", "+" + object.get("email"));                         personNumber = jsonObject.getString("telephone");                         personEmail = jsonObject.getString("email");                     }catch (JSONException je){                      }catch (ParseException pe){                      } 

this is email button

  emailPerson = (Button)findViewById(R.id.individualEmail);             emailPerson.setOnClickListener(new View.OnClickListener() {                 @Override                 public void onClick(View v) {                     Intent i = new Intent(Intent.ACTION_SEND);                     i.setData(Uri.parse("mailto:"));                     i.setType("plain/text");                     i.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {personEmail});                     startActivity(i);                 }             });             if(personEmail==null || personEmail.equals("")  || personEmail.equals(" ")){                 emailPerson.setClickable(false);                 emailPerson.setEnabled(false);                 emailPerson.setVisibility(View.GONE);             }             else{                 emailPerson.setEnabled(true);                 emailPerson.setClickable(true);                 emailPerson.setVisibility(View.VISIBLE);             } 

here it is working fine but this is a different table in same database . >in this table there is no hidden password field

try{                             corporateEmail = jsonObject.getString("email");                             if(corporateEmail == null || corporateEmail.equals("")){                                 emailCorporate.setVisibility(View.GONE);                                 emailCorporate.setEnabled(false);                                 emailCorporate.setClickable(false);                             } 

emailCorporate = (Button) findViewById(R.id.corporateEmail);         emailCorporate.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 Intent i = new Intent(Intent.ACTION_SEND);                 i.setData(Uri.parse("mailto:"));                 i.setType("plain/text");                 i.putExtra(Intent.EXTRA_EMAIL, new String[] {corporateEmail});                 startActivity(i);             }         }); 

 private JSONObject parseObjectToJson(ParseObject parseObject) throws ParseException, JSONException, com.parse.ParseException {         JSONObject jsonObject = new JSONObject();         parseObject.fetchIfNeeded();         Set<String> keys = parseObject.keySet();         for (String key : keys) {             Object objectValue = parseObject.get(key);             if (objectValue instanceof ParseObject) {                 jsonObject.put(key, parseObjectToJson(parseObject.getParseObject(key)));             } else if (objectValue instanceof ParseRelation) {             } else {                 jsonObject.put(key, objectValue.toString());             }         }         return jsonObject;     } 

1 Answers

Answers 1

if jsonObject is not null check to see if the parse database you are pulling your data from has the the "email" tag

Read More

Tuesday, January 31, 2017

Can you and how do you embed images in an email when using the Gmail API?

Leave a Comment

When creating a message and using it to create a draft or email using the Gmail API, can you have an image embedded in the body? I'm looking to have the image data actually embedded similar to how copying and pasting an image (the actual data, not the link) into a Gmail email will place the image right in the content.

Can it be done like this or do I need to upload the image to some other location and use HTML to embed the image in the email? Any pointers on how to do it?

1 Answers

Answers 1

The short answer is that you would do this the same way you would for any email service.

The long answer is that you need to create a multipart/related message, where one part is the HTML content of the email and the other part is the image. The image part contains a Content-ID header that specifies an ID for the image, and the HTML image tag references that ID in the src attribute using the format cid:ID_HERE.

An example of how to construct such an email in Python is here: http://stackoverflow.com/a/1633493

P.S. - A great way to see how emails are constructed is to look at the raw message. You can look at the raw message for a given email in Gmail by clicking the drop down arrow next to the message and selecting "Show original".

Read More

Thursday, June 30, 2016

Remove default Android padding from HTML emails

Leave a Comment

I have a responsive email layout where some elements stretch the entire width of the viewport, whatever that may be.

In Android (native mail and Gmail app on 4.4 at least) There appears to be a ~10px padding on either side. Is there any property or trick for negating this?

(I feel like this question should have been asked somewhere already, but searches provide only completely unrelated HTML email margin issues, so sorry if this is a duplicate).

Tried

Cancelling out the body margin. This affected the layout but did not fix the issue. The result of the following code simply removed the padding on the left but doubled the padding on the right in the native app.

html, body{     padding:0 !important;     margin:0 !important;     width:100% !important; } div[style*="margin: 16px 0"] {      margin:0 !important;      font-size:100% !important;      width:100% !important;  } 

No change in the Gmail app.

More insights

It seems the body remains the same width in the viewport regardless of width settings. If you set the width to 1000px, the email is shrunk to fit in the area with the margin on either side. The margin can be cancelled out using margin:0 on the body but the body stays the same size, resulting in the extra space appearing on the right.

I believe that the client is programmatically resizing the email to fit in a given width. The only way around this is likely to somehow "trick" the client. Nothing seems to have worked yet...

1 Answers

Answers 1

The problem is simply margins, the Android 4.4 email client is applying a margin value on all sides (but its not actually visible on the right side), so even before your email message is rendered, its messed with overall viewport already.

You can normalize it, via the below block.

body { margin:0 !important; } div[style*="margin: 16px 0"] { margin:0 !important; font-size:100% !important; } 

https://blog.jmwhite.co.uk/2015/09/19/revealing-why-emails-appear-off-centre-in-android-4-4-kitkat/

Read More

Saturday, June 25, 2016

certificate problems trying to send email with libcurl

Leave a Comment

This is my libcurl code. I am trying to send email to my own email domain in linux.

This is my sample libcurl code.

curl_easy_setopt(curl, CURLOPT_USERNAME, "username@mydomain.com");     curl_easy_setopt(curl, CURLOPT_PASSWORD, "mypassword");     curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.mydomain.com:25");     curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);     curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);     recipients = curl_slist_append(recipients, TO);     curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);     curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_size);     curl_easy_setopt(curl, CURLOPT_READFUNCTION, fileBuf_source);     curl_easy_setopt(curl, CURLOPT_READDATA, &file_upload_ctx);     curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //Dont display Curl Connection data Change 1L to 0      res = curl_easy_perform(curl); 

When I run this code, I am getting the below error.

* Rebuilt URL to: smtp://mail.mydomain.com:25/ * Hostname was NOT found in DNS cache *   Trying <My mail domain Ip address>... * Connected to mail.mydomain.com (<My mail domain Ip address>) port 25 (#0) < 220 mail.mydomain.com ESMTP > EHLO client6 < 250-mail.mydomain.com < 250-PIPELINING < 250-SIZE 20480000 < 250-VRFY < 250-ETRN < 250-STARTTLS < 250-AUTH PLAIN LOGIN < 250-ENHANCEDSTATUSCODES < 250-8BITMIME < 250 DSN > STARTTLS < 220 2.0.0 Ready to start TLS * successfully set certificate verify locations: *   CAfile: none   CApath: /etc/ssl/certs * SSL certificate problem: self signed certificate * Closing connection 0 curl_easy_perform() failed: Peer certificate cannot be authenticated with given CA certificates 

1 Answers

Answers 1

Your issue is that your server is providing a self-signed certificate so curl is not able to verify its provenance. You have several options:

  • The best option is to get a server certificate that is signed by a well-known certificate authority. Some CAs will issue a certificate you can use for free; search for "free ssl certificate". You will need to be able to provide some proof that you control the domain.

  • You can install your self-signed certificate to the list of trusted CAs on the computer(s) that run your libcurl code. The procedure to do this depends on your OS (even different distributions of Linux may do this differently). This link is a decent starting point for Linux.

  • Your program can tell libcurl to verify with the self-signed certificate. See Adding self-signed SSL certificate for libcurl.

  • You can create your own certificate authority and use either of the previous two approaches. The advantage of this over self-signing is it decouples the signing and the signed certificates. If you want to change the server certificate (e.g. if it expires or the host name changes) you don't necessarily need to reconfigure all the clients.

  • For completeness, you could disable verification by setting CURLOPT_SSL_VERIFYPEER to 0. This is highly discouraged, however, as it makes the access insecure. You should only do this for testing purposes, or in the rare case that the network between client and server is guaranteed to be secure.

Read More

Tuesday, June 14, 2016

Getting the new ID after moving an email in IMAP

Leave a Comment

I am using the IMAP functions in PHP to handle my emails and import them into the database. After they are imported, I move each email to a different folder to keep things seperated.

public function moveMail($mailId, $mailBox) {     return imap_mail_move($this->getImapStream(), $mailId, $mailBox, CP_UID) && $this->expungeDeletedMails(); } 

After moving them, I determine whether or not the email is relevant. If it isn't, I want to move it to a second folder. However, after moving it, the internal mail id is changed and so I can no longer move the email.

I am looking for a way to get the id of the moved email so I can move it a second time.

Any ideas?

3 Answers

Answers 1

(This is not PHP specific and does not answer your question directly)

There are two ways this is usually done:

1) The UIDPLUS extension, if supported, should give a COPYUID response in the OK response. This includes the UIDVALIDITY and new UID in the new folder when you copy the message.

2) When this fails, opening a new connection or switching to the destination folder, and doing a UID SEARCH for the Message-ID header. If you get a single response, that's probably your message. If you get multiple responses, the highest one is probably your message (assuming multiple clients aren't copying messages with the same Message-ID at about the same time.) Since Message-ID is a sender sent header, and is not necessarily unique (messages can be duplicated), this is imperfect, but gives reasonable results most of the time. The downside is it is slow.

Luckily, nearly all servers support UIDPLUS. Unfortunately, the PHP library probably does not.

Answers 2

After searching for a while I found out that there is no solution in the imap library in PHP to get the new uid. I wondered if I could just get the last uid and increment it by one but since a new email could come in that won't work either.

What might be my best solution is to use the UIDPLUS IMAP extension and consult the APPENDUID response code.

Conclusion

My final conclusion is that if the above mentioned extension is not available and your mail server does not support SEARCH HEADER, it is simply not possible to find a message by its Message-id and for that reason impossible to ever know what ID my new email got assigned.

Answers 3

The documentation tells the UID should not change: http://php.net/manual/en/function.imap-uid.php

Read More

Monday, April 11, 2016

dynamic group e-mail aliases from a database

Leave a Comment

I can remember working in groups where a group e-mail alias was available with a possibility, probably dynamic, to require a targeted delivery : e.g., all_except_mike@work.com would be resolved as all e-mails except Mike's. I have no clue how this was achieved, but I believe the solution could help me in what I'm willing to do, which is what follows.

I manage a group of people with a number of specialities (say, development and operations) and projects (say, Spoutnik and Apollo). I would like them to be able to exchange e-mails within subgroups based on either or both characteristic, e.g. spoutnik@work.com or operations@work.com or development_apollo@work.com. I would like to allow cross-mailing from anyone part of the larger group to subgroups it doesn't belong to, but not e-mails from the exterior (or only with a moderation option). Mailing list software don't seem to handle this (maybe mailman does partly?), would the solutions used in the above paragraph do?

0 Answers

Read More

Monday, April 4, 2016

Rails 4, Devise & Mandrill emails

Leave a Comment

I'm trying to make an app in Rails 4.

For the past 3 years, I've been struggling to figure out devise/omniauth (I am still trying to get it to work).

Stepping aside from the main problems while I try and find the will to live through this, I've tried to setup emails with Mandrill.

I found this tutorial, which I am trying to follow along: https://nvisium.com/blog/2014/10/08/mandrill-devise-and-mailchimp-templates/

I have a mailer called mandrill_devise_mailer.rb

class MandrillDeviseMailer < Devise::Mailer    def confirmation_instructions(record, token, opts={})     # code to be added here later   end    def reset_password_instructions(record, token, opts={})     options = {       :subject => "Reset your password",       :email => record.email,       :global_merge_vars => [         {           name: "password_reset_link",           # content: "http://www.example.com/users/password/edit?reset_password_token=#{token}"           content: "http://www.cr.com/users/password/edit?reset_password_token=#{token}"          },          {           name: "PASSWORD_RESET_REQUEST_FROM",           content: record.full_name          }       ],       :template => "Forgot Password"     }     mandrill_send options     end    def unlock_instructions(record, token, opts={})     # code to be added here later   end    def mandrill_send(opts={})     message = {        :subject=> "#{opts[:subject]}",        :from_name=> "Reset Instructions",       # :from_email=>"example@somecorp.com",       :from_email=>["PROD_WELCOME"],       :to=>             [{"name"=>"#{opts[:full_name]}",                 "email"=>"#{opts[:email]}",                 "type"=>"to"}],       :global_merge_vars => opts[:global_merge_vars]       }     sending = MANDRILL.messages.send_template opts[:template], [], message     rescue Mandrill::Error => e       Rails.logger.debug("#{e.class}: #{e.message}")       raise   end end 

The differences between the above and what they have done in the tutorial are:

In my mail chimp mandrill template, I have:

<a href="*|password_reset_link|*">Change my password </a> 

When I receive the email to reset the instructions, I get an underlined link to the change password form, which says 'change my password next to it. I want 'change my password to be the label which conceals the link text'.

Can anyone see what I've done wrong?

1 Answers

Answers 1

Here is how I created custom DeviseMailer

class MyDeviseMailer < Devise::Mailer      default template_path: 'devise/mailer' # to make sure that your mailer uses the devise views    def reset_password_instructions(record, token, opts={})     opts['from_email'] = "donotreply@mywebsite.com"     opts['from_name'] = "Password Reset"     #Rails.logger.mail.info "reset_password_instructions #{record.to_json} \n #{token.to_json} \n #{opts.to_json}"     super   end  end 

https://github.com/plataformatec/devise/wiki/How-To:-Use-custom-mailer and Add dynamic value in devise email subject

Read More