dsh-line-bot 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/README.en.md +19 -0
- package/README.ja.md +19 -0
- package/README.ko.md +19 -0
- package/README.md +19 -0
- package/README.zh-CN.md +19 -0
- package/bin/cli.mjs +86 -6
- package/lib/host.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.en.md
CHANGED
|
@@ -56,6 +56,25 @@ Then add `dsh-line-bot` to the `dsh.profile.bundles` array in `~/.dsh/profiles/d
|
|
|
56
56
|
>
|
|
57
57
|
> Or from source: `git clone https://github.com/Hanson0901/dsh-line-bot.git`, then choose that folder in the DSH panel's "Install bundle", or run `dsh plugin --profile desktop add /path/to/dsh-line-bot`.
|
|
58
58
|
|
|
59
|
+
## Companion plugins (optional)
|
|
60
|
+
|
|
61
|
+
The bot works on its own; these plugins add capabilities:
|
|
62
|
+
|
|
63
|
+
| Plugin | What it adds | Recommended |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `dsh-persona-dafeiyu` | Persona catalog and Tieba sync | Yes |
|
|
66
|
+
| `dsh-meme` | Image/sticker replies | Yes |
|
|
67
|
+
| `dsh-tieba-dive` | Source of Tieba learning sync | Optional |
|
|
68
|
+
|
|
69
|
+
The install CLI detects what is missing and offers to install it:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx dsh-line-bot install --with-companions
|
|
73
|
+
npx dsh-line-bot install --no-companions
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Without them: no dafeiyu means only plugin-local personas; no dsh-meme means text-only replies; no dsh-tieba-dive means Tieba sync stays off.
|
|
77
|
+
|
|
59
78
|
## First run (5 steps)
|
|
60
79
|
|
|
61
80
|
1. **Create / obtain credentials**: go to [LINE Official Account Manager](https://manager.line.biz/) and create an Official Account → [LINE Developers Console](https://developers.line.biz/console/) and create (or pick) a Messaging API channel → open the **Use webhook** toggle on the "Messaging API" tab → copy the **Channel ID** and **Channel secret**.
|
package/README.ja.md
CHANGED
|
@@ -56,6 +56,25 @@ dsh plugin --profile desktop add dsh-line-bot
|
|
|
56
56
|
>
|
|
57
57
|
> ソースからなら:`git clone https://github.com/Hanson0901/dsh-line-bot.git` して、DSH パネルの「bundle をインストール」でそのフォルダを選ぶか、`dsh plugin --profile desktop add /path/to/dsh-line-bot` を実行します。
|
|
58
58
|
|
|
59
|
+
## 連携プラグイン(任意)
|
|
60
|
+
|
|
61
|
+
LINE Bot は単体でも動きます。以下を入れると機能が増えます:
|
|
62
|
+
|
|
63
|
+
| プラグイン | 追加される機能 | 推奨 |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `dsh-persona-dafeiyu` | ペルソナ一覧と貼吧同期 | 推奨 |
|
|
66
|
+
| `dsh-meme` | 画像/スタンプ返信 | 推奨 |
|
|
67
|
+
| `dsh-tieba-dive` | 貼吧学習同期の取得元 | 任意 |
|
|
68
|
+
|
|
69
|
+
インストール CLI は不足を検出して、一緒に入れるか確認します:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx dsh-line-bot install --with-companions
|
|
73
|
+
npx dsh-line-bot install --no-companions
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
ない場合の影響:大肥魚なし → プラグイン内のペルソナのみ、dsh-meme なし → テキストのみ、貼吧プラグインなし → 貼吧同期は停止。
|
|
77
|
+
|
|
59
78
|
## 初回セットアップ(5 ステップ)
|
|
60
79
|
|
|
61
80
|
1. **認証情報を用意**:[LINE Official Account Manager](https://manager.line.biz/) で公式アカウントを作成 → [LINE Developers Console](https://developers.line.biz/console/) で Messaging API チャネルを作成(または選択)→ 「Messaging API」タブで **Use webhook** をオン → **Channel ID** と **Channel secret** をコピーします。
|
package/README.ko.md
CHANGED
|
@@ -56,6 +56,25 @@ dsh plugin --profile desktop add dsh-line-bot
|
|
|
56
56
|
>
|
|
57
57
|
> 소스에서 설치하려면 `git clone https://github.com/Hanson0901/dsh-line-bot.git` 후 DSH 패널의 "bundle 설치"에서 그 폴더를 선택하거나 `dsh plugin --profile desktop add /path/to/dsh-line-bot`을 실행합니다.
|
|
58
58
|
|
|
59
|
+
## 함께 쓰는 플러그인 (선택)
|
|
60
|
+
|
|
61
|
+
LINE Bot은 단독으로도 동작하며, 아래 플러그인을 설치하면 기능이 늘어납니다:
|
|
62
|
+
|
|
63
|
+
| 플러그인 | 추가 기능 | 권장 |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `dsh-persona-dafeiyu` | 페르소나 목록, 톄바 동기화 | 권장 |
|
|
66
|
+
| `dsh-meme` | 이미지/스티커 답장 | 권장 |
|
|
67
|
+
| `dsh-tieba-dive` | 톄바 학습 동기화 소스 | 선택 |
|
|
68
|
+
|
|
69
|
+
설치 CLI는 없는 것을 감지해 함께 설치할지 물어봅니다:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx dsh-line-bot install --with-companions
|
|
73
|
+
npx dsh-line-bot install --no-companions
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
없을 때: 대비어 없음 → 플러그인 자체 페르소나만, dsh-meme 없음 → 텍스트만, 톄바 플러그인 없음 → 톄바 동기화 꺼짐.
|
|
77
|
+
|
|
59
78
|
## 첫 구동(5단계)
|
|
60
79
|
|
|
61
80
|
1. **자격 증명 준비**: [LINE Official Account Manager](https://manager.line.biz/)에서 공식 계정 생성 → [LINE Developers Console](https://developers.line.biz/console/)에서 Messaging API 채널 생성(또는 선택) → "Messaging API" 탭에서 **Use webhook** 켜기 → **Channel ID**와 **Channel secret** 복사.
|
package/README.md
CHANGED
|
@@ -56,6 +56,25 @@ dsh plugin --profile desktop add dsh-line-bot
|
|
|
56
56
|
>
|
|
57
57
|
> 或從原始碼:`git clone https://github.com/Hanson0901/dsh-line-bot.git`,在 DSH 面板「安裝 bundle」選那個資料夾,或 `dsh plugin --profile desktop add /path/to/dsh-line-bot`。
|
|
58
58
|
|
|
59
|
+
## 搭配外掛(可選)
|
|
60
|
+
|
|
61
|
+
LINE Bot 可以獨立運作;裝了下面這些外掛會多出對應功能:
|
|
62
|
+
|
|
63
|
+
| 外掛 | 用途 | 建議 |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `dsh-persona-dafeiyu` | 人設清單、貼吧同步 | 建議 |
|
|
66
|
+
| `dsh-meme` | 讓角色回圖片/貼圖 | 建議 |
|
|
67
|
+
| `dsh-tieba-dive` | 貼吧學習同步的來源 | 可選 |
|
|
68
|
+
|
|
69
|
+
安裝時 CLI 會偵測缺哪些,並詢問要不要一起安裝:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx dsh-line-bot install --with-companions
|
|
73
|
+
npx dsh-line-bot install --no-companions
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
少了它們的影響:沒有大肥魚 → 人設只剩插件自訂的;沒有 dsh-meme → 只能回文字;沒有刷貼吧 → 貼吧同步自動停用。
|
|
77
|
+
|
|
59
78
|
## 第一次上線(5 步)
|
|
60
79
|
|
|
61
80
|
1. **建立/取得憑證**:到 [LINE Official Account Manager](https://manager.line.biz/) 建立官方帳號 → [LINE Developers Console](https://developers.line.biz/console/) 建立(或選用)Messaging API channel → 在「Messaging API」分頁把 **Use webhook** 打開 → 複製 **Channel ID** 與 **Channel secret**。
|
package/README.zh-CN.md
CHANGED
|
@@ -56,6 +56,25 @@ dsh plugin --profile desktop add dsh-line-bot
|
|
|
56
56
|
>
|
|
57
57
|
> 或从源码:`git clone https://github.com/Hanson0901/dsh-line-bot.git`,在 DSH 面板「安装 bundle」选那个文件夹,或 `dsh plugin --profile desktop add /path/to/dsh-line-bot`。
|
|
58
58
|
|
|
59
|
+
## 搭配插件(可选)
|
|
60
|
+
|
|
61
|
+
LINE Bot 可以独立运行;装上下面这些插件会多出对应功能:
|
|
62
|
+
|
|
63
|
+
| 插件 | 用途 | 建议 |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `dsh-persona-dafeiyu` | 人设清单、贴吧同步 | 建议 |
|
|
66
|
+
| `dsh-meme` | 让角色回图片/贴图 | 建议 |
|
|
67
|
+
| `dsh-tieba-dive` | 贴吧学习同步的来源 | 可选 |
|
|
68
|
+
|
|
69
|
+
安装时 CLI 会检测缺哪些,并询问要不要一起安装:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx dsh-line-bot install --with-companions
|
|
73
|
+
npx dsh-line-bot install --no-companions
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
少了它们的影响:没有大肥鱼 → 人设只剩插件自定义的;没有 dsh-meme → 只能回文字;没有刷贴吧 → 贴吧同步自动停用。
|
|
77
|
+
|
|
59
78
|
## 第一次上线(5 步)
|
|
60
79
|
|
|
61
80
|
1. **创建/取得凭证**:到 [LINE Official Account Manager](https://manager.line.biz/) 创建官方账号 → [LINE Developers Console](https://developers.line.biz/console/) 创建(或选用)Messaging API channel → 在「Messaging API」分页把 **Use webhook** 打开 → 复制 **Channel ID** 与 **Channel secret**。
|
package/bin/cli.mjs
CHANGED
|
@@ -16,6 +16,7 @@ import fs from 'node:fs'
|
|
|
16
16
|
import os from 'node:os'
|
|
17
17
|
import path from 'node:path'
|
|
18
18
|
import { spawnSync } from 'node:child_process'
|
|
19
|
+
import readline from 'node:readline/promises'
|
|
19
20
|
|
|
20
21
|
const IS_WIN = process.platform === 'win32'
|
|
21
22
|
import { fileURLToPath } from 'node:url'
|
|
@@ -23,6 +24,13 @@ import { fileURLToPath } from 'node:url'
|
|
|
23
24
|
const PKG = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
|
|
24
25
|
const NAME = PKG.name || 'dsh-line-bot'
|
|
25
26
|
|
|
27
|
+
// 搭配的外掛:不裝也能用,但少掉某些功能。安裝時會偵測並詢問是否一起裝。
|
|
28
|
+
const COMPANIONS = [
|
|
29
|
+
{ name: 'dsh-persona-dafeiyu', label: '大肥魚人設', hint: '人設清單、貼吧同步(建議)' },
|
|
30
|
+
{ name: 'dsh-meme', label: '表情包圖庫', hint: '讓角色回圖片/貼圖(建議)' },
|
|
31
|
+
{ name: 'dsh-tieba-dive', label: '刷貼吧', hint: '貼吧學習同步的來源(可選)' },
|
|
32
|
+
]
|
|
33
|
+
|
|
26
34
|
function out(line = '') {
|
|
27
35
|
process.stdout.write(`${line}\n`)
|
|
28
36
|
}
|
|
@@ -32,7 +40,7 @@ function fail(message) {
|
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
function parseArgs(argv) {
|
|
35
|
-
const options = { command: '', profile: '', version: '', spec: '', dryRun: false, enable: true }
|
|
43
|
+
const options = { command: '', profile: '', version: '', spec: '', dryRun: false, enable: true, companions: 'ask' }
|
|
36
44
|
const rest = [...argv]
|
|
37
45
|
options.command = (rest.shift() || 'help').toLowerCase()
|
|
38
46
|
for (let index = 0; index < rest.length; index += 1) {
|
|
@@ -56,6 +64,10 @@ function parseArgs(argv) {
|
|
|
56
64
|
options.spec = arg.slice('--spec='.length)
|
|
57
65
|
} else if (arg === '--no-enable') {
|
|
58
66
|
options.enable = false
|
|
67
|
+
} else if (arg === '--with-companions') {
|
|
68
|
+
options.companions = 'yes'
|
|
69
|
+
} else if (arg === '--no-companions') {
|
|
70
|
+
options.companions = 'no'
|
|
59
71
|
} else if (arg === '--help' || arg === '-h') {
|
|
60
72
|
options.command = 'help'
|
|
61
73
|
} else {
|
|
@@ -125,12 +137,12 @@ function bundlesOf(manifest) {
|
|
|
125
137
|
return Array.isArray(bundles) ? [...bundles] : []
|
|
126
138
|
}
|
|
127
139
|
|
|
128
|
-
function withBundle(manifest, enabled) {
|
|
140
|
+
function withBundle(manifest, enabled, name = NAME) {
|
|
129
141
|
const bundles = bundlesOf(manifest)
|
|
130
142
|
if (enabled) {
|
|
131
|
-
if (!bundles.includes(
|
|
143
|
+
if (!bundles.includes(name)) bundles.push(name)
|
|
132
144
|
} else {
|
|
133
|
-
const index = bundles.indexOf(
|
|
145
|
+
const index = bundles.indexOf(name)
|
|
134
146
|
if (index >= 0) bundles.splice(index, 1)
|
|
135
147
|
}
|
|
136
148
|
return {
|
|
@@ -218,7 +230,66 @@ function runInstall(profile, versionSpec, { dryRun }) {
|
|
|
218
230
|
}
|
|
219
231
|
}
|
|
220
232
|
|
|
221
|
-
function
|
|
233
|
+
function companionMissing(profile, dir, manifest, name) {
|
|
234
|
+
const deps = { ...(manifest.dependencies || {}), ...(manifest.devDependencies || {}) }
|
|
235
|
+
if (deps[name]) return false
|
|
236
|
+
if (bundlesOf(manifest).includes(name)) return false
|
|
237
|
+
return !fs.existsSync(path.join(dir, 'node_modules', name, 'package.json'))
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async function askYesNo(question) {
|
|
241
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
|
242
|
+
try {
|
|
243
|
+
const answer = (await rl.question(question)).trim().toLowerCase()
|
|
244
|
+
return answer === '' || answer === 'y' || answer === 'yes' || answer === '是'
|
|
245
|
+
} finally {
|
|
246
|
+
rl.close()
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function installCompanion(profile, name, options) {
|
|
251
|
+
runInstall(profile, `${name}@latest`, options)
|
|
252
|
+
if (options.dryRun) return
|
|
253
|
+
const { file } = readManifest(profile)
|
|
254
|
+
const current = readManifest(profile).manifest
|
|
255
|
+
const next = withBundle(current, true, name)
|
|
256
|
+
if (JSON.stringify(next) !== JSON.stringify(current)) {
|
|
257
|
+
writeManifestAtomic(file, next)
|
|
258
|
+
out(`✔ 已啟用 ${name}`)
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function setupCompanions(profile, options) {
|
|
263
|
+
const { dir, manifest } = readManifest(profile)
|
|
264
|
+
const missing = COMPANIONS.filter((item) => companionMissing(profile, dir, manifest, item.name))
|
|
265
|
+
if (missing.length === 0) {
|
|
266
|
+
out('• 搭配外掛都已安裝。')
|
|
267
|
+
return
|
|
268
|
+
}
|
|
269
|
+
out('')
|
|
270
|
+
out('搭配外掛(可選,不裝也能用):')
|
|
271
|
+
for (const item of missing) out(` • ${item.name} — ${item.label}:${item.hint}`)
|
|
272
|
+
if (options.dryRun) {
|
|
273
|
+
out(`→ 會詢問是否一起安裝 ${missing.map((item) => item.name).join('、')}`)
|
|
274
|
+
return
|
|
275
|
+
}
|
|
276
|
+
let install = false
|
|
277
|
+
if (options.companions === 'yes') install = true
|
|
278
|
+
else if (options.companions === 'no') install = false
|
|
279
|
+
else if (process.stdin.isTTY) install = await askYesNo('要一起安裝嗎?(Y/n) ')
|
|
280
|
+
else {
|
|
281
|
+
out('• 目前不是互動終端,略過搭配外掛;可加 --with-companions 一起安裝。')
|
|
282
|
+
return
|
|
283
|
+
}
|
|
284
|
+
if (!install) {
|
|
285
|
+
out('• 略過搭配外掛。之後可再跑 npx dsh-line-bot install --with-companions。')
|
|
286
|
+
return
|
|
287
|
+
}
|
|
288
|
+
for (const item of missing) installCompanion(profile, item.name, options)
|
|
289
|
+
out('✔ 搭配外掛安裝完成。')
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async function commandInstall(options) {
|
|
222
293
|
const profile = pickProfile(options.profile)
|
|
223
294
|
const { dir, file, manifest } = readManifest(profile)
|
|
224
295
|
const versionSpec = options.spec || (options.version ? `${NAME}@${options.version}` : `${NAME}@${PKG.version}`)
|
|
@@ -245,6 +316,8 @@ function commandInstall(options) {
|
|
|
245
316
|
}
|
|
246
317
|
}
|
|
247
318
|
|
|
319
|
+
await setupCompanions(profile, options)
|
|
320
|
+
|
|
248
321
|
out('')
|
|
249
322
|
out('完成。下一步:')
|
|
250
323
|
out(' 1. 完全結束並重開 DeepSeek Harness(桌面版請確認選單列沒有殘留)。')
|
|
@@ -295,6 +368,11 @@ function commandStatus(options) {
|
|
|
295
368
|
out(`profile:${profile}(${dir})`)
|
|
296
369
|
out(`依賴:${dependency || '(未安裝)'}`)
|
|
297
370
|
out(`bundle 啟用:${enabled ? '是' : '否'}`)
|
|
371
|
+
const companions = COMPANIONS.map((item) => {
|
|
372
|
+
const ok = !companionMissing(profile, dir, manifest, item.name)
|
|
373
|
+
return `${item.name}${ok ? '(已安裝)' : '(未安裝)'}`
|
|
374
|
+
})
|
|
375
|
+
out(`搭配外掛:${companions.join('、')}`)
|
|
298
376
|
if (fs.existsSync(path.join(dshHome(), 'line-bot', 'config.json'))) {
|
|
299
377
|
out('設定檔:<DSH_HOME>/line-bot/config.json(已存在)')
|
|
300
378
|
}
|
|
@@ -314,6 +392,8 @@ function commandHelp() {
|
|
|
314
392
|
out(' --version, -v <版本> 指定要安裝的版本(預設跟這個 CLI 相同)')
|
|
315
393
|
out(' --spec <pnpm 規格> 直接指定套件規格,例如 github:Hanson0901/dsh-line-bot')
|
|
316
394
|
out(' --no-enable 只安裝套件,不寫入 bundle 清單')
|
|
395
|
+
out(' --with-companions 一起安裝搭配外掛(dsh-persona-dafeiyu、dsh-meme、dsh-tieba-dive)')
|
|
396
|
+
out(' --no-companions 不詢問搭配外掛')
|
|
317
397
|
out(' --dry-run, -n 只顯示會做什麼,不寫入')
|
|
318
398
|
out(' --help, -h 顯示這段說明')
|
|
319
399
|
out('')
|
|
@@ -324,7 +404,7 @@ const options = parseArgs(process.argv.slice(2))
|
|
|
324
404
|
switch (options.command) {
|
|
325
405
|
case 'install':
|
|
326
406
|
case 'add':
|
|
327
|
-
commandInstall(options)
|
|
407
|
+
await commandInstall(options)
|
|
328
408
|
break
|
|
329
409
|
case 'uninstall':
|
|
330
410
|
case 'remove':
|
package/lib/host.mjs
CHANGED
|
@@ -41,7 +41,7 @@ const { createMemeSource } = memeSourceMod
|
|
|
41
41
|
const { createStickerImages } = stickerImageMod
|
|
42
42
|
const { chunkText, clip, inQuietWindow, jsonFail, jsonOk, maskSecret, readJsonBody, safeArray, sleep } = utilMod
|
|
43
43
|
|
|
44
|
-
export const VERSION = '0.5.
|
|
44
|
+
export const VERSION = '0.5.6'
|
|
45
45
|
|
|
46
46
|
// 環境變數提供的 Cloudflare API Token(方便用 shell 注入、不用把 token 寫進設定檔)。
|
|
47
47
|
// 設定檔裡的 token 優先;兩者都沒有時才用環境變數。
|