Minggu, 04 Desember 2016

Tutorial NodeMCU: Mengirim email beserta attachment melalui SMTP provider anda (ESP8266, WeMos, NodeMCU, Lua)

Tulisan ini membahas tentang pengiriman email melalui SMTP yang disediakan oleh provider anda. Dalam hal ini saya menggunakan internet Bolt, sehingga SMTP saya adalah:

local SMTP_SERVER = "smtp.internux.co.id"
local SMTP_PORT = "25"

Karena koneksi SMTP adalah tidak terenkripsi, sehingga ketika melakukan koneksi adalah menggunakan unsecure net socket connection.

smtp_socket = net.createConnection(net.TCP,0) -- 0 adalah unsecured
 Secara lengkap koding yang digunakan adalah:
-- Oleh Hendra Soewarno (0119067305)
  local MY_EMAIL = "hendra-it@internux.co.id"
 -- 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.internux.co.id"
 local SMTP_PORT = "25"
 -- The account you want to send email to
 local mail_to = "***********@gmail.com"
 -- 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", "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 = 5 --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("MAIL FROM:" .. MY_EMAIL .. "\r\n")
       elseif(count==2) then
         smtp_socket:send("RCPT TO:" .. mail_to .."\r\n")
       elseif(count==3) then
         smtp_socket:send("DATA\r\n")
       elseif(count==4) then
         fin=file.open("temp","r")

         -- read chunk by chunk from temp file to prevent 1460 hard limit
         local function send(localSocket)
            local msg_chunk=file.read(1024)
            if msg_chunk ~= nil then
               localSocket:send(string.gsub(msg_chunk,"\r\n.\r\n",""))
               print(msg_chunk)
            else
               smtp_socket:on("sent", function() end)
               localSocket:send("\r\n.\r\n") --end of message
            end
         end

         -- triggers the send() function again once the first chunk of data was sent
         smtp_socket:on("sent", send) -- trigger next chunck
         send(smtp_socket) -- send first chunck
      
       elseif(count==5) 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_plain, body_html, attachment)
    count = 0
    content = {}
    fin=file.open(attachment,"r")
    if fin then
       repeat
          local line=file.read(1024)
          if line then table.insert(content, line) end
       until not line     
       fin.close()     
    else
        print("File :" .. attachment .. " not found!")
        return 0
    end
  
    email_subject = subject
    -- put message at a temp file
    fout = file.open("temp","w")
    if fout then     
       fout:write("From: \"".. MY_EMAIL .."\"\r\n")
       fout:write("To: \"".. mail_to .. "\"\r\n")     
       fout:write("Subject: ".. email_subject .. "\r\n")
       fout:write("MIME-Version: 1.0\r\n")  
       fout:write("Content-Type: multipart/mixed; boundary=\"----=_MixPart_920403024\"\r\n\r\n")
       fout:write("------=_MixPart_920403024\r\n")
       fout:write("Content-Type: multipart/alternative; boundary=\"----=_AltPart_920403024\"\r\n\r\n")
       fout:write("------=_AltPart_920403024\r\n")
       fout:write("Content-type: text/plain; charset=iso-8859-1\r\n")
       fout:write("Content-Transfer-Encoding: quoted-printable\r\n\r\n")
       fout:write(body_plain .. "\r\n")
       fout:write("------=_AltPart_920403024\r\n")
       fout:write("Content-type: text/html; charset=iso-8859-1\r\n")
       fout:write("Content-Transfer-Encoding: quoted-printable\r\n\r\n")
       fout:write(body_html .. "\r\n")
       fout:write("------=_AltPart_920403024--\r\n")
       fout:write("------=_MixPart_920403024\r\n")
       fout:write("Content-Type: text/plain; name=" .. attachment .. "\r\n")
       fout:write("Content-Transfer-Encoding: 8bit\r\n")
       fout:write("Content-Disposition: attachment; filename=" .. attachment .. "\r\n\r\n")
       local i = 1
       while table.getn(content) > 0 do
           fout:write(table.remove(content,1))
       end
       fout:write("\r\n")
       fout:write("------=_MixPart_920403024--\r\n")
       fout:close()
    end
    print ("Open Connection")
    smtp_socket = net.createConnection(net.TCP,0)
    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 with attachment","Please refer to attachment","<p>Please refer to attachment!</p>","init.lua")

Tidak ada komentar:

Posting Komentar