Sendgrid-nodejs: inbound-mail-parserλ₯Ό μ‚¬μš©ν•˜μ—¬ μˆ˜μ‹  이메일을 ꡬ문 λΆ„μ„ν•˜λŠ” 예

에 λ§Œλ“  2017λ…„ 10μ›” 13일  Β·  35μ½”λ©˜νŠΈ  Β·  좜처: sendgrid/sendgrid-nodejs

문제 μš”μ•½

문제 및 λ¬Έμ œκ°€ λ°œμƒν•˜λŠ” ν™˜κ²½μ— λŒ€ν•œ μš”μ•½. μ μ ˆν•œ 경우 버그λ₯Ό μž¬ν˜„ν•˜λŠ” 데 ν•„μš”ν•œ 단계λ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€. 슀크린 μƒ·, 슀크린 캐슀트, μ½”λ“œ 예제λ₯Ό 자유둭게 ν¬ν•¨ν•˜μ‹­μ‹œμ˜€.

@ 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'μž…λ‹ˆλ‹€.
λ”°λΌμ„œ μ›μ‹œ 이메일 데이터에 μ•‘μ„ΈμŠ€ν•˜λŠ” 방법, λ‚˜μ€‘μ— ν•΄λ‹Ή λ°μ΄ν„°λ‘œ λ¬΄μ—‡μ„ν•΄μ•Όν•˜λŠ”μ§€, μΈλ°”μš΄λ“œ 메일 ꡬ문 뢄석기λ₯Ό μΈμŠ€ν„΄μŠ€ν™”ν•˜λŠ” 방법이 λͺ…ν™•ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ³΄κ³ λ˜λŠ” λ¬Έμ œμ™€ κ΄€λ ¨ν•˜μ—¬ κ³΅μœ ν•˜λ €λŠ” 기타 정보. 특히 이것이 버그라고 μƒκ°ν•˜λŠ” μ΄μœ λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? λŒ€μ‹  μ–΄λ–€ 일이 일어날 κ²ƒμœΌλ‘œ μ˜ˆμƒν•©λ‹ˆκΉŒ?

기술적 μ„ΈλΆ€ 사항:

  • sendgrid-nodejs 버전 : 6.1.4 (μ΅œμ‹  컀밋 : 4c6d1cc)
  • Node.js 버전 : 4.1.2
    "@ sendgrid / inbound-mail-parser": "^ 6.1.4",
    "@ sendgrid / mail": "^ 6.1.4",
easy help wanted docs update

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μ•ˆλ…•ν•˜μ„Έμš” @ZeroCho ,

μ—¬κΈ° 에 νŒ¨ν‚€μ§€κ°€ μžˆμ§€λ§Œ μ•ˆνƒ€κΉκ²Œλ„ 쒋은 μ‚¬μš© μ„€λͺ…μ„œκ°€ μ—†μŠ΅λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ Python Inbound Parser λ₯Ό ν™•μΈν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

λ§ˆμŒμ„ λ‹΄μ•„,

Elmer

λ”°λΌμ„œ λ¬Έμ„œλ₯Ό μž‘μ„±ν•΄μ•Όν•©λ‹ˆλ‹€.

λͺ¨λ“  35 λŒ“κΈ€

μ•ˆλ…•ν•˜μ„Έμš” @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 | μˆ˜μ„ μ†Œν”„νŠΈμ›¨μ–΄ μ—”μ§€λ‹ˆμ–΄

[email protected]

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, 예 _).

Example

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 ν΄λΌμš°λ“œ κΈ°λŠ₯μ—μ„œ 이것을 μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€.
μ œλŒ€λ‘œ μž‘λ™ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€.
λ‹€λ₯Έ 해결책이 μžˆμŠ΅λ‹ˆκΉŒ?

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰