Simple solution to send gmail via smtp

I have seen many topic on SparkCore forms…but I could not understand them…
What is best and easiest solution for sending gmail with SparkCore?
I am not good at writing C language, so please kindly show me info. Code is better.

Hi @Daisuke,

I wrote an example app for sending emails and posted the code here: https://gist.github.com/dmiddlecamp/8943011

Thanks!
David

Thank you :wink: I try it now.

How can I include them?

#include "application.h"
#include <string.h>

Thanks

Hi @Daisuke,

Are you using the build IDE? (https://www.spark.io/build ) You can simply paste this code in and they should be included, no?

Thanks,
David

Hi, @Dave,

Yes. I am using IDE. Btw, I have tried your code already. And the Core changed LED to Red color once, and nothing happened.

To send an email should it make D0 HIGH, right?
Can it send Gmail?

Should I change only here, correct?

#define SMTP_SERVER "smtp.gmail.com"
#define SMTP_USER_BASE64 "base64_encode_your_user"
#define SMTP_PASS_BASE64 "base64_encode_your_pass"
#define SMTP_FROM_EMAIL "email@from.com"
#define SMTP_TO_EMAIL "email@to.com"

Thanks,
Daisuke

Hi @Daisuke,

The SMTP part is tricky, you need a SMTP server that will let you send email unencrypted, and it’s good to try stepping through the commands manually first. SMTP is one of those “ye olde internet” protocols where you could actually do it by typing out the commands in plain text. I’m not sure if this is possible with gmail, I believe I used the smtp server that came with a Dreamhost account I had setup, so if you have a web hosting account somewhere, I would try using theirs.

:smile:

Thanks,
David

Dave is 100% correct about gmail requiring encrypted connections now. Your ISP email is your best bet–since you are “inside” the ISPs network, they generally let you send mail using only username/password without encryption.

In addition to the items above, you may have to change the port number used for SMTP since many ISPs block port 25. Check you ISPs instructions for hooking up a scanner that can send email–many of these do not support encrypted email either and so the instructions will perfect for use with the Spark core.

If you can’t get your ISP to send email for you, then you will have to look at commercial services like mailgun etc. These generally work over HTTP GET/PUT requests.

Thanks @Dave and @bko,
How can I change SMTP port with this code?

The SMTP port is here:

int SendEmail(char *smtpServer, char *username, char *password, char *fromEmail, char *toEmail, char *subject, char *body) {
 
    if (!client.connect(smtpServer, 25)) {
         return 0;
    }

Change 25 to your ISPs port (587 etc.).

1 Like

Thanks replied to me. I appreciate your teach.

I have tried to use port 587 and 465 already. But it seems failed.

I got code below from Mailgun…but I don’t know how to adopt it to the code…
Could you kindly teach me how to use it on the code?

public static RestResponse SendSimpleMessage() {
    RestClient client = new RestClient();
    client.BaseUrl = "https://api.mailgun.net/v2";
    client.Authenticator =
           new HttpBasicAuthenticator("api",
                                      "----my auth-----");
    RestRequest request = new RestRequest();
    request.AddParameter("domain",
                        "sandbox65244.mailgun.org", ParameterType.UrlSegment);
    request.Resource = "{domain}/messages";
    request.AddParameter("from", "Mailgun Sandbox <postmaster@sandbox65244.mailgun.org>");
    request.AddParameter("to", "may email <may email@gmail.com>");
    request.AddParameter("subject", "Hello my name");
    request.AddParameter("text", "Congratulations my name, you just sent an email with Mailgun!  You are truly awesome!  You can see a record of this email in your logs: https://mailgun.com/cp/log .  You can send up to 300 emails/day from this sandbox server.  Next, you should add your own domain so you can send 10,000 emails/month for free.");
    request.Method = Method.POST;
    return client.Execute(request);
} 

Thanks!

Hi @Daisuke

Maybe before go translating the Mailgun code to Spark (which is possible but some work) we could find out more about what you are trying to do?

What is your ISP? Can we figure out if they offer unencrypted SMTP?

You need to send email–would Spark.publish() events work just as well?

Can you use a different service like pushingbox.com or twillo.com etc.?

Can you wait for the upcoming Spark.publish() webhooks which should make things like this easier?

1.What is your ISP? Can we figure out if they offer unencrypted SMTP?

my ISP is Jcom(Japanese ISP). The ISP allow us to use unencrypted SMTP blow.
smtp.jcom.zaq.ne.jp 587

2.You need to send email--would Spark.publish() events work just as well?

Yes, I need to send notification of door opening.

3.Can you use a different service like pushingbox.com or twillo.com etc.?

I can use pushingbox.com with PC. I have inputed "api.pushingbox.com/pushingbox?devid=MyDevid" to my google Chrome. I have received push mail from pushingbox.
But the core filed to use it.

I have tried your code already...

const char server[] = "api.pushingbox.com";
const char url[] = "/pushingbox?devid=v0123456789ABCDE";  //replace with your devid
TCPClient myTCP;

void setup() {

}

void loop() {
    sendGetRequest(server, url);
    delay(10000); //be nice every 10 seconds
}

void sendGetRequest(const char * server, const char * url)
{
    if (myTCP.connect(server, 80)) {
        myTCP.print("GET ");
        myTCP.print(url);
        myTCP.println(" HTTP/1.0");
        myTCP.println("Connection: close");
        myTCP.print("Host: ");
        myTCP.println(server);
        myTCP.println("Accept: text/html, text/plain");
        myTCP.println();
        myTCP.flush();
    } 
}

I have used posting twitter code, it succeeded to post.

// Message to Post
char msg[] = "Hi, I'm a tweet from a Spark Core!";

// OAuth Key
#define TOKEN "my TOKEN"

// Twitter Proxy
#define LIB_DOMAIN "arduino-tweet.appspot.com"

TCPClient client;

void setup()
{
    delay(1000);

    client.connect(LIB_DOMAIN, 80);
    client.println("POST /update HTTP/1.0");
    client.println("Host: " LIB_DOMAIN);
    client.print("Content-Length: ");
    client.println(strlen(msg)+strlen(TOKEN)+14);
    client.println();
    client.print("token=");
    client.print(TOKEN);
    client.print("&status=");
    client.println(msg);
}

void loop() {

}

You need to send email--would Spark.publish() events work just as well?
Can you wait for the upcoming Spark.publish() webhooks which should make things like this easier?

I don't know about Spark.publish(). How can I use it?

If the REST API requires https://, you probably won’t be able to do it from the Core. The same goes with sending e-mail using TCP port 465 since that it commonly used for SMTPS (SMTP over SSL). However, if your ISP uses SMTP ports 25 or 587, you might be able to use TCPClient to send e-mail using simple SMTP commands. I don’t have a Core plugged in that I can test with, but Microsoft has a good example of a simple plain-text SMTP conversation for sending e-mail that makes for a good starting point. I tested with our local SMTP relay server here at work using telnet and it worked quite well.

I can’t speak for non-US ISPs, but many ISPs in the United States block outbound TCP ports 25 and 587 and require you to use their SMTP servers. By ISPs, I mean the company that provides the internet connection to your home or work, not the company who provides your e-mail hosting (although, they could be the same company, too!). You may need to check your ISP’s FAQ or troubleshooting section to see if outbound SMTP is restricted and if they offer an alternative for their customers.

Thanks @wgbartley Noted.
I will try it later.
If I cannot use Gmail and SMTP, what is alternative solution that sends me notification? I want receive it with Android phone and iPad.

So I am not sure what is wrong with the pushingbox.com code. I just tried it and it sent me emails until I stopped it. May sure you cut and paste the devid so that it is correct.

Was there anything special you had to do to make the twitter code work? One of the disadvantages of twitter is that you cannot send the same tweet over and over.

Spark.publish() is a new feature that was just announced–you can read a tutorial about it here:

I think e-mail is the only common protocol supported by those two devices. You might be able to use something like Prowl on your iPad. I don't have any Android devices on-hand to test, but you might be able to find a growl client for Android. I'm not sure on how you could send a single notification to a Growl service and also have it forward to Prowl, but it should be possible...in theory.

I really wish I had brought my :spark: to work instead of unplugged on the dining table. :frowning: This stuff would be fun to play with!

Good morning @bko

I have tried to change internet connection of Jcom to another one(Docomo).
Eventually the Core succeeded to push email by Pushingbox with your code. I think your Pushing Box code is just sending URL to Pushingbox server, right? I cannot find out what is issue. Do you have any idea?

By the way, I got error message with Gmail code what does it mean?

    Connected!
    waiting for the server to say hello...
    220heard response.
    Saying hello back.
     mx.google.com ESMTP c7sm12545292pbt.0 - gsmtp
    EHLO smtp.gmail.com
     mx.google.com ESMTP c7sm12545292pbt.0 - gsmtp
    250heard response.
    logging in...
    AUTH LOGIN
    -mx.google.com at your service, [110.132.238.21]
    250-SIZE 35882577
    250-8BITMIME
    250-STARTTLS
    250-ENHANCEDSTATUSCODES
    250 CHUNKING
    530 5.7.0 Must issue a STARTTLS command first. c7sm12545292pbt.0 - gsmtp
    timed out.
*beep* 64base my email
    502 5.5.1 Unrecognized command. c7sm12545292pbt.0 - gsmtp
    timed out.
*beep* 64base my password
    502 5.5.1 Unrecognized command. c7sm12545292pbt.0 - gsmtp
    timed out.
    sending mail...
    MAIL FROM:<iamworkingwell@gmail.com>
    RCPT TO:<zima.zima.zima@gmail.com>
    DATA
    from: iamworkingwell@gmail.com
    to: zima.zima.zima@gmail.com
    subject: Door notification
    
    Body body body
    .
    
    530 5.7.0 Must issue a STARTTLS command first. c7sm12545292pbt.0 - gsmtp
    530 5.7.0 Must issue a STARTTLS command first. c7sm12545292pbt.0 - gsmtp
    530 5.7.0 Must issue a STARTTLS command first. c7sm12545292pbt.0 - gsmtp
    502 5.5.1 Unrecognized command. c7sm12545292pbt.0 - gsmtp
    502 5.5.1 Unrecognized command. c7sm12545292pbt.0 - gsmtp
    554 5.7.0 Too Many Unauthenticated commands. c7sm12545292pbt.0 - gsmtp
    timed out.
    quit
    
    timed out.

Yes, in particular it just does a HTTP GET request which pushingbox.com can interpret as a command to post an event. It is just like when you go to a web page in your browser.

That is why I asked if you had to do anything special for the Twitter example--it uses a service similar to pushingbox.com but for Twitter. Do you use a proxy to connect to the internet for example?

My code completely throws away the response from the web server (pushingbox.com in this case) and assumes it has connected. You should probably look at client.available() and client.read() the response from the server and print it to the Serial port (over USB) to help debug this problem.

In your example from gmail, it says:

This means that gmail requires an encrypted connection using TLS via the STARTTLS command. The Spark core cannot directly send email using gmail service since it cannot do TLS encryption right now. You must use a service on the internet to act between the core and gmail. Pushingbox.com is one such service, but Spark will be introducing their own service that can do this in the future.