Pick up reply email content

Asked

Viewed 281 times

8

I’m using the library of imap to log into a company account and bring in the new emails, when it’s an email reply I’d like to pick up only the new content but I can’t get it just the full conversation. Let me give you an example:

A client sends me an e-mail with the following content: 'Hi'

I reply by saying: 'Hi all right ?'

He says to me: 'Everything great'

When I go check my email box by Node to save the text. I just want to pick up the last piece of content he sent me that would be 'All great', but the imap returns me the whole conversation like this:


Lorem ipsum dolor sit Amet, consectetur adipiscing Elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

5 de April de 2018 10:50, [email protected] (mailto:[email protected]) escreveu:teste

April 5, 2018 10:31, [email protected] (mailto:[email protected]) wrote: client response

5 de April de 2018 10:30, [email protected] (mailto:[email protected]) escreveu:resposta atendimento

5 April 2018 09:45, [email protected] (mailto:[email protected]) wrote: email sent by customer


In this example of the log I would like to pick up only lorem ipsum... which is the content of the last reply email.

My code:

imap.once('ready', function () {
    openInbox(imap, function (err, box) {
        if (err) throw err;
        var f = imap.seq.fetch('1:9999', {
            bodies: [''],
            struct: true
        });
        f.on('message', function (msg, seqno) {
            msg.on('body', function (stream, info) {
                var buffer = '';
                var prefix = '(#' + seqno + ') ';
                stream.on('data', function (chunk) {
                    buffer += chunk.toString('utf8');
                });

                stream.once('end', function () {
                    simpleParser(buffer).then(function(mail){
                        var email = {};
                        if (mail.headers.has('date')) {
                            email.date = (mail.headers.get('date'));
                        }
                        if (mail.headers.has('subject')) {
                            email.subject = (mail.headers.get('subject'));
                        }
                        if (mail.headers.has('from')) {
                            email.address = (mail.headers.get('from').value[0].address);
                        }

                        if (mail.inReplyTo) {
                            console.log(mail.text);
                            console.log('----');

                        } else {
                            email.text = mail.text;
                        }
                        // console.log(email);


                    }).catch(err => {
                        console.log(err);
                    });
                });
            });
            msg.once('attributes', function (attrs) {
                // console.log(prefix + 'Attributes: %s', inspect(attrs, false, 8));
            });
            msg.once('end', function () {
                // console.log(prefix + 'Finished');
            });
        });
        f.once('error', function (err) {
            console.log('Fetch error: ' + err);
        });
        f.once('end', function () {
            console.log('Done fetching all messages!');
            return imap.end();
        });
    });
});

imap.once('error', function (err) {
    console.log(err);
});

imap.once('end', function () {
    console.log('Connection ended');
});

imap.connect();

If someone could give me some help I would be very grateful. I thank you.

  • The email client will create a conversation, with what you send and what you receive, ok. You want to pick up only the last received reply or the last message, even if it is yours, that you sent?

  • The last message the client sent me, that is the last received reply

  • Can you show us what a conversation would look like in the Gmail pattern? You can create a Jsfiddle only with the text of the conversation (of course, by replacing the original texts with lorem ipsum or any example text)

  • link to text document .I put in this document an example of how console.log(mail.text) of a Gmail conversation. The content is irrelevant is just a copy of a promotional text I received, and used only for testing, the important thing would be to take this content.

  • Dude, it’s complicated to do that because the patterns can be different from one email client to another. The interesting thing would be to check the patterns of the mail clients that you work with and adjust the code that I posted so that it covers everyone as much as possible. I see this is the only way to resolve the issue. If you want I can create a chat here so that we can work on it, so as to arrive at a code as close to 100%, if the code of my answer can no longer be.

3 answers

2


Following the same example from @Diegomarques

/^(Em\s)?\d{1,2} de \w+ de \d{4}/gm

The above expression will separate if you find the following sequences: 5 de April de 2018 and or On April 10, 2018

The expression below is more complete:

^(Em\s)?\d{1,2}\sde\s\w+\sde\s\d{4}\s\d{1,2}:\d{1,2}([^@]+@\w+\.\w+\.\w+|,\s\sescreveu\:)?

and will separate if you find the following sequences:

5 de Abril de 2018 10:50, [email protected]
Em 5 de Abril de 2018 10:50, [email protected]

10 de abril de 2018 09:49
10 de abril de 2018 09:49,  escreveu:
Em 10 de abril de 2018 09:49
Em 10 de abril de 2018 09:49,  escreveu:

You can test in regex101.com

In the case of Outlook, the date comes with the standard:

Em qua, 11 de abr de 2018 às 09:08

Expression gets like this:

^(Em\s\w+,\s)|(Em\s)?\d{1,2}\sde\s\w+\sde\s\d{4}\s(às\s)?\d{1,2}:\d{1,2}([^@]+@\w+\.\w+\.\w+|,\s\sescreveu\:)?

Or simple way:

/^(Em\s\w+,\s)|(Em\s)?\d{1,2} de \w+ de \d{4}/gm

You can test in regex101.com

Example 1

let mail = {
   text: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

5 de Abril de 2018 10:50, [email protected] (mailto:[email protected]) escreveu:teste

5 de Abril de 2018 10:31, [email protected] (mailto:[email protected]) escreveu: resposta cliente

5 de Abril de 2018 10:30, [email protected] (mailto:[email protected]) escreveu:resposta atendimento

5 de Abril de 2018 09:45, [email protected] (mailto:[email protected]) escreveu: email enviado pelo cliente`
}

let reg = /^(Em\s)?\d{1,2} de \w+ de \d{4}/gm,
    separa = mail.text.split(reg);
console.log(separa[0]);

Example 2

let mail = {
   text: `Olá, como vai?

Se você é programador ou desenvolvedor de diversos tipos de aplicações C#
(web, desktop, mobile, etc.), então este lançamento é pra você:



Ao final deste curso você irá tirar proveito das melhorias de parâmetros
out e in, aprender a retornar múltiplos valores de forma simples com
tuplas, simplificar condições e conversões de valores com correspondência
de padrões, explorar funções locais e nova sintaxe de expressão no C# 7,
padronizar os estilos de código C# da sua equipe de desenvolvimento e muito
mais!
Comece já ️

Mais lançamentos ✨

*AspNet Identity*
Parte 1: Gerencie contas de usuários

Parte 2: Autenticação, segurança com lockout e "Esqueci a senha"

Parte 3: Autorização, autenticação externa com redes sociais

Parte 4: Autenticação mais segura com 2 fatores


*Lean Inbound*
Parte 1: Fundamentos de Marketing e Vendas para Novos Negócios

Parte 2: Práticas de Validação, Marketing e Vendas

*Recycler
View*
Parte 1:
Listas
flexíveis e performáticas



*Google Charts*Criando e customizando gráficos para a web


*DNS*
Entenda a resolução de nomes na internet


*Asp.NET Core*
Uma webapp usando o padrão MVC


*Final
Cut*
Introdução a Edição de Vídeos



Em 10 de abril de 2018 09:49,  escreveu:

> Resposta atendimento
>
>
> 10 de Abril de 2018 09:48, "erick zanetti"  > escreveu:
>
>
> Olá, erick,
> A data de entrega do seu trabalho Lista Vetores
>  é
> amanhã. Você deseja entregá-lo?
>
>
> Lista Vetores
> Prazo: 7 de abr
> ABRIR
>
> Se você não quiser receber e-mails do Sala de aula, cancele sua inscrição
> .
>
>
>`
}
let reg = /^(Em\s)?\d{1,2} de \w+ de \d{4}/gm,
    separa = mail.text.split(reg);
console.log(separa[0]);

  • Microsoft emails (Outlook or Hotmail) this will not work, it is even easier just need to mail.text.split(/______________________________/g);. With all the answers I had I managed to do what I wanted and leave everything very well validated, Thank you all.

  • Try so see if it works with Outlook: ^(Em\s\w+,\s)|(Em\s)?\d{1,2}\sde\s\w+\sde\s\d{4}\s(às\s)?\d{1,2}:\d{1,2}([^@]+@\w+\.\w+\.\w+|,\s\sescreveu\:)? .... i did the test with my email see the regex working: https://regex101.com/r/TEmSfl/1

2

The problem in this case is that the responses are actually concatenated with the message, and who does this is the email client of the user who is responding.

What you can do in this case is treat the whole text as a string and filter the desired content. What can help you in this case are regular expressions, which will help you clear unwanted text through patterns.

In this example you posted, you can notice the following pattern when the other answers are concatenated:

<dia> de <mês> de <ano> <hora>:<minuto>, <email> (mailto:<email>) escreveu:

Then follow a javascript example extracting content based on your example:

var msg = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."' +
'' +
'5 de Abril de 2018 10:50, [email protected] (mailto:[email protected]) escreveu:teste' +
'' +
'5 de Abril de 2018 10:31, [email protected] (mailto:[email protected]) escreveu: resposta cliente' +
'' +
'5 de Abril de 2018 10:30, [email protected] (mailto:[email protected]) escreveu:resposta atendimento' +
'' +
'5 de Abril de 2018 09:45, [email protected] (mailto:[email protected]) escreveu: email enviado pelo cliente';

var arrMsg = msg.split(/[0-9]+ de [a-zA-Z]+ de [0-9]+ [0-9:]+, [^@]+@[^ ]+ \(mailto:[^@]+@[^ ]+\) escreveu:/g);

var msgTratada = arrMsg[0];

console.log(msgTratada);

Remembering that if the pattern changes, you will have to adapt the treatment to cover these variations.

  • Very good, this will really work in this case, the problem is that for each source email manager will be a different standard, Gmail, Outlook, Webmail (which was used for this example), among others.

2

As his last reply or sent message always displays a line with a time in the format hh:mm, the way I did it was to detect in which line of the conversation there are strings with this information.

What I did was break all the conversation in array (msg_) separating by line break \n. Then a for going through the array to see what indexes they have hh:mm with the regex /\d+:\d+/ (next numbers before and after two points :), and storing the index and the text occurrences in an object (data_obj = {}).

What I need to know is which line you have hh:mm, and check whether on this line also has a date in the format "day of month of 20".

Assuming this example of conversation:

> Tudo bem! Estarei lá às 8:30
> 5 de Abril de 2018 10:50, [email protected] (mailto:[email protected]) escreveu:teste
> 5 de Abril de 2018 10:31, [email protected] (mailto:[email protected]) escreveu: resposta cliente

In the above case, what matters is to take only the text "> All right! I’ll be there at 8:30", which is the last conversation received.

In the first for, verifying hh:mm, will generate the object:

data_obj = {
0: "> tudo bem! estarei lá às 8:30",
1: "> 5 de abril de 2018 10:50, [email protected] (mailto:[email protected]) escreveu:teste",
2: "> 5 de abril de 2018 10:31, [email protected] (mailto:[email protected]) escreveu: resposta cliente"
}

In all lines were found the pattern hh:mm and added to the object, where key the position of the occurrence in the initially created array; and the value of the respective key the text (converted to lowercase for further checking). But note that the first item of the object, although it has a time (8:30) does not have a date (in the second for that will come, that item will be ignored).

With the object fed, I will make a for in by checking whether each text of the object has the pattern "day of month of 20" with the regex:

/\d\sde\s(jan|fev|mar|abr|mai|jun|jul|ago|set|out|nov|dez)[\w]+\sde\s20/

Note: the above regex will only work until the year 2099. : D

The first occurrence found, your key will be the position of the initial array (msg_) which is as far as I want to get the information. In this case, I do a join with \n (line breaking) and slice(0, nome_da_chave_encontrada).

The theoretical part is sometimes a little difficult to understand and explain, but seeing the code becomes clearer.

Take the example:

The text of the example conversation below is this:

Olá, como vai?
Se você é programador ou desenvolvedor de diversos tipos de aplicações C#
(web, desktop, mobile, etc.), então este lançamento é pra você:
Ao final deste curso você irá tirar proveito das melhorias de parâmetros
out e in, aprender a retornar múltiplos valores de forma simples com
tuplas, simplificar condições e conversões de valores com correspondência
de padrões, explorar funções locais e nova sintaxe de expressão no C# 7,
padronizar os estilos de código C# da sua equipe de desenvolvimento e muito
mais!
Comece já
Em 10 de abril de 2018 09:49,  escreveu:
> Resposta atendimento
>
>
> 10 de Abril de 2018 09:48, "erick zanetti"  > escreveu:
>
>
> Olá, erick,
> A data de entrega do seu trabalho Lista Vetores
>  é
> amanhã. Você deseja entregá-lo?

Obs.: In the example code, I added \n only to simulate line breaks.

var mail = {
   "text":
   'Olá, como vai?\n\n'
   +'Se você é programador ou desenvolvedor de diversos tipos de aplicações C#\n'
   +'(web, desktop, mobile, etc.), então este lançamento é pra você:\n\n\n'
   +'Ao final deste curso você irá tirar proveito das melhorias de parâmetros\n'
   +'out e in, aprender a retornar múltiplos valores de forma simples com\n'
   +'tuplas, simplificar condições e conversões de valores com correspondência\n'
   +'de padrões, explorar funções locais e nova sintaxe de expressão no C# 7,\n'
   +'padronizar os estilos de código C# da sua equipe de desenvolvimento e muito\n'
   +'mais!\n'
   +'Comece já\n\n'
   +'Em 10 de abril de 2018 09:49,  escreveu:\n\n'
   +'> Resposta atendimento\n'
   +'>\n'
   +'>\n'
   +'> 10 de Abril de 2018 09:48, "erick zanetti"  > escreveu:\n'
   +'>\n'
   +'>\n'
   +'> Olá, erick,\n'
   +'> A data de entrega do seu trabalho Lista Vetores\n'
   +'>  é\n'
   +'> amanhã. Você deseja entregá-lo?'
}

msg_ = mail.text.split("\n");

var idx_;
var data_obj = {};
for(var x=0; x<msg_.length; x++){
   if(msg_[x].match(/\d+:\d+/)){
      data_obj[x] = msg_[x].toLowerCase();
   }
}

for(var key in data_obj){
   if(data_obj[key].match(/\d\sde\s(jan|fev|mar|abr|mai|jun|jul|ago|set|out|nov|dez)[\w]+\sde\s20/)){
      idx_ = key;
      break;
   }
}

var ultima = msg_.slice(0,idx_).join("\n");

console.log(ultima);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.