NodeJS 中的 API Gmail:(节点:14592)UnhandledPromiseRejectionWarning:错误:委派被拒绝

Posted

技术标签:

【中文标题】NodeJS 中的 API Gmail:(节点:14592)UnhandledPromiseRejectionWarning:错误:委派被拒绝【英文标题】:API Gmail in NodeJS: (node:14592) UnhandledPromiseRejectionWarning: Error: Delegation denied 【发布时间】: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.');
    
);

【问题讨论】:

【参考方案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) 中的每个用户调用该函数。 对不起,我的意思是在我之前的评论中我错过了修改这一行,但现在我发现问题不是问题。

以上是关于NodeJS 中的 API Gmail:(节点:14592)UnhandledPromiseRejectionWarning:错误:委派被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

Gmail NodeJs客户端中的Gmail API userId用例?

用于在节点 js javascript 文件中发送用户消息的 gmail API

NodeJS:无法使用服务帐户访问 Gmail API

GMAIL API NodeJs

如何在 Nodejs 中使用 gmail api 在同一对话中回复电子邮件

尝试实现 NodeJS Gmail API 示例