【问题标题】:API Gmail in NodeJS: (node:14592) UnhandledPromiseRejectionWarning: Error: Delegation deniedNodeJS 中的 API Gmail:(节点:14592)UnhandledPromiseRejectionWarning:错误:委派被拒绝
【发布时间】:2020-10-19 20:36:57
【问题描述】:

我在使用 GMAIL API 时遇到了真正的问题,这是我的错误:

(node:14592) UnhandledPromiseRejectionWarning: Error: Delegation denied for ADMIN_EMAIL

这是我的代码,我想先用域的 gsuits 管理员更改我的签名。当我尝试检查并提示我的gmail信息帐户时,还可以,但是当我要修改签名时,出现了错误。 我使用 ID 服务帐户在 Wide-delegation 域中设置范围并下载 credentials.JSON

const {google} = require('googleapis');

const keys = require('./credentials.json');
const {JWT} = require('google-auth-library');

// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/admin.directory.user',
    'https://www.googleapis.com/auth/gmail.settings.basic',
    'https://www.googleapis.com/auth/gmail.settings.sharing',
    'https://www.googleapis.com/auth/gmail.modify',
    'https://mail.google.com',
    'https://www.googleapis.com/auth/gmail.compose',
    'https://www.googleapis.com/auth/gmail.readonly',
];

async function main() {
    const client = new JWT(
        {
            email: keys.client_email,
            key: keys.private_key,
            subject: ADMIN_EMAIL,
            scopes: SCOPES,
        }
    );
    const url = `https://dns.googleapis.com/dns/v1/projects/${keys.project_id}`;
    listUsers(client);
}

main();

/**
 * Lists all users in the domain and check if he's my email.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listUsers(auth) {
    const service = google.admin({version: 'directory_v1', auth});
    service.users.list({
        customer: 'my_customer',
        maxResults: 50,
        orderBy: 'email',
    }, (err, res) => {
        if (err) return console.error('The API returned an error:', err.message);

        const users = res.data.users;
        if (users.length) {
            console.log('Users:');
            users.forEach((user) => {
                //credentials

                //changer signature
                if (user.primaryEmail && user.primaryEmail === MY_EMAIL) {
                    /*const client = new JWT(
                        {
                            email: keys.client_email,
                            key: keys.private_key,
                            subject: ADMIN_EMAIL,
                            scopes: SCOPES,
                        }
                    );*/
                    //client.subject = user.primaryEmail;
                    const gmail = google.gmail({version: 'v1', auth});
                    gmail.users.settings.delegates.list({userId:user.primaryEmail});
                    gmail.users.settings.sendAs.update({
                        userId: user.primaryEmail,
                        sendAsEmail: user.primaryEmail,
                        fields: 'signature',
                        resource: {
                            signature: SIGNATURE
                        }
                    });
                } else {
                    console.log('Error: Not found');
                }
            });
        } else {
            console.log('No users found.');
        }
    });
}

编辑:我发现了我的错误,就像 ziganotschka 说的,我需要创建一个新的 JWT 客户端。 这是新的函数 listUsers:

function listUsers(auth) {
const service = google.admin({version: 'directory_v1', auth});
service.users.list({
    customer: 'my_customer',
    maxResults: 50,
    orderBy: 'email',
}, (err, res) => {
    if (err) return console.error('The API returned an error:', err.message);

    const users = res.data.users;
    if (users.length) {
        console.log('Users:');
        users.forEach((user) => {
            //changer signature
            if (user.primaryEmail && (user.primaryEmail === MY_SIGNATURE)) {
                const client = new JWT(
                    {
                        email: keys.client_email,
                        key: keys.private_key,
                        subject: user.primaryEmail,
                        scopes: SCOPES,
                    }
                );
                client.subject = user.primaryEmail;
                const gmail = google.gmail({version: 'v1', auth: client});
                gmail.users.settings.delegates.list({userId:user.primaryEmail});
                gmail.users.settings.sendAs.update({
                    userId: user.primaryEmail,
                    sendAsEmail: user.primaryEmail,
                    fields: 'signature',
                    resource: {
                        signature: SIGNATURE
                    }
                });
            } else {
                console.log('Error: Not found');
            }
        });
    } else {
        console.log('No users found.');
    }
});

}

【问题讨论】:

    标签: node.js api gmail-api delegation google-admin-sdk


    【解决方案1】:

    要更改用户的签名,您必须冒充该用户

    • 正如您已经正确地做的那样,要创建/更新用户签名,您必须使用具有域范围委派的服务帐户
    • 但是,如果服务帐户冒充管理员,您将收到错误Delegation denied for ADMIN_EMAIL
    • 这是因为管理员无权更改他自己以外的任何签名
    • 因此,您需要在循环 (users.forEach((user)) 中为每个用户创建一个新的 JWT 客户端 - 相应的用户电子邮件为 subject -

    【讨论】:

    • 我错过了这一行:const gmail = google.gmail({version: 'v1', client}); 并且错误消息发生了变化,现在是(node:2736) UnhandledPromiseRejectionWarning: Error: Login Required.
    • 我不太明白您所说的漏掉一行是什么意思。您是否使用new google.auth.JWT 构建您的客户端,例如here?当您检索客户端时,您需要将用户电子邮件作为subject 的参数传递给它。因此,最好将客户端构建打包到一个单独的函数中,为users.forEach((user) 中的每个用户调用该函数。
    • 对不起,我的意思是在我之前的评论中我错过了修改这一行,但现在我发现问题不是问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 2020-09-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多