如何让Wix上的Node.js应用自动访问Google Calendar?
Got it, let's fix that manual token headache once and for all. The key here is to use Google's OAuth 2.0 offline access flow, which gives you a long-lived refresh token that can automatically fetch new access tokens without any manual work. Since you're deploying on Wix, we'll tailor this to Velo (Wix's backend platform) to make it all work seamlessly.
Step 1: Set Up Google Cloud Project & OAuth Credentials
First, you need to properly configure your Google Cloud project to get the right credentials:
- Go to the Google Cloud Console, create a new project (or use an existing one), and enable the Google Calendar API under APIs & Services > Library.
- Head to APIs & Services > OAuth consent screen:
- If it's for internal use (only your Gmail account), select "Internal"; for external users, select "External" and complete the required fields (you'll need to add test users if it's not verified).
- Create an OAuth 2.0 Client ID under APIs & Services > Credentials:
- Application type: Choose "Web application".
- Add your Wix backend callback URI. It should look like
https://your-wix-site-domain.com/_functions/googleOAuthCallback(replaceyour-wix-site-domain.comwith your actual Wix site URL). - Save the client ID and client secret—you'll need these later.
Step 2: Implement OAuth Flow in Wix Backend
We'll create two backend functions: one to generate the authorization URL, and another to handle the callback and store tokens.
2.1 Generate Authorization URL (Frontend Trigger)
Add a button or link on your Wix site that triggers this backend function to get the auth URL, then redirect the user to it:
// Wix backend (google-oauth.jsw) import { fetch } from 'wix-fetch'; export function getAuthUrl() { const clientId = 'YOUR_GOOGLE_CLIENT_ID'; const redirectUri = 'https://your-wix-site-domain.com/_functions/googleOAuthCallback'; const scopes = [ 'https://www.googleapis.com/auth/calendar.events', 'offline_access' // Critical for getting a refresh token ].join(' '); return `https://accounts.google.com/o/oauth2/v2/auth?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${encodeURIComponent(scopes)}&access_type=offline&prompt=consent`; }
On your Wix frontend, add code to redirect the user when they click a button:
// Wix frontend page code import { getAuthUrl } from 'backend/google-oauth.jsw'; $w('#authButton').onClick(async () => { const authUrl = await getAuthUrl(); wixLocation.to(authUrl); });
2.2 Handle Callback & Store Tokens
Create the backend callback function that Google will redirect to after authorization:
// Wix backend (google-oauth.jsw) import { fetch } from 'wix-fetch'; import { secrets } from 'wix-secrets-backend'; export async function googleOAuthCallback(request) { const code = request.query.code; const clientId = 'YOUR_GOOGLE_CLIENT_ID'; const clientSecret = 'YOUR_GOOGLE_CLIENT_SECRET'; const redirectUri = 'https://your-wix-site-domain.com/_functions/googleOAuthCallback'; // Exchange authorization code for tokens const tokenResponse = await fetch('https://oauth2.googleapis.com/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `code=${code}&client_id=${clientId}&client_secret=${clientSecret}&redirect_uri=${encodeURIComponent(redirectUri)}&grant_type=authorization_code` }); const tokenData = await tokenResponse.json(); // Store refresh token and access token in Wix Secrets (secure storage) await secrets.set('googleRefreshToken', tokenData.refresh_token); await secrets.set('googleAccessToken', tokenData.access_token); await secrets.set('tokenExpiry', Date.now() + (tokenData.expires_in * 1000)); // Redirect user back to your site with a success message return { status: 302, headers: { Location: '/authorization-success' } }; }
Make sure to enable this function as an HTTP endpoint in Wix: go to your backend file, click the function name (googleOAuthCallback), toggle "Expose as API endpoint" on, and set the method to GET.
Step 3: Auto-Refresh Access Tokens
Now, create a function to check if the access token is expired, and refresh it using the stored refresh token if needed:
// Wix backend (google-oauth.jsw) import { fetch } from 'wix-fetch'; import { secrets } from 'wix-secrets-backend'; export async function getValidAccessToken() { const currentToken = await secrets.get('googleAccessToken'); const expiry = await secrets.get('tokenExpiry'); // Check if token is still valid if (Date.now() < expiry) { return currentToken; } // Refresh the token const refreshToken = await secrets.get('googleRefreshToken'); const clientId = 'YOUR_GOOGLE_CLIENT_ID'; const clientSecret = 'YOUR_GOOGLE_CLIENT_SECRET'; const refreshResponse = await fetch('https://oauth2.googleapis.com/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `refresh_token=${refreshToken}&client_id=${clientId}&client_secret=${clientSecret}&grant_type=refresh_token` }); const refreshData = await refreshResponse.json(); // Update stored tokens and expiry await secrets.set('googleAccessToken', refreshData.access_token); await secrets.set('tokenExpiry', Date.now() + (refreshData.expires_in * 1000)); return refreshData.access_token; }
Step 4: Send Calendar Invites Automatically
Modify your existing Node.js (Velo) code to use the valid access token when sending invites:
// Wix backend (calendar-invites.jsw) import { fetch } from 'wix-fetch'; import { getValidAccessToken } from 'backend/google-oauth.jsw'; export async function sendCalendarInvite(eventDetails) { const accessToken = await getValidAccessToken(); const event = { summary: eventDetails.title, location: eventDetails.location, description: eventDetails.description, start: { dateTime: eventDetails.startTime, timeZone: 'Your_Time_Zone' // e.g., 'America/New_York' }, end: { dateTime: eventDetails.endTime, timeZone: 'Your_Time_Zone' }, attendees: [{ email: eventDetails.attendeeEmail }], sendUpdates: 'all' // Send invites to attendees }; const response = await fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', { method: 'POST', headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify(event) }); return await response.json(); }
Key Notes for Wix Deployment
- Secure Storage: Always use Wix Secrets to store client secrets, refresh tokens, and access tokens—never hardcode them in your code.
- OAuth Consent: For external apps (users outside your Google Workspace), you'll need to submit your app for verification to Google to avoid "unverified app" warnings.
- Refresh Token Expiry: Google may revoke refresh tokens if they're unused for 6 months or if the user revokes access. Make sure your app handles token refresh failures gracefully (e.g., prompt the user to re-authorize if needed).
内容的提问来源于stack exchange,提问作者Dah

