@lumachat/lumachat 0.15.2 → 0.15.3
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/README.md +13 -3
- package/openclaw.plugin.json +3 -2
- package/package.json +5 -5
- package/src/index.ts +56 -38
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
该目录包含 LumaChat 的 OpenClaw 通道插件实现。
|
|
4
4
|
|
|
5
5
|
## 已实现功能
|
|
6
|
-
- 完整配对流程(请求配对码+安全码、轮询状态、保存 token 到 `channels.clawdchat`)。
|
|
6
|
+
- 完整配对流程(请求配对码+安全码、轮询状态、保存 token 到 `channels.lumachat`,兼容读取 `channels.clawdchat`)。
|
|
7
7
|
- 与 LumaChat 后端保持 WebSocket 长连接。
|
|
8
8
|
- 入站消息接入(LumaChat -> OpenClaw),按 `request_id` 回传回复。
|
|
9
9
|
- CLI 配对入口(`openclaw channels login --channel lumachat`)。
|
|
@@ -22,7 +22,7 @@ corepack prepare pnpm@latest --activate
|
|
|
22
22
|
|
|
23
23
|
安装插件:
|
|
24
24
|
```
|
|
25
|
-
openclaw plugins install @lumachat/lumachat@0.15.
|
|
25
|
+
openclaw plugins install @lumachat/lumachat@0.15.2
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## 更新
|
|
@@ -40,9 +40,17 @@ openclaw plugins install @lumachat/lumachat@0.15.0
|
|
|
40
40
|
- 支持返回并展示 6 位安全码(pairing confirm code),与 App 双码配对流程保持一致。
|
|
41
41
|
- 补齐 clawdchat 消息目标解析(`chat:<uuid>` / `clawdchat:<uuid>`),避免 `Unknown target` 导致回复丢失。
|
|
42
42
|
|
|
43
|
+
### 0.15.1
|
|
44
|
+
- 修复 `openclaw plugins install @lumachat/lumachat` 后配置校验 `plugin not found: lumachat` 的问题。
|
|
45
|
+
- 插件 ID 迁移为 `lumachat`,并保持对旧 ID `clawdchat` 的兼容读取。
|
|
46
|
+
- 若本地历史配置里存在 `plugins.entries.clawdchat`,请删除该键并改为 `plugins.entries.lumachat`。
|
|
47
|
+
|
|
48
|
+
### 0.15.2
|
|
49
|
+
- 发布 `@lumachat/lumachat@0.15.2`,作为当前稳定安装版本。
|
|
50
|
+
|
|
43
51
|
升级:
|
|
44
52
|
```
|
|
45
|
-
openclaw plugins install @lumachat/lumachat@0.15.
|
|
53
|
+
openclaw plugins install @lumachat/lumachat@0.15.2
|
|
46
54
|
```
|
|
47
55
|
|
|
48
56
|
## 配对流程(当前)
|
|
@@ -52,6 +60,8 @@ openclaw plugins install @lumachat/lumachat@0.15.0
|
|
|
52
60
|
4. 插件会保存通道 token 并自动连接后端。
|
|
53
61
|
|
|
54
62
|
## 可选配置
|
|
63
|
+
- `LUMACHAT_API_BASE_URL`:覆盖后端地址(默认:`https://api-love2.huaizuo2029.cn`;本地开发可设为 `http://127.0.0.1:8000`)。
|
|
64
|
+
- `LUMACHAT_CHANNEL_KEY` / `LUMACHAT_SHARED_KEY`:当后端要求 `X-Clawdchat-Channel-Key` 时使用。
|
|
55
65
|
- `CLAWDCHAT_API_BASE_URL`:覆盖后端地址(默认:`https://api-love2.huaizuo2029.cn`;本地开发可设为 `http://127.0.0.1:8000`)。
|
|
56
66
|
- `CLAWDCHAT_CHANNEL_KEY` / `CLAWDCHAT_SHARED_KEY`:当后端要求 `X-Clawdchat-Channel-Key` 时使用。
|
|
57
67
|
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumachat/lumachat",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.3",
|
|
4
4
|
"description": "LumaChat channel plugin for OpenClaw",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
"./src/index.ts"
|
|
22
22
|
],
|
|
23
23
|
"channel": {
|
|
24
|
-
"id": "
|
|
24
|
+
"id": "lumachat",
|
|
25
25
|
"label": "LumaChat",
|
|
26
26
|
"selectionLabel": "LumaChat (配对码)",
|
|
27
|
-
"docsPath": "/channels/
|
|
27
|
+
"docsPath": "/channels/lumachat",
|
|
28
28
|
"blurb": "通过配对码把 Clawdbot 接入 LumaChat。",
|
|
29
29
|
"aliases": [
|
|
30
|
-
"
|
|
31
|
-
"
|
|
30
|
+
"lumachat",
|
|
31
|
+
"clawdchat"
|
|
32
32
|
]
|
|
33
33
|
},
|
|
34
34
|
"install": {
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,8 @@ const RECONNECT_BASE_MS = 2_000;
|
|
|
17
17
|
const RECONNECT_MAX_MS = 20_000;
|
|
18
18
|
const PAIRING_POLL_INTERVAL_MS = 2_000;
|
|
19
19
|
const PAIRING_WAIT_TIMEOUT_MS = 10 * 60 * 1000;
|
|
20
|
+
const CHANNEL_ID = "lumachat";
|
|
21
|
+
const LEGACY_CHANNEL_ID = "clawdchat";
|
|
20
22
|
|
|
21
23
|
const HEADER_CHANNEL_KEY = "X-Clawdchat-Channel-Key";
|
|
22
24
|
const HEADER_PAIRING_SECRET = "X-Pairing-Secret";
|
|
@@ -83,15 +85,18 @@ const normalizeValue = (value?: string | null): string | undefined => {
|
|
|
83
85
|
};
|
|
84
86
|
|
|
85
87
|
const resolveClawdchatSection = (cfg: OpenClawConfig): ClawdchatConfigSection =>
|
|
86
|
-
(cfg.channels?.clawdchat ?? {}) as ClawdchatConfigSection;
|
|
88
|
+
(cfg.channels?.lumachat ?? cfg.channels?.clawdchat ?? {}) as ClawdchatConfigSection;
|
|
87
89
|
|
|
88
90
|
const resolveBaseUrl = (cfg: OpenClawConfig): string =>
|
|
89
91
|
normalizeValue(resolveClawdchatSection(cfg).baseUrl) ??
|
|
92
|
+
normalizeValue(process.env.LUMACHAT_API_BASE_URL) ??
|
|
90
93
|
normalizeValue(process.env.CLAWDCHAT_API_BASE_URL) ??
|
|
91
94
|
DEFAULT_BASE_URL;
|
|
92
95
|
|
|
93
96
|
const resolveSharedKey = (cfg: OpenClawConfig): string | undefined =>
|
|
94
97
|
normalizeValue(resolveClawdchatSection(cfg).sharedKey) ??
|
|
98
|
+
normalizeValue(process.env.LUMACHAT_CHANNEL_KEY) ??
|
|
99
|
+
normalizeValue(process.env.LUMACHAT_SHARED_KEY) ??
|
|
95
100
|
normalizeValue(process.env.CLAWDCHAT_CHANNEL_KEY) ??
|
|
96
101
|
normalizeValue(process.env.CLAWDCHAT_SHARED_KEY);
|
|
97
102
|
|
|
@@ -101,7 +106,7 @@ const buildConfigPatch = (cfg: OpenClawConfig, patch: Partial<ClawdchatConfigSec
|
|
|
101
106
|
...cfg,
|
|
102
107
|
channels: {
|
|
103
108
|
...cfg.channels,
|
|
104
|
-
|
|
109
|
+
lumachat: {
|
|
105
110
|
...current,
|
|
106
111
|
...patch,
|
|
107
112
|
},
|
|
@@ -111,14 +116,17 @@ const buildConfigPatch = (cfg: OpenClawConfig, patch: Partial<ClawdchatConfigSec
|
|
|
111
116
|
|
|
112
117
|
const removeClawdchatFields = (cfg: OpenClawConfig, fields: Array<keyof ClawdchatConfigSection>) => {
|
|
113
118
|
const current = { ...resolveClawdchatSection(cfg) } as Record<string, unknown>;
|
|
119
|
+
const legacy = { ...(cfg.channels?.clawdchat ?? {}) } as Record<string, unknown>;
|
|
114
120
|
for (const field of fields) {
|
|
115
121
|
delete current[field as string];
|
|
122
|
+
delete legacy[field as string];
|
|
116
123
|
}
|
|
117
124
|
return {
|
|
118
125
|
...cfg,
|
|
119
126
|
channels: {
|
|
120
127
|
...cfg.channels,
|
|
121
|
-
|
|
128
|
+
lumachat: current,
|
|
129
|
+
clawdchat: legacy,
|
|
122
130
|
},
|
|
123
131
|
} as OpenClawConfig;
|
|
124
132
|
};
|
|
@@ -204,7 +212,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
204
212
|
const resolveAccount = (cfg: OpenClawConfig, accountId?: string | null): ResolvedClawdchatAccount => {
|
|
205
213
|
const section = resolveClawdchatSection(cfg);
|
|
206
214
|
const resolvedId = accountId ?? DEFAULT_ACCOUNT_ID;
|
|
207
|
-
const name = section.name?.trim() || "
|
|
215
|
+
const name = section.name?.trim() || "LumaChat";
|
|
208
216
|
return {
|
|
209
217
|
accountId: resolvedId,
|
|
210
218
|
name,
|
|
@@ -299,18 +307,18 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
299
307
|
};
|
|
300
308
|
|
|
301
309
|
if (!requestId || !conversationId || !content) {
|
|
302
|
-
await respondError("invalid_message", "Invalid
|
|
310
|
+
await respondError("invalid_message", "Invalid lumachat payload.");
|
|
303
311
|
return;
|
|
304
312
|
}
|
|
305
313
|
|
|
306
314
|
const timestampMs = payload.timestamp ? Date.parse(payload.timestamp) : Date.now();
|
|
307
315
|
const route = api.runtime.channel.routing.resolveAgentRoute({
|
|
308
316
|
cfg,
|
|
309
|
-
channel:
|
|
317
|
+
channel: CHANNEL_ID,
|
|
310
318
|
peer: { kind: "dm", id: conversationId },
|
|
311
319
|
});
|
|
312
320
|
|
|
313
|
-
const senderLabel =
|
|
321
|
+
const senderLabel = `${CHANNEL_ID}:${conversationId}`;
|
|
314
322
|
const storePath = api.runtime.channel.session.resolveStorePath(cfg.session?.store, {
|
|
315
323
|
agentId: route.agentId,
|
|
316
324
|
});
|
|
@@ -320,7 +328,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
320
328
|
});
|
|
321
329
|
const envelopeOptions = api.runtime.channel.reply.resolveEnvelopeFormatOptions(cfg);
|
|
322
330
|
const body = api.runtime.channel.reply.formatAgentEnvelope({
|
|
323
|
-
channel: "
|
|
331
|
+
channel: "LumaChat",
|
|
324
332
|
from: senderLabel,
|
|
325
333
|
timestamp: timestampMs,
|
|
326
334
|
previousTimestamp,
|
|
@@ -340,13 +348,13 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
340
348
|
ConversationLabel: senderLabel,
|
|
341
349
|
SenderName: senderLabel,
|
|
342
350
|
SenderId: conversationId,
|
|
343
|
-
Provider:
|
|
344
|
-
Surface:
|
|
351
|
+
Provider: CHANNEL_ID as const,
|
|
352
|
+
Surface: CHANNEL_ID as const,
|
|
345
353
|
MessageSid: requestId,
|
|
346
354
|
Timestamp: timestampMs,
|
|
347
355
|
CommandAuthorized: true,
|
|
348
356
|
CommandSource: "text" as const,
|
|
349
|
-
OriginatingChannel:
|
|
357
|
+
OriginatingChannel: CHANNEL_ID as const,
|
|
350
358
|
OriginatingTo: `chat:${conversationId}`,
|
|
351
359
|
});
|
|
352
360
|
|
|
@@ -394,7 +402,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
394
402
|
}
|
|
395
403
|
},
|
|
396
404
|
onError: (err) => {
|
|
397
|
-
log?.warn?.(`
|
|
405
|
+
log?.warn?.(`lumachat reply error: ${String(err)}`);
|
|
398
406
|
},
|
|
399
407
|
});
|
|
400
408
|
|
|
@@ -420,7 +428,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
420
428
|
}
|
|
421
429
|
}
|
|
422
430
|
} catch (err) {
|
|
423
|
-
log?.error?.(`
|
|
431
|
+
log?.error?.(`lumachat dispatch failed: ${String(err)}`);
|
|
424
432
|
await respondError("assistant_unavailable", "Assistant unavailable.");
|
|
425
433
|
}
|
|
426
434
|
};
|
|
@@ -466,7 +474,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
466
474
|
heartbeat = setInterval(() => {
|
|
467
475
|
sendJson(socket, { type: "heartbeat" }).catch(() => undefined);
|
|
468
476
|
}, HEARTBEAT_INTERVAL_MS);
|
|
469
|
-
log?.info?.("
|
|
477
|
+
log?.info?.("lumachat channel connected");
|
|
470
478
|
});
|
|
471
479
|
|
|
472
480
|
socket.on("message", (data) => {
|
|
@@ -475,7 +483,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
475
483
|
try {
|
|
476
484
|
payload = JSON.parse(text) as InboundPayload;
|
|
477
485
|
} catch (err) {
|
|
478
|
-
log?.warn?.(`
|
|
486
|
+
log?.warn?.(`lumachat payload parse error: ${String(err)}`);
|
|
479
487
|
return;
|
|
480
488
|
}
|
|
481
489
|
if (payload.type === "heartbeat") {
|
|
@@ -495,7 +503,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
495
503
|
});
|
|
496
504
|
|
|
497
505
|
socket.on("error", (err) => {
|
|
498
|
-
log?.warn?.(`
|
|
506
|
+
log?.warn?.(`lumachat socket error: ${String(err)}`);
|
|
499
507
|
});
|
|
500
508
|
|
|
501
509
|
socket.on("close", (code, reason) => {
|
|
@@ -503,7 +511,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
503
511
|
signal.removeEventListener("abort", abortHandler);
|
|
504
512
|
update({ running: false, lastStopAt: new Date().toISOString() });
|
|
505
513
|
const reasonText = reason?.toString?.() ?? "";
|
|
506
|
-
log?.warn?.(`
|
|
514
|
+
log?.warn?.(`lumachat channel closed (${code}) ${reasonText}`);
|
|
507
515
|
resolve();
|
|
508
516
|
});
|
|
509
517
|
|
|
@@ -557,14 +565,14 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
557
565
|
};
|
|
558
566
|
|
|
559
567
|
return {
|
|
560
|
-
id:
|
|
568
|
+
id: CHANNEL_ID,
|
|
561
569
|
meta: {
|
|
562
|
-
id:
|
|
563
|
-
label: "
|
|
564
|
-
selectionLabel: "
|
|
565
|
-
docsPath: "/channels/
|
|
566
|
-
blurb: "Pair
|
|
567
|
-
aliases: [
|
|
570
|
+
id: CHANNEL_ID,
|
|
571
|
+
label: "LumaChat",
|
|
572
|
+
selectionLabel: "LumaChat (pair code)",
|
|
573
|
+
docsPath: "/channels/lumachat",
|
|
574
|
+
blurb: "Pair LumaChat with a 6-digit code.",
|
|
575
|
+
aliases: [CHANNEL_ID, LEGACY_CHANNEL_ID],
|
|
568
576
|
},
|
|
569
577
|
capabilities: {
|
|
570
578
|
chatTypes: ["direct"],
|
|
@@ -580,7 +588,10 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
580
588
|
if (!trimmed) return undefined;
|
|
581
589
|
const lower = trimmed.toLowerCase();
|
|
582
590
|
if (lower.startsWith("chat:")) return trimmed;
|
|
583
|
-
if (lower.startsWith(
|
|
591
|
+
if (lower.startsWith(`${CHANNEL_ID}:`)) return `chat:${trimmed.slice(`${CHANNEL_ID}:`.length)}`;
|
|
592
|
+
if (lower.startsWith(`${LEGACY_CHANNEL_ID}:`)) {
|
|
593
|
+
return `chat:${trimmed.slice(`${LEGACY_CHANNEL_ID}:`.length)}`;
|
|
594
|
+
}
|
|
584
595
|
if (UUID_REGEX.test(trimmed)) return `chat:${trimmed}`;
|
|
585
596
|
return undefined;
|
|
586
597
|
},
|
|
@@ -588,13 +599,20 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
588
599
|
looksLikeId: (raw, normalized) => {
|
|
589
600
|
const lower = raw.trim().toLowerCase();
|
|
590
601
|
if (!lower) return false;
|
|
591
|
-
if (
|
|
602
|
+
if (
|
|
603
|
+
lower.startsWith("chat:") ||
|
|
604
|
+
lower.startsWith(`${CHANNEL_ID}:`) ||
|
|
605
|
+
lower.startsWith(`${LEGACY_CHANNEL_ID}:`)
|
|
606
|
+
) {
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
592
609
|
if (UUID_REGEX.test(lower)) return true;
|
|
593
610
|
return Boolean(normalized && normalized.toLowerCase().startsWith("chat:"));
|
|
594
611
|
},
|
|
595
|
-
hint: "使用
|
|
612
|
+
hint: "使用 lumachat 会话 ID(形如 chat:<uuid>)。",
|
|
596
613
|
},
|
|
597
|
-
formatTargetDisplay: ({ target }) =>
|
|
614
|
+
formatTargetDisplay: ({ target }) =>
|
|
615
|
+
target.replace(/^chat:/i, "").replace(/^lumachat:/i, "").replace(/^clawdchat:/i, ""),
|
|
598
616
|
},
|
|
599
617
|
config: {
|
|
600
618
|
listAccountIds: () => [DEFAULT_ACCOUNT_ID],
|
|
@@ -616,7 +634,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
616
634
|
outbound: {
|
|
617
635
|
deliveryMode: "direct",
|
|
618
636
|
sendText: async () => {
|
|
619
|
-
throw new Error("
|
|
637
|
+
throw new Error("LumaChat outbound is only supported for inbound replies.");
|
|
620
638
|
},
|
|
621
639
|
},
|
|
622
640
|
status: {
|
|
@@ -632,10 +650,10 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
632
650
|
for (const account of accounts) {
|
|
633
651
|
if (!account.configured) {
|
|
634
652
|
issues.push({
|
|
635
|
-
channel:
|
|
653
|
+
channel: CHANNEL_ID,
|
|
636
654
|
accountId: account.accountId ?? DEFAULT_ACCOUNT_ID,
|
|
637
655
|
kind: "config",
|
|
638
|
-
message: "
|
|
656
|
+
message: "LumaChat channel not paired",
|
|
639
657
|
});
|
|
640
658
|
}
|
|
641
659
|
}
|
|
@@ -673,7 +691,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
673
691
|
const cfg = api.runtime.config.loadConfig();
|
|
674
692
|
const account = resolveAccount(cfg, resolvedId);
|
|
675
693
|
if (account.channelToken && !force) {
|
|
676
|
-
return { message: "
|
|
694
|
+
return { message: "LumaChat already paired." };
|
|
677
695
|
}
|
|
678
696
|
const baseUrl = account.baseUrl;
|
|
679
697
|
const sharedKey = account.sharedKey;
|
|
@@ -718,7 +736,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
718
736
|
});
|
|
719
737
|
await api.runtime.config.writeConfigFile(nextCfg);
|
|
720
738
|
pairingSessions.delete(resolvedId);
|
|
721
|
-
return { connected: true, message: "
|
|
739
|
+
return { connected: true, message: "LumaChat paired." };
|
|
722
740
|
}
|
|
723
741
|
if (status.status === "expired") {
|
|
724
742
|
pairingSessions.delete(resolvedId);
|
|
@@ -744,7 +762,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
744
762
|
const warn = runtime.error ?? console.warn;
|
|
745
763
|
|
|
746
764
|
if (account.channelToken) {
|
|
747
|
-
log("
|
|
765
|
+
log("LumaChat 已配对。若需重新配对,请先执行 `openclaw channels logout --channel lumachat`。");
|
|
748
766
|
return;
|
|
749
767
|
}
|
|
750
768
|
|
|
@@ -755,9 +773,9 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
755
773
|
if (!pairing.pairingId || !pairing.pairingCode || !pairing.pairingConfirmCode || !pairing.pairingSecret) {
|
|
756
774
|
throw new Error("Failed to request pairing code.");
|
|
757
775
|
}
|
|
758
|
-
log(`
|
|
759
|
-
log(`
|
|
760
|
-
log("请在
|
|
776
|
+
log(`LumaChat 配对码:${pairing.pairingCode}`);
|
|
777
|
+
log(`LumaChat 安全码:${pairing.pairingConfirmCode}`);
|
|
778
|
+
log("请在 LumaChat App -> 设置 -> Clawdbot 配对 中输入配对码与安全码。");
|
|
761
779
|
|
|
762
780
|
const session: PairingSession = {
|
|
763
781
|
accountId: resolvedId,
|
|
@@ -787,7 +805,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
|
|
|
787
805
|
pairedAt: new Date().toISOString(),
|
|
788
806
|
});
|
|
789
807
|
await api.runtime.config.writeConfigFile(nextCfg);
|
|
790
|
-
log("
|
|
808
|
+
log("LumaChat 配对成功。");
|
|
791
809
|
return;
|
|
792
810
|
}
|
|
793
811
|
if (status.status === "expired") {
|