【问题标题】:GMail API Replying to Email Thread Using NodeJS使用 NodeJS 回复电子邮件线程的 GMail API
【发布时间】:2021-04-17 16:32:10
【问题描述】:

亲爱的大家:我相信你们中的许多人在阅读完所有示例和参考资料后已经多次讨论过上述主题,我已经设法编写代码来回复相同的电子邮件 ThreadID。但不幸的是,当我回复相同的 ThreadID 电子邮件时,它会作为新电子邮件发送。我附上了完整的 NodeJS 代码,帮助我查看并告诉我应该在哪里进行更改。

const {google} = require('googleapis');
const mailComposer = require('nodemailer/lib/mail-composer');
var program_name = process.argv[0]; //value will be "node"
var script_path = process.argv[1]; //value will be "yourscript.js"
var Sender_Email = process.argv[2]; //value will be "Sender Email"
var Receiver_Email = process.argv[3]; //value will be "Email To"
//var CC_Email = process.argv[4]; //value will be "Email Cc"
var Email_Subject = process.argv[4]; //value will be "Email Subject"
var Email_Template = process.argv[5]; //value will be "Email Template"
var ThreadID = process.argv[6]; //Path to attach the file
var Dec_Message_ID = process.argv[7]; //Encoded messageid
var FileAttachment = process.argv[8]; //Path to attach the file
var dateFormat = require('dateformat');
var day=dateFormat(new Date(), "mmm dd, yyyy HH:MM tt");
class CreateMail{

    constructor(auth, to, cc, sub, body, task, attachmentSrc = [FileAttachment]){

        this.me = Sender_Email;
        this.task = task;
        this.auth = auth;
        this.to = Receiver_Email;
        //this.cc = CC_Email;
        this.sub = Email_Subject;       
        var fs = require('fs');
        this.body = fs.readFileSync(Email_Template,{encoding:'utf-8'});     
        
        this.gmail = google.gmail({version: 'v1', auth});
        this.attachment = attachmentSrc;
    }

    //Creates the mail body and encodes it to base64 format.
    makeBody(){
        if(this.attachment.length>0){
        var arr = [];
        for(var i=0;i<this.attachment.length;i++){
            arr[i] = {
                path: this.attachment[i],
                encoding: 'base64'
            }
        }
        }
        let mail;
        //Mail Body is created.
        if(this.attachment.length>0){
            mail = new mailComposer({
                
                from: "Arthanareeswaran Chandrasekaran <arthaaadhi@visha.page>",                            
                //sender: this.me,
                to: this.to,                
                //cc: this.cc,
                replyTo: this.to,
                
                inReplyTo: "<CAO29sXBTxmE8M=xyTkdFfsrxB_Mdr5e6N6vXiijwTY9rn1kzpQ@mail.gmail.com>",
                references: "<CAF7UyHwMrUvy-ZLNyRfjDmX876EKi5T-oc8E_tXy2PwO19dZ_Q@mail.gmail.com> <CAO29sXBH_B0yG4G2p6tdW1uk_tq9qFXmc01CPO5HJopkvMbU4Q@mail.gmail.com> <CAO29sXCcHv4LQSumjht_5zHEYvSzjfYkGr+yCEHfjwnqRvt0=Q@mail.gmail.com> <CAO29sXCPAxzWG0dC-TKEi4cR3xM8hbHhSJQ0ZAhbXBjsp503oA@mail.gmail.com> <CAO29sXA2mpqx6qbEeB5ke_6kUTrwXsqMD8ku0Aq3E_R07YzCLg@mail.gmail.com> <CAO29sXBTxmE8M=xyTkdFfsrxB_Mdr5e6N6vXiijwTY9rn1kzpQ@mail.gmail.com>",
                
                            
                subject: this.sub,  
                html: this.body,
                
                textEncoding: "base64",
                attachments: arr
                
            }); 
        }
        else{
            mail = new mailComposer({
                
                to: this.to,                
                cc: this.cc,
                html: this.body,
                subject: this.sub,              
                textEncoding: "base64"              
                
            });
        }
        
        //Compiles and encodes the mail.
        mail.compile().build((err, msg) => {
            if (err){
                return console.log('Error compiling email ' + error);
            } 
        
            const encodedMessage = Buffer.from(msg)
              .toString('base64')             
              .replace(/\+/g, '-')
              .replace(/\//g, '_')            
              .replace(/=+$/, '');
            
            if(this.task === 'mail'){
                this.sendMail(encodedMessage);
            }
            else{
                this.saveDraft(encodedMessage);
            }
        });
    }

    //Send the message to specified receiver.
        sendMail(encodedMessage){
        this.gmail.users.messages.send({
            userId: this.me,
            resource: {
                                                                                
                raw: encodedMessage,                                
                threadId: ThreadID

            }

        }, (err, result) => {
            if(err){
                return console.log('GMail API - The API returned an error: ' + err);
            }

            console.log("GMail API Sending Email Reply from server:", result.data);
        });
        }

    //Saves the draft.
        saveDraft(encodedMessage){
        this.gmail.users.drafts.create({
            'userId': this.me,
            'resource': {
              'message': {
                'raw': encodedMessage,
                threadId: ThreadID
              }
            }
        })
        }

    //Deletes the draft.
        deleteDraft(id){
        this.attachment.gmail.users.drafts.delete({
            id: id,
            userId: this.me
        });
        }

        }

module.exports = CreateMail;

感谢您的帮助...

【问题讨论】:

  • 只是分享我用于上述代码的输入参数 - node index.js "From Email ID" "To EmailID" "Re: Final Testing" "Report 4 - GMail.html" "ThreadID " "MessageID" "附件如果有的话"
  • 您好,为了将消息插入指定线程,ReferencesIn-Reply-To 标头必须按照 RFC 2822 标准设置。此外,Subject 标头也必须匹配。你能确认这些吗?
  • 您好@ale13 感谢您的回复。是的,我维护了 RFC 2822 中提到的标准。例如,这些是我传递的参数,References - MessageID's,In-Reply-To - MessageID(Recent),Subject - 带有前缀“Re:”的相同主题以及线程 ID = 线程 ID。一旦我从 Google 设置中关闭对话视图,我的电子邮件就会分成单独的电子邮件!请帮助我查看代码,如果我做错了任何项目,请告诉我。再次感谢您的回复。

标签: node.js email gmail-api


【解决方案1】:

我建议您将代码更新为此并检查 ReferencesIn-Reply-ToSubjects 标头是否匹配:

function replyToMessage(auth) {
    const gmail = google.gmail({
        version: 'v1',
        auth
    });
    const messages = [
        'From: NAME <email@email.com>',
        'To: NAME <email@email.com>',
        'References: <REFERENCE1> <REFERENCE2>',
        'In-Reply-To: <IN_REPLY_TO>',
        'Content-Type: text/html; charset=utf-8',
        'MIME-Version: 1.0',
        'Subject: Re: SUBJECT',
        '',
        'BODY_OF_THE_REPLY',
        '',
    ];
    const message = messages.join('\n');
    const encodedMessage = Buffer.from(message)
        .toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=+$/, '');
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        resource: {
            raw: encodedMessage,
            threadId: 'THREAD_ID'
        }
    });
}

另外请注意,要查看相应的回复,您必须从 Gmail 设置中打开对话视图

根据documentation

您可以选择是否在对话中对电子邮件的回复进行分组,或者是否将每封电子邮件单独显示在您的收件箱中。

因此,如果未启用此设置,电子邮件将单独显示在您的收件箱中。

参考

【讨论】:

  • 你好 Ale13:如果我们打开对话,只有分组电子邮件应该会消失,但如果我们通过 API 回复同一电子邮件,它应该在同一电子邮件下,但我收到的是新的单独电子邮件。
  • 嗨 Ale13:感谢您提供的简化代码。在您的代码中如果我需要在回复 ThreadID 时插入以前的电子邮件,我该如何实现它。很抱歉,我正在努力实现这一部分,你能帮我分享更新的代码,以展示我如何在回复最新的 threadID 时插入旧的电子邮件数据。请帮助我谢谢
  • 嗨 ale13/ 社区中的任何人请帮我解决这个请求,我在回复 gmail api 时插入以前的电子邮件这一挑战非常困难。
猜你喜欢
  • 2019-04-08
  • 2017-03-21
  • 2016-11-25
  • 1970-01-01
  • 2017-12-06
  • 2021-01-17
  • 2018-07-21
  • 2023-01-29
  • 2021-02-14
相关资源
最近更新 更多