{"id":22218235,"url":"https://github.com/gcloudlab/aging","last_synced_at":"2026-04-10T15:52:48.514Z","repository":{"id":154130781,"uuid":"631597900","full_name":"gcloudlab/aging","owner":"gcloudlab","description":"用一张照片生成你从年幼到年老的3秒GIF，基于 Replicate，集成邮箱/Github登录授权，部署在 Vercel。","archived":false,"fork":false,"pushed_at":"2023-04-27T01:39:51.000Z","size":1119,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-30T06:29:32.022Z","etag":null,"topics":["ai","mongodb-atlas","next-auth","nextjs","react","replicate","tailwindcss","typescript","upstash","vercel"],"latest_commit_sha":null,"homepage":"https://ai.aging.run","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gcloudlab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-23T14:28:48.000Z","updated_at":"2024-03-25T11:07:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"52a81cb7-94af-447a-b972-1d9c8b1b53f9","html_url":"https://github.com/gcloudlab/aging","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcloudlab%2Faging","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcloudlab%2Faging/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcloudlab%2Faging/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcloudlab%2Faging/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gcloudlab","download_url":"https://codeload.github.com/gcloudlab/aging/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245414551,"owners_count":20611367,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","mongodb-atlas","next-auth","nextjs","react","replicate","tailwindcss","typescript","upstash","vercel"],"created_at":"2024-12-02T22:19:42.698Z","updated_at":"2025-12-30T23:25:48.477Z","avatar_url":"https://github.com/gcloudlab.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eAging\u003c/h1\u003e\n\n## 特性与功能\n\n- 用一张照片生成你从年幼到年老的3秒GIF动图\n- 使用 Workers 从 Cloudflare R2 存储和检索照片\n- 通过 Upstash 缓存24小时后自动删除照片\n- NextAuth 授权，MongoDB 存储用户信息\n\n## 环境变量\n\n\u003e 将文件 `.env.example` 重命名为 `.env`\n\n\n| 变量                            | 描述             | 示例                                   |\n| ------------------------------- | ---------------- | -------------------------------------- |\n| `REPLICATE_API_TOKEN`           | replicate        | `fdsgsfasfadadasfasgdfhb`              |\n| `UPSTASH_REDIS_REST_URL`        |                  | `https://apn1-xxx-xxx                  |\n| .upstash.io`                    |\n| `UPSTASH_REDIS_REST_TOKEN`      |                  | `xxxxxx=`                              |\n| `QSTASH_TOKEN`                  |                  | `xxxxxx=`                              |\n| `QSTASH_CURRENT_SIGNING_KEY`    |                  | `sig_xxxxx`                            |\n| `QSTASH_NEXT_SIGNING_KEY`       |                  | `sig_xxxxx`                            |\n| `NEXT_PUBLIC_CLOUDFLARE_WORKER` |                  | `https://project.username.workers.dev` |\n| `CLOUDFLARE_WORKER_SECRET`      | 随机 token       | `sfhggdjhkghkgdk`                      |\n| `GITHUB_CLIENT_ID`              | OAuth App ID     | `dgvsfdahdfajdfag`                     |\n| `GITHUB_CLIENT_SECRET`          | OAuth App SECRET | `fsdagfadshfdahgfasgsadg`              |\n| `NEXTAUTH_SECRET`               | 随机 token       | `safadsgdsagfdgfdsgdf`                 |\n| `MONGODB_URI`                   | uri              | `mongodb+srv://...`                    |\n\n\n## 部署到 Vercel\n\n### 点击按钮一键部署\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-title=Aging%20%E2%80%93%C2%A0See%20how%20well%20you%20age%20with%20AI\u0026demo-description=Age%20transformation%20AI%20app%20powered%20by%20Next.js%2C%20Replicate%2C%20Upstash%2C%20and%20Cloudflare%20R2%20%2B%20Workers.\u0026demo-url=https%3A%2F%2Fai.aging.run%2F\u0026project-name=Aging%20%E2%80%93%C2%A0See%20how%20well%20you%20age%20with%20AI\u0026repository-name=Aging\u0026repository-url=https%3A%2F%2Fgithub.com%2Fgcloudlab%2Faging\u0026from=templates\u0026env=REPLICATE_API_TOKEN%2CREPLICATE_WEBHOOK_TOKEN%2CCLOUDFLARE_WORKER_SECRET%2CPOSTMARK_TOKEN\u0026envDescription=How%20to%20get%20these%20env%20variables%3A%20\u0026envLink=https%3A%2F%2Fgithub.com%2Fgcloudlab%2Faging%2Fblob%2Fmaster%2F.env.example)\n\n### 然后填写环境变量\n\n- 注册 [ReplicateHQ](https://replicate.com/) 帐户以获取 `REPLICATE_API_TOKEN` 环境变量。\n- 注册 [Upstash](https://upstash.com/) 帐户以获取 `Upstash Redis` 和 `QStash` 环境变量。\n- 创建一个 [Cloudflare R2 实例](https://www.cloudflare.com/lp/pg-r2/) 和 [Cloudflare Worker](https://workers.cloudflare.com/) 来处理图片上传和读取（下方有详细介绍）。\n\nCloudflare R2 设置说明\n\n- 在 Cloudflare 创建一个 [R2存储桶](https://www.cloudflare.com/lp/pg-r2/)(R2 bucket)。\n- 使用下面的代码创建一个 [Cloudflare Worker](https://workers.cloudflare.com/)。\n- 在 `Settings \u003e R2 Bucket Bindings` 将您的工作程序绑定到您的R2实例。\n- 为保证安全性，请在 `Settings \u003e Environment Variables` 下设置 `AUTH_KEY_SECRET` 变量（您可以在[此处](https://generate-secret.vercel.app/32)生成随机token）。\n- 用你自己的 Cloudflare Worker 端点替换项目中的 `older.yesmore.workers.dev` 代码片段。\n\nCloudflare Worker Code: \n\n```js\n// Check requests for a pre-shared secret\nconst hasValidHeader = (request, env) =\u003e {\n  return request.headers.get(\"X-CF-Secret\") === env.AUTH_KEY_SECRET;\n};\n\nfunction authorizeRequest(request, env, key) {\n  switch (request.method) {\n    case \"PUT\":\n    case \"DELETE\":\n      return hasValidHeader(request, env);\n    case \"GET\":\n      return true;\n    default:\n      return false;\n  }\n}\n\nexport default {\n  async fetch(request, env) {\n    const url = new URL(request.url);\n    const key = url.pathname.slice(1);\n\n    if (!authorizeRequest(request, env, key)) {\n      return new Response(\"Forbidden\", { status: 403 });\n    }\n\n    switch (request.method) {\n      case \"PUT\":\n        await env.MY_BUCKET.put(key, request.body);\n        return new Response(`Put ${key} successfully!`);\n      case \"GET\":\n        const object = await env.MY_BUCKET.get(key);\n\n        if (object === null) {\n          return new Response(\"Object Not Found\", { status: 404 });\n        }\n\n        const headers = new Headers();\n        object.writeHttpMetadata(headers);\n        headers.set(\"etag\", object.httpEtag);\n\n        return new Response(object.body, {\n          headers,\n        });\n      case \"DELETE\":\n        await env.MY_BUCKET.delete(key);\n        return new Response(\"Deleted!\");\n\n      default:\n        return new Response(\"Method Not Allowed\", {\n          status: 405,\n          headers: {\n            Allow: \"PUT, GET, DELETE\",\n          },\n        });\n    }\n  },\n};\n\n```\n\nthen have fun~\n## License\n\n[GPN](./LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgcloudlab%2Faging","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgcloudlab%2Faging","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgcloudlab%2Faging/lists"}