最新资讯
stackoverflow.blog 欢迎来到芯片时代:半导体制造、AI 数据中心与芯片设计的未来 www.youtube.com AI Agent 总犯同样的错:CentralAgent AI 将记忆重构为经验系统 pub.towardsai.net Netflix 科学家建议重采样 LLM 评判:5 次仅将误差棒缩小 13% pub.towardsai.net Jev 作为 LLM 前的静默层:构建提示感知的模型路由器 reddit.com OpenAI 称 Astra 仅满足 10% 安全任务标准 dev.to FreeToken:在自有 GPU 上运行前沿 MoE 模型及其内存需求 dev.to 当 AI Agent 说“完成”时,究竟完成了什么? dev.to 部署 Underdog Bark 3.0 Pro:逐字转写、自定义后端与分块设置 dev.to 为艰难对话构建 AI:五个 Agent、一条安全正则与一位盲评监督者 techcrunch.com Palo Alto Networks 洽谈以 5 亿美元收购 AI Agent 安全初创公司 Clutch theinformation.com 黄仁勋被要求就涉华间谍指控向国会作简报 www.infoq.com Edera 推出 Object Capability Bounded Authority,试图将凭证与 AI Agent 工作负载隔离
多元动态
登录 注册
智能体 dev.to · @Feedsmith

无需 OAuth,用 service account 定时把 JSON/CSV 写入 Google Sheets

原文 我的收藏

文章讨论无人值守定时向 Google Sheets 写入数据的痛点:OAuth 需要人工点击登录,cron、webhook 或 AI agent 无法完成,refresh token 可能被撤销或过期(测试模式应用为 7 天);简单追加会导致列错位和重复,Sheets API 不提供按行 upsert;此外还有 10 百万单元格上限、每分钟写入限流和请求体大小限制。作者给出 service account 方案,并介绍其封装的托管 Actor。

AI推荐理由 面向开发者的实操教程,指出定时写入 Google Sheets 时 OAuth 需人工介入、refresh token 会过期、追加写入易错位和重复、以及 10 百万单元格与写入限流等具体限制,并给出 service account 方案。属于经验性技术分享,非官方文档,且正文被截断,未展示完整实现与验证结果。

62

正文

Getting data into a Google Sheet is easy once. Doing it every hour, unattended, is where it breaks: OAuth needs a human. "Sign in with Google" works when you click it in a browser. A cron job, a webhook or an AI agent can't click, and refresh tokens get revoked or expire (7 days for apps in "testing" mode). Appending is not "write below the last row". The next batch has a new field, or fields in a different order, and your columns silently shift. Re-running creates duplicates. Daily price or stock checks need update this row if it exists, otherwise add it - which the Sheets API does not do for you. Limits show up late. A spreadsheet holds at most 10 million cells, write requests are rate limited per minute, and a request body can't be arbitrarily big. This post shows the service-account route, then a hosted Actor I built that wraps the annoying parts. Step 1: a service account (5 minutes, once) A service account is a robot Google identity in your own Google Cloud project. It signs its own tokens, so there is no consent screen and nothing to refresh by hand. console.cloud.google.com -> project dropdown -> New Project. APIs & Services -> Library -> "Google Sheets API" -> Enable. APIs & Services -> Credentials -> Create Credentials -> Service account (no roles needed). Open it -> Keys -> Add Key -> Create new key -> JSON. Keep that file private. In your Google Sheet: Share -> paste the client_email from the JSON -> Editor. The account can only touch sheets you explicitly share with it. Delete the key in the console and access stops immediately. Step 2: send rows The Actor is feedsmith/google-sheets-sync. From Python, with an Apify API token: import json, os, requests rows = [ {"sku": "A-100", "name": "Desk lamp", "price": {"usd": 24.9}, "tags": ["home", "light"]}, {"sku": "A-101", "name": "Monitor arm", "price": {"usd": 59.0}, "tags": ["office"]}, ] run = requests.post( "https://api.apify.com/v2/acts/feedsmith~google-sheets-sync/run-sync-get-dataset-items", params={"token": os.environ["APIFY_TOKEN"]}, json={ "serviceAccountKey": open("service-account.json").read(), "spreadsheet": "https://docs.google.com/spreadsheets/d//edit", "sheetName": "Prices", "mode": "upsert", "keyColumns": ["sku"], "rawData": rows, }, timeout=300, ) print(json.dumps(run.json(), indent=2)) Enter fullscreen mode Exit fullscreen mode The response is one summary item (real run, 8.6 s): [{"mode": "upsert", "spreadsheetId": "12EqRkXF...", "sheetName": "Prices", "rowsAppended": 2, "rowsUpdated": 0, "rowsSkippedDuplicate": 0, "newColumns": ["sku", "name", "price.usd", "tags"], "totalCellsAfter": 52104, "warnings": []}] Enter fullscreen mode Exit fullscreen mode Next day, send {"sku": "A-100", "price": {"usd": 19.9}} plus a new SKU A-102 with the same call. The summary says "rowsAppended": 1, "rowsUpdated": 1 and the tab reads: sku name price.usd tags A-100 Desk lamp 19.9 home, light A-101 Monitor arm 59 office A-102 Cable tray 12.5 A-100 kept its name and tags; only the price changed. What happened there: price.usd became its own column (nested objects are flattened to a.b.c), tags became home, light. upsert matched on sku: existing rows were updated in place, new SKUs were appended. Run it again tomorrow with new prices and you still have one row per SKU. The tab Prices didn't exist, so it was created. Other modes: append (never clears anything; unknown keys become new columns on the right, existing column order is kept), replace (clears the tab and rewrites it, after saving the old values as a JSON backup) and read (the tab comes back as JSON rows keyed by the header). Chain it after any scraper In Apify Console, open the scraper -> Integrations -> Connect Actor -> pick Google Sheets Import & Export and set datasetId to {{resource.defaultDatasetId}}. Every time the scraper finishes, its results land in the sheet. No code. Or let an AI agent do it Through the Apify MCP server an agent can call the Actor with rawData directly. Because the key does not need a browser login, it works the same from Claude, Cursor or any MCP client as it does from cron. Details that bite otherwise Formula injection. Scraped text like =IMPORTXML(...) or +1-... becomes a live formula if you write with USER_ENTERED. The default is RAW; with USER_ENTERED such values are escaped unless you set allowFormulas. In a real run with USER_ENTERED, =1+1 landed as the text =1+1 (not 2), +84 912 stayed a string, and 2026-09-27 became a real date. Cell limit. The Actor sums every tab's grid before writing and refuses with "about N rows fit" instead of failing halfway. Rate limits. Writes are chunked and paced; 429/5xx are retried with backoff. 20,000 rows x 6 columns went into a new tab in 24 s using 50 MB of memory. Errors you can act on. A sheet that wasn't shared fails with "Share the spreadsheet with sheets-sync@...iam.gserviceaccount.com as Editor (Share button in Google Sheets), then run again."; a disabled API says which project to enable it in. Cost $0.002 per successful run plus $0.005 per started 1,000 rows. A failed or dry run is not charged. A daily sync of 500 rows is about $0.21 a month; an hourly one about $5. Links Actor: https://apify.com/feedsmith/google-sheets-sync Google's service account docs: https://cloud.google.com/iam/docs/service-account-overview Not affiliated with Google. Disclosure: I built this Actor. This article was drafted with AI assistance (Claude); every output shown comes from a real run on 2026-09-27.

来源报道 · 1 篇 · 以下链接均前往原始媒体

← 返回精选动态 原文

更多内容