feat: 添加基于 Workers AI 的 Slug 自动生成 API 服务

This commit is contained in:
seahi committed 2026-08-07 14:21:25 +08:00
1 parent 4eff4de734
commit c3858c92ba
3 files changed
+90 -7

No files matched your search

+81
View File
@@ -0,0 +1,81 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
// 将英文文本转换为规范的 kebab-case Slug
function toSlug(str: string): string {
return str
.toLowerCase()
.replace(/[^\w\s-]/g, '')
.trim()
.replace(/[\s_]+/g, '-')
.replace(/-+/g, '-');
}
export const POST: RequestHandler = async ({ request, platform }) => {
try {
const body = (await request.json().catch(() => ({}))) as Record<string, unknown>;
const text = typeof body?.text === 'string' ? body.text.trim() : '';
if (!text) {
return json({ slug: '' });
}
// 若输入的文本已经是纯英文/数字(只包含 ASCII 字符、空格或连字符)
if (/^[a-zA-Z0-9\s-_]+$/.test(text)) {
return json({ slug: toSlug(text) });
}
let translatedText = '';
// 优先调用 Cloudflare Workers AI (@cf/meta/m2m100_418m 翻译模型)
if (platform?.env?.AI) {
try {
const res = (await platform.env.AI.run('@cf/meta/m2m100_418m', {
text,
target_lang: 'english'
})) as { translated_text?: string };
if (res?.translated_text) {
translatedText = res.translated_text;
}
} catch (err) {
console.warn('Workers AI 翻译异常,启动安全降级:', err);
}
}
// 降级策略:如果 Workers AI 未绑定或在线环境缺失,尝试轻量免费 API 作为备用
if (!translatedText) {
try {
const fallbackUrl = `https://api.mymemory.translated.net/get?q=${encodeURIComponent(text)}&langpair=zh-CN|en`;
const res = await fetch(fallbackUrl);
if (res.ok) {
const data = (await res.json()) as { responseData?: { translatedText?: string } };
if (data?.responseData?.translatedText) {
translatedText = data.responseData.translatedText;
}
}
} catch (e) {
console.warn('降级翻译服务调用失败:', e);
}
}
// 如果得到了英文翻译,格式化为 kebab-case Slug
if (translatedText) {
const formattedSlug = toSlug(translatedText);
if (formattedSlug) {
return json({ slug: formattedSlug });
}
}
// 最底层的安全兜底:若没有任何英文结果返回,生成基于拼音/基本替换的 slug
const fallbackSlug = text
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/[^\w-]/g, '');
return json({ slug: fallbackSlug || 'post' });
} catch (error) {
console.error('Slug生成接口未知错误:', error);
return json({ slug: '' }, { status: 500 });
}
};
+5 -6
View File
@@ -1,11 +1,12 @@
/* eslint-disable */ /* eslint-disable */
// Generated by Wrangler by running `wrangler types` (hash: 8e316e5cc1c036c1cc1ec926e6667c6d) // Generated by Wrangler by running `wrangler types` (hash: 9194822214de3b6a9d6a85fa866a429b)
// Runtime types generated with workerd@1.20260801.1 2026-08-07 nodejs_compat // Runtime types generated with workerd@1.20260801.1 2026-08-07 nodejs_compat
interface __BaseEnv_Env { interface __BaseEnv_Env {
R2: R2Bucket; R2: R2Bucket;
DB: D1Database; DB: D1Database;
CF_ACCESS_TEAM_DOMAIN: 'https://hisland.cloudflareaccess.com'; AI: Ai;
CF_ACCESS_AUD: '35b84a1c6ea81e1c036272ee68ecc4197041aadc1bed0815accac283a30e01ff'; CF_ACCESS_TEAM_DOMAIN: "https://hisland.cloudflareaccess.com";
CF_ACCESS_AUD: "35b84a1c6ea81e1c036272ee68ecc4197041aadc1bed0815accac283a30e01ff";
} }
declare namespace Cloudflare { declare namespace Cloudflare {
interface Env extends __BaseEnv_Env {} interface Env extends __BaseEnv_Env {}
@@ -15,9 +16,7 @@ type StringifyValues<EnvType extends Record<string, unknown>> = {
[Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string; [Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
}; };
declare namespace NodeJS { declare namespace NodeJS {
interface ProcessEnv extends StringifyValues< interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, "CF_ACCESS_TEAM_DOMAIN" | "CF_ACCESS_AUD">> {}
Pick<Cloudflare.Env, 'CF_ACCESS_TEAM_DOMAIN' | 'CF_ACCESS_AUD'>
> {}
} }
// Begin runtime types // Begin runtime types
+4 -1
View File
@@ -21,5 +21,8 @@
"binding": "R2", "binding": "R2",
"bucket_name": "blogflare-assets" "bucket_name": "blogflare-assets"
} }
] ],
"ai": {
"binding": "AI"
}
} }