Jumat, 02 Desember 2016

Tutorial NodeMCU: Sending email through gmail smtp using less secure apps (ESP8266, WeMos, NodeMCU, Lua)

This paper was written by some references from the Internet related to sending email through gmail using STMP NodeMCU based devices. Sending mail via smtp gmail account requires security settings to the mode Less secure apps. 

 Picture 1. Less secure apps setting

To run this example, you need to customize the firmware NodeMCU Lua by including several modules as follows:

NodeMCU custom build by frightanic.com
    branch: master
    commit: ec265a6c21db22640795f190bdcb8a4f014cdced
    SSL: true
    modules: crypto,dht,file,gpio,http,net,node,rtctime,sntp,tmr,uart,wifi
 build     built on: 2016-12-02 13:05
 powered by Lua 5.1.4 on SDK 1.5.4.1(39cb9a32)
 
Working code:
-- Modification for GMAIL by Hendra Soewarno, for a better performance version
 --- Using response code from GMAIL to determine next step, and not try
 --- all the step when error response from GMAIL. The original version using
 --- timer and counter to determine each request to server.
 ----- Modifications for GMAIL by Andreas "Andy" Reischle: www.AReResearch.net
 ----- See https://support.google.com/a/answer/176600?hl=de for details on smtp with gmail
 ----- Now that NodeMCU has working SSL support, we can also talk to email services that
 ----- require encryption.
 ----- Caveat: I have not looked into the SSL implementation, but I suspect it is vulnerable
 ----- to man-in-the-middle attacks as the client doesn't check the server's certificate.
 ----- 20160415 ARe
 -----------Original Credits:
 -----------
 ---------- Working Example: https://www.youtube.com/watch?v=CcRbFIJ8aeU
 ---------- @description a basic SMTP email example. You must use an account which can provide unencrypted authenticated access.
 ---------- This example was tested with an AOL and Time Warner email accounts. GMail does not offer unecrypted authenticated access.
 ---------- To obtain your email's SMTP server and port simply Google it e.g. [my email domain] SMTP settings
 ---------- For example for timewarner you'll get to this page http://www.timewarnercable.com/en/support/faqs/faqs-internet/e-mailacco/incoming-outgoing-server-addresses.html
 ---------- To Learn more about SMTP email visit:
 ---------- SMTP Commands Reference - http://www.samlogic.net/articles/smtp-commands-reference.htm
 ---------- See "SMTP transport example" in this page http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
 ---------- @author Miguel
 --no longer required because it is part of the crypto module: require("base64")
 -- The email and password from the account you want to send emails from
 local MY_EMAIL = "************@gmail.com"
 local EMAIL_PASSWORD = "e*********"
 -- The SMTP server and port of your email provider.
 -- If you don't know it google [my email provider] SMTP settings
 local SMTP_SERVER = "smtp.gmail.com"
 local SMTP_PORT = "465"
 -- The account you want to send email to
 local mail_to = "hendra-it@*******.co.id"
 -- These are global variables. Don't change their values
 -- they will be changed in the functions below
 local email_subject = ""
 local email_body = ""
 local count = 0 -- will be used to determine next action
 local good_news = {"220", "250", "334", "334", "235", "250", "250", "354", "250", "221"}
 
 local smtp_socket = nil -- will be used as socket to email server

  -- The display() function will be used to print the SMTP server's response
 function display(sck,response)
    print("Got a response: ")
    print(response)
    response_code = string.sub(response,1,3)
    --print(response_code)
    --print(good_news[count+1])
    if(response_code~=good_news[count+1])then
        print("Send email failed!")
        count = 8 --Quit
    end 
    do_next()
 end
 -- The do_next() function is used to send the SMTP commands to the SMTP server in the required sequence.
 -- I was going to use socket callbacks but the code would not run callbacks after the first 3.
 function do_next()
       if(count == 0)then
         local IP_ADDRESS = wifi.sta.getip()
         print ("Send my IP: " .. IP_ADDRESS)
         smtp_socket:send("HELO "..IP_ADDRESS.."\r\n")
       elseif(count==1) then
         smtp_socket:send("AUTH LOGIN\r\n")
       elseif(count == 2) then
         smtp_socket:send(crypto.toBase64(MY_EMAIL).."\r\n")
       elseif(count == 3) then
         smtp_socket:send(crypto.toBase64(EMAIL_PASSWORD).."\r\n")
       elseif(count==4) then
         smtp_socket:send("MAIL FROM:<" .. MY_EMAIL .. ">\r\n")
       elseif(count==5) then
         smtp_socket:send("RCPT TO:<" .. mail_to ..">\r\n")
       elseif(count==6) then
         smtp_socket:send("DATA\r\n")
       elseif(count==7) then
         local message = string.gsub(
         "From: \"".. MY_EMAIL .."\"<"..MY_EMAIL..">\r\n" ..
         "To: \"".. mail_to .. "\"<".. mail_to..">\r\n"..
         "Subject: ".. email_subject .. "\r\n\r\n" ..
         email_body,"\r\n.\r\n","")
         smtp_socket:send(message.."\r\n.\r\n")
       elseif(count==8) then
          tmr.stop(0)
          smtp_socket:send("QUIT\r\n")
       else
         smtp_socket:close()
         print("Disconnected.")
       end
       count = count + 1
 end
 -- The connectted() function is executed when the SMTP socket is connected to the SMTP server.
 -- This function will create a timer to call the do_next function which will send the SMTP commands
 -- in sequence, one by one, every 5000 seconds.
 -- You can change the time to be smaller if that works for you, I used 5000ms just because.
 function connected(sck)
   print("Connected - Starting...")
 end
 -- @name send_email
 -- @description Will initiated a socket connection to the SMTP server and trigger the connected() function
 -- @param subject The email's subject
 -- @param body The email's body
 function send_email(subject,body)
    count = 0
    email_subject = subject
    email_body = body
    print ("Open Connection")
    smtp_socket = net.createConnection(net.TCP,1)
    smtp_socket:on("connection",connected)
    smtp_socket:on("receive",display)
    smtp_socket:connect(SMTP_PORT,SMTP_SERVER)
 end
 -- Send an email
 print ("Sending started...")
 send_email("ESP8266-GMailSender","Hi there from Hendra Soewarno!")
Scenario 1: Succeed result
Sending started...
Open Connection
Connected - Starting...
Got a response:
220 smtp.gmail.com ESMTP n17sm10345037pfg.80 - gsmtp

Send my IP: 172.21.12.106
Got a response:
250 smtp.gmail.com at your service

Got a response:
334 VXNlcm5hbWU6

Got a response:
334 UGFzc3dvcmQ6

Got a response:
235 2.7.0 Accepted

Got a response:
250 2.1.0 OK n17sm10345037pfg.80 - gsmtp

Got a response:
250 2.1.5 OK n17sm10345037pfg.80 - gsmtp

Got a response:
354  Go ahead n17sm10345037pfg.80 - gsmtp

Got a response:
250 2.0.0 OK 1480729924 n17sm10345037pfg.80 - gsmtp

Got a response:
221 2.0.0 closing connection n17sm10345037pfg.80 - gsmtp

Disconnected.

Scenario 2: Failed result cause by invalid username or password:
Sending started...
Open Connection
Connected - Starting...
Got a response:
220 smtp.gmail.com ESMTP y200sm10420052pfb.16 - gsmtp

Send my IP: 172.21.12.106
Got a response:
250 smtp.gmail.com at your service

Got a response:
334 VXNlcm5hbWU6

Got a response:
334 UGFzc3dvcmQ6

Got a response:
535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8  https://support.google.com/mail/?p=BadCredentials y200sm10420052pfb.16 - gsmtp

Got a response:
221 2.0.0 closing connection y200sm10420052pfb.16 - gsmtp

Disconnected.
Scenario 3:  Failed result cause by not set Less secure apps option to ON
Open Connection
Connected - Starting Timer
Got a response:
220 smtp.gmail.com ESMTP f132sm10155943pfa.72 - gsmtp

Send my IP: 172.21.12.106
Got a response:
250 smtp.gmail.com at your service

Got a response:
334 VXNlcm5hbWU6

Got a response:
334 UGFzc3dvcmQ6

Got a response:
534-5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbsC
534-5.7.14 tAI07EFTWQ94dXI6x41TyfjIFDp_NIYPEzYsY3XzS04a7E3blJJsFKjG73SKKcBX0dyrSX
534-5.7.14 2JHBhmdVqZJjGZVUMOmHoEKaLbxvktU8REWZrutoRNO-WU3a1VZ2r0jl49OWir6nt-stsf
534-5.7.14 zMidIGW5QGmbdlK3bnQRUflcL3XlCTL0M2MjM5os1xQJVeZuG3Fsd65l-zc9T364YtYMVk
534-5.7.14 2N1LRsEQoIYeXU4IxmNOmC_G-jzwk> Please log in via your web browser and
534-5.7.14 then try again.
534-5.7.14  Learn more at
534 5.7.14  https://support.google.com/mail/answer/78754 f132sm10155943pfa.72 - gsmtp
Got a response:
221 2.0.0 closing connection y200sm10420052pfb.16 - gsmtp

Disconnected.

Tidak ada komentar:

Posting Komentar