Search code examples
gmailgmail-api

Gmail add SENT or DRAFT label


I have an mbox file that I got using Gmail's "archive" functionality. Each message in it has an "X-Gmail-Labels" header listing which labels/folders it goes in. When I import the messages from the mbox file into a new Gmail account (by opening the file in Thunderbird and copying the messages over), the message copies in the new Gmail account still have the X-Gmail-Labels header, but it doesn't do anything - messages are not actually marked with any labels. So I wrote a script to use the Gmail API to fetch each message, read its X-Gmail-Labels, and add those labels to the message. This mostly works, except that for two of the labels (SENT and DRAFT), I get an error that says it's an invalid label. Those label IDs definitely do exist. How do I add them to messages?

Here's the request I'm making:

curl -H "Authorization: Bearer OAUTH_TOKEN" \
-H "Content-Type: application/json" \
-X POST \
-d '{"addLabelIds": ["SENT"]}' \
https://www.googleapis.com/gmail/v1/users/me/messages/MESSAGE_ID/modify

Here's the response body:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalidArgument",
    "message": "Invalid label: SENT"
   }
  ],
  "code": 400,
  "message": "Invalid label: SENT"
 }
}

(Note: my actual script is in Python, but it's easier to see what's going on in curl.)


Solution

  • The SENT- and DRAFT-labels are special in that they can not be added to a message once it has been created. More information about each label can be found in this guide.

    Instead, you could insert your messages and give them the right labels right away.

    Here is an example, just encoding an example message in the Developer Console:

    A sent message

    var encodedMessage = btoa([
      'From: [email protected]', '\r\n',
      'To: [email protected]', '\r\n',
      'Subject: cool subject', '\r\n', 
      '\r\n',
      'this is my sent message'
    ].join('')) 
    

    Request

    POST https://www.googleapis.com/gmail/v1/users/me/messages?access_token={YOUR_API_KEY}
    {
     "raw": "RnJvbTogZW10aG9saW5AZ21haWwuY29tDQpUbzogZW10aG9saW5AZ21haWwuY29tDQpTdWJqZWN0OiBjb29sIHN1YmplY3QNCg0KdGhpcyBpcyBteSBzZW50IG1lc3NhZ2U=",
     "labelIds": [
      "SENT"
     ]
    }
    

    Response

    {
     "id": "1525643b0785e7d7",
     "threadId": "1525643b0785e7d7",
     "labelIds": [
      "SENT"
     ]
    }
    

    A draft

    Request

    POST https://www.googleapis.com/gmail/v1/users/me/messages?access_token={YOUR_API_KEY}
    {
     "raw": "RnJvbTogZW10aG9saW5AZ21haWwuY29tDQpUbzogZW10aG9saW5AZ21haWwuY29tDQpTdWJqZWN0OiBjb29sIHN1YmplY3QNCg0KdGhpcyBpcyBteSBzZW50IG1lc3NhZ2U=",
     "labelIds": [
      "DRAFT"
     ]
    }
    

    Response

    {
     "id": "1525644c9553906d",
     "threadId": "1525644c9553906d",
     "labelIds": [
      "DRAFT"
     ]
    }
    

    Also, if you want the created time to be the same as the Date-header in the inserted message, make sure you pass along the query parameter internalDateSource with the value of dateHeader.