web-dev-qa-db-fra.com

API Gmail pour l'envoi de mails dans Node.js

Avertissement:

  • J'ai suivi les instructions de Google Node.js quickstart guide et j'ai réussi à me connecter et à utiliser la fonctionnalité gmail.users.labels.list().
  • J'ai vérifié les questions/réponses ici, comme celui-ci (qui n'utilise pas l'API Node.js que je demande), ou celui-ci (similaire à - celui-ci ) qui est apparemment le même problème que moi mais la solution ne fonctionne pas.

Mon problème:

Lors de l'utilisation de API Node.js de Google je reçois une erreur en essayant d'envoyer un e-mail. L'erreur est:

{
    "code": 403,
    "errors": [{
        "domain": "global",
        "reason": "insufficientPermissions",
        "message": "Insufficient Permission"
    }]
}

Ma configuration:

fs.readFile(secretlocation, function processClientSecrets(err, content) {
    if (err) {
        console.log('Error loading client secret file: ' + err);
        return;
    }
    authorize(JSON.parse(content), sendMessage);
});

function sendMessage(auth) {
    var raw = makeBody('[email protected]', '[email protected]', 'subject', 'message test');
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        message: {
            raw: raw
        }
    }, function(err, response) {
        res.send(err || response)
    });
}

La fonction processClientSecrets provient du guide Google que j'ai mentionné ci-dessus. Il lit mon fichier .json Contenant mes access_token Et refresh_token. La fonction makeBody est un pour créer un message corporel codé.

Dans les variabels de config j'ai aussi:

var SCOPES = [
    'https://mail.google.com/',
    'https://www.googleapis.com/auth/gmail.modify',
    'https://www.googleapis.com/auth/gmail.compose',
    'https://www.googleapis.com/auth/gmail.send'
];

Pourquoi cela devrait fonctionner:

  • le processus d'autorisation fonctionne pour la méthode gmail.users.labels.list().
  • le corps du message que je teste fonctionne si je le teste sur page de test de Google .

Ma question:

Ma configuration est-elle incorrecte? Y a-t-il eu des changements dans l'API? Qu'est-ce que je rate?

18
Sergio

Ok, j'ai donc trouvé le (s) problème (s).

Problème n ° 1 En suivant le guide de démarrage rapide Node.js l'exemple de ce didacticiel contient

var SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];

Et quand j'ai eu le .json qui ressemble à:

{
    "access_token": "xxx_a_long_secret_string_i_hided_xxx",
    "token_type": "Bearer",
    "refresh_token": "xxx_a_token_i_hided_xxx",
    "expiry_date": 1451721044161
}

ces jetons ont été produits en tenant compte uniquement du auth/gmail.readonly portée dans le code du didacticiel.

J'ai donc supprimé le premier .json, a ajouté les portées de mon tableau de portées final (j'ai posté dans la question) et a exécuté à nouveau la configuration du didacticiel, en recevant un nouveau jeton.

Problème n ° 2

Dans l'objet transmis à l'API que j'envoyais:

{
    auth: auth,
    userId: 'me',
    message: {
        raw: raw
    }
}

mais c'est faux, la touche message doit être appelée resource.


Configuration finale:

Voici ce que j'ai ajouté au code du tutoriel:

function makeBody(to, from, subject, message) {
    var str = ["Content-Type: text/plain; charset=\"UTF-8\"\n",
        "MIME-Version: 1.0\n",
        "Content-Transfer-Encoding: 7bit\n",
        "to: ", to, "\n",
        "from: ", from, "\n",
        "subject: ", subject, "\n\n",
        message
    ].join('');

    var encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
        return encodedMail;
}

function sendMessage(auth) {
    var raw = makeBody('[email protected]', '[email protected]', 'test subject', 'test message');
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        resource: {
            raw: raw
        }
    }, function(err, response) {
        res.send(err || response)
    });
}

Et appelez tout avec:

fs.readFile(secretlocation, function processClientSecrets(err, content) {
    if (err) {
        console.log('Error loading client secret file: ' + err);
        return;
    }
    // Authorize a client with the loaded credentials, then call the
    // Gmail API.
    authorize(JSON.parse(content), sendMessage);
});
20
Sergio

Donc, pour tous ceux qui cherchent à obtenir un e-mail de test envoyé par leur API, mais ne peuvent pas obtenir ce travail, voici ce que vous devez faire:

Étape 1: remplacez le

var SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];

avec ça:

var SCOPES = [
    'https://mail.google.com/',
    'https://www.googleapis.com/auth/gmail.modify',
    'https://www.googleapis.com/auth/gmail.compose',
    'https://www.googleapis.com/auth/gmail.send'
];

Étape 2: à la fin de l'exemple de code Google, ajoutez ceci:

function makeBody(to, from, subject, message) {
    var str = ["Content-Type: text/plain; charset=\"UTF-8\"\n",
        "MIME-Version: 1.0\n",
        "Content-Transfer-Encoding: 7bit\n",
        "to: ", to, "\n",
        "from: ", from, "\n",
        "subject: ", subject, "\n\n",
        message
    ].join('');

    var encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
        return encodedMail;
}

function sendMessage(auth) {
    var raw = makeBody('[email protected]', 'whereyou'[email protected]', 'This is your subject', 'I got this working finally!!!');
    const gmail = google.gmail({version: 'v1', auth});
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        resource: {
            raw: raw
        }

    }, function(err, response) {
        return(err || response)
    });
}

fs.readFile('credentials.json', function processClientSecrets(err, content) {
    if (err) {
        console.log('Error loading client secret file: ' + err);
        return;
    }
    // Authorize a client with the loaded credentials, then call the
    // Gmail API.
    authorize(JSON.parse(content), sendMessage);
});

Étape 3 (facultatif)

Supprimer cette ligne:

authorize(JSON.parse(content), listLabels);

Et ceux-ci:

/**
 * Lists the labels in the user's account.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
 function listLabels(auth) {
   const gmail = google.gmail({version: 'v1', auth});
   gmail.users.labels.list({
     userId: 'me',
   }, (err, res) => {
     if (err) return console.log('The API returned an error: ' + err);
     const labels = res.data.labels;
     if (labels.length) {
       console.log('Labels:');
       labels.forEach((label) => {
         console.log(`- ${label.name}`);
       });
     } else {
       console.log('No labels found.');
     }
   });
 }

(Vous n'avez donc pas les étiquettes aléatoires dans votre console)

1
Vincent Morris