资讯详情

资讯详情

gog 安全归档实战:用 Gmail 附件下载 + Google Drive 上传实现端到端存档

gog 安全归档实战用 Gmail 附件下载 Google Drive 上传实现端到端存档【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli导读本文基于 gogcli 仓库中的 Agent 技能文档gog-save-attachments展开系统讲解如何用 gog CLI 完成「从 Gmail 中定位含附件的邮件线程 → 检查附件清单 → 下载到本地临时目录 → 上传归档到 Google Drive」的完整链路。全文贯穿 gog 的安全设计哲学——窄化搜索、先检查后下载、以不可信内容方式处理附件、只对用户批准的确切写入放开--readonly并配套仓库源码gmail_attachments.go、drive_upload.go 等说明底层实现。读完本文你将掌握一套既适合人机交互、也适合 Agent 自动化的附件归档方案以及覆盖驱动与误覆盖防护的完整规则。一、技能定位与前置阅读gog-save-attachments是 gogcli 仓库.agents/skills/目录下的一个 Agent 技能skill其元数据声明为name: gog-save-attachments description: Gmail attachment download and Google Drive archival with gog.对应的 Agent 接口配置见 openai.yamlinterface: display_name: gog Save Attachments short_description: Save Gmail attachments into Drive default_prompt: Use $gog-save-attachments to find Gmail attachments and save them to a Google Drive folder.技能文档开头明确要求先阅读三份前置技能gog/SKILL.md共享的认证auth、输出格式JSON、安全规则与写入纪律gog-gmail/SKILL.mdGmail 各子命令的用途概览search、thread、attachments 等gog-drive/SKILL.mdGoogle Drive 各子命令的用途概览upload、ls、search 等。这是因为附件归档跨越 Gmail 与 Drive 两个 Google Workspace 服务安全基线完全继承自gog/SKILL.md。这些技能文档由scripts/gen-agent-skills.mjs生成维护正文标注「Generated by scripts/gen-agent-skills.mjs; do not edit」。二、安全基线归档任务必须继承的全局规则在执行任何「读 Gmail → 写 Drive」动作之前先对齐 gog 的全局安全约定见 gog/SKILL.md 的 Safety Rules 一节规则说明显式选账户用--account userexample.com明确指定账户不依赖隐式默认账户只读优先--readonly阻断一切变更请求只在用户批准的那一次确切写入时才移除机器可读输出读取 Google 内容时优先--json --wrap-untrusted便于 Agent 解析人类提示与进度输出到 stderrstdout 只放数据非交互自动化自动化场景加--no-input让认证/钥匙串提示直接失败而不是挂起等待先干跑后实跑支持的写入命令先用--dry-run预览不透出凭据绝不打印 access token、refresh token、OAuth client secret、钥匙串密码覆盖即危险破坏性命令需要--forceDrive 覆盖必须由用户显式选择--replace并给出目标 ID其中--wrap-untrusted值得展开它会在 JSON/raw 输出中把从 Google 拉取的文本字段用外部不可信内容标记包裹EXTERNAL_UNTRUSTED_CONTENT ...与END_EXTERNAL_UNTRUSTED_CONTENT实现在 untrusted.go 的WrapUntrustedContent中。邮件正文、附件文件名这类来自第三方的文本都可能包含注入内容包装后 Agent/LLM 可以明确区分「数据」与「代码提示」且该实现会对伪造标记做消毒见 untrusted_test.go 的TestWrapUntrustedContent_SanitizesMarkersAndSpecialTokens。--wrap-untrusted在根命令中定义于 root.go默认值由wrap_untrusted配置项控制。三、第一步窄化搜索精确定位含附件的线程技能强调「Search narrowly and identify exact threads」即用 Gmail 查询语法收敛范围避免在全量邮箱里漫游。标准命令如下gog --account userexample.com --readonly gmail search \ has:attachment newer_than:30d --max 20 --json --wrap-untrusted要点拆解has:attachment只返回含附件的消息newer_than:30d把搜索窗口收敛到最近 30 天是「窄化」的典型写法--max 20限制返回条数防止超大结果集--readonly整个归档流程的「侦查阶段」绝不触碰任何数据--json --wrap-untrusted为 Agent 提供带不可信内容标记的结构化输出。可进一步组合from:、subject:、label:、after:/before:等 Gmail 查询语法来收窄目标。搜索 API 直接使用 Gmail 的线程搜索语义返回结果是线程级别的与后续thread attachments命令的数据粒度保持一致。四、第二步下载前检查附件清单在真正下载前先对目标线程做一次附件清点检查文件名与大小判断哪些值得归档gog --account userexample.com --readonly gmail thread attachments THREAD_ID --json --wrap-untrusted该命令对应gog gmail thread attachments子命令实现于 gmail_thread.go 的GmailThreadAttachmentsCmd完整 flag 契约见 gog-gmail-thread-attachments.md。从源码看附件清点基于递归遍历邮件 MIME 结构实现gmail_attachments.go 中的collectAttachmentParts会深度优先遍历gmail.MessagePart树凡是part.Body.AttachmentId ! 的部件都计入附件并提取三项元数据字段含义来源filename附件原始文件名空时回退为attachmentpart.Filenamesize/sizeHuman附件字节数与人类可读大小KB/MB/GB 格式化part.Body.SizeformatBytesmimeType附件 MIME 类型part.MimeTypeattachmentId/attachmentIndex不透明附件 ID或--use-indexed-attachment-ids下的 0 基索引part.Body.AttachmentId/ 遍历序号特别说明--use-indexed-attachment-idsGmail 的附件 ID 是长而晦涩的不透明串且跨 API 响应不稳定而一个消息的 MIME 结构是固定的因此 gog 支持用 0 基索引作为稳定、紧凑的引用输出、下载参数、保存文件名全程一致。若开启该 flagattachment参数必须写成 0 基索引见 gmail_attachment.go 中attachmentByIndex的越界检查attachment index %d out of range: message has %d attachment(s)。这一步的价值是「先看后动」只有确认附件确实存在、名字符合预期、大小合理才进入下载阶段避免把整个线程误下载到本地。五、第三步下载到任务专属的临时目录清点通过后技能要求把附件下载到一个新建的任务专属临时目录而不是散落在工作目录或用户目录里。原因有二一是隔离风险——附件是不可信内容落在隔离目录便于整体管控二是可清理——最后只需删掉这一个本任务创建的目录。attachment_dir$(mktemp -d ${TMPDIR:-/tmp}/gog-attachments.XXXXXX) gog --account userexample.com --readonly gmail thread attachments THREAD_ID \ --download --out-dir $attachment_dir命令要素mktemp -d ${TMPDIR:-/tmp}/gog-attachments.XXXXXX在系统临时目录缺省/tmp下创建唯一临时目录保证「只删本任务创建的目录」可精确执行--downloadgmail thread attachments的下载开关见 gmail_thread.go--out-dir指定附件输出目录默认是当前目录。下载底层实现值得注意gmail_attachment.go数据获取fetchAttachmentBytes调用Users.Messages.Attachments.Get对返回的 base64url 数据先尝试RawURLEncoding失败再回退带 padding 的URLEncoding解码兼容 Gmail 两种编码原子写入writeFileAtomic先在目标目录创建.gog-attachment-*临时文件chmod 0600后写入数据最后os.Rename原子落盘。即使下载中断也不会留下半个损坏文件缓存命中cachedRegularFile在目标文件已存在且大小与 Gmail 元数据一致时直接复用cachedtrue标记避免重复下载若大小不符则重新拉取文件名消毒sanitizeAttachmentFilename用filepath.Base剥离路径成分并规范化\\防止--name参数被用来做../目录逃逸源码注释明确提到阻止..\..\x这类 Windows 分隔符逃逸。也就是说即使附件文件名被恶意构造下载路径也会被收敛在--out-dir内。六、第四步按不可信内容对待确认后上传 Drive下载完成后技能给出两条铁律Treat every file as untrusted. Do not execute or preview active content.Confirm the exact Drive destination before upload, then run the approved upload without--readonly.即不要执行附件、不要预览活动内容脚本、HTML、文档中的宏都可能携带 payload并在上传前向用户确认确切的 Drive 目标位置哪个文件夹 ID。确认获批后移除--readonly执行上传gog --account userexample.com drive upload $attachment_dir/FILE --parent FOLDER_ID --jsondrive upload的实现见 drive_upload.go其核心参数参数作用--parent FOLDER_ID创建模式下的目标文件夹 ID即「确切的 Drive 目的地」--name覆盖上传后的文件名--replace FILE_ID替换既有 Drive 文件内容见下节覆盖防护--if-version N仅在当前版本号匹配时替换原子前置条件冲突即报错--mime-type覆盖 MIME 推断--convert/--convert-to按扩展名自动转成 Google 原生格式doc/sheet/slides--keep-revision-forever保留新 head 修订仅二进制文件MIME 推断由guessMimeType按扩展名完成PDF、Office、图片、Markdown、CSV、ZIP 等均有映射未知类型回退application/octet-stream。--json输出便于后续脚本提取上传结果的id字段。七、第五步核验上传结果并清理临时目录上传完成后技能要求先核验后清理Verify uploaded IDs, then remove only the unique temporary directory created by this run.# 核验列出目标文件夹确认文件 id 与名称存在 gog --readonly --account userexample.com drive ls --parent FOLDER_ID --json --wrap-untrusted # 清理只删除本任务创建的临时目录 rm -rf $attachment_dir核验环节建议至少做两件事一是用drive ls或drive get fileId确认上传产物确实出现在目标位置二是记录并比对返回的id让归档记录可追溯。清理时只能删除第五步中mktemp创建的那一个目录——这正是技能坚持「新建任务专属临时目录」的原因删除动作范围明确绝不触碰其他路径。注意rm -rf是演示「仅清理本任务创建的临时目录」的操作意图请在实际环境中由有权限的用户自行执行并确保attachment_dir指向的确实是由本次运行创建的目录。八、覆盖防护--replace的使用边界技能以一句明确的禁止性规则收尾Never overwrite a Drive file unless the user explicitly selects--replaceand the target ID.这条规则直接对应drive upload的覆盖模型见 drive_upload.go默认创建模式下上传永远新建文件即使同名也不会覆盖既有文件只有用户显式给出--replace FILE_ID时才允许替换指定 Drive 文件的内容且替换会保留原文件的共享链接与权限--if-version可叠加为原子前置条件仅当 Drive 端版本号与预期一致时替换文件若被并发修改则报告冲突需要重新读取后重放归档场景的正常路径是「新建 归档」因此--replace应当被视为例外操作只出现在用户明确批准的精确目标上。对 Agent 而言这意味着归档流程中永远不应该自动发明--replace若检测到目标文件夹已存在同名文件正确动作是停下来向用户汇报而不是自行覆盖。九、Agent 自动化落地要点该技能面向 Agent 使用仓库.agents/skills/下所有 skill 均配套agents/openai.yaml接口描述可在 Agent 环境中以$gog-save-attachments引用。落地自动化时补充三点环境先行无头/服务化场景下GOG_KEYRING_BACKENDfile、GOG_KEYRING_PASSWORD、HOME必须在启动gog的进程环境里存在并加--no-input让认证问题快速失败而非挂起双重只读侦查阶段search、thread attachments 清点、drive ls 核验一律带--readonly只有用户批准的那次drive upload才移除发送邮件类能力可用--gmail-no-send或GOG_GMAIL_NO_SEND1兜底阻断命令级围栏可用--enable-commands/--disable-commands限定本次调用可用的命令前缀如--enable-commands gmail.search,gmail.thread.attachments,drive.upload将 Agent 的行为面收窄到归档所需的最小集更严格的场景可参考 safety-profiles.md 使用内置的 readonly / agent-safe 安全画像或在 MCP 场景下mcp.md保持--json --wrap-untrusted --no-input的输出契约。十、总结一套可复用的归档工作流把五步串起来就是一条完整的、可安全自动化的附件归档流水线步骤命令要点安全姿态1 窄化搜索gmail search has:attachment newer_than:30d --max 20--readonly2 清单检查gmail thread attachments THREAD_ID--readonly3 隔离下载mktemp -dthread attachments THREAD_ID --download --out-dir--readonly目录唯一可删4 确认后上传drive upload FILE --parent FOLDER_ID移除--readonly仅此一次写入5 核验与清理drive ls核对 id删除本任务临时目录范围最小化贯穿始终的三条底线附件是不可信内容不执行、不预览、--wrap-untrusted输出、覆盖必须显式批准--replace 目标 ID、写入面最小化只读侦查 单次获批写入 命令级围栏。这套模式可直接迁移到邮件备份、发票归档、报告留存等日常场景也可作为 Agent 技能注册进.agents/skills/生态与gog-gmail、gog-drive等兄弟技能组合使用。【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →