Skip to content

Instantly share code, notes, and snippets.

@irr
Forked from agentzh/gmail-stmp-tls.lua
Created August 18, 2016 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save irr/ab16f43f98c53f9f1e7e9d470003864a to your computer and use it in GitHub Desktop.
Save irr/ab16f43f98c53f9f1e7e9d470003864a to your computer and use it in GitHub Desktop.
local account = "blah@gmail.com" -- use your own gmail account
local password = "password" -- if you enable 2-phase authentication, you need to
-- generate and use a application-specific password here...
local sender_name = "Jon Snow"
local recipient = "recipient@foo.com"
local recipient_name = "Arya Stark"
local mail_title = "This is a test mail"
local mail_body = [[<html><body><p>Mail Body...</body></html>]]
----------------------------------------------
local find = ngx.re.find
local gsub = ngx.re.gsub
local sub = string.sub
local tostring = tostring
local tonumber = tonumber
local encode_base64 = ngx.encode_base64
local sock
local function send_cmd(cmd)
assert(sock:send(cmd .. "\r\n"))
ngx.say(">> ", cmd)
do
local lines = {}
local i = 0
local line = assert(sock:receive())
while true do
local fr, to, err = find(line, [[^(\d+)-]], "jo", nil, 1)
if err then
error("failed to call ngx.re.find: " .. tostring(err))
end
if not fr then
break
end
local status = tonumber(sub(line, fr, to))
if status >= 400 then
return nil, line
end
i = i + 1
lines[i] = line
line = assert(sock:receive())
end
local fr, to, err = find(line, [[^(\d+) ]], "jo", nil, 1)
if err then
error("failed to call ngx.re.find: " .. tostring(err))
end
if not fr then
error("syntax error: " .. line);
end
local status = tonumber(sub(line, fr, to))
if status >= 400 then
return nil, line
end
i = i + 1
lines[i] = line
ngx.say(table.concat(lines, "\n"))
end
return true
end
sock = ngx.socket.tcp()
assert(sock:connect("smtp.gmail.com", 587))
local line = assert(sock:receive())
ngx.say(line)
assert(send_cmd("EHLO smtp.gmail.com"))
assert(send_cmd("STARTTLS"))
assert(sock:sslhandshake()) -- well, we could verify the SSL handshake here...
assert(send_cmd("EHLO smtp.gmail.com"))
local auth = ngx.encode_base64("\0" .. account .. "\0" .. password)
assert(send_cmd("AUTH PLAIN " .. auth))
assert(send_cmd("MAIL FROM:<" .. account .. ">")) -- well, you could use a different email address than
-- the one specified in the account variable if you
-- have configured alternative "send email as" entries
-- in your gmail account
assert(send_cmd("RCPT TO:<" .. recipient .. ">"))
assert(sock:send("DATA\r\n"))
assert(sock:send("FROM: " .. sender_name .. " <" .. account .. ">\r\n"))
assert(sock:send("Subject: " .. mail_title .. "\r\n"))
assert(sock:send("To: " .. recipient_name .. " <" .. recipient .. ">\r\n"))
assert(sock:send("Content-Transfer-Encoding: base64\r\n"))
assert(sock:send("Content-Type: text/html; charset=utf-8\r\n\r\n"))
assert(sock:send(gsub(encode_base64(mail_body), [[(.{76})]], "$1\n", "jo") .. "\n"))
assert(send_cmd("\r\n."))
assert(send_cmd("QUIT"))
assert(sock:close())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment