ozellik: google oauth, gmail-drive araclari ve admin durum kartlarini ekle

This commit is contained in:
2026-03-22 18:50:06 +03:00
parent 177fd8e1a7
commit ad847b1cf4
20 changed files with 970 additions and 14 deletions

110
backend/app/tools/gmail.py Normal file
View File

@@ -0,0 +1,110 @@
import asyncio
from typing import Any
from googleapiclient.discovery import build
from app.google.auth import GoogleAuthError, GoogleAuthManager
from app.tools.base import Tool
class GmailTool(Tool):
name = "gmail"
description = "List and search Gmail messages for the connected Google account."
def __init__(self, auth_manager: GoogleAuthManager) -> None:
self.auth_manager = auth_manager
def parameters_schema(self) -> dict[str, Any]:
return {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Optional Gmail search query such as from:someone newer_than:7d.",
},
"max_results": {
"type": "integer",
"description": "Maximum number of messages to return, from 1 to 20.",
"minimum": 1,
"maximum": 20,
},
"label_ids": {
"type": "array",
"items": {"type": "string"},
"description": "Optional Gmail label filters. Defaults to INBOX.",
},
},
"additionalProperties": False,
}
async def run(self, payload: dict[str, Any]) -> dict[str, Any]:
query = str(payload.get("query", "")).strip()
max_results = max(1, min(20, int(payload.get("max_results", 10) or 10)))
label_ids = payload.get("label_ids")
if not isinstance(label_ids, list) or not label_ids:
label_ids = ["INBOX"]
try:
creds = await self.auth_manager.get_credentials()
except GoogleAuthError as exc:
return {"tool": self.name, "status": "error", "message": str(exc)}
return await asyncio.to_thread(
self._list_messages,
creds,
query,
max_results,
[str(label) for label in label_ids],
)
def _list_messages(
self,
credentials: Any,
query: str,
max_results: int,
label_ids: list[str],
) -> dict[str, Any]:
service = build("gmail", "v1", credentials=credentials, cache_discovery=False)
response = (
service.users()
.messages()
.list(userId="me", q=query or None, labelIds=label_ids, maxResults=max_results)
.execute()
)
message_refs = response.get("messages", [])
messages = []
for item in message_refs:
detail = (
service.users()
.messages()
.get(
userId="me",
id=item["id"],
format="metadata",
metadataHeaders=["From", "Subject", "Date"],
)
.execute()
)
headers = {
header.get("name", "").lower(): header.get("value", "")
for header in detail.get("payload", {}).get("headers", [])
}
messages.append(
{
"id": detail.get("id", ""),
"thread_id": detail.get("threadId", ""),
"from": headers.get("from", ""),
"subject": headers.get("subject", "(no subject)"),
"date": headers.get("date", ""),
"snippet": detail.get("snippet", ""),
"label_ids": detail.get("labelIds", []),
}
)
return {
"tool": self.name,
"status": "ok",
"query": query,
"count": len(messages),
"messages": messages,
}