mioku-plugin-meme 3.0.0 → 3.0.2

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/index.ts CHANGED
@@ -42,8 +42,6 @@ function stripCommandPrefix(
42
42
 
43
43
  const memePlugin = definePlugin({
44
44
  name: "meme",
45
- version: "1.0.0",
46
- description: "基于 meme-generator API 的表情包制作插件",
47
45
 
48
46
  async setup(ctx: MiokuContext) {
49
47
  const configService = getService(ctx, Services.Config);
@@ -147,6 +145,96 @@ const memePlugin = definePlugin({
147
145
  );
148
146
  }
149
147
 
148
+ ctx.command({
149
+ name: "/meme 菜单",
150
+ match: /^(?:(?:表情|meme)包?(?:菜单|展示|制作(?:列表)?)|meme\s+(?:菜单|列表|展示))$/i,
151
+ prefixes: baseConfig.trigger.prefixes,
152
+ description: "查看已同步的表情菜单",
153
+ usage: "/meme 菜单",
154
+ handler: ({ event }) => runtime.sendMenu(ctx, event),
155
+ });
156
+ ctx.command({
157
+ name: "/随机表情",
158
+ match: /^随机(?:表情|meme)(?:包)?$/i,
159
+ prefixes: baseConfig.trigger.prefixes,
160
+ description: "随机生成一个头像类表情",
161
+ usage: "/随机表情",
162
+ handler: ({ event }) => runtime.sendRandom(ctx, event),
163
+ });
164
+ ctx.command({
165
+ name: "/meme 帮助",
166
+ match: /^(?:(?:头像|文字)?(?:表情|meme)包?(?:制作(?:菜单|教程)?|帮助|说明|指令|使用说明)|(?:头像|文字)(?:表情|meme)包?|meme\s+帮助)$/i,
167
+ prefixes: baseConfig.trigger.prefixes,
168
+ description: "查看表情制作教程与参数说明",
169
+ usage: "/meme 帮助",
170
+ handler: ({ event }) => runtime.sendHelp(ctx, event),
171
+ });
172
+ ctx.command({
173
+ name: "/meme 搜索",
174
+ match: /^(?:表情|meme)包?(?:搜索|检索)\s*(.*)$/i,
175
+ prefixes: baseConfig.trigger.prefixes,
176
+ description: "搜索相关表情关键词",
177
+ usage: "/meme 搜索 摸",
178
+ handler: async ({ event, match }) => {
179
+ const query = String(match?.[1] ?? "").trim();
180
+ if (!query) {
181
+ await notifyByAIRuntime(
182
+ event,
183
+ "用户发起了 meme 搜索但没有给关键词。请自然提醒他补一个搜索词",
184
+ "你想搜什么?",
185
+ );
186
+ return;
187
+ }
188
+ await runtime.sendSearch(ctx, event, query);
189
+ },
190
+ });
191
+ ctx.command({
192
+ name: "/meme 详情",
193
+ match: /^meme包?\s+详情\s+(.+)$/i,
194
+ prefixes: baseConfig.trigger.prefixes,
195
+ description: "查看表情参数和预览",
196
+ usage: "/meme 详情 摸头",
197
+ handler: async ({ event, match }) => {
198
+ const keyword = String(match?.[1] ?? "").trim();
199
+ if (!runtime.getDetail(keyword)) {
200
+ await notifyByAIRuntime(
201
+ event,
202
+ `用户查询了不存在的表情详情关键词 "${keyword}"。请自然提醒先搜索可用关键词`,
203
+ `未找到表情关键词:${keyword}`,
204
+ );
205
+ return;
206
+ }
207
+ await runtime.sendDetail(ctx, event, keyword);
208
+ },
209
+ });
210
+ ctx.command({
211
+ name: "/meme 更新",
212
+ match: /^(?:(?:表情|meme)包?更新|meme\s+更新)$/i,
213
+ prefixes: baseConfig.trigger.prefixes,
214
+ permission: baseConfig.permissions.ownerOnlyUpdate ? "master" : "member",
215
+ description: "刷新远端表情缓存",
216
+ usage: "/meme 更新",
217
+ handler: async ({ event }) => {
218
+ await replyWithParts({
219
+ ctx,
220
+ event,
221
+ parts: ["开始刷新 meme 缓存,请稍等..."],
222
+ quoteReply: baseConfig.behavior.quoteReply,
223
+ });
224
+ try {
225
+ await runtime.refreshCache();
226
+ await runtime.sendMenu(ctx, event);
227
+ } catch (error) {
228
+ await notifyByAIRuntime(
229
+ event,
230
+ `meme 缓存刷新失败,错误信息:${error}。请自然告知用户稍后重试或让管理员检查 meme API 服务状态。`,
231
+ `刷新 meme 缓存失败:${error}`,
232
+ error,
233
+ );
234
+ }
235
+ },
236
+ });
237
+
150
238
  ctx.handle("message", async (event) => {
151
239
  const rawText = ctx.text(event)?.trim();
152
240
  if (!rawText) {
@@ -169,99 +257,6 @@ const memePlugin = definePlugin({
169
257
  : rawText;
170
258
 
171
259
  try {
172
- if (
173
- commandText &&
174
- (/^(?:表情|meme)包?(?:菜单|展示|制作(?:列表)?)$/i.test(commandText) ||
175
- /^meme\s+(?:菜单|列表|展示)$/i.test(commandText))
176
- ) {
177
- await runtime.sendMenu(ctx, event);
178
- return;
179
- }
180
-
181
- if (commandText && /^随机(?:表情|meme)(?:包)?$/i.test(commandText)) {
182
- await runtime.sendRandom(ctx, event);
183
- return;
184
- }
185
-
186
- if (
187
- commandText &&
188
- (/^(?:(?:头像|文字)?(?:表情|meme)包?(?:制作(?:菜单|教程)?|帮助|说明|指令|使用说明)|(?:头像|文字)(?:表情|meme)包?)$/i.test(
189
- commandText,
190
- ) ||
191
- /^meme\s+帮助$/i.test(commandText))
192
- ) {
193
- await runtime.sendHelp(ctx, event);
194
- return;
195
- }
196
-
197
- const searchMatch = commandText.match(
198
- /^(?:表情|meme)包?(?:搜索|检索)\s*(.*)$/i,
199
- );
200
- if (searchMatch) {
201
- const query = (searchMatch[1] || "").trim();
202
- if (!query) {
203
- await notifyByAIRuntime(
204
- event,
205
- "用户发起了 meme 搜索但没有给关键词。请自然提醒他补一个搜索词",
206
- "你想搜什么?",
207
- );
208
- return;
209
- }
210
- await runtime.sendSearch(ctx, event, query);
211
- return;
212
- }
213
-
214
- const detailCommandMatch =
215
- commandText.match(/^meme包?\s+详情\s+(.+)$/i);
216
- if (detailCommandMatch) {
217
- const keyword = detailCommandMatch[1].trim();
218
- if (!runtime.getDetail(keyword)) {
219
- await notifyByAIRuntime(
220
- event,
221
- `用户查询了不存在的表情详情关键词 "${keyword}"。请自然提醒先搜索可用关键词`,
222
- `未找到表情关键词:${keyword}`,
223
- );
224
- return;
225
- }
226
- await runtime.sendDetail(ctx, event, keyword);
227
- return;
228
- }
229
-
230
- if (
231
- commandText &&
232
- (/^(?:表情|meme)包?更新$/i.test(commandText) ||
233
- /^meme\s+更新$/i.test(commandText))
234
- ) {
235
- if (baseConfig.permissions.ownerOnlyUpdate && !ctx.isOwner(event)) {
236
- await notifyByAIRuntime(
237
- event,
238
- "用户尝试刷新 meme 缓存,但权限不足。请自然提醒该操作仅主人可用",
239
- "不支持小男娘使用喵",
240
- );
241
- return;
242
- }
243
-
244
- await replyWithParts({
245
- ctx,
246
- event,
247
- parts: ["开始刷新 meme 缓存,请稍等..."],
248
- quoteReply: baseConfig.behavior.quoteReply,
249
- });
250
-
251
- try {
252
- await runtime.refreshCache();
253
- await runtime.sendMenu(ctx, event);
254
- } catch (error) {
255
- await notifyByAIRuntime(
256
- event,
257
- `meme 缓存刷新失败,错误信息:${error}。请自然告知用户稍后重试或让管理员检查 meme API 服务状态。`,
258
- `刷新 meme 缓存失败:${error}`,
259
- error,
260
- );
261
- }
262
- return;
263
- }
264
-
265
260
  const genericGenerateMatch = commandText.match(
266
261
  /^meme包?\s+(?:生成|制作)\s+(.+)$/i,
267
262
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mioku-plugin-meme",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "基于 meme-generator API 的表情包制作插件",
5
5
  "main": "index.ts",
6
6
  "type": "module",
@@ -15,71 +15,7 @@
15
15
  "services": [
16
16
  "config",
17
17
  "ai"
18
- ],
19
- "accessHooks": [
20
- {
21
- "id": "meme-菜单",
22
- "match": "/^\\/meme\\s*菜单/"
23
- },
24
- {
25
- "id": "meme-搜索",
26
- "match": "/^\\/meme\\s*搜索/"
27
- },
28
- {
29
- "id": "meme-详情",
30
- "match": "/^\\/meme\\s*详情/"
31
- },
32
- {
33
- "id": "meme-更新",
34
- "match": "/^\\/meme\\s*更新/"
35
- },
36
- {
37
- "id": "随机表情",
38
- "match": "/^\\/随机表情/"
39
- }
40
- ],
41
- "help": {
42
- "title": "Meme 表情包",
43
- "description": "接入 meme-generator API 的表情包制作插件",
44
- "commands": [
45
- {
46
- "cmd": "/meme 菜单",
47
- "desc": "查看已同步的表情菜单",
48
- "usage": "/meme 菜单",
49
- "role": "member"
50
- },
51
- {
52
- "cmd": "/meme 搜索 <关键词>",
53
- "desc": "搜索相关表情关键词",
54
- "usage": "/meme 搜索 摸",
55
- "role": "member"
56
- },
57
- {
58
- "cmd": "/meme 详情 <关键词>",
59
- "desc": "查看表情参数和预览",
60
- "usage": "/meme 详情 摸头",
61
- "role": "member"
62
- },
63
- {
64
- "cmd": "/随机表情",
65
- "desc": "随机生成一个头像类表情",
66
- "usage": "/随机表情",
67
- "role": "member"
68
- },
69
- {
70
- "cmd": "<表情关键词> [文本1/文本2][#参数]",
71
- "desc": "直接按关键词生成表情",
72
- "usage": "摸头 小明#圆",
73
- "role": "member"
74
- },
75
- {
76
- "cmd": "/meme 更新",
77
- "desc": "刷新远端表情缓存",
78
- "usage": "/meme 更新",
79
- "role": "master"
80
- }
81
- ]
82
- }
18
+ ]
83
19
  },
84
20
  "peerDependencies": {
85
21
  "mioku": "^1.0.0"
package/shared.ts CHANGED
@@ -914,8 +914,8 @@ export class MemePluginRuntime {
914
914
  }
915
915
 
916
916
  if (sourceType === "message_image") {
917
- const messageId = Number(source?.messageId);
918
- if (!Number.isFinite(messageId) || messageId <= 0) {
917
+ const messageId = String(source?.messageId ?? "").trim();
918
+ if (!messageId) {
919
919
  return [];
920
920
  }
921
921
  const imageUrl = await this.getImageUrlByMessageId(ctx, event, messageId);
@@ -959,7 +959,7 @@ export class MemePluginRuntime {
959
959
  private async getImageUrlByMessageId(
960
960
  ctx: any,
961
961
  event: any,
962
- messageId: number,
962
+ messageId: string | number,
963
963
  ): Promise<string | null> {
964
964
  try {
965
965
  const bot = event?.bot;
package/skills/meme.ts CHANGED
@@ -33,8 +33,8 @@ function parseImageSource(args: any): {
33
33
  }
34
34
 
35
35
  if (sourceType === "message_image") {
36
- const messageId = Number(args?.message_id);
37
- if (!Number.isFinite(messageId) || messageId <= 0) {
36
+ const messageId = String(args?.message_id ?? "").trim();
37
+ if (!messageId) {
38
38
  return {
39
39
  ok: false,
40
40
  message: "source_type=message_image 时必须提供有效的 message_id。",
@@ -114,9 +114,9 @@ export function createMemeSkills(runtime: MemePluginRuntime): AISkill[] {
114
114
  description: "source_type=user_avatar 时必填,头像对应 QQ 号",
115
115
  },
116
116
  message_id: {
117
- type: "number",
117
+ type: ["number", "string"],
118
118
  description:
119
- "source_type=message_image 时必填,包含图片的消息 message_id",
119
+ "source_type=message_image 时必填,包含图片的消息 message_id(支持数字或含字母的字符串 id)",
120
120
  },
121
121
  },
122
122
  required: ["keyword", "source_type"],
package/types.ts CHANGED
@@ -43,7 +43,7 @@ export type MemeImageSourceType = "auto" | "user_avatar" | "message_image";
43
43
  export interface MemeImageSourceOptions {
44
44
  type?: MemeImageSourceType;
45
45
  qq?: number;
46
- messageId?: number;
46
+ messageId?: number | string;
47
47
  }
48
48
 
49
49
  export interface MemeInfoParams {