mailjet / mailjet-apiv3-nodejs

[API v3] Official Mailjet API v3 NodeJS wrapper
https://dev.mailjet.com
MIT License
236 stars 69 forks source link

MailJet broken on Cloudflare workers due to Axios RequestInitializerDict being broken in 1.7.4 (fixed in 1.7.5) #285

Open robert-hoffmann opened 1 month ago

robert-hoffmann commented 1 month ago

Mailjet is broken on Cloudflare, and when using NuxtJS projects deployed on NuxtHub

Sending a mail triggers a 500 error : The 'credentials' field on 'RequestInitializerDict' is not implemented.

This is apparently due to this issue with Axios https://github.com/axios/axios/issues/6565

As mentioned here https://github.com/axios/axios/issues/6565#issuecomment-2327408217

Solution: Upgrade MailJet Axios dependency to at least 1.7.5 (currently 1.7.7)

robert-hoffmann commented 1 month ago

Here is the full error message from mailjet api

{
    "result": {
        "config": {
            "transitional": {
                "silentJSONParsing": true,
                "forcedJSONParsing": true,
                "clarifyTimeoutError": false
            },
            "adapter": [
                "xhr",
                "http",
                "fetch"
            ],
            "transformRequest": [
                null
            ],
            "timeout": 0,
            "xsrfCookieName": "XSRF-TOKEN",
            "xsrfHeaderName": "X-XSRF-TOKEN",
            "maxContentLength": -1,
            "maxBodyLength": -1,
            "env": {},
            "headers": {
                "Accept": "application/json, text/plain, */*",
                "Content-Type": "application/json",
                "User-Agent": "mailjet-api-v3-nodejs/6.0.6"
            },
            "url": "https://api.mailjet.com/v3.1/send",
            "params": {},
            "data": "{\"Messages\":[{\"From\":{\"Email\":\"noreply@redacted.com\",\"Name\":\"Noreply redacted Digital\"},\"To\":[{\"Email\":\"redacted.redacted@gmail.com\",\"Name\":\"redacted redacted\"}],\"Subject\":\"A test email\",\"TextPart\":\"test message\",\"HTMLPart\":\"test message\"}]}",
            "method": "post",
            "responseType": "json",
            "auth": {
                "username": "redacted",
                "password": "redacted"
            }
        },
        "response": null,
        "statusCode": null,
        "statusText": null,
        "originalMessage": "The 'credentials' field on 'RequestInitializerDict' is not implemented.",
        "message": "Unsuccessful: Error Code: \"undefined\" Message: \"The 'credentials' field on 'RequestInitializerDict' is not implemented.\""
    }
}
robert-hoffmann commented 1 month ago

I actually haven't been able to resolve this using overrides in my package.json (maybe i have some caching issues on cloudflare)

In any case, according to the issues on axios, this seems on their end, and resolved currently

robert-hoffmann commented 1 month ago

So, i worked around this by using the api directly: https://api.mailjet.com/v3/send (https://dev.mailjet.com/email/reference/send-emails#v3_post_send)

Maybe remove dependencies from Axios, and simply implement the fetch yourself ?

If you need advanced functionality over fetch, have a look at ofetch, which is what is used in nuxt and other libraries, and uses fetch under the hood, which is compatible in both browser and nodejs clients

https://github.com/unjs/ofetch

Btw, you could add an example on the API page, showing how to use JS to do the fetch stuff

Here what i replaced the nodejs library with:

function sendEmail(data) {
  const url  = 'https://api.mailjet.com/v3/send';
  const body = {
    "FromEmail" : data.fromEmail,
    "FromName"  : data.fromName,
    "Subject"   : data.subject,
    "Text-part" : data.text,
    "Html-part" : data.html,
    "Recipients": [
      { "Email": data.email, "Name": data.name }
    ]
  };

  return fetch(url, {
    method : 'POST',
    headers: {
      'Content-Type' : 'application/json',
      'Authorization': `Basic ${process.env.MJ_APIKEY_PUBLIC}:${process.env.MJ_APIKEY_PRIVATE}`
    },
    body: JSON.stringify(body)
  })
}
Maze-fr commented 1 month ago

There is the cURL example here : https://dev.mailjet.com/email/guides/send-api-v31/
It's easy to adapt to JS fetch.
But I get CORS error...

robert-hoffmann commented 1 month ago

But I get CORS error...

You can't use this on the client, which i suppose you are doing (maybe with some tweaks, but probably not)

My fetch code is executed on the server by nodejs, not in the browser. Also often companies like MailJet will deny usage in the browser (cors), because that means you are exposing your secret keys to the whole world

This works fine on the server (easy to adapt to plain java, c#, php, etc), without using any library dependency:

https://github.com/mailjet/mailjet-apiv3-nodejs/issues/285#issuecomment-2407009629

Maze-fr commented 1 month ago

But I get CORS error...

You can't use this on the client, which i suppose you are doing (maybe with some tweaks, but probably not)

My fetch code is executed on the server by nodejs, not in the browser. Also often companies like MailJet will deny usage in the browser (cors), because that means you are exposing your secret keys to the whole world

That makes sense...
And it's also written here : https://github.com/mailjet/mailjet-apiv3-nodejs