使用 NextJS 对 Gmail API 进行故障排除:消息对象为空,无法获取电子邮件列表和正文

问题描述 投票:0回答:1

我正在使用 NextJS 来处理 Gmail API。按照 Google 的文档,我实现了下面的代码,并于昨天成功检索了特定帐户的电子邮件列表及其正文。但是,当我今天运行相同的代码时,消息对象为空,并且我无法获取电子邮件和正文列表。昨天和今天之间代码没有变化,控制台中也没有显示任何错误。我可以采取什么步骤来解决这个问题?

'use client'
import { useEffect, useState } from 'react';

const CLIENT_ID = process.env.NEXT_PUBLIC_CLIENT_ID;
const API_KEY = process.env.NEXT_PUBLIC_API_KEY;
const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest';
const SCOPES = 'https://www.googleapis.com/auth/gmail.readonly';

export default function Home() {
    const [tokenClient, setTokenClient] = useState(null);
    const [labels, setLabels] = useState([]);
    const [messages, setMessages] = useState([]);

    useEffect(() => {
        const scriptGapi = document.createElement('script');
        scriptGapi.src = 'https://apis.google.com/js/api.js';
        scriptGapi.async = true;
        scriptGapi.defer = true;
        scriptGapi.onload = gapiLoaded;
        document.body.appendChild(scriptGapi);

        const scriptGis = document.createElement('script');
        scriptGis.src = 'https://accounts.google.com/gsi/client';
        scriptGis.async = true;
        scriptGis.defer = true;
        scriptGis.onload = gisLoaded;
        document.body.appendChild(scriptGis);

        return () => {
            document.body.removeChild(scriptGapi);
            document.body.removeChild(scriptGis);
        };
    }, []);

    const gapiLoaded = () => {
        window.gapi.load('client', initializeGapiClient);
    };

    const initializeGapiClient = async () => {
        await window.gapi.client.init({
            apiKey: API_KEY,
            discoveryDocs: [DISCOVERY_DOC],
        });
    };

    const gisLoaded = () => {
        const tokenClient = window.google.accounts.oauth2.initTokenClient({
            client_id: CLIENT_ID,
            scope: SCOPES,
            callback: '',
        });
        setTokenClient(tokenClient);
    };

    const listMessages = async () => {
        try {
            let nextPageToken = null;
            let allMessages = [];

            do {
                const response = await window.gapi.client.gmail.users.messages.list({
                    'userId': 'me',
                    'labelIds': ['INBOX'],
                    'pageToken': nextPageToken,
                });

                const messages = response.result.messages || [];
                allMessages = [...allMessages, ...messages];

                nextPageToken = response.result.nextPageToken;
            } while (nextPageToken);

            if (allMessages.length === 0) {
                document.getElementById('content').innerText = 'No messages found.';
            } else {
                const detailedMessages = await Promise.all(
                    allMessages.map(async (message) => {
                        const detailedResponse = await window.gapi.client.gmail.users.messages.get({
                            'userId': 'me',
                            'id': message.id,
                        });

                        return detailedResponse.result;
                    })
                );
                setMessages(detailedMessages);
            }
        } catch (err) {
            document.getElementById('content').innerText = err.message;
        }
    };

    const handleAuthClick = async () => {
        if (tokenClient) {
            tokenClient.callback = async (resp) => {
                if (resp.error !== undefined) {
                    throw resp;
                }
                document.getElementById('signout_button').style.visibility = 'visible';
                document.getElementById('authorize_button').innerText = 'Refresh';
                await listLabels();
                await listMessages();
            };

            if (window.gapi.client.getToken() === null) {
                tokenClient.requestAccessToken({ prompt: 'consent' });
            } else {
                tokenClient.requestAccessToken({ prompt: '' });
            }
        }
    };

    const handleSignoutClick = () => {
        const token = window.gapi.client.getToken();
        if (token !== null) {
            google.accounts.oauth2.revoke(token.access_token);
            window.gapi.client.setToken('');
            setLabels([]);
            document.getElementById('content').innerText = '';
            document.getElementById('authorize_button').innerText = 'Authorize';
            document.getElementById('signout_button').style.visibility = 'hidden';

            window.location.reload();
        }
    };

    const listLabels = async () => {
        try {
            const response = await window.gapi.client.gmail.users.labels.list({
                'userId': 'me',
            });
            const labels = response.result.labels || [];
            setLabels(labels);
            if (labels.length === 0) {
                document.getElementById('content').innerText = 'No labels found.';
            }
        } catch (err) {
            document.getElementById('content').innerText = err.message;
        }
    };

    function removeHTMLTags(str) {
        return str.replace(/<[^>]*>/g, '');
    }

    function getFullMessageBody(message) {
        if (message.payload) {
            if (message.payload.parts) {
                const bodyParts = message.payload.parts.filter(part => part.mimeType === 'text/plain');
                if (bodyParts.length > 0) {
                    const fullBody = bodyParts.reduce((body, part) => {
                        if (part.body && part.body.data) {
                            const modifiedData = part.body.data.replace(/-/g, '+').replace(/_/g, '/');
                            return body + decodeURIComponent(escape(atob(modifiedData)));
                        }
                        return body;
                    }, '');
                    return removeHTMLTags(fullBody) || 'N/A';
                }
            } else if (message.payload.body && message.payload.body.data) {
                const modifiedData = message.payload.body.data.replace(/-/g, '+').replace(/_/g, '/');
                return removeHTMLTags(decodeURIComponent(escape(atob(modifiedData)))) || 'N/A';
            }
        }

        return 'N/A';
    }

    console.log('messages', messages)

    return (
        <div>
            <p>Gmail API Quickstart</p>
            <button id="authorize_button" onClick={handleAuthClick}>
                Authorize
            </button>
            <button id="signout_button" onClick={handleSignoutClick}>
                Sign Out
            </button>
            <div id="content">
                {messages.map((message) => (
                    <div key={message.id}>
                        <div>--------------------------------------------</div>
                        <div>From: {message.payload.headers.find(h => h.name === 'From').value}</div>
                        <div>Subject: {message.payload.headers.find(h => h.name === 'Subject').value}</div>
                        <div>Date: {message.payload.headers.find(h => h.name === 'Date').value}</div>
                        <div>Body: {getFullMessageBody(message)}</div>
                        <div>--------------------------------------------</div>
                    </div>
                ))}
            </div>
        </div>
    );
}

我不知道如何解决这个问题。

reactjs next.js gmail
1个回答
0
投票

您解决了这个问题吗?您能告诉我您是如何解决这个错误的吗? 如果您分享解决方案将会很有帮助

© www.soinside.com 2019 - 2024. All rights reserved.