mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
Refactor Gmail metadata synchronization logic
- Updated the `syncGmailMetadataToBackend` function to accept a new `GmailStateForSync` interface, enhancing type safety and clarity. - Introduced a new `GmailEmailSummaryLike` interface to represent email summaries in the synchronization process. - Adjusted the handling of Gmail profile data to ensure proper extraction and emission of metadata to the backend. - Updated the `SkillProvider` to dispatch Gmail emails to the Redux store and synchronize the Gmail state effectively.
This commit is contained in:
@@ -6,34 +6,51 @@
|
||||
import { emitViaRustSocket } from '../../../utils/tauriSocket';
|
||||
|
||||
const INTEGRATION_METADATA_SYNC_EVENT = 'integration:metadata-sync';
|
||||
const PROVIDER_GOOGLE = 'gmail';
|
||||
const PROVIDER_GOOGLE = 'google';
|
||||
|
||||
/** Gmail profile shape from skill state (snake_case). */
|
||||
export interface GmailProfileLike {
|
||||
interface GmailProfileLike {
|
||||
email_address: string;
|
||||
messages_total: number;
|
||||
threads_total: number;
|
||||
history_id: string;
|
||||
}
|
||||
|
||||
/** Single email summary from skill state. */
|
||||
interface GmailEmailSummaryLike {
|
||||
id: string;
|
||||
threadId: string;
|
||||
snippet?: string;
|
||||
subject?: string;
|
||||
from?: string;
|
||||
date?: string;
|
||||
}
|
||||
|
||||
/** Gmail skill state slice we care about for metadata sync. */
|
||||
export interface GmailStateForSync {
|
||||
profile?: GmailProfileLike | null;
|
||||
emails?: GmailEmailSummaryLike[] | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit `integration:metadata-sync` with Gmail profile and emails so the
|
||||
* backend can merge them into the user's Google OAuth integration.
|
||||
* No-op when profile is missing or not in Tauri.
|
||||
*/
|
||||
export function syncGmailMetadataToBackend(gmailState: GmailProfileLike | undefined): void {
|
||||
if (!gmailState) return;
|
||||
export function syncGmailMetadataToBackend(gmailState: GmailStateForSync | undefined): void {
|
||||
if (!gmailState?.profile || typeof gmailState.profile !== 'object') return;
|
||||
|
||||
const profile = gmailState.profile as GmailProfileLike;
|
||||
const metadata: Record<string, unknown> = {
|
||||
email_address: gmailState.email_address,
|
||||
messages_total: gmailState.messages_total,
|
||||
threads_total: gmailState.threads_total,
|
||||
history_id: gmailState.history_id,
|
||||
email_address: profile.email_address,
|
||||
messages_total: profile.messages_total,
|
||||
threads_total: profile.threads_total,
|
||||
history_id: profile.history_id,
|
||||
};
|
||||
|
||||
// if (Array.isArray(gmailState.emails) && gmailState.emails.length > 0) {
|
||||
// metadata.emails = gmailState.emails as GmailEmailSummaryLike[];
|
||||
// }
|
||||
if (Array.isArray(gmailState.emails) && gmailState.emails.length > 0) {
|
||||
metadata.emails = gmailState.emails as GmailEmailSummaryLike[];
|
||||
}
|
||||
|
||||
const payload = { requestId: crypto.randomUUID(), provider: PROVIDER_GOOGLE, metadata };
|
||||
|
||||
|
||||
@@ -9,16 +9,21 @@ import { listen } from '@tauri-apps/api/event';
|
||||
import { type ReactNode, useEffect, useRef } from 'react';
|
||||
|
||||
import {
|
||||
type GmailProfileLike,
|
||||
type GmailStateForSync,
|
||||
syncGmailMetadataToBackend,
|
||||
} from '../lib/gmail/services/metadataSync';
|
||||
import { syncNotionMetadataToBackend } from '../lib/notion/services/metadataSync';
|
||||
import { skillManager } from '../lib/skills/manager';
|
||||
import type { SkillManifest } from '../lib/skills/types';
|
||||
import { buildManualSentryEvent, enqueueError } from '../services/errorReportQueue';
|
||||
import { type GmailProfile, setGmailProfile } from '../store/gmailSlice';
|
||||
import { setNotionProfile, type NotionUserProfile } from '../store/notionSlice';
|
||||
import {
|
||||
GmailEmailSummary,
|
||||
type GmailProfile,
|
||||
setGmailEmails,
|
||||
setGmailProfile,
|
||||
} from '../store/gmailSlice';
|
||||
import { useAppDispatch, useAppSelector } from '../store/hooks';
|
||||
import { type NotionUserProfile, setNotionProfile } from '../store/notionSlice';
|
||||
import { setSkillError, setSkillState, setSkillStatus } from '../store/skillsSlice';
|
||||
import { DEV_AUTO_LOAD_SKILL, IS_DEV } from '../utils/config';
|
||||
|
||||
@@ -85,12 +90,16 @@ function syncGmailStateToSlice(
|
||||
: null
|
||||
)
|
||||
);
|
||||
syncGmailMetadataToBackend(gmailState.profile as GmailProfileLike);
|
||||
dispatch(
|
||||
setGmailEmails(
|
||||
Array.isArray(gmailState.emails) ? (gmailState.emails as GmailEmailSummary[]) : []
|
||||
)
|
||||
);
|
||||
|
||||
syncGmailMetadataToBackend(gmailState as GmailStateForSync);
|
||||
}
|
||||
|
||||
async function syncNotionUserOnConnect(
|
||||
dispatch: ReturnType<typeof useAppDispatch>
|
||||
): Promise<void> {
|
||||
async function syncNotionUserOnConnect(dispatch: ReturnType<typeof useAppDispatch>): Promise<void> {
|
||||
try {
|
||||
const toolResult = await skillManager.callTool('notion', 'get-user', { user_id: 'me' });
|
||||
if (!toolResult || toolResult.isError || toolResult.content.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user