web-dev-qa-db-ja.com

Node.jsでメールを送信するためのGmail API

免責事項:

  • 私はGoogle独自の Node.jsクイックスタートガイド に従い、正常に接続してgmail.users.labels.list()機能を使用しています。
  • this one (私が尋ねているNode.js APIを使用していない)、または this one (-に類似)などの質問/回答をここで確認しました これ )これは明らかに私が持っているのと同じ問題ですが、解決策は機能しません。

私の問題:

GoogleのNode.js API を使用している場合、メールを送信しようとするとエラーが発生します。エラーは:

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

私のセットアップ:

_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)
    });
}
_

関数processClientSecretsは、前述のGoogleガイドからのものです。 _.json_と_access_token_を含む_refresh_token_ファイルを読み取ります。 makeBody function は、エンコードされた本文メッセージを作成するためのものです。

Config variabelsでも私は持っています:

_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'
];
_

なぜ機能するのか:

  • 承認プロセスはgmail.users.labels.list()メソッドに対して機能します。
  • Googleのテストページ でテストすると、テストしているメッセージ本文が機能します。

私の質問:

私の設定は間違っていますか? APIに変更はありますか?何が欠けていますか?

18
Sergio

わかりましたので、問題を見つけました。

問題#1Node.jsクイックスタートガイド を実行している間、そのチュートリアルの例には

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

そして、私が.jsonを得たとき、それは次のようになります:

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

チュートリアルコードのauth/gmail.readonlyスコープonlyを考慮して生成されたトークン.

そこで、最初の.jsonを削除し、最後のスコープ配列(質問に投稿しました)からスコープを追加して、チュートリアルのセットアップを再度実行し、新しいトークンを受け取りました。

問題#2

私が送信していたAPIに渡されたオブジェクトで:

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

しかしそれは間違っています。messageキーはresourceと呼ばれるべきです。


最終的なセットアップ:

これは私がチュートリアルのコードに追加したものです:

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)
    });
}

そして、すべてを呼び出す:

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

したがって、APIからテスト電子メールを送信しようとしているが、この作業を取得できない場合は、次のようにします。

手順1:を交換する

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

これとともに:

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'
];

ステップ2:googlesサンプルコードの最後にこれを追加します:

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);
});

ステップ3(オプション)

この行を削除:

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

そしてこれら:

/**
 * 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.');
     }
   });
 }

(したがって、コンソールにランダムなラベルが表示されません)

1
Vincent Morris