16

Edit: addressing the first comment below and for clarity, this isn't a code question. The question is simply:

What do I put into the URI querystring of the new Gmail UI to view a draft message created by the Gmail API?

Despite this not really being a code question, I'm asking on Stack Overflow as it's Google's preferred platform for Gmail API questions.

--

If I view a draft message in the new Gmail UI, the URI is something like this:

https://mail.google.com/mail/u/1/?zx=iij9apqgzdf4#drafts?compose=jrjtXSqXwlFGnSGCQgDCdnHGVFdlpFMgzsCNgpQstQLxdLCMkjKstBmWZkCmjhWTQnpsZCJF

I can't see any way to create such a link from the Id or ThreadId of a message created via the Gmail API.

Previously, one could do this:

https://mail.google.com/mail/u/1/?zx=ov61dxfbrcga#drafts?compose=1631caae9dbb074d

where the value of "compose" is the Id.

How can the same thing be accomplished in the new UI?

Chris Wood
  • 521
  • 6
  • 13
  • Can you add any details like: code used, error problem encountered? [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask), [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) Show the community what you have tried. – ReyAnthonyRenacia May 02 '18 at 09:32
  • Since this week it seems to work. When I open the new UI with an older threadId, it redirects to the new threadId of the mail/answer. Can you confirm that? – Frank Szilinski Oct 01 '18 at 14:54
  • Not happening for me, Frank. Do you mean like this? https://mail.google.com/mail/ca/u/1/#drafts?compose=1661237c4db71ace – Chris Wood Oct 02 '18 at 15:04
  • 1
    Aaah, like this is working: https://mail.google.com/mail/ca/u/1/#drafts/1661237c4db71ace – Chris Wood Oct 02 '18 at 15:19

5 Answers5

13

I've been encountering the same problem and have had some success in this problem, as well as some issues I still can't get past.

Good news: The new compose parameter format is some kind of "base40" encoding. I searched the Gmail source for a restricted alphabet string, and found and deobfuscated the bit of code doing this encoding/decoding: https://gist.github.com/danrouse/52212f0de2fbfe33cfc56583f20ccb74

This code includes an encode and decode function which should work for Gmail-format query parameters.

Bad news: The values that it is encoding to open draft emails do not appear to be available using the Gmail API. Specifically, they look like this: thread-f:NEW_THREAD_ID+msg-a:DRAFT_ID -- while the draft ID is the same as it was before, the Thread ID does not appear to match any of the IDs that the Gmail API returns.

Interestingly, if you inspect the subject row in the Gmail UI, it has dataset attributes including all of both the old format and new format IDs - but it's still unclear how to get the new ones programatically.

kremonte
  • 141
  • 3
  • 1
    Wow - great research, kremonte! Will take a look myself and see if I can get us any further! – Chris Wood May 03 '18 at 16:58
  • 1
    Taken a look at this myself tonight. Have reproduced what you said about base40 and can see the data-* attributes you mention. Interesting that the IDs we're used to seeing are prefixed with "data-legacy". You mention that the draft IDs are the same - that doesn't seem to be the case looking at the data attributes. The legacy draft and thread ids are the same for me (for a newly created draft) and don't resemble the new ones. – Chris Wood May 03 '18 at 19:21
  • 1
    Ah - yes, thread-f and msg-f seem to have some mapping to the old IDs. But if you decrypt a compose parameter from the querystring, thread-a and msg-a are used instead. – Chris Wood May 03 '18 at 20:01
  • 3
    Good news - looking at this again several months later, the NEW_THREAD_ID value is now just the decimal representation of the hex thread id returned by the Gmail API. – Chris Wood Aug 15 '18 at 20:03
  • Are you sure? I have tried to convert to decimal no match – AndrewG Aug 21 '18 at 15:05
  • I just tried to convert the result of `decode` from base10 to base16 and it *almost* gives me the right ID, seems to be off by a smallish amount (25~65) so I'm guessing there's something wrong with the decoder – Juan Campa Aug 26 '18 at 21:18
  • 2
    Oh, I was doing the conversion using JS ints which don't have enough precision. BigInt ftw. – Juan Campa Aug 26 '18 at 21:38
  • Just to muddy the waters - the format of the compose identifier seems to be changing again, but only for some users... I'm seeing `thread-f:NEW_THREAD_ID|msg-a:DRAFT_ID+msg-a:DRAFT_ID` but I've no idea what discriminates between the two formats. – Chris Wood Sep 25 '18 at 12:47
  • @ChrisWood There are a few times where the thread is something like this:- `thread-a:r-986439393737` And when I convert hex threadid to something like `thread-f:987654321`, gmail web app is saying thread not found. Any ideas @JuanCampa – Dilip Oct 23 '18 at 09:44
  • I've found that in the dataset attributes within a compose window you can see a "draft" one which has the new id format. Generally if it has a format like #msg-a:r3213213131 you can use the part after the colon to query that id using the Draft's endpoint, but thats still flaky. – r0bb077 Nov 01 '18 at 01:36
  • `thread-f:` is straightforward, any ideas about `thread-a:r`? I've seen it used with and without a `-` after the `r`. – SirTophamHatt Dec 04 '18 at 15:15
  • Any clues how to transfer from message id to id by decoding base40? – Nyuokimi Apr 26 '22 at 07:47
6

Thanks to @frank-szilinski - he pointed out that the old format is now translated. I.e. this now works again:

https://mail.google.com/mail/ca/u/1/#drafts/1661237c4db71ace

It doesn't seem to work when the Gmail tab isn't already open, however.

Chris Wood
  • 521
  • 6
  • 13
  • No more true... See this question: https://stackoverflow.com/questions/64022899/how-to-open-a-draft-created-with-gmail-api-in-browser – jogo Sep 30 '20 at 16:57
4

Building on @kremonte gist, and @chris-wood comments, I made a rails gem that correctly creates the open-the-draft-inside-gmail URL.

It's here - https://github.com/GoodMeasuresLLC/gmail_compose_encoder

It's for the use case of "my code created a draft (prepopulated with some text, of course) and now I want to open the draft in compose mode so that my user can review it before hitting "send".

Rob
  • 4,404
  • 2
  • 32
  • 33
  • Thanks for spending the time creating that! Not wanting to dampen any spirits at all, but see my final comment on the original question above. The way the tokens are composed has changed again, but only for some people and not others. The two different types are incompatible with each other and there's no (clean) way of knowing which type of token a user is using. We thought we'd cracked it once we figured out the token format, but it's just not stable enough to rely on. – Chris Wood Sep 29 '18 at 20:36
  • I did see that comment, but I didn't encounter that situation when I was testing, so I crossed my fingers and shipped it for my application, since having it work mostly was better than having it not work at all (which was the current situation) – Rob Sep 30 '18 at 12:33
  • Ah, ya, now I'm getting reports that it doesn't work again. Sigh. :( – Rob Nov 02 '18 at 19:05
1

How to get the URL for a draft

If, for example you use a list request from which you get your draft objects:

{
  "id": string,
  "message": {
    object (Message)
  }
}

You can take this id and put it into a URL in this format:

mail.google.com/mail/#inbox?compose=[id]

Eg.

mail.google.com/mail/#inbox?compose=3doinm3d08932d

This will open up GMail with the relevant draft open.

iansedano
  • 6,169
  • 2
  • 12
  • 24
1

I was struggling because I wanted it to work with multiple accounts. However the authuser parameter did not help.

Inserting the email address instead of the integer after the u/ component solved the problem.

https://mail.google.com/mail/u/{email_address}/#drafts?compose={message_id}

The message id is the one provided by the API.

Stefanf
  • 1,663
  • 13
  • 15
  • Does it works with other email types? For example if email is in Sent folder? – Nyuokimi Apr 26 '22 at 07:07
  • @Nyuokimi i doubt that you can open a composer on a already sent message. But you could probably just navigate to a message and display it to the user. – Stefanf Apr 26 '22 at 07:11
  • What do you mean by navigate to a message and display it? I have only that msg id and email of email owner. – Nyuokimi Apr 26 '22 at 07:13
  • @Nyuokimi i wanted to let the user modify and send a draft that I prepared via API. This is why I needed an URL to the Gmail UI. I don’t know what you try to achieve with that URL. – Stefanf Apr 26 '22 at 07:17
  • I want to open existng email by url in new window if I know that email id. – Nyuokimi Apr 26 '22 at 07:19