<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh_CN">
  <title>Polo</title>
  <subtitle>记录与分享</subtitle>
  <link href="https://blog.drtob.com/" rel="alternate" type="text/html"/>
  <link href="https://blog.drtob.com/atom.xml" rel="self" type="application/atom+xml"/>
  <id>https://blog.drtob.com/</id>
  <updated>2026-04-15T00:00:00.000Z</updated>
  <entry>
    <title>Claude Code+Cliproxy+CC Switch/ChatGpt无限使用</title>
    <link href="https://blog.drtob.com/posts/cc--cliproxy-ccs/" rel="alternate" type="text/html"/>
    <id>https://blog.drtob.com/posts/cc--cliproxy-ccs/</id>
    <published>2026-04-15T00:00:00.000Z</published>
    <updated>2026-04-15T00:00:00.000Z</updated>
    <summary>Cliproxy反代出api，通过CC Switch配置给Claude Code，形成Claude Code+ChatGpt的无限使用</summary>
    <content type="html"><![CDATA[<blockquote>
<p>⚠️ <strong>声明</strong>：本文仅供学习交流使用，请遵守各服务提供商的服务条款。</p>
</blockquote>
<h2>目录</h2>
<ul>
<li><a href="#%E5%89%8D%E8%A8%80">前言</a></li>
<li><a href="#cliproxy-%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE">Cliproxy 安装配置</a></li>
<li><a href="#cc-switch-%E5%AE%89%E8%A3%85">CC Switch 安装</a></li>
<li><a href="#%E6%8E%A5%E5%85%A5Claude-Code">接入Claude Code</a></li>
</ul>
<hr />
<h2>前言</h2>
<p>Claude Code 是 Anthropic 官方提供的 AI 编程助手，功能强大，但免费版本有使用限制。而 ChatGPT 的 Codex 模型（在 OpenAI API 中）同样具备强大的代码能力，且有免费额度可以使用。</p>
<p>本文将教你如何在 <strong>Windows 10</strong> 系统上部署 <strong>Cliproxy</strong> 和 <strong>CC Switch</strong>，通过反代的方式将 Codex API 配置给 Claude Code 使用。</p>
<hr />
<h2>Cliproxy 安装配置</h2>
<p>Cliproxy 是一个开源的 API 反向代理工具，支持将请求转发到 OpenAI API 兼容的后端。</p>
<h3>下载解压</h3>
<ul>
<li>从 <a href="https://github.com/router-for-me/CLIProxyAPI/releases">CLIProxyAPI Releases</a> 下载可执行文件，我这里是用win10演示，就下载windows版本。</li>
</ul>
<p><img src="./cli-download.webp" alt="配图" /></p>
<ul>
<li>解压下载的压缩包</li>
</ul>
<h3>编辑配置</h3>
<ul>
<li>在解压目录下新建 <code>auths</code> 文件夹，将 <code>config.example.yaml</code> 重命名为 <code>config.yaml</code></li>
</ul>
<p><img src="./edit-show.webp" alt="配图" /></p>
<ul>
<li>用文本编辑器打开 <code>config.yaml</code> ，仅需保留并修改以下基础配置项：</li>
</ul>
<pre><code>port: 8317

# 文件夹位置按你的实际情况填写
auth-dir: "F:\\CLIProxyAPI\\auths"

# 用关于登录WebUI的密码
secret-key: "admin@1234"

request-retry: 3

quota-exceeded:
  switch-project: true
  switch-preview-model: true

api-keys:
# Key请自行设置，用于客户端访问代理
- "ABC-123456"
</code></pre>
<ul>
<li>有兴趣折腾的话，具体配置和教程可参考<a href="https://help.router-for.me/cn/hands-on/tutorial-0.html">官方文档</a></li>
</ul>
<h4>登录WebUI</h4>
<ul>
<li>双击exe执行程序启动</li>
<li>浏览器网站输入<br />
<a href="http://localhost:8317/management.html#/login">http://localhost:8317/management.html#/login</a><br />
或<br />
<a href="http://127.0.0.1:8317/management.html#/login">http://127.0.0.1:8317/management.html#/login</a></li>
<li>管理密钥输入前面配置文件填写的 <code>secret-key</code>,比如<code>admin@1234</code>,进行登录</li>
</ul>
<p><img src="./login.webp" alt="配图" /></p>
<h3>代理配置</h3>
<ul>
<li>本地部署cliproxy，因为后面要用到codex auth认证，需要先修改代理配置，将<code>代理URL</code>修改为本地魔法的端口地址</li>
</ul>
<p><img src="./proxy.webp" alt="配图" /></p>
<h3>OAuth认证</h3>
<ul>
<li>打开链接进行Codex OAuth登陆认证，按正常登陆Chatgpt的账号操作即可</li>
</ul>
<p><img src="./codex-login.webp" alt="配图" /></p>
<ul>
<li>认证成功后，可以在<code>认证文件</code>页面查看并管理，生成的认证json文件也会保存在前面配置的本地<code>auths</code>路径，若已有多个账号的认证json，也可以在这里上传导入</li>
</ul>
<p><img src="./auths.webp" alt="配图" /></p>
<blockquote>
<p>💡 建议：批量注册账号组成号池，效果更佳</p>
</blockquote>
<h2>CC Switch 安装</h2>
<p>CC Switch 是 Claude Code 的配置管理工具，支持快速切换 API 端点。</p>
<h3>安装方式</h3>
<p>从 <a href="https://github.com/farion1231/cc-switch/releases">CC Switch Releases</a> 下载 Windows 可执行文件，进行安装即可。</p>
<h2>接入Claude Code</h2>
<p>利用CC Switch将反代的api接入Claude Code，达成Claude Code+Chatgpt模型的组合使用</p>
<h3>CC Switch配置</h3>
<ul>
<li>打开CC Switch程序，选择Claude Code，点击<code>+</code>，添加新供应商</li>
</ul>
<p><img src="./ccs-add.webp" alt="配图" /></p>
<ul>
<li>按图中配置填写配置<br />
<code>预设供应商</code>：自定义配置<br />
<code>供应商名称</code>：随便填<br />
<code>API Key</code>:前面config.yaml配置文件里的<code>api-keys</code>，比如示例中的<code>ABC-123456</code><br />
<code>请求地址</code>:<code>http://localhost:8317</code>或<code>http://127.0.0.1:8317</code><br />
<code>API 格式</code>:按自己需求填写，也可与图中一样<br />
<code>认证字段</code>:按自己需求填写，也可与图中一样</li>
</ul>
<p><img src="./ccs-config1.webp" alt="配图" /></p>
<ul>
<li>模型按自己需要的填写，在Cliproxy的WebUI中可以看到支持的认证模型</li>
</ul>
<p><img src="./models.webp" alt="配图" /></p>
<ul>
<li>模型后面可以添加(minimal/medium/high/xhigh)，表示不同的推理程度</li>
</ul>
<p><img src="./ccs-models.webp" alt="配图" /></p>
<ul>
<li>保存配置后进行启用</li>
</ul>
<p><img src="./ccs-start.webp" alt="配图" /></p>
<h3>Claude Code+Chatgpt验证</h3>
<p>现在可以愉快的在Claude Code使用Chatgpt系列大模型了</p>
<ul>
<li>以VScode中的Claude Code为例</li>
</ul>
<p><img src="./test.webp" alt="配图" /></p>
<hr />
]]></content>
    <author><name>Polo</name></author>
    <category term="技术教程"/>
  </entry>
  <entry>
    <title>Cloudflare Workers / Pages / R2 IP 优选指南</title>
    <link href="https://blog.drtob.com/posts/cloudflare-ip-optimization/" rel="alternate" type="text/html"/>
    <id>https://blog.drtob.com/posts/cloudflare-ip-optimization/</id>
    <published>2026-03-24T00:00:00.000Z</published>
    <updated>2026-03-24T00:00:00.000Z</updated>
    <summary>使用Worker 以及各种方法对 Cloudflare Workers、Pages、R2 进行 IP 优选，提高网站可用性和访问速度</summary>
    <content type="html"><![CDATA[<p>Cloudflare 作为全球领先的 CDN 和边缘计算平台，在全球拥有超过 300 个数据中心。但由于网络路由、运营商策略等因素，用户默认分配到的节点可能并非最优。本文将详细介绍如何对 <strong>Cloudflare Workers</strong>、<strong>Cloudflare Pages</strong> 和 <strong>Cloudflare R2</strong> 进行 IP 优选，提升国内访问速度！</p>
<h2>目录</h2>
<ul>
<li><a href="#%E5%8E%9F%E7%90%86%E6%A6%82%E8%BF%B0">原理概述</a></li>
<li><a href="#%E5%85%AC%E5%85%B1%E4%BC%98%E9%80%89%E5%9F%9F%E5%90%8Dip">公共优选域名/IP</a></li>
<li><a href="#pages-%E4%BC%98%E9%80%89%E5%9F%9F%E5%90%8D">Pages 优选域名</a></li>
<li><a href="#workers-%E4%BC%98%E9%80%89%E5%9F%9F%E5%90%8D">Workers 优选域名</a></li>
<li><a href="#r2-%E7%9A%84-ip-%E4%BC%98%E9%80%89">R2 的 IP 优选</a></li>
</ul>
<hr />
<h2>原理概述</h2>
<h3>什么是 IP 优选？</h3>
<p>IP 优选是通过测试 Cloudflare 不同数据中心的 IP 地址，找到对当前网络环境延迟最低、速度最快的节点，然后通过修改 DNS 或 Hosts 的方式将域名解析到该 IP，从而实现加速访问。</p>
<h3>为什么要做 IP 优选？</h3>
<p>Cloudflare 使用 <strong>Anycast</strong> 技术，同一个 IP 地址在全球多个数据中心同时广播。理论上用户会自动连接到最近的节点，但实际中：</p>
<ul>
<li>运营商路由策略可能导致绕路</li>
<li>国际出口拥塞影响访问质量</li>
<li>部分地区运营商对特定 IP 段有优化</li>
</ul>
<p>通过 IP 优选，我们可以绕过这些限制，直接连接到最优节点。</p>
<hr />
<h2>公共优选域名/IP</h2>
<ul>
<li>社区优选域名：https://cf.090227.xyz/ ，进入地址挑选延迟较低域名即可</li>
<li>优选IP：https://github.com/XIU2/CloudflareSpeedTest ，使用大佬的工具测试出合适的IP</li>
</ul>
<hr />
<h2>Pages 优选域名</h2>
<h3>使用 DNSPod 进行优选（推荐）</h3>
<h4>1. 在 Pages 中添加自定义域</h4>
<p>进入 Cloudflare Pages 控制台：</p>
<ol>
<li>选择你的 Pages 项目</li>
<li>点击 <strong>设置</strong> → <strong>自定义域</strong></li>
<li>点击 <strong>设置自定义域</strong>，输入你的域名（如 <code>page.yourdomain.com</code>）</li>
<li>等待自定义域验证成功（状态显示为 <strong>活动</strong>）</li>
</ol>
<p><img src="./pages-domain.webp" alt="配图" /></p>
<h4>2. 在 DNSPod 中添加域名</h4>
<p>登录 <a href="https://console.dnspod.cn/">DNSPod</a>：</p>
<ol>
<li>点击 <strong>添加域名</strong></li>
<li>输入你在 Pages 中添加的自定义域名</li>
<li>点击 <strong>确定</strong></li>
<li>复制<strong>主机记录</strong>、<strong>记录值</strong></li>
</ol>
<p><img src="./dnspod-add-domain.webp" alt="配图" /></p>
<h4>3. 在 Cloudflare 添加 TXT 验证记录</h4>
<p>由于域名托管在 Cloudflare，需要返回cloudflare，为 Pages 的自定义域名添加一条TXT验证记录，使用上面复制的<strong>主机记录</strong>、<strong>记录值</strong>即可：</p>
<p><img src="./dnspodcheck.webp" alt="配图" /></p>
<h4>4. 在 DNSPod 中验证域名</h4>
<p>返回 DNSPod：</p>
<ol>
<li>点击 <strong>验证</strong>，选择 <strong>手动验证</strong></li>
<li>等待验证通过</li>
<li>点击 <strong>立即激活</strong> 开启解析，提示为域名设置NS记录，复制两条NS记录</li>
</ol>
<h4>5. 在 Cloudflare 添加 NS 记录</h4>
<p>回到 Cloudflare DNS 管理：</p>
<ol>
<li>添加复制的 NS 记录，将自定义域名指向 DNSPod</li>
</ol>
<p><img src="./add-ns.webp" alt="配图" /></p>
<h4>6. 在 DNSPod 添加优选记录</h4>
<p>进入 DNSPod 的解析记录页面：</p>
<ol>
<li>使用优选域名 添加CNAME记录（推荐）</li>
<li>使用优选 IP 添加A记录</li>
<li>建议添加3条线路，默认、国内指向优选域名/IP，境外指向pages默认分配的域名</li>
</ol>
<p><img src="./dnspod-ip.webp" alt="配图" /></p>
<blockquote>
<p>💡 <strong>提示</strong>：使用优选域名的好处是，当 IP 失效时，域名维护者会更新记录，你不需要手动修改。</p>
</blockquote>
<hr />
<h2>Workers 优选域名</h2>
<p>Workers 的优选相对简单，使用 <strong>Workers 路由</strong> 功能即可。</p>
<h3>使用Workers路由匹配</h3>
<h4>1. 在 Cloudflare DNS 添加 CNAME 记录</h4>
<p>进入 Cloudflare DNS 管理，添加记录将自定义域名(work.youdomian.com)指向优选域名：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>名称</th>
<th>目标</th>
<th>代理状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>CNAME</td>
<td>worker</td>
<td>cf.090227.xyz</td>
<td>已禁用（灰色云）</td>
</tr>
</tbody>
</table>
<blockquote>
<p>⚠️ <strong>关键</strong>：<strong>代理状态必须关闭</strong>（灰色云），否则无法实现 IP 优选！</p>
</blockquote>
<h4>2. 添加 Workers 路由</h4>
<ol>
<li>进入 Cloudflare 控制台 → <strong>Workers 和 Pages</strong></li>
<li>进入 要配置的<strong>Workers</strong></li>
<li>点击 <strong>添加路由</strong></li>
</ol>
<p><img src="./worker-router.webp" alt="配图" /></p>
<p><strong>路由配置：</strong></p>
<ul>
<li><strong>路由</strong>：<code>worker.yourdomain.com/*</code> （注意加上 <code>/*</code>）</li>
</ul>
<p><img src="./add-router.webp" alt="配图" /></p>
<h4>3. 验证访问</h4>
<p>等待 DNS 生效后，访问 <code>worker.yourdomain.com</code>，如果正常返回 Worker 内容，说明配置成功。</p>
<h4>4.Workers 路由匹配规则</h4>
<table>
<thead>
<tr>
<th>路由示例</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>example.com/*</code></td>
<td>匹配所有路径</td>
</tr>
<tr>
<td><code>*.example.com/*</code></td>
<td>匹配所有子域名</td>
</tr>
<tr>
<td><code>example.com/api/*</code></td>
<td>仅匹配 <code>/api/</code> 路径</td>
</tr>
</tbody>
</table>
<hr />
<h2>R2 的 IP 优选</h2>
<h3>使用Cloud Connector配置</h3>
<p>⚠️ <strong>这个方案参考网上大佬的，我没成功，我使用的下面另一种方案：Workers代理加速</strong></p>
<h4>1. 创建 R2桶 并绑定自定义域名</h4>
<p><img src="./r2-domain.webp" alt="配图" /></p>
<h4>2. 进入规则 - Cloud Connector - Cloudflare R2</h4>
<p><img src="./choose-r2.webp" alt="配图" /></p>
<h4>3. 选择R2桶以及自定义的域名</h4>
<p><img src="./ch-r2.webp" alt="配图" /></p>
<h4>4. 给R2桶域名配置CAME指向优选域名</h4>
<p><img src="./r2-cname.webp" alt="配图" /></p>
<h3>使用Workers代理加速</h3>
<p>本质是通过Workers+优选IP加速访问</p>
<h4>1. 配置代理域名指向优选域名/IP</h4>
<p><img src="./proxy-domain.webp" alt="配图" /></p>
<h4>2. 新建worker，写入代码后部署，用于代理</h4>
<p>代码可根据实际情况修改，通过worker域名加速访问节点后，再去构造R2桶域名请求，由于已经完成加速，后续请求都是在CF内网完成，速度极快</p>
<pre><code>const R2_DOMAIN = 'twikoo.r2.novoai.top'; //改成你的R2桶域名
const ALLOWED_DOMAINS = ['blog.novoai.top', 'www.blog.novoai.top']; // 允许的域名列表

async function handleRequest(request) {
  try {
    const url = new URL(request.url);
    
    // ===== 防盗链检查开始 =====
    const referer = request.headers.get('Referer') || '';
    
    // 如果不是直接访问（有Referer），检查是否来自允许的域名
    // 注意：如果是直接访问图片 (无Referer)，通常也允许，或者你可以选择禁止
    if (referer !== '') {
      let isAllowed = false;
      for (const domain of ALLOWED_DOMAINS) {
        if (referer.includes(domain)) {
          isAllowed = true;
          break;
        }
      }
      
      if (!isAllowed) {
        return new Response('Hotlinking not allowed', { 
          status: 403,
          headers: { 'Content-Type': 'text/plain' }
        });
      }
    }
    
    // ===== 构造 R2 请求 =====
    const targetUrl = new URL(`https://${R2_DOMAIN}`);
    targetUrl.pathname = url.pathname;
    targetUrl.search = url.search;

    // 复制请求头，但修改 Host
    const headers = new Headers(request.headers);
    headers.set('Host', R2_DOMAIN);
    
    // 移除一些可能引起问题的跳板头
    headers.delete('cf-connecting-ip'); 
    headers.delete('x-forwarded-for');

    const newRequest = new Request(targetUrl, {
      method: request.method,
      headers: headers,
    });
    
    // ===== 发起请求并处理缓存 =====
    let response = await fetch(newRequest);
    
    // 如果请求成功 (200)，添加缓存头，让 CF 边缘节点缓存图片
    if (response.status === 200) {
      // 克隆响应对象以便修改头
      const newResponse = new Response(response.body, response);
      
      // 设置浏览器缓存 (1年)
      newResponse.headers.set("Cache-Control", "public, max-age=31536000, immutable");
      
      // 设置 CF 边缘缓存 (1年) - 关键！这样后续请求直接由 CF 返回，不运行 Worker
      newResponse.headers.set("CDN-Cache-Control", "public, max-age=31536000");
      
      // 确保内容类型正确
      if (!newResponse.headers.has("Content-Type")) {
         // 如果 R2 没返回 Content-Type，可以根据后缀简单判断，或者依赖 R2 的元数据
         // 这里假设 R2 已经存好了 Content-Type
      }
      
      return newResponse;
    }
    
    return response;
    
  } catch (err) {
    return new Response(err.stack, { status: 500 });
  }
}

addEventListener('fetch', event =&gt; {
  event.respondWith(handleRequest(event.request));
});
</code></pre>
<h4>3. 添加worker路由，完成worker和优选域名/IP的绑定</h4>
<p><img src="./proxy-router.webp" alt="配图" /></p>
<h4>4. 图片访问测速</h4>
<ol>
<li>原R2桶域名访问图片延迟200ms</li>
</ol>
<ul>
<li>https://twikoo.r2.novoai.top/2026/03/0a81d686ef428d9bcb02d2c477b0822b.webp</li>
</ul>
<ol>
<li>使用worker加速后的代理域名访问同一图片延迟50ms</li>
</ol>
<ul>
<li>https://proxy.novoai.top/2026/03/0a81d686ef428d9bcb02d2c477b0822b.webp</li>
</ul>
<hr />
]]></content>
    <author><name>Polo</name></author>
    <category term="技术教程"/>
  </entry>
  <entry>
    <title>Twikoo评论系统配置Resend评论邮件通知</title>
    <link href="https://blog.drtob.com/posts/twikoo-resend/" rel="alternate" type="text/html"/>
    <id>https://blog.drtob.com/posts/twikoo-resend/</id>
    <published>2026-03-13T00:00:00.000Z</published>
    <updated>2026-03-13T00:00:00.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<h2>关于 Resend</h2>
<p>Resend 是一款面向开发者的邮件发送服务（API-first），主打简单集成、高送达率和对无服务器环境的良好支持。常见用途包括注册/验证邮件、重置密码、订单与交易通知、系统告警，以及站点/应用内通知（例如评论邮件提醒），免费额度充足（每天 100 封，对于我个人博客的评论邮件通知完全够用）。</p>
<p>本文将重点介绍：注册 Resend、配置发件域名、生成 API Key、发送测试，以及如何将 Resend 配置到 Twikoo 实现评论邮件通知。</p>
<h2>一. 注册与初始配置</h2>
<ol>
<li>
<p>注册账号：访问 https://resend.com/ ，使用邮箱/GitHub/Google登录并完成邮箱验证。免费额度适合轻量通知场景（文档以官网为准）。</p>
</li>
<li>
<p>登录后进入 <code>Domains</code> -&gt; <code>Add domain</code>，建议使用子域名（例如 <code>mail.yourdomain.com</code> 或 <code>news.yourdomain.com</code>），与网站主域分离更安全。</p>
</li>
<li>
<p>Resend 会给出若干 DNS 记录（通常是 SPF 的 TXT、_domainkey 的 CNAME、以及可选的 DMARC TXT），在 Cloudflare 托管的主域名下把这些记录手工添加，或使用 Resend 的 Cloudflare 授权一键添加功能。
<img src="./resend_dns.webp" alt="配图" /></p>
</li>
<li>
<p>等待 DNS 生效（几分钟到数小时），回到 Resend 控制台点击 <code>Verify domain</code>，显示 <code>Verified</code> 即可在该域名下发信。</p>
</li>
<li>
<p>在 <code>API Keys</code> 页面创建 API Key（例如命名为 <code>twikoo-prod</code>），生成后请立即复制并存放在安全处（只显示一次）。
<img src="./resend_token.webp" alt="配图" /></p>
</li>
</ol>
<h2>二. 发送方式与测试</h2>
<p>推荐在后端或 Serverless 环境使用官方 SDK 或 HTTP API 发送邮件，避免在浏览器端暴露 API Key。</p>
<ol>
<li>Node（官方 SDK）示例：</li>
</ol>
<pre><code>npm install resend
</code></pre>
<pre><code>import Resend from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);

await resend.emails.send({
  from: 'Site Name &lt;no-reply@mail.yourdomain.com&gt;',
  to: 'you@example.com',
  subject: '测试邮件 — Resend',
  html: '&lt;p&gt;发送成功&lt;/p&gt;',
});
</code></pre>
<ol>
<li>HTTP API（curl）示例：</li>
</ol>
<pre><code>curl -X POST https://api.resend.com/emails \
  -H "Authorization: Bearer $RESEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"no-reply@mail.yourdomain.com","to":"you@example.com","subject":"测试","html":"&lt;p&gt;hi&lt;/p&gt;"}'
</code></pre>
<ol>
<li>可选：Resend 支持 SMTP（smtp.resend.com），便于兼容传统客户端或系统。</li>
</ol>
<p>验证发送结果：登录 Resend 控制台 <code>Emails</code> 页面查看发送状态（Sent/Delivered/Bounced）并排查问题。</p>
<h2>三. 在 Twikoo 中配置评论邮件通知</h2>
<ol>
<li>
<p>进入Twikoo评论管理后台，点击配置管理-邮件通知。
<img src="./twikoo_mailnotice.webp" alt="配图" /></p>
</li>
<li>
<p>填写SENDER_EMAIL、SMTP_SERVICE、SMTP_PASS参数，其他留空后保存，评论即可收到邮件通知。</p>
<p><code>SENDER_EMAIL</code>：任意名+Resend添加域名（例如 <code>novo@mail.novoai.top</code>）。</p>
<p><code>SMTP_SERVICE</code>：resend</p>
<p><code>SMTP_PASS</code>：Resend生成的API Key（例如 <code>resend_prod_xxx</code>）</p>
</li>
<li>
<p>在通用页面中配置BLOGGER_EMAIL用于接受评论邮件通知。</p>
</li>
<li>
<p>带有图片的评论邮件通知可能会被识别为垃圾邮件，导致被过滤，可以在邮件接收方添加发件人到白名单。</p>
</li>
</ol>
]]></content>
    <author><name>Polo</name></author>
    <category term="建站"/>
  </entry>
  <entry>
    <title>博客添加Twikoo评论系统-cloudflare部署</title>
    <link href="https://blog.drtob.com/posts/twikoo-cloudflare/" rel="alternate" type="text/html"/>
    <id>https://blog.drtob.com/posts/twikoo-cloudflare/</id>
    <published>2026-03-05T00:00:00.000Z</published>
    <updated>2026-03-05T00:00:00.000Z</updated>
    <summary>利用cloudflare部署Twikoo评论系统，为自己的博客添加评论交互</summary>
    <content type="html"><![CDATA[<h2>简介</h2>
<p>Twikoo 是一个轻量且美观的评论系统，本文介绍基于 Cloudflare 的部署方案（使用 Worker + D1 + R2）。优点是：不需要额外托管服务器、在国内访问稳定，并且和 Cloudflare 的存储/函数安全集成。</p>
<p>本文适用场景：你已有一个支持接入Twikoo功能的静态博客，如Mizuki，并拥有 Cloudflare 帐号；拥有自定义域名(可选)以绑定 Twikoo 服务。</p>
<h2>一、准备工作</h2>
<ul>
<li>GitHub 账号（用于 Fork/托管 twikoo-cloudflare 源码）</li>
<li>Cloudflare 账号（用于创建 D1、R2、Workers、Turnstile）</li>
<li>可选：一个域名（用于绑定 R2 或 Worker 的自定义域）</li>
</ul>
<h2>二、Fork 并初始化仓库</h2>
<ol>
<li>
<p>访问仓库并 Fork：</p>
<ul>
<li>仓库地址：https://github.com/Aholicoco/twikoo-cloudflare</li>
</ul>
</li>
<li>
<p>仓库中包含 <code>wrangler.toml</code>、<code>schema.sql</code> 等文件。</p>
</li>
</ol>
<h2>三、在 Cloudflare 上创建 D1（数据库）</h2>
<ol>
<li>登录 Cloudflare 控制面板：<code>存储和数据库</code> -&gt; <code>D1 SQL 数据库</code> -&gt; <code>创建</code>，命名为 <code>twikoo</code>。</li>
<li>创建完成后进入该数据库的 <code>Explore Data</code> 页面，复制仓库根目录 <code>schema.sql</code> 的内容到查询界面并执行 <code>Run all statement</code>（创建所需表结构）。
<img src="./Sql_query.webp" alt="配图" /></li>
<li>在数据库列表页复制该数据库的 <code>ID</code>（随后替换仓库根目录 <code>wrangler.toml</code> 中的 <code>database_id</code>）。
<img src="./D1_id.webp" alt="配图" /></li>
</ol>
<p>在 <code>wrangler.toml</code> 中的示例段落（请替换为你自己的 ID）：</p>
<pre><code>[[d1_databases]]
binding = "DB"
database_name = "twikoo"
database_id = "f47ac10b-58cc-4372-a567-0e02b2c3d479" # 替换为你的 D1 ID
</code></pre>
<h2>四、创建 R2 存储（用于图片等附件）</h2>
<ol>
<li>Cloudflare 左侧栏选择 <code>R2 对象存储</code>，创建存储桶名 <code>twikoo</code>。</li>
<li>进入该存储桶的 <code>设置</code> -&gt; <code>自定义域</code>，配置一个子域（例如 <code>twikoo.r2.yourdomain.com</code>），等待激活。
<img src="./R2_domain.webp" alt="配图" /></li>
<li>在 <code>wrangler.toml</code> 中加入或修改变量：</li>
</ol>
<pre><code>[vars]
R2_PUBLIC_URL = "https://twikoo.r2.yourdomain.com" # 替换为你设置的域名或 R2 公共 URL
</code></pre>
<p>（如果不使用自定义域，也可以暂时使用 R2 的默认访问地址，但建议绑定自有域名以避免跨源或访问限制）</p>
<h2>五、部署 Worker（Twikoo 云函数）</h2>
<ol>
<li>在 Cloudflare 控制台中进入 <code>Workers 和 Pages</code> -&gt; <code>创建 Worker</code>，并连接你 Fork 的仓库。</li>
<li>在连接仓库时，选择 <code>main</code>（或你使用的分支），构建/部署命令填写：</li>
</ol>
<pre><code>npx wrangler deploy --minify
</code></pre>
<ol>
<li>部署成功后访问 Worker 的 URL（或你后续绑定的自定义域），应看到类似：</li>
</ol>
<pre><code>{
	"code": 100,
	"message": "Twikoo 云函数运行正常，请参考 https://twikoo.js.org/frontend.html 完成前端的配置",
	"version": "x.x.x"
}
</code></pre>
<h2>六、将 Worker 绑定自定义域（可选，但建议）</h2>
<p>在 <code>Workers 和 Pages</code> 的 <code>域和路由</code> 中添加自定义域，例如 <code>twikoo.yourdomain.com</code>，完成后你的 Twikoo 服务将通过该域名对外提供 API 与文件托管，我这里选择添加路由。
<img src="./Add_router.webp" alt="配图" /></p>
<h2>七、在博客中启用 Twikoo（前端配置）</h2>
<p>Mizuki 已内置 Twikoo 支持，修改站点配置即可启用（不同博客站点的配置文件不一样，自己找一下）：</p>
<ul>
<li>打开 <code>src/config.ts</code>，找到 <code>commentConfig.twikoo.envId</code>，将其替换为你部署并绑定的 Twikoo 域名（包含协议），设置 <code>commentConfig.enable</code> 为 <code>true</code> 表示启用评论，示例：</li>
</ul>
<pre><code>export const commentConfig: CommentConfig = {
	enable: true,
	twikoo: {
		envId: "https://twikoo.yourdomain.com",
		lang: SITE_LANG,
	},
};
</code></pre>
<p>保存后重新构建/部署你的静态博客站点（例如 GitHub Pages / Cloudflare Pages），刷新博客文章页面底部，应能看到 Twikoo 评论区。
<img src="./Comment.webp" alt="配图" /></p>
<h2>八、配置 Twikoo 管理面板（首次访问）</h2>
<ol>
<li>点击评论区的小齿轮图标，首次进入会要求设置管理员密码。</li>
<li>进入 <code>配置管理</code>：
<ul>
<li>在 <code>隐私</code> 中将 <code>IMAGE_CDN</code> 设置为 <code>cloudflare</code>，启用图片上传到 R2。</li>
<li>在 <code>通用</code> 中为 <code>HIDE_ADMIN_CRYPT</code> 设置暗号，隐藏管理入口。</li>
<li>其他功能可自行摸索，保存配置后退出管理面板，就可以开始发表文字、图片进行评论了。</li>
</ul>
</li>
</ol>
]]></content>
    <author><name>Polo</name></author>
    <category term="建站"/>
  </entry>
</feed>
