Javascript fetch fails to read Multipart response from GMail API Batch request

I need to use GMail API to retrieve multiple emails data so I am using Batch API. I could finally craft a good enough request but the problem is Javascript doesn’t seem to properly parse the response. Note that this is pure browser Javascript, I am not using any server.

Please refer the code below. The request/response was good upon inspection, but at the line where I call r.formData() method, I receive this error with no further explanation:

TypeError: Failed to fetch

    async getGmailMessageMetadatasAsync(ids: string[], token: string): Promise<IGmailMetaData[]> {
        if (!ids.length) {
            return [];
        }

        const url = `https://gmail.googleapis.com/batch/gmail/v1`;

        const body = new FormData();
        for (let id of ids) {
            const blobContent = `GET /gmail/v1/users/me/messages/${encodeURI(id)}?format=METADATA`;
            const blob = new Blob([blobContent], {
                type: "application/http",
            });

            body.append("dummy", blob);
        }

        const r = await fetch(url, {
            body: body,
            method: "POST",
            headers: this.getAuthHeader(token),
        });

        if (!r.ok) {
            throw r;
        }

        try {
            const content = await r.formData(); // This won't work

            debugger;
            for (let key of content) {

            }
        } catch (e) {
            console.error(e);
            debugger;
        }
        

        return <any>[];
    }

If I replace r.formData() with r.text(), it works but then I have to parse the text by myself which I don’t think is good. The response has correct content-type: multipart/form-data; boundary=batch_HViQtsA3Z_aYrPoOlukRFgkPEUDoDh23 and the body looks like this:

"
--batch_HViQtsA3Z_aYrPoOlukRFgkPEUDoDh23
Content-Type: application/http
Content-ID: response-

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer

{
  "id": "1778c9cc9345a9f4",
  "threadId": "1778c9cc9345a9f4",
  "labelIds": [
    "IMPORTANT",
    "CATEGORY_PERSONAL",
    "INBOX"
  ],

<More content>

How do I properly parse this response and get the JSON content of each email?

3 thoughts on “Javascript fetch fails to read Multipart response from GMail API Batch request”

  1. I was not able to test your code sample. However reading the documentation I see a potential mistake in your code. Indeed you are using a Content-Type multipart/form-data in your request but according to the Google documentation, you should instead use a multipart/mixed Content-Type. Quoting the doc:

    A batch request is a single standard HTTP request containing multiple Gmail API calls, using the multipart/mixed content type. Within that main HTTP request, each of the parts contains a nested HTTP request.

    My guess is that the Google API kindly accepts your Content-Type: multipart/form-data and returns the same Content-Type header in the response even if the content itself is probably not a form-data1 as specified in RFC7578. It’s probably the reason why the Response.formData() API fails to parse the content.


    1 I stay voluntarily cautious because [disclaimer again] I did not test your code and I therefore didn’t see the full result of the response.

    Reply

Leave a Comment