@cored-im/openclaw-plugin 0.1.3 → 0.1.5
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/dist/index.cjs +196 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -60
- package/dist/index.d.ts +11 -60
- package/dist/index.js +201 -54
- package/dist/index.js.map +1 -1
- package/dist/setup-entry.cjs +311 -36
- package/dist/setup-entry.cjs.map +1 -1
- package/dist/setup-entry.d.cts +9 -1
- package/dist/setup-entry.d.ts +9 -1
- package/dist/setup-entry.js +314 -36
- package/dist/setup-entry.js.map +1 -1
- package/openclaw.plugin.json +2 -3
- package/package.json +3 -3
- package/src/channel.ts +152 -4
- package/src/index.test.ts +52 -26
- package/src/index.ts +56 -44
- package/src/messaging/inbound.ts +43 -11
- package/src/setup-entry.ts +2 -46
- package/src/types.ts +3 -33
- package/src/typings/openclaw-plugin-sdk.d.ts +152 -19
package/dist/index.cjs
CHANGED
|
@@ -20,9 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
default: () =>
|
|
23
|
+
default: () => index_default
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
var import_core2 = require("openclaw/plugin-sdk/core");
|
|
27
|
+
|
|
28
|
+
// src/channel.ts
|
|
29
|
+
var import_core = require("openclaw/plugin-sdk/core");
|
|
26
30
|
|
|
27
31
|
// src/config.ts
|
|
28
32
|
var DEFAULTS = {
|
|
@@ -332,23 +336,79 @@ function parseTarget(to) {
|
|
|
332
336
|
}
|
|
333
337
|
|
|
334
338
|
// src/channel.ts
|
|
335
|
-
|
|
336
|
-
|
|
339
|
+
function resolveAccount(cfg, accountId) {
|
|
340
|
+
const section = cfg.channels?.["cored"];
|
|
341
|
+
const accounts = section?.accounts;
|
|
342
|
+
const defaultAccount = section?.defaultAccount;
|
|
343
|
+
if (accounts && Object.keys(accounts).length > 0) {
|
|
344
|
+
const targetId = accountId ?? defaultAccount ?? Object.keys(accounts)[0];
|
|
345
|
+
const account = accounts[targetId];
|
|
346
|
+
if (!account) {
|
|
347
|
+
throw new Error(`cored: account "${targetId}" not found`);
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
accountId: targetId,
|
|
351
|
+
appId: account.appId,
|
|
352
|
+
appSecret: account.appSecret,
|
|
353
|
+
backendUrl: account.backendUrl,
|
|
354
|
+
enableEncryption: account.enableEncryption ?? section.enableEncryption ?? true,
|
|
355
|
+
requestTimeout: account.requestTimeout ?? section.requestTimeout ?? 3e4,
|
|
356
|
+
requireMention: account.requireMention ?? section.requireMention ?? true
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
const appId = section?.appId;
|
|
360
|
+
const appSecret = section?.appSecret;
|
|
361
|
+
const backendUrl = section?.backendUrl;
|
|
362
|
+
if (!appId || !appSecret || !backendUrl) {
|
|
363
|
+
throw new Error("cored: appId, appSecret, and backendUrl are required");
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
accountId: null,
|
|
367
|
+
appId,
|
|
368
|
+
appSecret,
|
|
369
|
+
backendUrl,
|
|
370
|
+
enableEncryption: section?.enableEncryption ?? true,
|
|
371
|
+
requestTimeout: section?.requestTimeout ?? 3e4,
|
|
372
|
+
requireMention: section?.requireMention ?? true
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
var coredPlugin = (0, import_core.createChatChannelPlugin)({
|
|
376
|
+
base: (0, import_core.createChannelPluginBase)({
|
|
377
|
+
id: "cored",
|
|
378
|
+
setup: {
|
|
379
|
+
resolveAccount,
|
|
380
|
+
inspectAccount(cfg, accountId) {
|
|
381
|
+
const section = cfg.channels?.["cored"];
|
|
382
|
+
const hasConfig = Boolean(
|
|
383
|
+
section?.appId && section?.appSecret && section?.backendUrl
|
|
384
|
+
);
|
|
385
|
+
return {
|
|
386
|
+
enabled: Boolean(section?.enabled !== false),
|
|
387
|
+
configured: hasConfig,
|
|
388
|
+
tokenStatus: hasConfig ? "available" : "missing"
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}),
|
|
393
|
+
// Plugin metadata
|
|
337
394
|
meta: {
|
|
338
395
|
id: "cored",
|
|
339
396
|
label: "Cored",
|
|
340
397
|
selectionLabel: "Cored",
|
|
341
398
|
docsPath: "/channels/cored",
|
|
342
|
-
blurb: "
|
|
399
|
+
blurb: "Connect OpenClaw to Cored",
|
|
343
400
|
aliases: ["cored", "co"]
|
|
344
401
|
},
|
|
402
|
+
// Capabilities
|
|
345
403
|
capabilities: {
|
|
346
404
|
chatTypes: ["direct", "group"]
|
|
347
405
|
},
|
|
406
|
+
// Config
|
|
348
407
|
config: {
|
|
349
408
|
listAccountIds: (cfg) => listAccountIds(cfg),
|
|
350
409
|
resolveAccount: (cfg, accountId) => resolveAccountConfig(cfg, accountId)
|
|
351
410
|
},
|
|
411
|
+
// Outbound messaging
|
|
352
412
|
outbound: {
|
|
353
413
|
deliveryMode: "direct",
|
|
354
414
|
resolveTarget: ({ to }) => {
|
|
@@ -377,8 +437,70 @@ var coredPlugin = {
|
|
|
377
437
|
}
|
|
378
438
|
return sendText(target.id, text, accountId);
|
|
379
439
|
}
|
|
440
|
+
},
|
|
441
|
+
// Setup wizard for openclaw onboard
|
|
442
|
+
setupWizard: {
|
|
443
|
+
channel: "cored",
|
|
444
|
+
status: {
|
|
445
|
+
configuredLabel: "Connected",
|
|
446
|
+
unconfiguredLabel: "Not configured",
|
|
447
|
+
resolveConfigured: ({ cfg }) => {
|
|
448
|
+
const section = cfg.channels?.["cored"];
|
|
449
|
+
return Boolean(section?.appId && section?.appSecret && section?.backendUrl);
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
credentials: [
|
|
453
|
+
{
|
|
454
|
+
inputKey: "appId",
|
|
455
|
+
providerHint: "cored",
|
|
456
|
+
credentialLabel: "App ID",
|
|
457
|
+
preferredEnvVar: "CORED_APP_ID",
|
|
458
|
+
envPrompt: "Use CORED_APP_ID from environment?",
|
|
459
|
+
keepPrompt: "Keep current App ID?",
|
|
460
|
+
inputPrompt: "Enter your Cored App ID:",
|
|
461
|
+
inspect: ({ cfg }) => {
|
|
462
|
+
const section = cfg.channels?.["cored"];
|
|
463
|
+
return {
|
|
464
|
+
accountConfigured: Boolean(section?.appId),
|
|
465
|
+
hasConfiguredValue: Boolean(section?.appId)
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
inputKey: "appSecret",
|
|
471
|
+
providerHint: "cored",
|
|
472
|
+
credentialLabel: "App Secret",
|
|
473
|
+
preferredEnvVar: "CORED_APP_SECRET",
|
|
474
|
+
envPrompt: "Use CORED_APP_SECRET from environment?",
|
|
475
|
+
keepPrompt: "Keep current App Secret?",
|
|
476
|
+
inputPrompt: "Enter your Cored App Secret:",
|
|
477
|
+
inspect: ({ cfg }) => {
|
|
478
|
+
const section = cfg.channels?.["cored"];
|
|
479
|
+
return {
|
|
480
|
+
accountConfigured: Boolean(section?.appSecret),
|
|
481
|
+
hasConfiguredValue: Boolean(section?.appSecret)
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
inputKey: "backendUrl",
|
|
487
|
+
providerHint: "cored",
|
|
488
|
+
credentialLabel: "Backend URL",
|
|
489
|
+
preferredEnvVar: "CORED_BACKEND_URL",
|
|
490
|
+
envPrompt: "Use CORED_BACKEND_URL from environment?",
|
|
491
|
+
keepPrompt: "Keep current Backend URL?",
|
|
492
|
+
inputPrompt: "Enter your Cored backend server URL:",
|
|
493
|
+
inspect: ({ cfg }) => {
|
|
494
|
+
const section = cfg.channels?.["cored"];
|
|
495
|
+
return {
|
|
496
|
+
accountConfigured: Boolean(section?.backendUrl),
|
|
497
|
+
hasConfiguredValue: Boolean(section?.backendUrl)
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
]
|
|
380
502
|
}
|
|
381
|
-
};
|
|
503
|
+
});
|
|
382
504
|
|
|
383
505
|
// src/messaging/inbound.ts
|
|
384
506
|
function parseMessageEvent(event) {
|
|
@@ -497,33 +619,47 @@ function buildContext(msg, account) {
|
|
|
497
619
|
}
|
|
498
620
|
async function processInboundMessage(api, account, event, opts) {
|
|
499
621
|
const logger = api.logger;
|
|
622
|
+
const log = {
|
|
623
|
+
debug: (msg) => {
|
|
624
|
+
logger?.debug?.(msg);
|
|
625
|
+
},
|
|
626
|
+
info: (msg) => {
|
|
627
|
+
logger?.info?.(msg);
|
|
628
|
+
},
|
|
629
|
+
warn: (msg) => {
|
|
630
|
+
logger?.warn?.(msg);
|
|
631
|
+
},
|
|
632
|
+
error: (msg) => {
|
|
633
|
+
logger?.error?.(msg);
|
|
634
|
+
}
|
|
635
|
+
};
|
|
500
636
|
const parsed = parseMessageEvent(event);
|
|
501
637
|
if (!parsed) {
|
|
502
|
-
|
|
638
|
+
log.debug(
|
|
503
639
|
`[cored] ignoring unparseable event (messageId=${event?.message?.messageId ?? "unknown"} messageType=${event?.message?.messageType ?? "undefined"})`
|
|
504
640
|
);
|
|
505
641
|
return false;
|
|
506
642
|
}
|
|
507
643
|
const gate = checkMessageGate(parsed, account);
|
|
508
644
|
if (!gate.pass) {
|
|
509
|
-
|
|
645
|
+
log.debug(
|
|
510
646
|
`[cored] gated message=${parsed.messageId} reason=${gate.reason} chat=${parsed.chatId}`
|
|
511
647
|
);
|
|
512
648
|
return false;
|
|
513
649
|
}
|
|
514
650
|
if (isDuplicate(parsed.messageId)) {
|
|
515
|
-
|
|
651
|
+
log.debug(
|
|
516
652
|
`[cored] duplicate message=${parsed.messageId} chat=${parsed.chatId}`
|
|
517
653
|
);
|
|
518
654
|
return false;
|
|
519
655
|
}
|
|
520
656
|
const ctx = buildContext(parsed, account);
|
|
521
|
-
|
|
657
|
+
log.info(
|
|
522
658
|
`[cored] dispatching message=${parsed.messageId} chat=${parsed.chatId} sender=${parsed.senderId} type=${parsed.chatType}`
|
|
523
659
|
);
|
|
524
660
|
const runtime = api.runtime;
|
|
525
661
|
if (!runtime?.channel?.reply?.dispatchReplyWithBufferedBlockDispatcher) {
|
|
526
|
-
|
|
662
|
+
log.warn("[cored] runtime.channel.reply not available \u2014 cannot dispatch");
|
|
527
663
|
return false;
|
|
528
664
|
}
|
|
529
665
|
const cfgSession = api.config?.session;
|
|
@@ -542,7 +678,7 @@ async function processInboundMessage(api, account, event, opts) {
|
|
|
542
678
|
accountId: account.accountId
|
|
543
679
|
} : void 0
|
|
544
680
|
});
|
|
545
|
-
|
|
681
|
+
log.debug(
|
|
546
682
|
`[cored] dispatch starting for message=${parsed.messageId} session=${ctx.SessionKey}`
|
|
547
683
|
);
|
|
548
684
|
await runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
@@ -550,77 +686,83 @@ async function processInboundMessage(api, account, event, opts) {
|
|
|
550
686
|
cfg: api.config,
|
|
551
687
|
dispatcherOptions: {
|
|
552
688
|
deliver: async (payload) => {
|
|
553
|
-
|
|
689
|
+
log.info(
|
|
554
690
|
`[cored] deliver callback called for message=${parsed.messageId} hasText=${!!payload.text} textLen=${payload.text?.length ?? 0}`
|
|
555
691
|
);
|
|
556
692
|
if (payload.text) {
|
|
557
693
|
await opts.deliver(parsed.chatId, payload.text);
|
|
558
|
-
|
|
694
|
+
log.info(
|
|
559
695
|
`[cored] deliver completed for message=${parsed.messageId} chat=${parsed.chatId}`
|
|
560
696
|
);
|
|
561
697
|
}
|
|
562
698
|
},
|
|
563
699
|
onError: (err, info) => {
|
|
564
|
-
|
|
700
|
+
log.error(
|
|
565
701
|
`[cored] ${info?.kind ?? "reply"} error for message=${parsed.messageId}: ${err}`
|
|
566
702
|
);
|
|
567
703
|
}
|
|
568
704
|
}
|
|
569
705
|
});
|
|
570
|
-
|
|
706
|
+
log.info(
|
|
571
707
|
`[cored] dispatch finished for message=${parsed.messageId}`
|
|
572
708
|
);
|
|
573
709
|
return true;
|
|
574
710
|
}
|
|
575
711
|
|
|
576
712
|
// src/index.ts
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
`[cored] skipping account=${account.accountId}: ${errors.map((e) => e.message).join("; ")}`
|
|
593
|
-
);
|
|
594
|
-
continue;
|
|
713
|
+
var index_default = (0, import_core2.defineChannelPluginEntry)({
|
|
714
|
+
id: "cored",
|
|
715
|
+
name: "Cored",
|
|
716
|
+
description: "Connect OpenClaw with Cored",
|
|
717
|
+
plugin: coredPlugin,
|
|
718
|
+
registerFull(api) {
|
|
719
|
+
const typedApi = api;
|
|
720
|
+
typedApi.registerService({
|
|
721
|
+
id: "cored-sdk",
|
|
722
|
+
start: async () => {
|
|
723
|
+
if (clientCount() > 0) return;
|
|
724
|
+
const accounts = listEnabledAccountConfigs(typedApi.config);
|
|
725
|
+
if (accounts.length === 0) {
|
|
726
|
+
typedApi.logger?.warn?.("[cored] no enabled account config found \u2014 service idle");
|
|
727
|
+
return;
|
|
595
728
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
729
|
+
for (const account of accounts) {
|
|
730
|
+
const errors = validateAccountConfig(account);
|
|
731
|
+
if (errors.length > 0) {
|
|
732
|
+
typedApi.logger?.warn?.(
|
|
733
|
+
`[cored] skipping account=${account.accountId}: ${errors.map((e) => e.message).join("; ")}`
|
|
734
|
+
);
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
try {
|
|
738
|
+
await startAccount(typedApi, account);
|
|
739
|
+
typedApi.logger?.info?.(
|
|
740
|
+
`[cored] account=${account.accountId} connected (appId=${account.appId})`
|
|
741
|
+
);
|
|
742
|
+
} catch (err) {
|
|
743
|
+
typedApi.logger?.error?.(
|
|
744
|
+
`[cored] account=${account.accountId} failed to start: ${err instanceof Error ? err.message : String(err)}`
|
|
745
|
+
);
|
|
746
|
+
}
|
|
605
747
|
}
|
|
748
|
+
typedApi.logger?.info?.(`[cored] service started with ${clientCount()} account(s)`);
|
|
749
|
+
},
|
|
750
|
+
stop: async () => {
|
|
751
|
+
await destroyAllClients();
|
|
752
|
+
typedApi.logger?.info?.("[cored] service stopped \u2014 all clients disconnected");
|
|
606
753
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
api.logger?.info("[cored] service stopped \u2014 all clients disconnected");
|
|
612
|
-
}
|
|
613
|
-
});
|
|
614
|
-
api.logger?.info("[cored] plugin registered");
|
|
615
|
-
}
|
|
754
|
+
});
|
|
755
|
+
typedApi.logger?.info?.("[cored] plugin registered");
|
|
756
|
+
}
|
|
757
|
+
});
|
|
616
758
|
async function startAccount(api, account) {
|
|
617
|
-
const deliver = makeDeliver(account.accountId, (msg) => api.logger?.warn(msg));
|
|
759
|
+
const deliver = makeDeliver(account.accountId, (msg) => api.logger?.warn?.(msg));
|
|
618
760
|
await createClient({
|
|
619
761
|
config: account,
|
|
620
|
-
log: (msg) => api.logger?.debug(msg),
|
|
762
|
+
log: (msg) => api.logger?.debug?.(msg),
|
|
621
763
|
onMessage: (event, accountConfig) => {
|
|
622
764
|
handleInbound(api, accountConfig, event, deliver).catch((err) => {
|
|
623
|
-
api.logger?.error(
|
|
765
|
+
api.logger?.error?.(
|
|
624
766
|
`[cored] unhandled inbound error for account=${accountConfig.accountId}: ${err}`
|
|
625
767
|
);
|
|
626
768
|
});
|