-
Notifications
You must be signed in to change notification settings - Fork 406
Expand file tree
/
Copy pathtrendpublish.config.example.ts
More file actions
328 lines (309 loc) · 8.37 KB
/
trendpublish.config.example.ts
File metadata and controls
328 lines (309 loc) · 8.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
import { defineConfig } from "@src/utils/config/define-config.ts";
export default defineConfig({
/**
* 服务配置。
*
* `apiKey` 用于 JSON-RPC 接口鉴权:
* Authorization: Bearer <apiKey>
*/
server: {
apiKey: "change-me",
port: 8000,
},
/**
* 外部服务凭证。
*
* 这里只放凭证和 provider 默认参数。功能是否启用、使用哪个 provider、
* 使用什么参数,都放在 `features.article` 里。
*/
providers: {
/**
* 全文章链路默认使用的 LLM。
*
* 排序、摘要、标题生成、动态模板和 AI 提示词都会使用这组配置。
* 这里支持任意 OpenAI Chat Completions 兼容接口。
*/
ai: {
baseUrl: "https://api.deepseek.com/v1",
apiKey: "",
model: "deepseek-chat",
},
/**
* 内容抓取 provider 凭证。
*
* 只需要填写 `fetchGroups` 会用到,或 `auto` 会推断到的 provider。
* 例如 Twitter/X URL 需要 twitter provider;普通网页默认通常需要
* FireCrawl,除非你把它路由到 Jina。
*/
fetch: {
firecrawl: {
apiKey: "",
},
twitter: {
bearerToken: "",
xquikApiKey: "",
},
jina: {
apiKey: "",
},
rss: {
baseUrl: "https://rsshub.app",
},
},
/**
* 图片生成凭证。
*
* 支持阿里云图片生成和 MiniMax 图片生成。
*
* 功能里 `provider: "dashscope"` 时读取 dashscope.apiKey;
* 功能里 `provider: "minimax"` 时读取 minimax.apiKey。
*/
image: {
dashscope: {
apiKey: "",
},
minimax: {
apiKey: "",
apiHost: "https://api.minimax.io",
},
},
/**
* 发布凭证。
*
* 只有 `features.article.dryRun` 为 false,也就是真正发布到公众号时才必填。
*/
publish: {
weixin: {
appId: "",
appSecret: "",
author: "AI Trend Publish",
needOpenComment: true,
onlyFansCanComment: false,
},
/**
* Cloudflare Worker 没有固定出口 IP。真实发布建议让 Cloudflare 调用
* 固定 IP 机器上的 weixin-relay,由 relay 保存微信 appId/appSecret。
*/
weixinRelay: {
url: "",
token: "",
},
},
/**
* 通知凭证。
*
* 在这里填写 webhook 不会自动开启通知。是否开启通知由
* `features.article.notifications.channels` 决定。
*/
notify: {
bark: {
url: "",
},
dingtalk: {
webhook: "",
},
feishu: {
webhookUrl: "",
},
},
/**
* 文章去重使用的 embedding 凭证。
*
* 是否启用去重由 `features.article.deduplication.enabled` 决定。
*/
vector: {
embedding: {
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
apiKey: "",
model: "text-embedding-v3",
},
},
},
/**
* 抓取路由分组。
*
* `sources` 里的数据源可以是普通 URL,也可以带分组前缀:
* - "https://example.com" 使用 `default` 分组
* - "web:https://example.com" 使用 `web` 分组
*
* 分组里的 provider 会按顺序 fallback。谁先返回内容,就使用谁的结果。
* `auto` 会按 URL 自动推断 provider:
* - x.com / twitter.com -> twitter
* - RSS / RSSHub / feed URL -> rss
* - 其他网页 -> firecrawl
*/
fetchGroups: {
default: ["auto"],
web: ["firecrawl", "jina"],
social: ["twitter"],
reliableWeb: ["firecrawl", "jina"],
},
/**
* 功能配置。
*
* 当前项目主流程聚焦微信公众号文章发布。
*/
features: {
article: {
/**
* 文章数据源列表。
*
* 新手可以先只写普通 URL。只有某个数据源需要指定抓取策略时,
* 再添加 `group:url` 前缀。
*/
sources: [
"https://news.ycombinator.com/",
"web:https://example.com/ai-news",
"social:https://x.com/OpenAIDevs",
"reliableWeb:https://openai.com/news/",
],
/**
* 发布 provider 选择。
*
* - 本地/Docker 固定 IP 直连微信:`weixin`
* - Cloudflare 等无固定出口 IP 环境:`weixin-relay`
*/
publisher: {
provider: "weixin",
},
/**
* 微信文章渲染配置。
*
* `template` 控制视觉模板。使用 `dynamic` 时,AI 会根据本次文章列表
* 实时生成微信兼容的内联 HTML。
*
* `promptProfile` 控制内容口径,会统一影响排序、摘要、标题、动态排版、
* 封面提示词和正文配图提示词。
*/
renderer: {
template: "dynamic",
promptProfile: "technology",
},
/**
* 每次发布保留多少篇排序后的文章。
*/
count: 10,
/**
* 安全本地模式。
*
* true: 只生成 HTML artifact,不上传图片、不发布到公众号。
* 本地/Docker 会写入 `src/temp`,Cloudflare 会写入 R2。
* false: 上传图片并发布 / 创建微信公众号草稿。
*/
dryRun: true,
/**
* 工作流通知。
*
* 留空表示关闭通知。需要开启时,在 channels 中加入渠道名,并配置
* 对应 `providers.notify.*` 凭证:
* ["bark"]、["dingtalk"]、["feishu"],也可以组合多个渠道。
*/
notifications: {
channels: [],
},
/**
* 封面图生成。
*
* provider 可选:
* - "dashscope": 阿里云图片生成,例如 qwen-image-2.0-pro
* - "minimax": MiniMax 图片生成,例如 image-01
*
* 如果 provider 未配置或生成失败,流程会回退到内置默认封面。
*/
cover: {
enabled: true,
provider: "dashscope",
model: "qwen-image-2.0-pro",
},
/**
* 正文 AI 配图。
*
* mode:
* - "off": 不生成正文配图。
* - "missing": 只给没有抓取到原文图片的文章补图。
* - "all": 每篇文章都尝试生成正文配图。
*/
bodyImages: {
mode: "off",
provider: "dashscope",
model: "qwen-image-2.0",
count: 1,
size: "1024*1024",
},
/**
* 文章向量去重。
*
* 开启后会计算文章 embedding,并和历史向量做相似度对比。
* 本地/Docker 默认使用 SQLite,Cloudflare 原生模式使用 D1。
* SQLite 会自动执行内置建表 SQL;Cloudflare D1 使用 migrations 目录。
*/
deduplication: {
enabled: false,
embeddingProvider: "dashscope",
vectorStore: "sqlite",
},
},
},
/**
* 业务数据和运行产物存储。
*
* artifact/runState 支撑内置看板和 dry-run 产物。
* runtimeConfig 保存 Dashboard 可编辑的业务配置,本地/Docker 用 SQLite,
* Cloudflare 用 D1。密钥不会写入 runtimeConfig。
*/
storage: {
artifacts: {
provider: "local",
outputDir: "src/temp",
},
runState: {
provider: "local-json",
outputDir: "src/temp",
},
runtimeConfig: {
provider: "sqlite",
sqlitePath: "src/temp/trendpublish.sqlite3",
},
vector: {
provider: "sqlite",
sqlitePath: "src/temp/trendpublish.sqlite3",
},
},
/**
* logger 观测镜像。
*
* 所有 `new Logger(...).info/warn/error/debug` 输出都会进入这里配置的 sink。
* 原 logger 仍会正常输出;stdout sink 会额外输出一份结构化 JSON。
* 接 Axiom / Better Stack / 自建 collector 时,开启 http sink。
*/
observability: {
enabled: true,
serviceName: "trendpublish",
environment: "local",
stdout: {
enabled: false,
format: "json",
},
http: {
enabled: false,
endpoint: "",
bearerToken: "",
headers: {},
format: "object",
timeoutMs: 5000,
},
axiom: {
enabled: false,
dataset: "",
token: "",
apiUrl: "https://api.axiom.co",
timeoutMs: 5000,
},
betterStack: {
enabled: false,
sourceToken: "",
ingestingHost: "https://in.logs.betterstack.com",
timeoutMs: 5000,
},
},
});