gewe-openclaw 2026.1.29

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.
@@ -0,0 +1,74 @@
1
+ const DEFAULT_MIN_DELAY_MS = 3000;
2
+ const DEFAULT_MAX_DELAY_MS = 10000;
3
+ const DEDUPE_TTL_MS = 12 * 60 * 60 * 1000;
4
+
5
+ export type GeweDownloadJob = {
6
+ key: string;
7
+ run: () => Promise<void>;
8
+ };
9
+
10
+ export class GeweDownloadQueue {
11
+ private readonly queue: GeweDownloadJob[] = [];
12
+ private readonly seen = new Map<string, number>();
13
+ private running = false;
14
+ private minDelayMs: number;
15
+ private maxDelayMs: number;
16
+
17
+ constructor(opts?: { minDelayMs?: number; maxDelayMs?: number }) {
18
+ this.minDelayMs = opts?.minDelayMs ?? DEFAULT_MIN_DELAY_MS;
19
+ this.maxDelayMs = opts?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;
20
+ }
21
+
22
+ updateDelayRange(minDelayMs?: number, maxDelayMs?: number) {
23
+ if (typeof minDelayMs === "number" && minDelayMs >= 0) {
24
+ this.minDelayMs = minDelayMs;
25
+ }
26
+ if (typeof maxDelayMs === "number" && maxDelayMs >= 0) {
27
+ this.maxDelayMs = maxDelayMs;
28
+ }
29
+ }
30
+
31
+ enqueue(job: GeweDownloadJob): boolean {
32
+ this.cleanup();
33
+ if (this.seen.has(job.key)) return false;
34
+ this.seen.set(job.key, Date.now());
35
+ this.queue.push(job);
36
+ void this.run();
37
+ return true;
38
+ }
39
+
40
+ private cleanup() {
41
+ const now = Date.now();
42
+ for (const [key, ts] of this.seen.entries()) {
43
+ if (now - ts > DEDUPE_TTL_MS) {
44
+ this.seen.delete(key);
45
+ }
46
+ }
47
+ }
48
+
49
+ private async run() {
50
+ if (this.running) return;
51
+ this.running = true;
52
+ try {
53
+ while (this.queue.length > 0) {
54
+ const job = this.queue.shift();
55
+ if (!job) continue;
56
+ await sleep(this.nextDelayMs());
57
+ await job.run();
58
+ }
59
+ } finally {
60
+ this.running = false;
61
+ }
62
+ }
63
+
64
+ private nextDelayMs(): number {
65
+ const min = Math.max(0, this.minDelayMs);
66
+ const max = Math.max(min, this.maxDelayMs);
67
+ if (max === min) return min;
68
+ return Math.floor(Math.random() * (max - min + 1)) + min;
69
+ }
70
+ }
71
+
72
+ function sleep(ms: number): Promise<void> {
73
+ return new Promise((resolve) => setTimeout(resolve, ms));
74
+ }
@@ -0,0 +1,84 @@
1
+ import { assertGeweOk, postGeweJson } from "./api.js";
2
+ import type { ResolvedGeweAccount } from "./types.js";
3
+
4
+ type DownloadResult = { fileUrl: string };
5
+
6
+ function resolveBaseUrl(account: ResolvedGeweAccount): string {
7
+ return account.config.apiBaseUrl?.trim() || "http://api.geweapi.com";
8
+ }
9
+
10
+ export async function downloadGeweImage(params: {
11
+ account: ResolvedGeweAccount;
12
+ xml: string;
13
+ type: 1 | 2 | 3;
14
+ }): Promise<string> {
15
+ const resp = await postGeweJson<DownloadResult>({
16
+ baseUrl: resolveBaseUrl(params.account),
17
+ token: params.account.token,
18
+ path: "/gewe/v2/api/message/downloadImage",
19
+ body: {
20
+ appId: params.account.appId,
21
+ xml: params.xml,
22
+ type: params.type,
23
+ },
24
+ });
25
+ const data = assertGeweOk(resp, "downloadImage");
26
+ if (!data?.fileUrl) throw new Error("GeWe downloadImage missing fileUrl");
27
+ return data.fileUrl;
28
+ }
29
+
30
+ export async function downloadGeweVoice(params: {
31
+ account: ResolvedGeweAccount;
32
+ xml: string;
33
+ msgId: number;
34
+ }): Promise<string> {
35
+ const resp = await postGeweJson<DownloadResult>({
36
+ baseUrl: resolveBaseUrl(params.account),
37
+ token: params.account.token,
38
+ path: "/gewe/v2/api/message/downloadVoice",
39
+ body: {
40
+ appId: params.account.appId,
41
+ xml: params.xml,
42
+ msgId: params.msgId,
43
+ },
44
+ });
45
+ const data = assertGeweOk(resp, "downloadVoice");
46
+ if (!data?.fileUrl) throw new Error("GeWe downloadVoice missing fileUrl");
47
+ return data.fileUrl;
48
+ }
49
+
50
+ export async function downloadGeweVideo(params: {
51
+ account: ResolvedGeweAccount;
52
+ xml: string;
53
+ }): Promise<string> {
54
+ const resp = await postGeweJson<DownloadResult>({
55
+ baseUrl: resolveBaseUrl(params.account),
56
+ token: params.account.token,
57
+ path: "/gewe/v2/api/message/downloadVideo",
58
+ body: {
59
+ appId: params.account.appId,
60
+ xml: params.xml,
61
+ },
62
+ });
63
+ const data = assertGeweOk(resp, "downloadVideo");
64
+ if (!data?.fileUrl) throw new Error("GeWe downloadVideo missing fileUrl");
65
+ return data.fileUrl;
66
+ }
67
+
68
+ export async function downloadGeweFile(params: {
69
+ account: ResolvedGeweAccount;
70
+ xml: string;
71
+ }): Promise<string> {
72
+ const resp = await postGeweJson<DownloadResult>({
73
+ baseUrl: resolveBaseUrl(params.account),
74
+ token: params.account.token,
75
+ path: "/gewe/v2/api/message/downloadFile",
76
+ body: {
77
+ appId: params.account.appId,
78
+ xml: params.xml,
79
+ },
80
+ });
81
+ const data = assertGeweOk(resp, "downloadFile");
82
+ if (!data?.fileUrl) throw new Error("GeWe downloadFile missing fileUrl");
83
+ return data.fileUrl;
84
+ }