λ¬Έμ λ° λ¬Έμ κ° λ°μνλ νκ²½μ λν μμ½. μ μ ν κ²½μ° λ²κ·Έλ₯Ό μ¬ννλ λ° νμν λ¨κ³λ₯Ό ν¬ν¨ν©λλ€. μ€ν¬λ¦° μ·, μ€ν¬λ¦° μΊμ€νΈ, μ½λ μμ λ₯Ό μμ λ‘κ² ν¬ν¨νμμμ€.
@ sendgrid / inbound-mail-parser ν¨ν€μ§λ₯Ό μ¬μ©νμ¬ μΈλ°μ΄λ μ΄λ©μΌμ ꡬ문 λΆμνλ λ°©λ²μ μμλΌ μ μμ΅λλ€. μμ μ½λκ° νμν©λλ€
sendgridμμ ꡬ문 λΆμ κ²½λ‘λ₯Ό μ€μ ν©λλ€ (μ¬κΈ°μ λ§ν¬ λ¨ :
https://www.dropbox.com/s/cb6lwrmon9qwjzq/Screenshot%202017-10-12%2016.03.49.png?dl=0)
λ€μμ ngrokμ κ²½λ‘μ λν μμ μ΄λ©μΌμ λ΄μ©μ
λλ€.
https://gist.github.com/machinshin/e38cf7d20ec6319edcfda63ff7aca594
νμ λ‘νΈλ₯Ό λ΄ μΉν μ λ€μκ³Ό κ°μ΄ μ°κ²°νμ΅λλ€.
router.post('/api/email/parseroute', (req, res, next) => {
// have also tried:
router.post('/api/email/parseroute', bodyParser.raw(), (req, res, next) => {
console.log(`-------------`)
console.log(req.body)
console.log(`-------------`)
console.log(req.rawBody)
console.log(`-------------`)
}
보μλ€μνΌ req.bodyλ λΉμ΄ μκ³ req.rawBodyλ 'undefined'μ
λλ€.
λ°λΌμ μμ μ΄λ©μΌ λ°μ΄ν°μ μ‘μΈμ€νλ λ°©λ², λμ€μ ν΄λΉ λ°μ΄ν°λ‘ 무μμν΄μΌνλμ§, μΈλ°μ΄λ λ©μΌ ꡬ문 λΆμκΈ°λ₯Ό μΈμ€ν΄μ€ννλ λ°©λ²μ΄ λͺ
ννμ§ μμ΅λλ€.
λ³΄κ³ λλ λ¬Έμ μ κ΄λ ¨νμ¬ κ³΅μ νλ €λ κΈ°ν μ 보. νΉν μ΄κ²μ΄ λ²κ·ΈλΌκ³ μκ°νλ μ΄μ λ 무μμ λκΉ? λμ μ΄λ€ μΌμ΄ μΌμ΄λ κ²μΌλ‘ μμν©λκΉ?
μλ νμΈμ @machinshin ,
μ κ³ ν΄ μ£Όμ μ κ°μ¬ν©λλ€. μΆκ° μ‘°μ¬λ₯Ό μν΄μ΄λ₯Ό λ°± λ‘κ·Έμ μΆκ°νμ΅λλ€.
μμ λν μ λ°μ΄νΈκ° μμ΅λκΉ? μ΄ νμλ₯Ό μ λ§λ‘ μ¬μ©ν΄μΌνλλ° λ°©λ²μ λͺ¨λ₯΄κ² μ΅λλ€.
μλ νμΈμ @ZeroCho ,
μ¬κΈ° μ ν¨ν€μ§κ° μμ§λ§ μνκΉκ²λ μ’μ μ¬μ© μ€λͺ μκ° μμ΅λλ€. μ΄λ₯Ό μν΄ Python Inbound Parser λ₯Ό νμΈνλ κ²μ΄ μ’μ΅λλ€.
λ§μμ λ΄μ,
Elmer
SendGridλ JSON μΈλ°μ΄λ ꡬ문 λΆμ λ°μ΄ν°λ₯Ό μμ / λ€μ€ ννΈ λ°μ΄ν°λ‘ 보λ λλ€. body-parserκ° ν΄λΉ νμμ μ²λ¦¬νμ§ μμΌλ―λ‘ req.bodyμ μν΄ μ¦μ μ‘μΈμ€λμ§ μμ΅λλ€. λλ λ©ν°λ₯Ό λμμΌλ‘ μ¬μ©ν κ²μ λλ€.
@ shishido92 κ·Έκ²μ μννλ λ°©λ²μ λν μ’μ μλ₯Ό νμ₯ ν΄ μ£Ό
@stephenfjohnson @machinshin expressjsλ₯Ό μ¬μ©νλ κ²½μ° λμμ΄ λ μ μμ΅λλ€.
app.use(express.json({limit: '10mb'}));
app.use(express.urlencoded({
extended: true,
type: "multipart/form-data",
limit: '10mb'
}));
app.post('/endpoint', function (req, res, next) {
// req.body contains the text fields
console.log(req.body);
console.log('body' + req.body);
res.status(200).json('ok');
})
μ΄λ κ²νλ©΄ μμ² λ³Έλ¬Έμ μμ² λ΄μ©μ΄ μ 곡λ©λλ€.
μ΄κ²μ μ²¨λΆ νμΌμ 무μν©λλ€.
@nathfreder μ°λ¦¬λ μ°μ μμμ μΌνμΌλ‘ μ΄μ μμ½μ λν΄ μμ§
@ childish-sambino, @satyajeetjadhav π
κ²°μ½ λ¦κ²;)
μ
λ°μ΄νΈ ν΄μ£Όμ
μ κ°μ¬ν©λλ€.
λλ μ΄κ²μ΄ μ’ κ²°λμμμ μκ³ μμ§λ§ λ°©κΈμ΄ λ¬Έμ λ₯Ό λ°κ²¬νμΌλ©° μΈλ°μ΄λ λ©μΌ νμκ° μλνλ κ²μΌλ‘ νννμ΅λλ€. λ΄κ°ν΄μΌ ν κ°μ₯ μ€μν κ²μ multer λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ multipart / form-data μ λ ₯μ μ²λ¦¬ ν λ€μ @ sendgrid / inbound-mail-parser λΌμ΄λΈλ¬λ¦¬μ keyValues ββ() λ©μλλ₯Ό μλμ κ°μ΄ μ¬μ©νλ κ²μ λλ€.
multer λ° Sendgridμμ νμ :
const multer = require ( 'multer');
const μ λ‘λ = multer ();
const mailParse = require ( '@ sendgrid / inbound-mail-parser');
POST λ©μλμ λν λΌμ°ν° μ μΈμμ ν μ€νΈλ₯Ό μ»μμΌλ―λ‘ upload.none () λ©μλλ₯Ό μ¬μ©νμμμ€ (μ²¨λΆ νμΌ μμ).
router.post ( '/ mail', upload.none (), function (req, res, next)
POST μ μ λ΄μμ keyValues ββ() λ©μλλ₯Ό μ¬μ©νμ¬ μ΄λ©μΌμ κ΄λ ¨ λΆλΆμ κ°μ Έμ΅λλ€.
{
const config = {keys : [ 'to', 'from', 'subject', 'text',]};
const ꡬ문 λΆμ = new mailParse (config, req.body);
let response = parsing.keyValues ββ();
let to = response.to;
let from = response.from;
let subject = response.subject;
let messageBody = response.text
console.log ( 'μ΄κ²μ λ©μΌμ μ λͺ©μ λλ€ :', subject);
}
κ·Έκ²μ΄ μ΄λ μ λ μ¬μ©λκΈ°λ₯Ό λ°λλλ€.
μλ νμΈμ, λκ΅°κ° μ²¨λΆ νμΌμ ꡬ문 λΆμνλ λ°©λ²μ μλ₯Ό 곡μ ν μ μμ΅λκΉ? λμΌν ꡬμ±μ μ¬μ©νκ³ μμ§λ§ μ²¨λΆ νμΌμ΄ μ½μ μμλ λ¬Έμμ΄λ‘ νμλ©λλ€.
const app = express();
app.use(cors);
app.use(busboy());
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies.
app.use(bodyParser.json({limit: '5mb'}));
router.post('', upload.any(),function(req, res) {
// console.log(req.body);
// console.log(req.files);
// res.send(req.body);
const config = {keys: ['to', 'from', 'subject', 'text','attachments']};
const parsing = new mailParse(config, req.body);
let response = parsing.keyValues();
let to = response.to;
let from = response.from;
let subject = response.subject;
let messageBody = response.text
console.log('This is the subject from the mail: ', response);
res.send(200);
});
@ jhorsfield-twμ μν΄ κ²μ λ μ½λλ @sendgrid/inbound-mail-parser
μ λ¬Έμκ° μκΈ° λλ¬Έμ λ§€μ° λμμ΄λμμ§λ§ μ μκ²λ κ·Έλ€μ§ ν¨κ³Όκ° μμμ΅λλ€. mailParse
μ μμ±μλ μμ² λ³Έλ¬Έμ΄ μλ λ§€κ° λ³μλ‘ request
λ₯Ό μ¬μ©ν©λλ€.
const parsing = new mailParse(config, req);
μλ νμΈμ @ZeroCho ,
μ¬κΈ° μ ν¨ν€μ§κ° μμ§λ§ μνκΉκ²λ μ’μ μ¬μ© μ€λͺ μκ° μμ΅λλ€. μ΄λ₯Ό μν΄ Python Inbound Parser λ₯Ό νμΈνλ κ²μ΄ μ’μ΅λλ€.
λ§μμ λ΄μ,
Elmer
λ°λΌμ λ¬Έμλ₯Ό μμ±ν΄μΌν©λλ€.
μμ§ λ¬Έμνλμ§ μμ μ΄μ
μ¬μ ν nodejs expressλ‘ μμλΌ μ μμ΅λλ€ ...
λ¬Έμμ μ¬μ ν μ΄μ λν μκ° μμΌλ―λ‘ λ€μ μ½λ λ€.
μ΄ κΈ°λ₯μ μΆκ°νκΈ°μν ν μμ²μ νμνλ©° μ°μ μμμ λ°λΌ κ²ν λμ§λ§ Twilio SendGridλ λΌμ΄λΈλ¬λ¦¬μ λν μλ‘μ΄ κΈ°λ₯μ μ κ·Ήμ μΌλ‘ ꡬμΆνμ§ μμ΅λλ€.
μ²¨λΆ νμΌμ λ°μΌλ €κ³ νμ§λ§ μ¬μ ν μ΄μ΄ μμ΅λλ€ ...
μ²¨λΆ νμΌμ λ°μΌλ €κ³ νμ§λ§ μ¬μ ν μ΄μ΄ μμ΅λλ€ ...
RAW μ¬μ©
const config = {
keys: ['to', 'from', 'subject', 'text', 'attachments']
};
const parsedMail = new parse(config, req); // req is https.Request type
parsedMail.getRawEmail((rawMail: any) => {
console.log(rawMail); // returns null or {}
}
parsedMail.attachments((attachmentData: Attachment[]) => {
console.log('attachments1:'); // returns [ ]
console.log(attachmentData);
console.log(JSON.stringify(attachmentData));
});
λλ κ·Έκ²μ μλνκ³ μμ§λ§ μ΄μ΄ μλ€ ... λΉ κ°μ²΄λ₯Ό λ°ννκ³ .attachments()
ν λ λΉ λ°°μ΄λ μ»μ΅λλ€.
λλ firebase ν΄λΌμ°λ κΈ°λ₯μ μ¬μ©νκ³ μμΌλ©° μΈλ°μ΄λ λ©μΌ νμλ₯Ό μ¬μ©νμ¬ μ±κ³΅νμ§ λͺ»νκ³ λΌμ΄λΈλ¬λ¦¬ μ¬μ©μ λμμ΄ λ λͺ κ°μ§ λ¬Έμλ₯Ό κΈ°λνκ³ μμ΅λλ€.
κ·Έλ¬λ busboyλ₯Ό μ¬μ©νκ³ (Sendgrid μ€μ μμ "raw"λ₯Ό μ ν ν΄μ νλ) λ©μΌ νμλ₯Ό μ¬μ©νλ €κ³ νλ ν κ°μ§ λ¬Έμ λ₯Ό μ μΈνκ³ λ κ½€ μ μλν©λλ€.
Sendgridλ λ€μκ³Ό κ°μ΄ "charsets"νλμ λ€λ₯Έ μΈμ½λ©μ λμ΄ν©λλ€.
Gmailμ μ΄λ©μΌ :
{ "to": "UTF-8", "html": "UTF-8", "subject": "UTF-8", "from": "UTF-8", "text": "UTF-8" }
Outlookμ μ΄λ©μΌ :
{ "to": "UTF-8", "html": "iso-8859-1", "subject": "UTF-8", "from": "UTF-8", "text": "iso- 8859-1 "}
μ΄λ©μΌμ κ΅μ λ¬Έμ (μ : ΓΓΓ )κ° ν¬ν¨ λ κ²½μ° κ²°κ³Όλ ν μ€νΈ λ° html νλμ μ€μ λΆμ λ½ λ¬Έμ λμ λ¬Όμνκ° ν¬ν¨λ©λλ€.
busboyμ defCharsetμ Windows-1252λ‘ λ³κ²½νλ©΄ ν μ€νΈ λ° html κ°μ΄ μ¬λ°λ₯΄κ² νμλμ§λ§ λ€λ₯Έ νλλ μλͺ» νμλ©λλ€.
μ΄κ²μ λ©μΌ νμμμλ λ¬Έμ κ°λ©λκΉ? μλλ©΄ λ©μΌ νμκ° νλμμ λ€λ₯Έ μΈμ½λ©μ μ²λ¦¬ν©λκΉ?
κ΄μ¬μλ μ¬λμ μν΄ busboyλ₯Ό μ¬μ©νμ¬ κ΅¬λ¬Έ λΆμνλ λ΄ μ½λ :
(λκ΅°κ°κ° busboyλ₯Ό μ¬μ©νμ¬ μμ λ¬Έμ λ₯Ό μ΄λ»κ² ν΄κ²°νλμ§ λ§ν΄ μ€ μ μλ€λ©΄ κ°μ¬ ν κ²μ
λλ€ ..)
exports.sendgridparse = functions.https.onRequest ((req, res) => {
const κ²½λ‘ = require ( 'path');
const os = require ( 'os');
const fs = require ( 'fs');
const Busboy = require ( 'busboy');
if (req.method !== 'POST') {
// Return a "method not allowed" error
return res.status(405).end();
}
const busboy = new Busboy({ headers: req.headers });
const fields = {};
busboy.on('field', function(fieldname, value, fieldnameTruncated, valTruncated, encoding, mimetype){
console.log('Busboy fild [' + fieldname + ']: value: ' + val);
fields[fieldname] = value;
});
let imageToBeUploaded = {};
let imagestobeuploaded = [];
let imageFileName;
busboy.on ( 'file', (νλ μ΄λ¦, νμΌ, νμΌ μ΄λ¦, μΈμ½λ©, mimetype) => {
console.log (νλ μ΄λ¦, νμΌ, νμΌ μ΄λ¦, μΈμ½λ©, MIME μ ν);
file.on ( 'data', function (data) {
console.log ( 'File ['+ fieldname + '] got'+ data.length + 'bytes');
});
file.on ( 'end', function () {
console.log ( 'File ['+ fieldname + '] Finished');
});
const imageExtension = filename.split ( '.') [filename.split ( '.'). length-1];
imageFileName = ${Math.round(Math.random() * 1000000000000).toString()}.${imageExtension}
;
const νμΌ κ²½λ‘ = path.join (os.tmpdir (), imageFileName);
const URL = https://firebasestorage.googleapis.com/v0/b/${environment.firebase.storageBucket}/o/${imageFileName}?alt=media
;
imageToBeUploaded = {νμΌ κ²½λ‘, mimetype, imageFileName, imageExtension, url};
imagestobeuploaded.push (imageToBeUploaded);
file.pipe (fs.createWriteStream (filepath));
});
busboy.on ( 'finish', async () => {
// λͺ¨λ νλλ₯Ό μ¬μ©ν μ μμΌλ©° (μ
λ‘λ ν μ΄λ―Έμ§ λ° νλ) dbμ μ μ₯ν μ μμ΅λλ€.
res.send (200);
});
busboy.end (req.rawBody);
});
@hhetland κ·Έλμ
@matheustavaresdev- μ,
λ¨Όμ busboy.on ( 'file')μ tmp ν΄λμ μ μ₯ ν λ€μ "imagestobeuploaded"λ³μμ μ 보λ₯Ό μ¬μ©νμ¬ busboy.on ( 'finish')μ firebase μ μ₯μ λ²ν·μ μ μ₯ν©λλ€.
κ°μ¬ν©λλ€ !!!!!!!!!!!!
2020 λ 4 μ, μμ§ κ³΅μ λ¬Έμκ° μμ£ ?
λλ μ΄κ²μ΄ μ’ κ²°λμμμ μκ³ μμ§λ§ λ°©κΈμ΄ λ¬Έμ λ₯Ό λ°κ²¬νμΌλ©° μΈλ°μ΄λ λ©μΌ νμκ° μλνλ κ²μΌλ‘ νννμ΅λλ€. λ΄κ°ν΄μΌ ν κ°μ₯ μ€μν κ²μ multer λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ multipart / form-data μ λ ₯μ μ²λ¦¬ ν λ€μ @ sendgrid / inbound-mail-parser λΌμ΄λΈλ¬λ¦¬μ keyValues ββ() λ©μλλ₯Ό μλμ κ°μ΄ μ¬μ©νλ κ²μ λλ€.
multer λ° Sendgridμμ νμ :
const multer = require ( 'multer');
const μ λ‘λ = multer ();
const mailParse = require ( '@ sendgrid / inbound-mail-parser');POST λ©μλμ λν λΌμ°ν° μ μΈμμ ν μ€νΈλ₯Ό μ»μμΌλ―λ‘ upload.none () λ©μλλ₯Ό μ¬μ©νμμμ€ (μ²¨λΆ νμΌ μμ).
router.post ( '/ mail', upload.none (), function (req, res, next)
POST μ μ λ΄μμ keyValues ββ() λ©μλλ₯Ό μ¬μ©νμ¬ μ΄λ©μΌμ κ΄λ ¨ λΆλΆμ κ°μ Έμ΅λλ€.
{
const config = {keys : [ 'to', 'from', 'subject', 'text',]};
const ꡬ문 λΆμ = new mailParse (config, req.body);
let response = parsing.keyValues ββ();
let to = response.to;
let from = response.from;
let subject = response.subject;
let messageBody = response.text
console.log ( 'μ΄κ²μ λ©μΌμ μ λͺ©μ λλ€ :', subject);
}κ·Έκ²μ΄ μ΄λ μ λ μ¬μ©λκΈ°λ₯Ό λ°λλλ€.
λ΄κ° μ°Ύμ κ²μ request.bodyκ° μμ λ°μ΄ν°μ μκ³ μ€λ₯κ° μλ€λ κ²μ
λλ€.
[Nest] 24687-05/01/2020, 1:29:51 PM [ExceptionsHandler] μ΄κΈ° κ°μ΄μλ λΉ λ°°μ΄ μΆμ
TypeError : μ΄κΈ° κ°μ΄μλ λΉ λ°°μ΄ μΆμ
Array.reduce (
μ½λ:
keyValues ββ() {
this.keys λ°ν
.filter (key => this.payload [key])
.map (key => ({[key] : this.payload [key]}))
.reduce ((keyValues, keyPayload) => Object.assign (keyValues, keyPayload));
}
this.payloadλ ꡬ쑰ν λ λ°μ΄ν°κ° μλμ§λ§ μ¬λ¬ λΆλΆμΌλ‘ ꡬμ±λ λ°μ΄ν°μ΄λ―λ‘ μ€λ₯λ₯Ό λ°νν©λλ€.
λλ μ΄κ²μ nest-jsλ‘ μλμν¬ μ μμμ΅λλ€. NestJS 컨νΈλ‘€λ¬μμ μμ νλ μΉν λ°μ΄ν°λ λ€μ€ νμ λ°μ΄ν°μ λλ€. μ΄ κ²½μ° Multerλ₯Ό μ¬μ©νλ λ°©λ²μ μ λͺ¨λ₯΄κ² μ΅λλ€.
outer.post ( '/ mail', upload.none (), function (req, res, next)
λλ μ΄κ²μ μλνλ€.
export class MultiformParser implements NestMiddleware {
async use(req: Request, res: Response, next: Function) {
console.log("before: ", req.body)
var upload = multer();
await new Promise((resolve, reject) => {
upload.none()(req, res, err => {
if (err) {
console.log(err)
reject(err)
} else {
resolve()
console.log("request: ", req.body)
}
});
});
console.log("after: ", req.body)
next();
}
}
κ·Έλ¬λ req.bodyλ λ€μμ λ°νν©λλ€.
request: [Object: null prototype] {}
μ΄μ μ μ¬λ¬ νμμ λ°μ΄ν°λ₯Ό μΈμν©λλ€.
μλ²λ¦¬μ€ (κ΅¬κΈ ν΄λΌμ°λ κΈ°λ₯ λλ νμ΄μ΄λ² μ΄μ€)λ₯Ό μ¬μ©νλ κ²½μ°
μ΄κ²μ΄ λμμ΄ λ μ μμ΅λλ€ : https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase/48648805#48648805
μ΄κ²μ busboyλ₯Ό μ¬μ©ν©λλ€. https://stackoverflow.com/questions/51484307/how-to-parse-multipart-form-data-on-firebase-cloud-functions
μλ²λ¦¬μ€μμ λ©ν° ννΈ κ΅¬λ¬Έ λΆμμ Formidable μ¬μ© : https://github.com/DanisHack/formidable-serverless
λλ : https://github.com/cristovao-trevisan/express-multipart-file-parser
λ©ν°λ₯Ό μ¬μ©ν μ μλλ‘ λ³κ²½ν΄μΌνλ μ¬νμ λ€μκ³Ό κ°μ΅λλ€.
app.use (express.json ())
app.use (express.urlencoded ({extended : true}));
const μ
λ‘λ = multer ();
app.use (upload.none ());
μ΄ μμ
μ μν ν ν multerλ₯Ό μ¬μ©νμ¬ μΉν
λ°μ΄ν°λ₯Ό
ꡬ쑰ν λ ν€, κ° μ.
2020 λ
5 μ 24 μΌ μΌμμΌ μ€ν 4:51 λ΄λ§ν¬μ΄ Mohd [email protected]
μΌλ€ :
μλ²λ¦¬μ€ (κ΅¬κΈ ν΄λΌμ°λ κΈ°λ₯ λλ νμ΄μ΄λ² μ΄μ€)λ₯Ό μ¬μ©νλ κ²½μ°
λμμ΄ λ μ μμ΅λλ€.
https://stackoverflow.com/questions/47242340/how-to-perform-an-http-file-upload-using-express-on-cloud-functions-for-firebase/48648805#48648805μλ²λ¦¬μ€μμ λ©ν° ννΈλ₯Ό ꡬ문 λΆμνλ €λ©΄ Formidableμ μ¬μ©νμμμ€.
https://github.com/DanisHack/formidable-serverlessβ
λκΈμ λ¬μ κΈ° λλ¬Έμ μμ ν κ²μ λλ€.
μ΄ μ΄λ©μΌμ μ§μ λ΅μ₯νκ³ GitHubμμ νμΈνμΈμ.
https://github.com/sendgrid/sendgrid-nodejs/issues/482#issuecomment-633312295 ,
λλ ꡬλ μ·¨μ
https://github.com/notifications/unsubscribe-auth/AB2ATHHFKBRZZDGGJ2D7SOLRTGQHNANCNFSM4D67CVZQ
.
-
Shweta Bhandare, PhD | μμ μννΈμ¨μ΄ μμ§λμ΄
https://hicleo.com/
hicleo.com | λ§ν¬λ μΈ https://www.linkedin.com/company/hicleo/ | νΈμν°
https://twitter.com/hi_cleo/ | μΈμ€ ν κ·Έλ¨
https://www.instagram.com/hicleo.co/ | νμ΄μ€ λΆ
https://www.facebook.com/hicleolabs
-
μ΄ λ©μμ§λ κΈ°λ°, λ
μ λλ 보νΈλ₯Ό ν¬ν¨ ν μ μμ΅λλ€.μ 보.
μ΄ λ©μμ§κ° μλͺ» μμ λ κ²½μ°νμ μ΄λ©μΌλ‘ λ°μ μμκ² μλ¦¬κ³ μ΄ λ©μμ§λ₯Ό μμ νμμμ€.
μ°λ¦¬λ Busboyμ ν¨κ» Google Cloud Functionsμμμ΄ μμ μ μννκΈ° μν΄ λ§μ μκ°μ 보λμΌλ©° μ΄λ€ νν 리μΌμ΄λ ν¬μΈν°λ₯Ό λ°λλμ§μ μκ΄μμ΄μ΄λ₯Ό μ€νν μ μμμ΅λλ€.
λ°λΌμ μ½κ°μ μ μ°μ±μ΄μλ λΉμ·ν μν©μμ λ€μ μ¬λμ μν΄ μ¬κΈ°μ λ¨κ²¨ λκ² μ΅λλ€. Python Inbound Parserλ₯Ό μ¬μ©νμμμ€. κ·Έλ€μ΄ μ 곡νλ μ½λμμ λ³΅μ¬ / λΆμ¬ λ£κΈ° μμ μ΄μκ³ μ€ννλ λ° ν μκ°λ κ±Έλ¦¬μ§ μμμ΅λλ€.
λλ μ΄κ²μ΄ μ¬κΈ°μ λ¬Έμ λ₯Ό ν΄κ²°νμ§ λͺ»νλ€λ κ²μ μκ³ μμ§λ§, μ΄κ²μ΄ λ€λ₯Έ λκ΅°κ°μ ν€λ λ± νΉ μκ°μ μ μ½ ν μ μκΈ°λ₯Ό λ°λλλ€.
μ΄ ν°μΌμ λ°κ²¬ν΄μ λ€νμ λλ€ ... μ΄κ²μ λν λ¬Έμλ₯Ό μ°ΎμΌλ €κ³ λ―Έμ³ κ°κ³ μμλλ° , μ΄μ¨λ
μ¬μ€ λΉν© μ€λ½μ΅λλ€. μ λ νμ€ λ¬Έμκ°μμ κ²μ΄λΌκ³ κ°μ νμ΅λλ€. νΉν μ΄κ²μ΄ μ€ν μμ€μ΄μ§λ§ SendGrid (κ·Έλ¦¬κ³ κΆκ·Ήμ μΌλ‘ νμμ μΈ λ¬Έμκ°μλ Twilio)κ° μ§μνκΈ° λλ¬Έμ λλ€.
μ΄μ κ°μ΄ κ°λ¨ν κ²μ μν΄ μ μ΄λ μκ° μλ€κ³ μμν κ²μ λλ€.
κ·ΈλΌμλ λΆκ΅¬νκ³ μ΄ λ¬Έμ λ₯Ό μ νλ μ¬λμκ²λ ...
λμ MailParser λ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
λλ μ΄κ²μ΄ νλ μλμμ κ·Έκ²μ μ¬μ©νλ€κ³ νμ νμ§λ§ μ μ΄λ MailParserμλ λ§μ λ¬Έμκ° μμ΅λλ€. μΈλ°μ΄λ ꡬ문 λΆμ μ€μ μμ μλμ κ°μ΄ POST the raw, full MIME message
μ νλμ΄ μλμ§ νμΈνμμμ€ (_wow, μ _).
MailParser λ¬Έμλ₯Ό μ½μ ν λͺ λΆλ§μ μλ£λμμ΅λλ€.
import { Request, Response } from "express";
import { simpleParser } from "mailparser";
export const inboundEmails = async (req: Request, res: Response) => {
const parsedEmail = await simpleParser(req.body.email);
console.log("subject", parsedEmail.subject);
console.log("from", parsedEmail.from);
console.log("to", parsedEmail.to);
console.log("cc", parsedEmail.cc);
console.log("bcc", parsedEmail.bcc);
console.log("date", parsedEmail.date);
console.log("messageId", parsedEmail.messageId);
console.log("inReplyTo", parsedEmail.inReplyTo);
console.log("replyTo", parsedEmail.replyTo);
console.log("references", parsedEmail.references);
console.log("html", parsedEmail.html);
console.log("text", parsedEmail.text);
console.log("textAsHtml", parsedEmail.textAsHtml);
console.log("attachments", parsedEmail.attachments);
res.sendStatus(200);
};
λͺ¨λ λ°μ΄ν°λ μνλλλ‘μ λλ€.
λν Multer λ―Έλ€μ¨μ΄λ₯Ό μ¬μ©νμ¬
λ―Έλ€μ¨μ΄ νλ¦ λ΄μμ multer().any()
λ§νΌ κ°λ¨ν©λλ€.
건배
μμ μ 체 MIME λ©μμ§λ₯Ό μ¬μ©νκ³ simpleParserμ ν¨κ» μλνλλ‘νμ§λ§ simpleParserκ° MIMEλ₯Ό ν μ€νΈμ htmlλ‘ λ©μ§κ² λ³ννμ§ μκΈ° λλ¬Έμ μ²λ¦¬ λ λ²μ μΌλ‘ λ€μ μ ννκ³ sengridμ μΈλ°μ΄λ λ©μΌ νμλ₯Ό μ¬μ©νκ³ μμ΅λλ€.
κ·Έλλ λͺ κ°μ§ λ¬Έμκ° νμν©λλ€.
@theweiweiway λ κ°μ§ λ°©λ² μ¬μ΄μ ν μ€νΈμ htmlμ μ°¨μ΄μ μ λν μλ₯Ό κ²μ ν΄ μ£Όμκ² μ΅λκΉ? λλ μ΄λ€ μ°¨μ΄λ λμΉ μ±μ§ λͺ»νκ³ κΆκΈν©λλ€.
ν μ€νΈ
Hi 123 Hi 123 Hi 123 www.hello.com
vs
Hi 123 Hi 123 Hi 123 www. <http://www.hello.com/>hello <http://www.hello.com/>.com <http://www.hello.com/>
^ μ κ·Έλ° μΌμ΄ μΌμ΄ λ¬λμ§ λͺ°λΌ
HTML μ©
<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi 123<div class=""><b class="">Hi 123</b></div><div class=""><b class=""><u class="">Hi 123</u></b></div><div class=""><b class=""><u class="">www.</u>hello</b>.com</div></body></html>
vs
<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Hi 123</span><div class="" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"><b class="">Hi 123</b></div><div class="" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"><b class=""><u class="">Hi 123</u></b></div><div class="" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"><b class=""><u class=""><a href="http://www.hello.com" class="">www.</a></u><a href="http://www.hello.com" class="">hello</a></b><a href="http://www.hello.com" class="">.com</a></div></body></html>
λλ κ·Έκ²μ΄ simpleParser ν¨ν€μ§μ λ κ΄λ ¨μ΄ μλ€κ³ μκ°ν©λλ€.
λ€μμ express / multerλ₯Ό μ¬μ©νλ λ΄ repo express-sendgrid-inbound-parse μ
λλ€. μμνκΈ° μ¬μ΄ μ±μ
λλ€. λ λ§μ μ΄λ©μΌ λ°μ΄ν°μ μ‘μΈμ€ ν μ μμΌλ―λ‘ POST the raw, full MIME message
μ ννμ§ μμ μνλ‘ λλ κ²μ΄ μ’μ΅λλ€.
console.log('dkim: ', body.dkim)
console.log('to: ', body.to)
console.log('cc: ', body.cc)
console.log('from: ', body.from)
console.log('subject: ', body.subject)
console.log('sender_ip: ', body.sender_ip)
console.log('spam_report: ', body.spam_report)
console.log('envelope: ', body.envelope)
console.log('charsets: ', body.charsets)
console.log('SPF: ', body.SPF)
console.log('spam_score: ', body.spam_score)
if (rawFullMimeMessageChecked) {
console.log('email: ', body.email)
} else {
console.log('headers: ', body.headers)
console.log('html: ', body.html)
console.log('text: ', body.text)
console.log('attachments: ', body.attachments)
console.log('attachment-info: ', body['attachment-info'])
console.log('content-ids: ', body['content-ids'])
}
firebase ν΄λΌμ°λ κΈ°λ₯μμ μ΄κ²μ μλνμ΅λλ€.
μ λλ‘ μλνμ§ λ§μμμ€.
λ€λ₯Έ ν΄κ²°μ±
μ΄ μμ΅λκΉ?
κ°μ₯ μ μ©ν λκΈ
λ°λΌμ λ¬Έμλ₯Ό μμ±ν΄μΌν©λλ€.