I have received a successful response of a email using gmail.users.messages.send() which is like
{ "id": "1231212312", "labelIds": ["UNREAD", "SENT", "INBOX"], "threadId": "23123123" }
I need to send an email again to the same email address but on the same thread not as a new email i.e using thread id to send email.
See below the output of my program (I removed part of the body['raw'] in case it included some private data I am not aware).
'Send e-mail with body: First message 2019-06-20 16:00:26.922694'
{'raw': 'Q29udGVudC1UeXBlOiB0ZXh0L...C5jb20K...uOTIyNjk0'}
'Got'
{u'id': u'16b753049239ba7c',
u'labelIds': [u'SENT'],
u'threadId': u'16b753049239ba7c'}
'============'
'Send e-mail with body: Second message 2019-06-20 16:00:26.922694'
{'raw': 'Q29udGVudC1UeXBlOiB0ZXh0...b...OjAwOjI2LjkyMjY5NA==', 'threadId': u'
16b753049239ba7c
'}
'Got'
{u'id': u'16b75304c6165b0d',
u'labelIds': [u'SENT'],
u'threadId': u'16b753049239ba7c'}
'============'
'Send e-mail with body: Third message 2019-06-20 16:00:26.922694'
{'raw': 'Q29udGVudC1UeXBlOiB0ZXh0L...C5jb20KZn...TIyNjk0', 'threadId': u'
16b753049239ba7c
'}
'Got'
{u'id': u'16b75304f40b1d95',
u'labelIds': [u'SENT'],
u'threadId': u'16b753049239ba7c'}
'============'
It looks that the threadId is ok and the sender have them in a thread, but as you can see in the screenshots I attached at the end of this message, the recipient doesn't have it.
I am aware that we are told that we need to use the "References" and "In-Reply-To" but I'm afraid the send endpoint doesn't give me that and in order to get the e-mail I sent I think I need further permissions (read e-mail?) I would prefer to avoid.
def CreateMessage(sender, to, subject, message_text, threadId):
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
raw_message = base64.urlsafe_b64encode(message.as_string().encode("utf-8"))
return { 'raw': raw_message.decode("utf-8"), 'threadId': threadId }
Hi, thank for your comment, I already sent the threadId and I complained because it stopped working on June 2019. I am not sure if this is because we use G Suite or if it is working again without the References and In-Reply-To headers.
See https://developers.google.com/gmail/api/guides/sending#sending_messages
For your information:
We wanted to send a batch of e-mails during a batch process. On June 2019 just sending the threadId wasn't enough and we needed to send the References and In-Reply-To headers as well.
Our problem was that the first "send" didn't return the created message-id so we could not use it directly for the next messages.
We came up with a workaround. In order to group all the messages, besides the threadId (like you said) we made up a fake message-id and we add the headers with this fake message-id in all the messages we wanted grouped.
It still works today, so not bad at all.
Cheers!
Hi, thank for your comment, I already sent the threadId and I complained because it stopped working on June 2019. I am not sure if this is because we use G Suite or if it is working again without the References and In-Reply-To headers.
See https://developers.google.com/gmail/api/guides/sending#sending_messages
For your information:
We wanted to send a batch of e-mails during a batch process. On June 2019 just sending the threadId wasn't enough and we needed to send the References and In-Reply-To headers as well.
Our problem was that the first "send" didn't return the created message-id so we could not use it directly for the next messages.
We came up with a workaround. In order to group all the messages, besides the threadId (like you said) we made up a fake message-id and we add the headers with this fake message-id in all the messages we wanted grouped.
It still works today, so not bad at all.
Cheers!
Hello!
Can you please share the code for the same? I am working on the same problem, I need to reply to emails via the gmail API and all the replies should be in the same thread.
Hi Sorry for the late reply.
In order to use the in_reply_to I add it to the MIME Message like this:
message = MIMEText(body)
message['to'] = to
message['from'] = sender # Not sure if this one does anything.
message['subject'] = subject
if cc:
message['cc'] = cc
if bcc:
message['bcc'] = bcc
if in_reply_to:
# For properly treating thread in receiver side.
message['In-Reply-To'] = in_reply_to
message['References'] = in_reply_to
sz_message = message.as_string()
raw_msg_byte =
base64.urlsafe_b64encode(six.ensure_binary(sz_message))
raw_msg = six.ensure_str(raw_msg_byte)
new_email = {'raw': raw_msg}
if thread_id:
# For properly treating the thread in sender side
new_email['threadId'] = thread_id
return gmail_client.users().messages().send(
userId='me', body=new_email,
).execute()
In order to get the in_reply_to as an example we make a fake message id,
this is directly the previous in_reply_to:
from email.mime.text import MIMEText
from email.utils import make_msgid
@staticmethod
def get_fake_message_id(idstring=None):
"""Get a fake message id (for threading).
:param idstring: An optional string as in email.utils.make_msgid.
return make_msgid(idstring)
I hope it helps!
Zorion
On Fri, Sep 18, 2020 at 9:32 PM Chen Mor ***@***.***> wrote:
I'm also interested in your solution
@zorion <
https://github.com/zorion>
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<
#710 (comment)>,
or unsubscribe
<
https://github.com/notifications/unsubscribe-auth/AAQ63BZGDO6HAPOVXU7PMG3SGOYTHANCNFSM4DAURQ2A>
Hi Sorry for the late reply.
In order to use the in_reply_to I add it to the MIME Message like this:
message = MIMEText(body)
message['to'] = to
message['from'] = sender # Not sure if this one does anything.
message['subject'] = subject
if cc:
message['cc'] = cc
if bcc:
message['bcc'] = bcc
if in_reply_to:
# For properly treating thread in receiver side.
message['In-Reply-To'] = in_reply_to
message['References'] = in_reply_to
sz_message = message.as_string()
raw_msg_byte =
base64.urlsafe_b64encode(six.ensure_binary(sz_message))
raw_msg = six.ensure_str(raw_msg_byte)
new_email = {'raw': raw_msg}
if thread_id:
# For properly treating the thread in sender side
new_email['threadId'] = thread_id
return gmail_client.users().messages().send(
userId='me', body=new_email,
).execute()
In order to get the in_reply_to as an example we make a fake message id,
this is directly the previous in_reply_to:
from email.mime.text import MIMEText
from email.utils import make_msgid
@staticmethod
def get_fake_message_id(idstring=None):
"""Get a fake message id (for threading).
:param idstring: An optional string as in email.utils.make_msgid.
return make_msgid(idstring)
I hope it helps!
PS: I send this message twice because I was requested twice and I'm not
sure if everyone will be notified replying just to one of them. Sorry if
someone finds it a bit spammic, I hope I won't do it again.
Zorion
On Tue, Aug 11, 2020 at 1:11 PM Kushagra Anand ***@***.***> wrote:
Hi, thank for your comment, I already sent the threadId and I complained
because it stopped working on June 2019. I am not sure if this is because
we use G Suite or if it is working again without the References and
In-Reply-To headers.
https://developers.google.com/gmail/api/guides/sending#sending_messages
For your information:
We wanted to send a batch of e-mails during a batch process. On June 2019
just sending the threadId wasn't enough and we needed to send the
References and In-Reply-To headers as well.
Our problem was that the first "send" didn't return the created message-id
so we could not use it directly for the next messages.
We came up with a workaround. In order to group all the messages, besides
the threadId (like you said) we made up a fake message-id and we add the
headers with this fake message-id in all the messages we wanted grouped.
It still works today, so not bad at all.
Cheers!
Hello!
Can you please share the code for the same? I am working on the same
problem, I need to reply to emails via the gmail API and all the replies
should be in the same thread.
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<
#710 (comment)>,
or unsubscribe
<
https://github.com/notifications/unsubscribe-auth/AAQ63BZIDI534J5WT6MUVEDSAERPFANCNFSM4DAURQ2A>
Oh, I didn't notice that this is a nodejs library. My solution is in python
but I hope you can do the same in nodejs.
On Fri, Sep 25, 2020 at 3:37 PM Zorion ***@***.***> wrote:
Hi Sorry for the late reply.
In order to use the in_reply_to I add it to the MIME Message like this:
message = MIMEText(body)
message['to'] = to
message['from'] = sender # Not sure if this one does anything.
message['subject'] = subject
if cc:
message['cc'] = cc
if bcc:
message['bcc'] = bcc
if in_reply_to:
# For properly treating thread in receiver side.
message['In-Reply-To'] = in_reply_to
message['References'] = in_reply_to
sz_message = message.as_string()
raw_msg_byte =
base64.urlsafe_b64encode(six.ensure_binary(sz_message))
raw_msg = six.ensure_str(raw_msg_byte)
new_email = {'raw': raw_msg}
if thread_id:
# For properly treating the thread in sender side
new_email['threadId'] = thread_id
return gmail_client.users().messages().send(
userId='me', body=new_email,
).execute()
In order to get the in_reply_to as an example we make a fake message id,
this is directly the previous in_reply_to:
from email.mime.text import MIMEText
from email.utils import make_msgid
@staticmethod
def get_fake_message_id(idstring=None):
"""Get a fake message id (for threading).
:param idstring: An optional string as in email.utils.make_msgid.
return make_msgid(idstring)
I hope it helps!
Zorion
On Fri, Sep 18, 2020 at 9:32 PM Chen Mor ***@***.***> wrote:
> I'm also interested in your solution
@zorion <
https://github.com/zorion>
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <
#710 (comment)>,
> or unsubscribe
> <
https://github.com/notifications/unsubscribe-auth/AAQ63BZGDO6HAPOVXU7PMG3SGOYTHANCNFSM4DAURQ2A>
Hi Zorion,
Thanks for the help. Can you please tell me how to get the MIME Message-ID header for the the message['In-Reply-To'] and message['References'] field.
I have generated a fake string using the method you told and I am getting something like:
160386124446.10116.2885793118650215377@LAPTOP-FFPUFH6K
But in most cases the message-id seems to be something like:
CAGvK4+W5G3KnYQmjvcpTJ=OCfvPQeWUHcLJG39JVGX4V3y1efA@mail.gmail.com
I am not able to generate @mail.gmail.com part or should i retrieve it from the mail I sent(for which i want to sent the reply to)?
I had similar fake-ids and they worked for my purposes.
I mean, after the "@" I had the hostname of the server I'm using which
isn't a valid internet domain name, but it's ok in my case.
Did you try using this weird fake id? It may work for you as well.
Best regards
Zorion
El dc., 28 d’oct. 2020, 6:03, sudb97 <
[email protected]> va escriure:
Hi Zorion,
Thanks for the help. Can you please tell me how to get the *MIME
Message-ID header* for the the *message['In-Reply-To']* and
*message['References']* field.
I have generated a fake string using the method you told and I am getting
something like:
***@***.***
But in most cases the message-id seems to be something like:
***@***.***
I am not able to generate @mail.gmail.com part or should i retrieve it
from the mail I sent(for which i want to sent the reply to)?
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<
#710 (comment)>,
or unsubscribe
<
https://github.com/notifications/unsubscribe-auth/AAQ63B42FONQGMYVW73NGK3SM6Q2DANCNFSM4DAURQ2A>
Hi Zorion,
Yes i tried using fake-ids, it wasn't working.
But i used https://developers.google.com/gmail/api/reference/rest/v1/users.messages/get?authuser=1 gmail API to get my message-id. It worked fine.
Gmail automatically assigns a Message-id to the mail you are sending via its api.
I was just not able to get the correct api request.
Now i am able to thread all the replies.
Just working on how to retrieve the message-ids for email sent via my python code. Then will be able to send replies that will be chained.
Thanks for your code though :)
I'm glad you have something working!
I am not sure we are doing the same so in case my needs can fit yours I add
a metadata sample.
It works for us with the following metadata (with some part redacted just
in case).
In-Reply-To: <
*
[email protected].****redacted*****.internal*>
References: <
*
[email protected].****redacted*****.internal*>
Date: Wed, 26 Feb 2020 04:30:24 -0800
Message-ID: <CAAe2CVM***redacted*****
[email protected]>
When I send the e-mail I do include "In-Reply-To" and "References".
This is the fake ID, and my first e-mail already "replies" to the fake id
e-mail.
The field Message-Id I don't send, it is generated way after I send the
"send e-mail" request. I assume the send request is not directly a send, so
the e-mail doesn't have a message-id until it is indeed sent in the
server's background (this is an assumption on why the send request doesn't
return the message-id).
This meta data above I got from the e-mail I sent in my GMAIL web ui
message -> 3 vertical dots -> show-original
So the process was:
1) I generated a *fake message-id* from the server and I got
*
[email protected].****redacted*****.internal*
2) I made the e-mail with the *in-reply-to* and *references* including the
fake id generated
3) I requested gmail api to send the first e-mail with those fields sets
4) I requested gmail api to send the other e-mail with those fields set
same way (same *in-reply-to* and *references*)
5) I can see all of them in the same thread and I can now get the
message-id if I wanted to.
On the other hand, technically I assume that it works like this:
I tell gmail that I have a (fake) local e-mail I am replying to with the
fake id that may be currently deleted.
I tell gmail that all e-mails I am sending are direct replies to that same
fake local e-mail.
GMail groups all these e-mails because they are related, they are a
conversation to the fake e-mail, but they don't have dependencies to each
other except for the timestamps so Gmail groups them and sorts them by
timestamp.
I am not sure this is the case but it works for us like a charm!
If you send the first e-mail and want to use its message id you are doing
it properly, but you will need to wait until the message-id is indeed
generated which may not be immediate.
Of course you may dismiss this e-mail since it's a workaround and you have
your own workaround.
Having the message-id in the send-email-request is what both of us would
miss.
Best regards,
Zorion
On Wed, Oct 28, 2020 at 7:44 AM sudb97 ***@***.***> wrote:
Hi Zorion,
Yes i tried using fake-ids, it wasn't working.
But i used *
https://developers.google.com/gmail/api/reference/rest/v1/users.messages/get?authuser=1
<
https://developers.google.com/gmail/api/reference/rest/v1/users.messages/get?authuser=1>*
gmail API to get my message-id. It worked fine.
Gmail automatically assigns a Message-id to the mail you are sending via
its api.
I was just not able to get the correct api request.
Now i am able to thread all the replies.
Just working on how to retrieve the message-ids for email sent via my
python code. Then will be able to send replies that will be chained.
Thanks for your code though :)
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<
#710 (comment)>,
or unsubscribe
<
https://github.com/notifications/unsubscribe-auth/AAQ63B2XCGD2WITTUABNVVDSM64T3ANCNFSM4DAURQ2A>
Hi Zorion,
Yes i tried using fake-ids, it wasn't working.
But i used https://developers.google.com/gmail/api/reference/rest/v1/users.messages/get?authuser=1 gmail API to get my message-id. It worked fine.
Gmail automatically assigns a Message-id to the mail you are sending via its api.
I was just not able to get the correct api request.
Now i am able to thread all the replies.
Just working on how to retrieve the message-ids for email sent via my python code. Then will be able to send replies that will be chained.
Thanks for your code though :)
Hey, I think i am going through similar issue, can you share the code snippet which you are using to Reply Email in thread. I am having hard time understanding what should go with In-Reply-To and References fields. I am able to find Message-Id and threadId through API response though.
Hi raumildhandhukia,
I am not sure if the question is for me or for sudb97.
I understand that the fields in-reply-to
and references
should contain the message-id
you have.
In case of python
this is similar to:
message = MIMEText(body)
message['to'] = to
message['from'] = sender # Not sure if this one does anything.
message['subject'] = subject
if cc:
message['cc'] = cc
if bcc:
message['bcc'] = bcc
if in_reply_to:
# For properly treating thread in receiver side.
message['In-Reply-To'] = message_id
message['References'] = message_id
What I missed in my code was the first message_id
(from the first e-mail) and what I did is creating fake message-id
so I was replying to a fake thread (but all subsequent e-mails went to the same thread, although it was originally fake).