How to check if email was sent by SMTP

I set up an email procedure in my Web App. The purpose is to send emails emails about several events in the app, both to users and to myself as the admin.

I used the way it was described by Paul Lelebvre in: https://documentation.xojo.com/topics/communication/internet/sending_email_from_your_app.htmlHo

However I used another SMTP server and did some minor changes.


MailSemaphore.Signal

' Connect to mailersend
MailSocket.Address = "smtp.mailersend.net"
MailSocket.Port = 587

MailSocket.SSLConnectionType = SSLSocket.SSLConnectionTypes.TLSv1 
MailSocket.SMTPConnectionType = SMTPSecureSocket.SMTPConnectionTypes.STARTTLS  '.ModeSSLTLS
MailSocket.Secure = True
MailSocket.SSLEnabled = True

MailSocket.Username = "***********"
MailSocket.Password = "***********"

' Create EmailMessage
Var mail As New EmailMessage
mail.FromAddress = "chiel@harmsenvanseters.nl"
mail.AddRecipient(toAddress)
mail.Subject = subject
mail.BodyPlainText = message
mail.Headers.AppendHeader("X-Mailer","SMTP Test")

' Send it
MailSocket.Messages.AddRow(mail)

MailSocket.SendMail
MailSocket.Close    '' added because I got error messages saying a time out occured while closing the connection - seems to have solved that problem

CurrentSession = sess

Nothing seems to be happing when I activate this code with the next line:

App.SendMail("chiel@harmsenvanseters.nl", "Nieuw wachtwoord voor de Koormuziekbank", "Nieuwe wachtwoord is: Welkom123", Session)

Any clue?

Moderator Edit: Removed potential user credentials. @Chiel_Harmsen , if that was a true password, I suggest you change it immediately.

I recommend that you subclass the SMTPSecureSocket, and then add logging to all of the events in the new subclass, which would look like this:

image

Also remove the line MailSocket.Close as this will prevent it working at all.

Are you getting ConnectionEstablished? ServerError?

1 Like

Thanks you, but honestly, I wouldn’t know how to fix that. Is there somewhere an example which I can follow?

First you need to check which error you get and then we can give you tips on how to fix the problem. For instance, your email sending code could go out of scope. You could use the wrong SSL value, the wrong port etc.

1 Like

Hi Chiel, I’m not sure what you are asking about, but here are some tips:
• Making a subclass: OOP design concepts — Xojo documentation.
• Adding Event Handlers: Event driven programming — Xojo documentation.
• Logging: Try adding
System.DebugLog CurrentMethodName
to each handler
When you run the debug app in the IDE, you will see these messages in the Messages pane if you click the icon at the bottom:
image

1 Like

This helped. Now I can see what’s going on. I tried to use the SMPT Server from a marketing service provider at which I opened an account. But they require all email-to addresses to be validated first, which is not an option.
Error message was: 450 The from.email domain must be verified in your account to send emails. #MS42207 (and 2 more errors) The from.email domain must be verified in your account to send emails. #MS42207,The recipient domain xxx.nl must be one of the verified domains.

Then I tried to use the office365 smtp server. I enabled SMTP for my Office365 account, but even then Office 365 did not allow my account to send SMTP mails.
Error message was: 535 5.7.139 Authentication unsuccessful, user is locked by your organization’s security defaults policy.

As I believe, Google (gmail.com) isn’t supporting SMTP for these purposes anymore, so I think I need to open a emailaccount at a provider that still supports this.
Any suggestions?

I use a hosting provider for hosting a couple of websites and a small number of domains. They provide email servers too, so I can have unlimited email addresses for any of the domains I own. Perhaps you need a service such as that?

I don’t know about recent changes, but the last time I tried to use gmail it worked, but it would also send a security notice to me every time my app would send an email :roll_eyes:

When was this that you last sent such a mail?

I’m guessing ca 2019…

OK. SInce then, Google decided it wanted to tighten things up, so it started by dis-allowing email clients from logging into gmail accounts to send mail, unless you, the gmail account owner, had previously gone into your gmail security settings and enabled “Allow less secure apps”. That was the first step.

Second step was to announce and some time later enforce that such less secure apps had to login to gmail via OAUTH2, and I wasn’t about to bother with that. Then, however, I found they allowed a work-around: if you enable two-factor authentication in your google account, AND ask (from within your account) to be given an app-specific password, and then use that password in your email client’s gmail account, that will allow your third-party email client to work with logging in to gmail just as it always had.

So what this boiled down to was their enforcing your use of a better password in your email client, for gmail logins. That is the situation today AFAIK and I’ve not had any more mails from google on the matter since then.

1 Like

Why is validating the domain not an option? It’s the default these days for sending emails with any marketing service.

How many emails do you need to send? If you want to send the occasional email then you can send the email with your hosting company. But this is not a good idea for more emails.

Hi Beatrix, Thanks for thinking along with me.
The first thing I want to use the emails for is to setup a password-forgotten procedure. So, whenever a user (with all kind of different emailadresses/domains) indicate that she/he forgot the password, a new password will be generated and a email is to be sent to the users emailaddress.
As I understand it, I should validate all users emailaddresses at the website of this marketing service provider. Appears to be not doable.

Nope, you need to validate your own domain and not the email address of your customers. The company should show you some arcane stuff that you have to add to your txt records of the domain or some such.

2 Likes

Probably an SPF record is needed for the domain you’re sending from.

Sender Policy Framework (SPF) records allow you to list the mail servers that are permitted to send email for your domain. Many email services will filter messages from domains that do not publish an SPF record, or that is sent from a server that is not listed in the SPF record for your domain.

2 Likes

Happy to tell you all that I was able to setup an email address and to use it successfully to send emails from my XOJO App.
Following Paul Lefebvre’s example (see video in: Sending email from your app — Xojo documentation) I was expecting to see a message box telling me that the email was sent. But that didn’t work. “No session available”

image

Any clue how to overcome this?

Thanks a lot.

The MailSent event happens asynchronously, which means it will not be associated with any session. If you need to associate it with a session, you’d need to store WebSession.Identifier when you queue the email, and then get the session again in the Mailsent event like this:

MailSent
  var s as Session = App.SessionWithIdentifier(id)

It would be possible for the session to be closed, or nil, by the time this event fires, so you should make sure you handle those situations.

1 Like

I get the rough idea, but I gues there’s more to it.

In the proc where I initiate the email, the sessionid added as parameter:

App.SendMail(“chiel@harmsenvanseters.nl”, “Nieuw wachtwoord voor de Koormuziekbank”, “Nieuwe wachtwoord is: xxxx”, currentSessionId)

In the App.MailSend proc this sessionid is placed in App property CurrentSession

CurrentSession = sess

And finaly, this is the MailSendHandler:

System.DebugLog CurrentMethodName

var csi as string = CurrentSession
var s as Session = App.SessionWithIdentifier(csi)

MessageBox “The email was sent”
MailSemaphore.Release ’ Release the Semaphore to make the socket available for use

Apparently, this is not enough.
Can you indicate the missing part?

Stuff that happens within the App. class is all “Sessionless”. Sessions only exist where a UI (Browser) is open.

A technique that I use is to have App methods (and Email events, for example) report their results to some properties of the App class (or written to a log file). I then use a Web Timer in my UI web page to periodically check the contents of those App. properties or log file to view the event results. But be aware that any App properties will be seen or shared with all sessions (users).

or, as mentioned elsewhere in this thread, you can push results from App events directly to a known Session(s) to force a screen update or MsgBox etc…

The general mindset has to be that App methods and events all happen on the server, but all UI that you (or your clients) see in a browser is driven by a unique Session that exists for each open screen.

In your example, I would subclass the mailer within the Session object, not App, in circumstances where the end-user is going to initiate the sending of the email (ie, password reset request). This way, the user’s Session gets access to the mailer events, and those events can be used to display progress bars, or status messages uniquely to that use…

1 Like