Android Question Using SMTP to send email via a SSL enabled server

Anser

Well-Known Member
Licensed User
Longtime User
Hi,

I used to send emails from my already existing B4A existing app as well as from my PHP Webapplication.

Few days back I changed the Email Service provider. The new service provider uses SSL.

In my PHP web application the following code works fine now and I am able to send email successfully.
B4X:
$mail = new PHPMailer;
$mail->Host = "mail.myemailserver.com";
$mail->Port = 587;
$mail->SMTPSecure = 'tls';
$mail->SMTPAuth = true;

$mail->Username = "[email protected]";
$mail->Password = "MyPassword";

I am unable to send emails from the same email server using B4A with the following code which is equivalent to the above given PHP code

B4X:
iPort = 587
SMTP.Initialize(sServer, iPort, sUser, sPW, "SMTP" )
SMTP.AuthMethod = SMTP.AUTH_LOGIN '
SMTP.StartTLSMode = True

The email is not sent and I get the following LastException.Message
java.lang.RuntimeException: Empty writer returned: 503 5.5.1 Error:need RCPT command

Tried SMTP.UseSSL = True along with above given code, but I get the same error as statd above in red color

I tried different combinations like StartTLSMode = True, UseSSL = True etc

Contacted the service provider and collected the log and as per them the following is the log and their explanation

LOG from the Email Service Provider :-
Jul 7 12:12:26 mail postfix/submission/smtpd[16044]: NOQUEUE: reject: RCPT from unknown[My IP Address]: 554 5.7.1 <unknown[My IP Address]>: Client host rejected: Access denied; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<MyLanIP>

Explanation from the Email Service Provider :-
The above error is generated in the mail log: This issue occurs when the username/password is not passed through successfully to our server. If the username/password is not passed to our server successfully, the server will block the IP from establishing a connection to our MTA. (Mail Transfer Agent).

If I use
B4X:
SMPT.UseSSL = True
SMTP.StartTLSMode = False
SMTP.AuthMethod = SMTP.AUTH_LOGIN

The email is not sent and I get the following LastException.Message
javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb7ba0e88: Failure in SSL library, usually a protocol error
error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol (external/openssl/ssl/s23_clnt.c:766 0x96f92926:0x00000000)



The php code used to send email is working fine on the same server.

May I know how to enable "My Server require authentication" via SMTP
Is the code SMTP.AuthMethod = SMTP.AUTH_LOGIN is what that does the above ?

It is not an Internet Service provider issue blocking port 587, I tried sending the email using the Emulator, My Phone via 4G and from my phone via Wi-Fi

Any hep will be appreciated.

Regards
Anser
 
Last edited:

Anser

Well-Known Member
Licensed User
Longtime User
Have you tried it with AUTH_PLAIN and StartTLSMode ?
Yes I tried that too. I get the same runtime exception message
java.lang.RuntimeException: Empty writer returned: 503 5.5.1 Error: need RCPT command

What is the equivalent for "My Server Requires Authentication" using this SMTP ?. My Email Service Provider say that this is not done in the app and that is the cause of this issue.
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
What is the equivalent for "My Server Requires Authentication" using this SMTP ?
It is one of the authentication modes.

java.lang.RuntimeException: Empty writer returned: 503 5.5.1 Error: need RCPT command
This is a different error. Can you post the code that you use to send the mail?
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
Can you post the code that you use to send the mail?
B4X:
#Region  Project Attributes
    #ApplicationLabel: Test Postiefs Email
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Private SMTP As SMTP
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
 
    Dim IME1 As IME
    Private sv As ScrollView
    Private UseSSL,StartTLSmode As Boolean
    Private nAuthTpe As Int

    Private btnSendMail As Button
    Private cbStartTLSmode As CheckBox
    Private cbUseSSL As CheckBox
    Private etMailServer As FloatLabeledEditText
    Private etMessage As FloatLabeledEditText
    Private etPort As FloatLabeledEditText
    Private etSmtpPassword As FloatLabeledEditText
    Private etSmtpUser As FloatLabeledEditText
    Private etSubject As FloatLabeledEditText
    Private etToAddress As FloatLabeledEditText
    Private LblStatus As Label
    Private spnrAuthMethode As Spinner
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("sv")
    Activity.Title = "Test Email Service"
 
    sv.Panel.LoadLayout("MessagingScreen")
    sv.Panel.Height = sv.Panel.Height + 250dip
 
    etMessage.EditText.SingleLine = False
 
    LblStatus.Text = ""
    LblStatus.Gravity = Bit.Or(Gravity.TOP,Gravity.FILL)
 
    UseSSL = False
    StartTLSmode    = False
    nAuthTpe = 0
 
    Dim mapAuthentications As Map    : mapAuthentications.Initialize
    mapAuthentications.Put(0,"")
    mapAuthentications.Put(1,SMTP.AUTH_PLAIN)
    mapAuthentications.Put(2,SMTP.AUTH_LOGIN)
    mapAuthentications.Put(3,SMTP.AUTH_CRAM_MD5)
 
    spnrAuthMethode.AddAll(Array As String("None","AUTH_PLAIN", "AUTH_LOGIN", "AUTH_CRAM_MD5"))
    spnrAuthMethode.Tag = mapAuthentications


End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub cbUseSSL_CheckedChange(Checked As Boolean)
    If Checked = True Then
        UseSSL = True
    Else
        UseSSL = False
    End If
End Sub

Sub cbStartTLSmode_CheckedChange(Checked As Boolean)
    If Checked = True Then
        StartTLSmode = True
    Else
        StartTLSmode = False
    End If
End Sub

Sub spnrAuthMethode_ItemClick (Position As Int, Value As Object)
     nAuthTpe = Position
End Sub

Sub btnSendMail_Click
  Dim SpinnerMap As Map
  SpinnerMap = spnrAuthMethode.Tag                 
 
    LblStatus.Text = ""
    LblStatus.Text = "Auth Type : " & SpinnerMap.GetValueAt(nAuthTpe) & CRLF
     
    SMTP.Initialize( etMailServer.EditText.Text, etPort.EditText.Text, etSmtpUser.EditText.Text, etSmtpPassword.EditText.Text, "SMTP") 

    SMTP.UseSSL = UseSSL
    SMTP.StartTLSMode = StartTLSmode
 
    If nAuthTpe > 0 Then
        SMTP.AuthMethod = SpinnerMap.GetValueAt(nAuthTpe)
    End If     
 
    SMTP.To.Add(etToAddress.EditText.Text)
    SMTP.Subject = etSubject.EditText.Text
    SMTP.Body = etMessage.EditText.Text
 
     
    If UseSSL Then
        LblStatus.Text = LblStatus.Text & "Use SSL : Yes" & CRLF
    Else
        LblStatus.Text = LblStatus.Text & "Use SSL : No" & CRLF
    End If
 
    If StartTLSmode Then
        LblStatus.Text = LblStatus.Text & "StartTLSmode : Yes" & CRLF
    Else
        LblStatus.Text = LblStatus.Text & "StartTLSmode : No" & CRLF
    End If 
 
    SMTP.Send

    ProgressDialogShow("Sending Email")

End Sub

Sub SMTP_MessageSent(Success As Boolean)
  Log(Success)
  ProgressDialogHide
  If Success Then
        ToastMessageShow("Email Message sent successfully", True)
        LblStatus.Text = "Email Message sent successfully"
  Else
        ToastMessageShow("Error sending Email", True)
        LblStatus.Text = LblStatus.Text & "Error sending Email" & CRLF
        LblStatus.Text = LblStatus.Text &CRLF& LastException.Message
        Log(LastException.Message)
  End If
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
(This is not the correct way to use a Map. Use a List if you want to get the items based on the index.)

Here is a complete example that works with Gmail. Please try it with your server:
B4X:
Sub Process_Globals
   Private smtp As SMTP
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
     smtp.Initialize("smtp.gmail.com", 587, "[email protected]", "aaaaaaa", "smtp")
     smtp.StartTLSMode = True
   End If
End Sub

Sub Activity_Click
   smtp.To.Add("[email protected]")
   smtp.Body = "body"
   smtp.Subject = "Test"
   smtp.Send
   Log("sending message")
End Sub

Sub smtp_MessageSent(Success As Boolean)
   Log($"smtp: ${Success}"$)
   If Not(Success) Then Log(LastException)
End Sub
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
I get the same runtime exception message.

** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
sending message
smtp: false
(RuntimeException) java.lang.RuntimeException: Empty writer returned: 503 5.5.1 Error: need RCPT command
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
Spoke with the Mail Service Provider. They enabled Port 465 and advised to use SSL. Then the following code worked.

B4X:
Sub Process_Globals
   Private smtp As SMTP
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
     smtp.Initialize("smtp.gmail.com", 465, "[email protected]", "aaaaaaa", "smtp")
     smtp.UseSSL = True
   End If
End Sub

Sub Activity_Click
   smtp.To.Add("[email protected]")
   smtp.Body = "body"
   smtp.Subject = "Test"
   smtp.Send
   Log("sending message")
End Sub

Sub smtp_MessageSent(Success As Boolean)
   Log($"smtp: ${Success}"$)
   If Not(Success) Then Log(LastException)
End Sub
 
Upvote 0
Top