Node.js sendmail without library
I'm sick of being fucked by sudden API changes by 3rd party library. So here's a 70 lines of codes to send email by using Socket.
* This setup is good for when you have a centralized local relay such as postfix or exim4.
* Does not support attachments, it's only 70 lines of codes and I'm sure you can modify it to suit your needs.
* If the mail content starts with . then it'll go funny. You can fix this easily by replacing the starting . with ... So I'm not going to fix this here since all my mail does not start with .
Debug logs from this blog
* This setup is good for when you have a centralized local relay such as postfix or exim4.
* Does not support attachments, it's only 70 lines of codes and I'm sure you can modify it to suit your needs.
"use strict";
const net = require( "net" );
const [ HOST, PORT ] = "localhost:25000".split( ":" );
const MAIL_FROM = "noreply@example.com";
const Sendmail = ( address, senderName, subject, mesg, callback ) => {
subject = subject.replaceAll( "\r", "" ).replaceAll( "\n", "" );
mesg = mesg.replaceAll( "\r", "" ).replaceAll( "\n.", "\n.." );
senderName = senderName.replaceAll( "\"", "\\\"" ).replaceAll( "'", "\\'" );
var _mesgs = [
[
( x ) => ( x.indexOf( "220 " ) === 0 )
, ""
]
, [
( x ) => ( x.indexOf( "250-" ) === 0 )
, `EHLO ${HOST}`
]
, [
( x ) => ( x == "250 2.1.0 Ok" )
, `MAIL FROM: <${MAIL_FROM}>`
]
, [
( x ) => ( x == "250 2.1.5 Ok" )
, `RCPT TO: ${address}`
]
, [
( x ) => ( x.indexOf( "354 End data with" ) === 0 )
, `DATA`
]
, [
( x ) => ( x.indexOf( "250 2.0.0 Ok" ) === 0 )
, `From: "${senderName}"<${MAIL_FROM}> \nTo: ${address}\nSubject: ${subject}\n\n${mesg}\r\n.\r`
]
, [
( x ) => ( x.indexOf( "221 2.0.0" ) === 0 )
, `QUIT`
]
];
var i = 0, l = _mesgs.length;
var _error = new Error( "Unknown error occurred" );
var sock = net.connect( PORT, HOST, () => {
console.log( `CONNECTED TO: ${HOST}:${PORT}` );
});
sock.addListener( "error", ( e ) => { _error = e; } );
sock.addListener( "data", x => {
x = x.toString().trim();
var [ expect, data ] = _mesgs[i];
console.log( `SMTP: < ${x}` );
if( expect( x ) )
{
if( ( i + 1 ) < l )
{
[ expect, data ] = _mesgs[++i];
console.log( `SMTP: > ${data}` );
sock.write( data + "\r\n" );
}
}
else
{
_error = new Error( `${x}: "${data}"` );
sock.destroy( _error );
}
});
sock.addListener( "close", ( hadError ) => {
console.log( "Connection closed" );
if( hadError )
{
callback( _error );
}
else
{
callback();
}
});
};_mesgs[][]
The lambda ( x ) => ( x == "250..." ) is the expected return from the server. Following is the data to write to the server. Use the output to craft your on lambda expect.Caveats
* Only use this to connect to a local mail server ( e.g. exim4 / postfix ) since this does not support TLS or authentication. Use a library if you want those features.* If the mail content starts with . then it'll go funny. You can fix this easily by replacing the starting . with ... So I'm not going to fix this here since all my mail does not start with .
Usage
Sendmail(
"test@example.com", "My Sender Name"
, "Test Mail Subject"
, "Test Mail Content"
, ( err ) => {
if( err )
console.error( err );
} );
Outputs
CONNECTED TO: localhost:25000
SMTP: < 220 postfix-69676b6b47-546sn.localdomain ESMTP Postfix
SMTP: > EHLO localhost
SMTP: < 250-postfix-69676b6b47-546sn.localdomain
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
SMTP: > MAIL FROM: <noreply@example.com>
SMTP: < 250 2.1.0 Ok
SMTP: > RCPT TO: test@example.com
SMTP: < 454 4.7.1 <test@example.com>: Relay access denied
Connection closed
Error: 454 4.7.1 <test@example.com>: Relay access denied: "RCPT TO: test@example.com"Debug logs from this blog
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: > MAIL FROM: <noreply@astropenguin.net>
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: < 250 2.1.0 Ok
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: > RCPT TO: tgckpg@gmail.com
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: < 250 2.1.5 Ok
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: > DATA
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: < 354 End data with <CR><LF>.<CR><LF>
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: > From: "Penguin\'s Blog // Rosemary"<noreply@astropenguin.net>
To: tgckpg@gmail.com
Subject: Test Mail Subject
Test Mail Content
.
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: < 250 2.0.0 Ok: queued as 588608E10A0
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: > QUIT
[ M:1001 ] [ 2022-09-02 08:32:06 ] SMTP: < 221 2.0.0 Bye
[ M:1001 ] [ 2022-09-02 08:32:06 ] Connection closed
Fri Sep 02 2022 07:57:53 GMT+0000 (Coordinated Universal Time)
Last modified: Fri Sep 02 2022 09:00:03 GMT+0000 (Coordinated Universal Time)
Comments
No comments here.
Do you even comment?
website:
Not a valid website
Invalid email format
Please enter your email
*Name:
Please enter a name
Submit
抱歉,Google Recaptcha 服務被牆掉了,所以不能回覆了