koishi-plugin-dew-bot 1.0.249 → 1.0.250
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/lib/index.js +75 -6
- package/lib/plugin/serverHandel/qqPageMessage.d.ts +5 -0
- package/lib/plugin/serverHandel/qqTransactionMessage.d.ts +5 -0
- package/lib/shared/face/index.d.ts +2 -0
- package/package.json +1 -1
- package/src/plugin/serverHandel/qqPageMessage.ts +8 -3
- package/src/plugin/serverHandel/qqTransactionMessage.ts +62 -0
- package/src/plugin/serverHandel/text.ts +5 -3
- package/src/shared/bot/serviceProto.ts +9 -1
- package/src/shared/face/index.ts +2 -0
package/lib/index.js
CHANGED
|
@@ -839,8 +839,12 @@ function canSendQQPage(session, data) {
|
|
|
839
839
|
}
|
|
840
840
|
__name(canSendQQPage, "canSendQQPage");
|
|
841
841
|
async function sendQQPage(session, data) {
|
|
842
|
-
const internal = session.bot.internal;
|
|
843
842
|
const markdown = renderQQPageMarkdown(data, session.event?.channel?.type === 0);
|
|
843
|
+
await sendQQMarkdown(session, markdown);
|
|
844
|
+
}
|
|
845
|
+
__name(sendQQPage, "sendQQPage");
|
|
846
|
+
async function sendQQMarkdown(session, markdown) {
|
|
847
|
+
const internal = session.bot.internal;
|
|
844
848
|
const request = {
|
|
845
849
|
// With msg_type=2, QQ requires the ordinary content field to be empty.
|
|
846
850
|
content: "",
|
|
@@ -858,7 +862,63 @@ async function sendQQPage(session, data) {
|
|
|
858
862
|
const pendingAudit = response?.code === 304023 && !!response.data?.message_audit?.audit_id;
|
|
859
863
|
if (!response?.id && !response?.audit_id && !pendingAudit) throw new Error("QQ 未确认消息已接收");
|
|
860
864
|
}
|
|
861
|
-
__name(
|
|
865
|
+
__name(sendQQMarkdown, "sendQQMarkdown");
|
|
866
|
+
|
|
867
|
+
// src/plugin/serverHandel/qqTransactionMessage.ts
|
|
868
|
+
function renderQQTransactionMarkdown(data, showGreeting) {
|
|
869
|
+
const sections = [];
|
|
870
|
+
const bodyLines = [];
|
|
871
|
+
const actions = [];
|
|
872
|
+
const flushBody = /* @__PURE__ */ __name(() => {
|
|
873
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
874
|
+
}, "flushBody");
|
|
875
|
+
const flushActions = /* @__PURE__ */ __name(() => {
|
|
876
|
+
if (actions.length) sections.push(actions.splice(0).join(" · "));
|
|
877
|
+
}, "flushActions");
|
|
878
|
+
const flush = /* @__PURE__ */ __name(() => {
|
|
879
|
+
flushBody();
|
|
880
|
+
flushActions();
|
|
881
|
+
}, "flush");
|
|
882
|
+
if (showGreeting) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
883
|
+
for (const item of data.line) {
|
|
884
|
+
if (item.type === 0 /* title */) {
|
|
885
|
+
flush();
|
|
886
|
+
sections.push(`**${escapeMarkdown(item.content)}**`);
|
|
887
|
+
continue;
|
|
888
|
+
}
|
|
889
|
+
if (item.type === 2 /* error */) {
|
|
890
|
+
flush();
|
|
891
|
+
sections.push(`❌ 出错了!错误原因:${escapeMarkdown(item.content)},请反馈至联系开发者`);
|
|
892
|
+
continue;
|
|
893
|
+
}
|
|
894
|
+
if (item.type !== 1 /* line */) continue;
|
|
895
|
+
const action = data.transaction && (item.content === "[是]确认交易" ? { command: "是", label: "确认交易" } : item.content === "[否]取消交易" ? { command: "否", label: "取消交易" } : void 0);
|
|
896
|
+
if (action) {
|
|
897
|
+
flushBody();
|
|
898
|
+
actions.push(`[${action.command}](${inlineCommandUrl(action.command)}) ${action.label}`);
|
|
899
|
+
continue;
|
|
900
|
+
}
|
|
901
|
+
flushActions();
|
|
902
|
+
if (!item.content.trim()) {
|
|
903
|
+
flushBody();
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
const section = /^┄━═(.+)═━┄$/.exec(item.content);
|
|
907
|
+
if (section || item.content === "【还缺】") {
|
|
908
|
+
flushBody();
|
|
909
|
+
sections.push(`**${escapeMarkdown(section?.[1] ?? "还缺")}**`);
|
|
910
|
+
} else {
|
|
911
|
+
bodyLines.push(escapeMarkdown(item.content));
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
flush();
|
|
915
|
+
return sections.join("\n\n") || " ";
|
|
916
|
+
}
|
|
917
|
+
__name(renderQQTransactionMarkdown, "renderQQTransactionMarkdown");
|
|
918
|
+
async function sendQQTransaction(session, data) {
|
|
919
|
+
await sendQQMarkdown(session, renderQQTransactionMarkdown(data, session.event?.channel?.type === 0));
|
|
920
|
+
}
|
|
921
|
+
__name(sendQQTransaction, "sendQQTransaction");
|
|
862
922
|
|
|
863
923
|
// src/plugin/serverHandel/text.ts
|
|
864
924
|
var handelr_text = class extends handel_base {
|
|
@@ -868,10 +928,11 @@ var handelr_text = class extends handel_base {
|
|
|
868
928
|
async start(data) {
|
|
869
929
|
const content = new AnalysisMsg().parse(data);
|
|
870
930
|
const session = sessions_default.get(sessionKey(data.botId, data.userId, data.channelId));
|
|
871
|
-
if (data.pageNav && canSendQQPage(session, data)) {
|
|
931
|
+
if ((data.transaction || data.pageNav) && canSendQQPage(session, data)) {
|
|
872
932
|
const sendStartedAt = this.timing ? performance.now() : 0;
|
|
873
933
|
try {
|
|
874
|
-
await
|
|
934
|
+
if (data.transaction) await sendQQTransaction(session, data);
|
|
935
|
+
else await sendQQPage(session, data);
|
|
875
936
|
if (this.timing) {
|
|
876
937
|
this.timing.delivery = "qq-markdown";
|
|
877
938
|
this.timing.sendMs = performance.now() - sendStartedAt;
|
|
@@ -880,7 +941,7 @@ var handelr_text = class extends handel_base {
|
|
|
880
941
|
} catch (error) {
|
|
881
942
|
this.ctx.logger.warn("QQ Markdown 发送失败,改用普通文字", error instanceof Error ? error.message : error);
|
|
882
943
|
}
|
|
883
|
-
const commands = pageCommandLines(data.pageNav);
|
|
944
|
+
const commands = !data.transaction && data.pageNav ? pageCommandLines(data.pageNav) : [];
|
|
884
945
|
await this.send(data, commands.length ? `${content.trimEnd()}
|
|
885
946
|
${commands.join("\n")}` : content);
|
|
886
947
|
return;
|
|
@@ -953,7 +1014,7 @@ var import_tsrpc = require("tsrpc");
|
|
|
953
1014
|
|
|
954
1015
|
// src/shared/bot/serviceProto.ts
|
|
955
1016
|
var serviceProto = {
|
|
956
|
-
"version":
|
|
1017
|
+
"version": 12,
|
|
957
1018
|
"services": [
|
|
958
1019
|
{
|
|
959
1020
|
"id": 0,
|
|
@@ -1088,6 +1149,14 @@ var serviceProto = {
|
|
|
1088
1149
|
},
|
|
1089
1150
|
"optional": true
|
|
1090
1151
|
},
|
|
1152
|
+
{
|
|
1153
|
+
"id": 8,
|
|
1154
|
+
"name": "transaction",
|
|
1155
|
+
"type": {
|
|
1156
|
+
"type": "Boolean"
|
|
1157
|
+
},
|
|
1158
|
+
"optional": true
|
|
1159
|
+
},
|
|
1091
1160
|
{
|
|
1092
1161
|
"id": 1,
|
|
1093
1162
|
"name": "line",
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { Session } from 'koishi';
|
|
2
2
|
import { type PageNavData } from '../../shared/face';
|
|
3
3
|
import type { MsgMessage } from '../../shared/bot/MsgMessage';
|
|
4
|
+
/** Escape server-provided lines before embedding them in native QQ Markdown. */
|
|
5
|
+
export declare function escapeMarkdown(value: string): string;
|
|
6
|
+
export declare function inlineCommandUrl(command: string): string;
|
|
4
7
|
export declare function pageCommandLines(nav: PageNavData): string[];
|
|
5
8
|
export declare function renderQQPageMarkdown(data: MsgMessage, showGreeting: boolean): string;
|
|
6
9
|
/** Returns false if this is not the matching QQ session or the adapter has no native API. */
|
|
7
10
|
export declare function canSendQQPage(session: Session | undefined, data: MsgMessage): session is Session;
|
|
8
11
|
/** Send a native QQ Markdown page with inline command links. */
|
|
9
12
|
export declare function sendQQPage(session: Session, data: MsgMessage): Promise<void>;
|
|
13
|
+
/** Reuse the adapter's native reply API for structured Markdown messages. */
|
|
14
|
+
export declare function sendQQMarkdown(session: Session, markdown: string): Promise<void>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Session } from 'koishi';
|
|
2
|
+
import type { MsgMessage } from '../../shared/bot/MsgMessage';
|
|
3
|
+
/** Render only explicitly marked transactions; line content never enables this channel. */
|
|
4
|
+
export declare function renderQQTransactionMarkdown(data: MsgMessage, showGreeting: boolean): string;
|
|
5
|
+
export declare function sendQQTransaction(session: Session, data: MsgMessage): Promise<void>;
|
|
@@ -130,6 +130,8 @@ export interface IMessage {
|
|
|
130
130
|
equipmentCard?: EquipmentCardData;
|
|
131
131
|
leaderboard?: LeaderboardImageData;
|
|
132
132
|
pageNav?: PageNavData;
|
|
133
|
+
/** 通用交易确认、结果与失败消息;客户端可使用交易 Markdown 展示。 */
|
|
134
|
+
transaction?: boolean;
|
|
133
135
|
/** 消息项列表 **/
|
|
134
136
|
line: IMessageItem[];
|
|
135
137
|
}
|
package/package.json
CHANGED
|
@@ -23,7 +23,7 @@ type QQResponse = {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/** Escape server-provided lines before embedding them in native QQ Markdown. */
|
|
26
|
-
function escapeMarkdown(value: string): string {
|
|
26
|
+
export function escapeMarkdown(value: string): string {
|
|
27
27
|
return value.replace(/[\\`*_{}\[\]()#+\-.!|>~<&]/g, '\\$&')
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -44,7 +44,7 @@ function compactListLabel(value: string): string {
|
|
|
44
44
|
: label
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
function inlineCommandUrl(command: string): string {
|
|
47
|
+
export function inlineCommandUrl(command: string): string {
|
|
48
48
|
// encodeURIComponent leaves parentheses unescaped, which would close the
|
|
49
49
|
// surrounding Markdown link if an item ID ever contained one.
|
|
50
50
|
const encoded = encodeURIComponent(command).replace(/[!'()*]/g, character =>
|
|
@@ -167,8 +167,13 @@ export function canSendQQPage(session: Session | undefined, data: MsgMessage): s
|
|
|
167
167
|
|
|
168
168
|
/** Send a native QQ Markdown page with inline command links. */
|
|
169
169
|
export async function sendQQPage(session: Session, data: MsgMessage): Promise<void> {
|
|
170
|
-
const internal = (session.bot as typeof session.bot & { internal: QQInternal }).internal
|
|
171
170
|
const markdown = renderQQPageMarkdown(data, session.event?.channel?.type === 0)
|
|
171
|
+
await sendQQMarkdown(session, markdown)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Reuse the adapter's native reply API for structured Markdown messages. */
|
|
175
|
+
export async function sendQQMarkdown(session: Session, markdown: string): Promise<void> {
|
|
176
|
+
const internal = (session.bot as typeof session.bot & { internal: QQInternal }).internal
|
|
172
177
|
const request: QQRequest = {
|
|
173
178
|
// With msg_type=2, QQ requires the ordinary content field to be empty.
|
|
174
179
|
content: '',
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Session } from 'koishi'
|
|
2
|
+
import { MessageType } from '../../shared/face'
|
|
3
|
+
import type { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
4
|
+
import { escapeMarkdown, inlineCommandUrl, sendQQMarkdown } from './qqPageMessage'
|
|
5
|
+
|
|
6
|
+
/** Render only explicitly marked transactions; line content never enables this channel. */
|
|
7
|
+
export function renderQQTransactionMarkdown(data: MsgMessage, showGreeting: boolean): string {
|
|
8
|
+
const sections: string[] = []
|
|
9
|
+
const bodyLines: string[] = []
|
|
10
|
+
const actions: string[] = []
|
|
11
|
+
const flushBody = () => {
|
|
12
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
|
|
13
|
+
}
|
|
14
|
+
const flushActions = () => {
|
|
15
|
+
if (actions.length) sections.push(actions.splice(0).join(' · '))
|
|
16
|
+
}
|
|
17
|
+
const flush = () => { flushBody(); flushActions() }
|
|
18
|
+
if (showGreeting) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
19
|
+
for (const item of data.line) {
|
|
20
|
+
if (item.type === MessageType.title) {
|
|
21
|
+
flush()
|
|
22
|
+
sections.push(`**${escapeMarkdown(item.content)}**`)
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
25
|
+
if (item.type === MessageType.error) {
|
|
26
|
+
flush()
|
|
27
|
+
sections.push(`❌ 出错了!错误原因:${escapeMarkdown(item.content)},请反馈至联系开发者`)
|
|
28
|
+
continue
|
|
29
|
+
}
|
|
30
|
+
if (item.type !== MessageType.line) continue
|
|
31
|
+
// These are the common trade actions. Names, reasons and arbitrary bracketed
|
|
32
|
+
// material text remain escaped display text rather than executable commands.
|
|
33
|
+
const action = data.transaction && (item.content === '[是]确认交易'
|
|
34
|
+
? { command: '是', label: '确认交易' }
|
|
35
|
+
: item.content === '[否]取消交易' ? { command: '否', label: '取消交易' } : undefined)
|
|
36
|
+
if (action) {
|
|
37
|
+
flushBody()
|
|
38
|
+
actions.push(`[${action.command}](${inlineCommandUrl(action.command)}) ${action.label}`)
|
|
39
|
+
continue
|
|
40
|
+
}
|
|
41
|
+
flushActions()
|
|
42
|
+
if (!item.content.trim()) {
|
|
43
|
+
flushBody()
|
|
44
|
+
continue
|
|
45
|
+
}
|
|
46
|
+
const section = /^┄━═(.+)═━┄$/.exec(item.content)
|
|
47
|
+
if (section || item.content === '【还缺】') {
|
|
48
|
+
flushBody()
|
|
49
|
+
sections.push(`**${escapeMarkdown(section?.[1] ?? '还缺')}**`)
|
|
50
|
+
} else {
|
|
51
|
+
// Preserve the server's quoted amounts, names and descriptions verbatim
|
|
52
|
+
// apart from Markdown escaping; rendering never recalculates payments.
|
|
53
|
+
bodyLines.push(escapeMarkdown(item.content))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
flush()
|
|
57
|
+
return sections.join('\n\n') || ' '
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function sendQQTransaction(session: Session, data: MsgMessage): Promise<void> {
|
|
61
|
+
await sendQQMarkdown(session, renderQQTransactionMarkdown(data, session.event?.channel?.type === 0))
|
|
62
|
+
}
|
|
@@ -3,15 +3,17 @@ import { MsgMessage } from '../../shared/bot/MsgMessage'
|
|
|
3
3
|
import sessions, { sessionKey } from '../sessions'
|
|
4
4
|
import handel_base from './handel_base'
|
|
5
5
|
import { canSendQQPage, pageCommandLines, sendQQPage } from './qqPageMessage'
|
|
6
|
+
import { sendQQTransaction } from './qqTransactionMessage'
|
|
6
7
|
|
|
7
8
|
export default class handelr_text extends handel_base {
|
|
8
9
|
async start(data: MsgMessage) {
|
|
9
10
|
const content = new AnalysisMsg().parse(data)
|
|
10
11
|
const session = sessions.get(sessionKey(data.botId, data.userId, data.channelId))
|
|
11
|
-
if (data.pageNav && canSendQQPage(session, data)) {
|
|
12
|
+
if ((data.transaction || data.pageNav) && canSendQQPage(session, data)) {
|
|
12
13
|
const sendStartedAt = this.timing ? performance.now() : 0
|
|
13
14
|
try {
|
|
14
|
-
await
|
|
15
|
+
if (data.transaction) await sendQQTransaction(session, data)
|
|
16
|
+
else await sendQQPage(session, data)
|
|
15
17
|
if (this.timing) {
|
|
16
18
|
this.timing.delivery = 'qq-markdown'
|
|
17
19
|
this.timing.sendMs = performance.now() - sendStartedAt
|
|
@@ -20,7 +22,7 @@ export default class handelr_text extends handel_base {
|
|
|
20
22
|
} catch (error) {
|
|
21
23
|
this.ctx.logger.warn('QQ Markdown 发送失败,改用普通文字', error instanceof Error ? error.message : error)
|
|
22
24
|
}
|
|
23
|
-
const commands = pageCommandLines(data.pageNav)
|
|
25
|
+
const commands = !data.transaction && data.pageNav ? pageCommandLines(data.pageNav) : []
|
|
24
26
|
await this.send(data, commands.length ? `${content.trimEnd()}\n${commands.join('\n')}` : content)
|
|
25
27
|
return
|
|
26
28
|
}
|
|
@@ -20,7 +20,7 @@ export interface ServiceType {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const serviceProto: ServiceProto<ServiceType> = {
|
|
23
|
-
"version":
|
|
23
|
+
"version": 12,
|
|
24
24
|
"services": [
|
|
25
25
|
{
|
|
26
26
|
"id": 0,
|
|
@@ -155,6 +155,14 @@ export const serviceProto: ServiceProto<ServiceType> = {
|
|
|
155
155
|
},
|
|
156
156
|
"optional": true
|
|
157
157
|
},
|
|
158
|
+
{
|
|
159
|
+
"id": 8,
|
|
160
|
+
"name": "transaction",
|
|
161
|
+
"type": {
|
|
162
|
+
"type": "Boolean"
|
|
163
|
+
},
|
|
164
|
+
"optional": true
|
|
165
|
+
},
|
|
158
166
|
{
|
|
159
167
|
"id": 1,
|
|
160
168
|
"name": "line",
|
package/src/shared/face/index.ts
CHANGED
|
@@ -103,6 +103,8 @@ export interface IMessage {
|
|
|
103
103
|
equipmentCard?: EquipmentCardData;
|
|
104
104
|
leaderboard?: LeaderboardImageData;
|
|
105
105
|
pageNav?: PageNavData;
|
|
106
|
+
/** 通用交易确认、结果与失败消息;客户端可使用交易 Markdown 展示。 */
|
|
107
|
+
transaction?: boolean;
|
|
106
108
|
/** 消息项列表 **/
|
|
107
109
|
line: IMessageItem[];
|
|
108
110
|
}
|