@openclaw/line 2026.5.9-beta.1 → 2026.5.10-beta.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/dist/api.js +1 -1
- package/dist/{channel-DkbpfXGE.js → channel-CQemYfAf.js} +2 -2
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-De0BoY61.js → channel.runtime-7a5SEVBm.js} +1 -1
- package/dist/{monitor-vLNFYADv.js → monitor-PVeb2tJQ.js} +133 -169
- package/dist/monitor.runtime-D0Xj2uQz.js +2 -0
- package/dist/runtime-api.js +2 -2
- package/package.json +4 -4
- package/dist/monitor.runtime-C1Toz0OI.js +0 -2
package/dist/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as lineChannelPluginCommon, t as linePlugin } from "./channel-
|
|
1
|
+
import { n as lineChannelPluginCommon, t as linePlugin } from "./channel-CQemYfAf.js";
|
|
2
2
|
import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-DCH7CE-y.js";
|
|
3
3
|
//#region extensions/line/src/channel.setup.ts
|
|
4
4
|
const lineSetupPlugin = {
|
|
@@ -108,7 +108,7 @@ const lineChannelPluginCommon = {
|
|
|
108
108
|
//#endregion
|
|
109
109
|
//#region extensions/line/src/gateway.ts
|
|
110
110
|
const loadLineProbeRuntime$1 = createLazyRuntimeModule(() => import("./probe.runtime-N91OWW1J.js"));
|
|
111
|
-
const loadLineMonitorRuntime = createLazyRuntimeModule(() => import("./monitor.runtime-
|
|
111
|
+
const loadLineMonitorRuntime = createLazyRuntimeModule(() => import("./monitor.runtime-D0Xj2uQz.js"));
|
|
112
112
|
const lineGatewayAdapter = {
|
|
113
113
|
startAccount: async (ctx) => {
|
|
114
114
|
const account = ctx.account;
|
|
@@ -533,7 +533,7 @@ const lineStatusAdapter = createComputedAccountStatusAdapter({
|
|
|
533
533
|
});
|
|
534
534
|
//#endregion
|
|
535
535
|
//#region extensions/line/src/channel.ts
|
|
536
|
-
const loadLineChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-
|
|
536
|
+
const loadLineChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-7a5SEVBm.js"));
|
|
537
537
|
const lineSecurityAdapter = createRestrictSendersChannelSecurity({
|
|
538
538
|
channelKey: "line",
|
|
539
539
|
resolveDmPolicy: (account) => account.config.dmPolicy,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as linePlugin } from "./channel-
|
|
1
|
+
import { t as linePlugin } from "./channel-CQemYfAf.js";
|
|
2
2
|
export { linePlugin };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { S as pushMessageLine } from "./markdown-to-line-DASNAjBq.js";
|
|
2
|
-
import { t as monitorLineProvider } from "./monitor-
|
|
2
|
+
import { t as monitorLineProvider } from "./monitor-PVeb2tJQ.js";
|
|
3
3
|
import { t as probeLineBot } from "./probe-D9BPzb2n.js";
|
|
4
4
|
export { monitorLineProvider, probeLineBot, pushMessageLine };
|
|
@@ -4,8 +4,8 @@ import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, E as reply
|
|
|
4
4
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
5
5
|
import { createMessageReceiveContext, hasFinalChannelTurnDispatch } from "openclaw/plugin-sdk/channel-message";
|
|
6
6
|
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
|
7
|
-
import { lowercasePreservingWhitespace, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
|
8
|
-
import { firstDefined
|
|
7
|
+
import { lowercasePreservingWhitespace, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/text-runtime";
|
|
8
|
+
import { firstDefined } from "openclaw/plugin-sdk/allow-from";
|
|
9
9
|
import { messagingApi } from "@line/bot-sdk";
|
|
10
10
|
import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
|
|
11
11
|
import { createNonExitingRuntime, danger, logVerbose, shouldLogVerbose, waitForAbortSignal } from "openclaw/plugin-sdk/runtime-env";
|
|
@@ -15,35 +15,30 @@ import { isRequestBodyLimitError, normalizePluginHttpPath, registerWebhookTarget
|
|
|
15
15
|
import { beginWebhookRequestPipelineOrReject, createWebhookInFlightLimiter, isRequestBodyLimitError as isRequestBodyLimitError$1, readRequestBodyWithLimit, requestBodyErrorToText as requestBodyErrorToText$1 } from "openclaw/plugin-sdk/webhook-request-guards";
|
|
16
16
|
import { DEFAULT_GROUP_HISTORY_LIMIT, clearHistoryEntriesIfEnabled, recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history";
|
|
17
17
|
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
|
18
|
-
import { buildMentionRegexes, formatInboundEnvelope, formatLocationText, matchesMentionPatterns,
|
|
19
|
-
import {
|
|
18
|
+
import { buildMentionRegexes, formatInboundEnvelope, formatLocationText, matchesMentionPatterns, resolveInboundSessionEnvelopeContext, toLocationContext } from "openclaw/plugin-sdk/channel-inbound";
|
|
19
|
+
import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
20
|
+
import { shouldComputeCommandAuthorized } from "openclaw/plugin-sdk/command-auth-native";
|
|
20
21
|
import { ensureConfiguredBindingRouteReady, readChannelAllowFromStore, resolveConfiguredBindingRoute, resolvePairingIdLabel, resolvePinnedMainDmOwnerFromAllowlist, resolveRuntimeConversationBindingRoute, upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
|
21
|
-
import { evaluateMatchedGroupAccessForPolicy } from "openclaw/plugin-sdk/group-access";
|
|
22
22
|
import { createClaimableDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
|
|
23
23
|
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
|
24
24
|
import { resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
25
25
|
import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-dispatch-runtime";
|
|
26
26
|
import crypto from "node:crypto";
|
|
27
27
|
//#region extensions/line/src/bot-access.ts
|
|
28
|
-
function
|
|
28
|
+
function normalizeLineAllowEntry(value) {
|
|
29
29
|
const trimmed = String(value).trim();
|
|
30
30
|
if (!trimmed) return "";
|
|
31
31
|
if (trimmed === "*") return "*";
|
|
32
32
|
return trimmed.replace(/^line:(?:user:)?/i, "");
|
|
33
33
|
}
|
|
34
34
|
const normalizeAllowFrom = (list) => {
|
|
35
|
-
const entries = (list ?? []).map((value) =>
|
|
35
|
+
const entries = (list ?? []).map((value) => normalizeLineAllowEntry(value)).filter(Boolean);
|
|
36
36
|
return {
|
|
37
37
|
entries,
|
|
38
38
|
hasWildcard: entries.includes("*"),
|
|
39
39
|
hasEntries: entries.length > 0
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
|
-
const normalizeDmAllowFromWithStore = (params) => normalizeAllowFrom(mergeDmAllowFromSources(params));
|
|
43
|
-
const isSenderAllowed = (params) => {
|
|
44
|
-
const { allow, senderId } = params;
|
|
45
|
-
return isSenderIdAllowed(allow, senderId, false);
|
|
46
|
-
};
|
|
47
42
|
//#endregion
|
|
48
43
|
//#region extensions/line/src/download.ts
|
|
49
44
|
const AUDIO_BRANDS = new Set([
|
|
@@ -580,6 +575,9 @@ function isDownloadableLineMessageType(messageType) {
|
|
|
580
575
|
}
|
|
581
576
|
const LINE_WEBHOOK_REPLAY_WINDOW_MS = 600 * 1e3;
|
|
582
577
|
const LINE_WEBHOOK_REPLAY_MAX_ENTRIES = 4096;
|
|
578
|
+
function normalizeLineIngressEntry(value) {
|
|
579
|
+
return normalizeLineAllowEntry(value) || null;
|
|
580
|
+
}
|
|
583
581
|
var LineRetryableWebhookError = class extends Error {
|
|
584
582
|
constructor(message, options) {
|
|
585
583
|
super(message, options);
|
|
@@ -688,33 +686,91 @@ async function sendLinePairingReply(params) {
|
|
|
688
686
|
});
|
|
689
687
|
}
|
|
690
688
|
async function shouldProcessLineEvent(event, context) {
|
|
691
|
-
const denied = {
|
|
692
|
-
allowed: false,
|
|
693
|
-
commandAuthorized: false
|
|
694
|
-
};
|
|
695
689
|
const { cfg, account } = context;
|
|
696
690
|
const { userId, groupId, roomId, isGroup } = getLineSourceInfo(event.source);
|
|
697
691
|
const senderId = userId ?? "";
|
|
698
|
-
const dmPolicy = account.config.dmPolicy ?? "pairing";
|
|
699
|
-
const storeAllowFrom = await readChannelAllowFromStore("line", void 0, account.accountId).catch(() => []);
|
|
700
|
-
const effectiveDmAllow = normalizeDmAllowFromWithStore({
|
|
701
|
-
allowFrom: account.config.allowFrom,
|
|
702
|
-
storeAllowFrom,
|
|
703
|
-
dmPolicy
|
|
704
|
-
});
|
|
705
692
|
const groupConfig = resolveLineGroupConfig({
|
|
706
693
|
config: account.config,
|
|
707
694
|
groupId,
|
|
708
695
|
roomId
|
|
709
696
|
});
|
|
710
|
-
const
|
|
711
|
-
const
|
|
712
|
-
const
|
|
713
|
-
const
|
|
714
|
-
const { groupPolicy, providerMissingFallbackApplied } = resolveAllowlistProviderRuntimeGroupPolicy({
|
|
697
|
+
const rawText = resolveEventRawText(event);
|
|
698
|
+
const requireMention = isGroup ? groupConfig?.requireMention !== false : false;
|
|
699
|
+
const dmPolicy = account.config.dmPolicy ?? "pairing";
|
|
700
|
+
const { groupPolicy: runtimeGroupPolicy, providerMissingFallbackApplied } = resolveAllowlistProviderRuntimeGroupPolicy({
|
|
715
701
|
providerConfigPresent: cfg.channels?.line !== void 0,
|
|
716
702
|
groupPolicy: account.config.groupPolicy,
|
|
717
|
-
defaultGroupPolicy
|
|
703
|
+
defaultGroupPolicy: resolveDefaultGroupPolicy(cfg)
|
|
704
|
+
});
|
|
705
|
+
const groupPolicy = runtimeGroupPolicy === "disabled" ? "disabled" : groupConfig?.allowFrom !== void 0 ? "allowlist" : runtimeGroupPolicy;
|
|
706
|
+
const groupAllowFrom = normalizeStringEntries(firstDefined(groupConfig?.allowFrom, account.config.groupAllowFrom, account.config.allowFrom?.length ? account.config.allowFrom : void 0));
|
|
707
|
+
const mentionFacts = (() => {
|
|
708
|
+
if (!isGroup || event.type !== "message") return {
|
|
709
|
+
canDetectMention: false,
|
|
710
|
+
wasMentioned: false,
|
|
711
|
+
hasAnyMention: false
|
|
712
|
+
};
|
|
713
|
+
const peerId = groupId ?? roomId ?? userId ?? "unknown";
|
|
714
|
+
const { agentId } = resolveAgentRoute({
|
|
715
|
+
cfg,
|
|
716
|
+
channel: "line",
|
|
717
|
+
accountId: account.accountId,
|
|
718
|
+
peer: {
|
|
719
|
+
kind: "group",
|
|
720
|
+
id: peerId
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
const mentionRegexes = buildMentionRegexes(cfg, agentId);
|
|
724
|
+
const wasMentionedByNative = isLineBotMentioned(event.message);
|
|
725
|
+
const wasMentionedByPattern = event.message.type === "text" ? matchesMentionPatterns(rawText, mentionRegexes) : false;
|
|
726
|
+
return {
|
|
727
|
+
canDetectMention: event.message.type === "text",
|
|
728
|
+
wasMentioned: wasMentionedByNative || wasMentionedByPattern,
|
|
729
|
+
hasAnyMention: hasAnyLineMention(event.message)
|
|
730
|
+
};
|
|
731
|
+
})();
|
|
732
|
+
const access = await resolveStableChannelMessageIngress({
|
|
733
|
+
channelId: "line",
|
|
734
|
+
accountId: account.accountId,
|
|
735
|
+
identity: {
|
|
736
|
+
key: "line-user-id",
|
|
737
|
+
normalize: normalizeLineIngressEntry,
|
|
738
|
+
sensitivity: "pii",
|
|
739
|
+
entryIdPrefix: "line-entry"
|
|
740
|
+
},
|
|
741
|
+
cfg,
|
|
742
|
+
readStoreAllowFrom: async () => await readChannelAllowFromStore("line", void 0, account.accountId),
|
|
743
|
+
subject: { stableId: senderId },
|
|
744
|
+
conversation: {
|
|
745
|
+
kind: isGroup ? "group" : "direct",
|
|
746
|
+
id: (groupId ?? roomId ?? senderId) || "unknown"
|
|
747
|
+
},
|
|
748
|
+
...isGroup && groupConfig?.enabled === false ? { route: {
|
|
749
|
+
id: "line:group-config",
|
|
750
|
+
enabled: false
|
|
751
|
+
} } : {},
|
|
752
|
+
mentionFacts: isGroup && event.type === "message" ? {
|
|
753
|
+
canDetectMention: mentionFacts.canDetectMention,
|
|
754
|
+
wasMentioned: mentionFacts.wasMentioned,
|
|
755
|
+
hasAnyMention: mentionFacts.hasAnyMention,
|
|
756
|
+
implicitMentionKinds: []
|
|
757
|
+
} : void 0,
|
|
758
|
+
event: { kind: event.type === "postback" ? "postback" : "message" },
|
|
759
|
+
dmPolicy,
|
|
760
|
+
groupPolicy,
|
|
761
|
+
policy: {
|
|
762
|
+
groupAllowFromFallbackToAllowFrom: false,
|
|
763
|
+
activation: {
|
|
764
|
+
requireMention: isGroup && event.type === "message" && requireMention,
|
|
765
|
+
allowTextCommands: true
|
|
766
|
+
}
|
|
767
|
+
},
|
|
768
|
+
allowFrom: normalizeStringEntries(account.config.allowFrom),
|
|
769
|
+
groupAllowFrom,
|
|
770
|
+
command: {
|
|
771
|
+
hasControlCommand: shouldComputeCommandAuthorized(rawText, cfg),
|
|
772
|
+
groupOwnerAllowFrom: "none"
|
|
773
|
+
}
|
|
718
774
|
});
|
|
719
775
|
warnMissingProviderGroupPolicyFallbackOnce({
|
|
720
776
|
providerMissingFallbackApplied,
|
|
@@ -722,90 +778,50 @@ async function shouldProcessLineEvent(event, context) {
|
|
|
722
778
|
accountId: account.accountId,
|
|
723
779
|
log: (message) => logVerbose(message)
|
|
724
780
|
});
|
|
781
|
+
if (access.senderAccess.decision === "allow" && (access.ingress.admission === "dispatch" || access.ingress.admission === "observe" || access.ingress.admission === "skip")) return access;
|
|
782
|
+
if (access.senderAccess.decision === "allow") {
|
|
783
|
+
logVerbose(`Blocked line event (${access.ingress.reasonCode})`);
|
|
784
|
+
return null;
|
|
785
|
+
}
|
|
725
786
|
if (isGroup) {
|
|
726
787
|
if (groupConfig?.enabled === false) {
|
|
727
788
|
logVerbose(`Blocked line group ${groupId ?? roomId ?? "unknown"} (group disabled)`);
|
|
728
|
-
return
|
|
789
|
+
return null;
|
|
729
790
|
}
|
|
730
|
-
if (
|
|
791
|
+
if (groupConfig?.allowFrom !== void 0) {
|
|
731
792
|
if (!senderId) {
|
|
732
793
|
logVerbose("Blocked line group message (group allowFrom override, no sender ID)");
|
|
733
|
-
return
|
|
794
|
+
return null;
|
|
734
795
|
}
|
|
735
|
-
if (
|
|
736
|
-
allow: effectiveGroupAllow,
|
|
737
|
-
senderId
|
|
738
|
-
})) {
|
|
796
|
+
if (access.senderAccess.reasonCode !== "group_policy_allowed") {
|
|
739
797
|
logVerbose(`Blocked line group sender ${senderId} (group allowFrom override)`);
|
|
740
|
-
return
|
|
798
|
+
return null;
|
|
741
799
|
}
|
|
742
800
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
allowlistMatched: Boolean(senderId) && isSenderAllowed({
|
|
749
|
-
allow: effectiveGroupAllow,
|
|
750
|
-
senderId
|
|
751
|
-
})
|
|
752
|
-
});
|
|
753
|
-
if (!senderGroupAccess.allowed && senderGroupAccess.reason === "disabled") {
|
|
754
|
-
logVerbose("Blocked line group message (groupPolicy: disabled)");
|
|
755
|
-
return denied;
|
|
756
|
-
}
|
|
757
|
-
if (!senderGroupAccess.allowed && senderGroupAccess.reason === "missing_match_input") {
|
|
758
|
-
logVerbose("Blocked line group message (no sender ID, groupPolicy: allowlist)");
|
|
759
|
-
return denied;
|
|
760
|
-
}
|
|
761
|
-
if (!senderGroupAccess.allowed && senderGroupAccess.reason === "empty_allowlist") {
|
|
762
|
-
logVerbose("Blocked line group message (groupPolicy: allowlist, no groupAllowFrom)");
|
|
763
|
-
return denied;
|
|
764
|
-
}
|
|
765
|
-
if (!senderGroupAccess.allowed && senderGroupAccess.reason === "not_allowlisted") {
|
|
766
|
-
logVerbose(`Blocked line group message from ${senderId} (groupPolicy: allowlist)`);
|
|
767
|
-
return denied;
|
|
768
|
-
}
|
|
769
|
-
return {
|
|
770
|
-
allowed: true,
|
|
771
|
-
commandAuthorized: resolveLineCommandAuthorized({
|
|
772
|
-
cfg,
|
|
773
|
-
event,
|
|
774
|
-
senderId,
|
|
775
|
-
allow: effectiveGroupAllow
|
|
776
|
-
})
|
|
777
|
-
};
|
|
801
|
+
if (access.senderAccess.reasonCode === "group_policy_disabled") logVerbose("Blocked line group message (groupPolicy: disabled)");
|
|
802
|
+
else if (!senderId && groupPolicy === "allowlist") logVerbose("Blocked line group message (no sender ID, groupPolicy: allowlist)");
|
|
803
|
+
else if (access.senderAccess.reasonCode === "group_policy_empty_allowlist") logVerbose("Blocked line group message (groupPolicy: allowlist, no groupAllowFrom)");
|
|
804
|
+
else logVerbose(`Blocked line group message from ${senderId} (groupPolicy: allowlist)`);
|
|
805
|
+
return null;
|
|
778
806
|
}
|
|
779
|
-
if (
|
|
807
|
+
if (access.senderAccess.reasonCode === "dm_policy_disabled") {
|
|
780
808
|
logVerbose("Blocked line sender (dmPolicy: disabled)");
|
|
781
|
-
return
|
|
782
|
-
}
|
|
783
|
-
if (!isSenderAllowed({
|
|
784
|
-
allow: effectiveDmAllow,
|
|
785
|
-
senderId
|
|
786
|
-
})) {
|
|
787
|
-
if (dmPolicy === "pairing") {
|
|
788
|
-
if (!senderId) {
|
|
789
|
-
logVerbose("Blocked line sender (dmPolicy: pairing, no sender ID)");
|
|
790
|
-
return denied;
|
|
791
|
-
}
|
|
792
|
-
await sendLinePairingReply({
|
|
793
|
-
senderId,
|
|
794
|
-
replyToken: "replyToken" in event ? event.replyToken : void 0,
|
|
795
|
-
context
|
|
796
|
-
});
|
|
797
|
-
} else logVerbose(`Blocked line sender ${senderId || "unknown"} (dmPolicy: ${dmPolicy})`);
|
|
798
|
-
return denied;
|
|
809
|
+
return null;
|
|
799
810
|
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
811
|
+
if (access.senderAccess.decision === "pairing") {
|
|
812
|
+
if (!senderId) {
|
|
813
|
+
logVerbose("Blocked line sender (dmPolicy: pairing, no sender ID)");
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
await sendLinePairingReply({
|
|
805
817
|
senderId,
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
818
|
+
replyToken: "replyToken" in event ? event.replyToken : void 0,
|
|
819
|
+
context
|
|
820
|
+
});
|
|
821
|
+
return null;
|
|
822
|
+
}
|
|
823
|
+
logVerbose(`Blocked line sender ${senderId || "unknown"} (dmPolicy: ${account.config.dmPolicy ?? "pairing"})`);
|
|
824
|
+
return null;
|
|
809
825
|
}
|
|
810
826
|
function getLineMentionees(message) {
|
|
811
827
|
if (message.type !== "text") return [];
|
|
@@ -827,81 +843,29 @@ function resolveEventRawText(event) {
|
|
|
827
843
|
if (event.type === "postback") return event.postback?.data?.trim() ?? "";
|
|
828
844
|
return "";
|
|
829
845
|
}
|
|
830
|
-
function resolveLineCommandAuthorized(params) {
|
|
831
|
-
const senderAllowedForCommands = isSenderAllowed({
|
|
832
|
-
allow: params.allow,
|
|
833
|
-
senderId: params.senderId
|
|
834
|
-
});
|
|
835
|
-
const useAccessGroups = params.cfg.commands?.useAccessGroups !== false;
|
|
836
|
-
const rawText = resolveEventRawText(params.event);
|
|
837
|
-
return resolveControlCommandGate({
|
|
838
|
-
useAccessGroups,
|
|
839
|
-
authorizers: [{
|
|
840
|
-
configured: params.allow.hasEntries,
|
|
841
|
-
allowed: senderAllowedForCommands
|
|
842
|
-
}],
|
|
843
|
-
allowTextCommands: true,
|
|
844
|
-
hasControlCommand: hasControlCommand(rawText, params.cfg)
|
|
845
|
-
}).commandAuthorized;
|
|
846
|
-
}
|
|
847
846
|
async function handleMessageEvent(event, context) {
|
|
848
847
|
const { cfg, account, runtime, mediaMaxBytes, processMessage } = context;
|
|
849
848
|
const message = event.message;
|
|
850
849
|
const decision = await shouldProcessLineEvent(event, context);
|
|
851
|
-
if (!decision
|
|
850
|
+
if (!decision) return;
|
|
852
851
|
const { isGroup, groupId, roomId } = getLineSourceInfo(event.source);
|
|
853
|
-
if (isGroup) {
|
|
854
|
-
const requireMention = resolveLineGroupConfig({
|
|
855
|
-
config: account.config,
|
|
856
|
-
groupId,
|
|
857
|
-
roomId
|
|
858
|
-
})?.requireMention !== false;
|
|
852
|
+
if (isGroup && decision.activationAccess.shouldSkip) {
|
|
859
853
|
const rawText = message.type === "text" ? message.text : "";
|
|
860
854
|
const sourceInfo = getLineSourceInfo(event.source);
|
|
861
|
-
|
|
862
|
-
const
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
855
|
+
logVerbose(`line: skipping group message (requireMention, not mentioned)`);
|
|
856
|
+
const historyKey = groupId ?? roomId;
|
|
857
|
+
const senderId = sourceInfo.userId ?? "unknown";
|
|
858
|
+
if (historyKey && context.groupHistories) recordPendingHistoryEntryIfEnabled({
|
|
859
|
+
historyMap: context.groupHistories,
|
|
860
|
+
historyKey,
|
|
861
|
+
limit: context.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT,
|
|
862
|
+
entry: {
|
|
863
|
+
sender: `user:${senderId}`,
|
|
864
|
+
body: rawText || `<${message.type}>`,
|
|
865
|
+
timestamp: event.timestamp
|
|
869
866
|
}
|
|
870
867
|
});
|
|
871
|
-
|
|
872
|
-
const wasMentionedByNative = isLineBotMentioned(message);
|
|
873
|
-
const wasMentionedByPattern = message.type === "text" ? matchesMentionPatterns(rawText, mentionRegexes) : false;
|
|
874
|
-
const wasMentioned = wasMentionedByNative || wasMentionedByPattern;
|
|
875
|
-
if (resolveInboundMentionDecision({
|
|
876
|
-
facts: {
|
|
877
|
-
canDetectMention: message.type === "text",
|
|
878
|
-
wasMentioned,
|
|
879
|
-
hasAnyMention: hasAnyLineMention(message),
|
|
880
|
-
implicitMentionKinds: []
|
|
881
|
-
},
|
|
882
|
-
policy: {
|
|
883
|
-
isGroup: true,
|
|
884
|
-
requireMention,
|
|
885
|
-
allowTextCommands: true,
|
|
886
|
-
hasControlCommand: hasControlCommand(rawText, cfg),
|
|
887
|
-
commandAuthorized: decision.commandAuthorized
|
|
888
|
-
}
|
|
889
|
-
}).shouldSkip) {
|
|
890
|
-
logVerbose(`line: skipping group message (requireMention, not mentioned)`);
|
|
891
|
-
const historyKey = groupId ?? roomId;
|
|
892
|
-
const senderId = sourceInfo.userId ?? "unknown";
|
|
893
|
-
if (historyKey && context.groupHistories) recordPendingHistoryEntryIfEnabled({
|
|
894
|
-
historyMap: context.groupHistories,
|
|
895
|
-
historyKey,
|
|
896
|
-
limit: context.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT,
|
|
897
|
-
entry: {
|
|
898
|
-
sender: `user:${senderId}`,
|
|
899
|
-
body: rawText || `<${message.type}>`,
|
|
900
|
-
timestamp: event.timestamp
|
|
901
|
-
}
|
|
902
|
-
});
|
|
903
|
-
return;
|
|
904
|
-
}
|
|
868
|
+
return;
|
|
905
869
|
}
|
|
906
870
|
const allMedia = [];
|
|
907
871
|
if (isDownloadableLineMessageType(message.type)) try {
|
|
@@ -920,7 +884,7 @@ async function handleMessageEvent(event, context) {
|
|
|
920
884
|
allMedia,
|
|
921
885
|
cfg,
|
|
922
886
|
account,
|
|
923
|
-
commandAuthorized: decision.
|
|
887
|
+
commandAuthorized: decision.commandAccess.authorized,
|
|
924
888
|
groupHistories: context.groupHistories,
|
|
925
889
|
historyLimit: context.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT
|
|
926
890
|
});
|
|
@@ -958,12 +922,12 @@ async function handlePostbackEvent(event, context) {
|
|
|
958
922
|
const data = event.postback.data;
|
|
959
923
|
logVerbose(`line: received postback: ${data}`);
|
|
960
924
|
const decision = await shouldProcessLineEvent(event, context);
|
|
961
|
-
if (!decision
|
|
925
|
+
if (!decision) return;
|
|
962
926
|
const postbackContext = await buildLinePostbackContext({
|
|
963
927
|
event,
|
|
964
928
|
cfg: context.cfg,
|
|
965
929
|
account: context.account,
|
|
966
|
-
commandAuthorized: decision.
|
|
930
|
+
commandAuthorized: decision.commandAccess.authorized
|
|
967
931
|
});
|
|
968
932
|
if (!postbackContext) return;
|
|
969
933
|
await context.processMessage(postbackContext);
|
|
@@ -1545,4 +1509,4 @@ async function monitorLineProvider(opts) {
|
|
|
1545
1509
|
};
|
|
1546
1510
|
}
|
|
1547
1511
|
//#endregion
|
|
1548
|
-
export { validateLineSignature as a,
|
|
1512
|
+
export { validateLineSignature as a, normalizeAllowFrom as c, parseLineWebhookBody as i, createLineNodeWebhookHandler as n, downloadLineMedia as o, readLineWebhookRequestBody as r, firstDefined as s, monitorLineProvider as t };
|
package/dist/runtime-api.js
CHANGED
|
@@ -4,7 +4,7 @@ import { a as createMediaPlayerCard, i as createDeviceControlCard, n as parseLin
|
|
|
4
4
|
import { n as createEventCard, r as createReceiptCard, t as createAgendaCard } from "./schedule-cards-BwQChTdM.js";
|
|
5
5
|
import { a as createListCard, i as createInfoCard, n as createCarousel, o as createNotificationBubble, r as createImageCard, t as createActionCard } from "./basic-cards-7DTG6E-A.js";
|
|
6
6
|
import { A as buildTemplateMessageFromPayload, B as createYesNoConfirm, C as pushMessagesLine, D as sendMessageLine, E as replyMessageLine, F as createImageCarousel, G as toFlexMessage, H as messageAction, I as createImageCarouselColumn, L as createLinkMenu, M as createButtonTemplate, N as createCarouselColumn, O as showLoadingAnimation, P as createConfirmTemplate, R as createProductCarousel, S as pushMessageLine, T as pushTextMessageWithQuickReplies, U as postbackAction, V as datetimePickerAction, W as uriAction, _ as getUserDisplayName, a as extractLinks, b as pushImageMessage, c as processLineMessage, d as createFlexMessage, f as createImageMessage, g as createVideoMessage, h as createTextMessageWithQuickReplies, i as extractCodeBlocks, j as createButtonMenu, k as resolveLineChannelAccessToken, l as stripMarkdown, m as createQuickReplyItems, n as convertLinksToFlexBubble, o as extractMarkdownTables, p as createLocationMessage, r as convertTableToFlexBubble, s as hasMarkdownToConvert, t as convertCodeBlockToFlexBubble, u as createAudioMessage, v as getUserProfile, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage, z as createTemplateCarousel } from "./markdown-to-line-DASNAjBq.js";
|
|
7
|
-
import { a as validateLineSignature, c as
|
|
7
|
+
import { a as validateLineSignature, c as normalizeAllowFrom, i as parseLineWebhookBody, n as createLineNodeWebhookHandler, o as downloadLineMedia, r as readLineWebhookRequestBody, s as firstDefined, t as monitorLineProvider } from "./monitor-PVeb2tJQ.js";
|
|
8
8
|
import { t as probeLineBot } from "./probe-D9BPzb2n.js";
|
|
9
9
|
import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
|
|
10
10
|
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
|
|
@@ -287,4 +287,4 @@ function createDefaultMenuConfig() {
|
|
|
287
287
|
};
|
|
288
288
|
}
|
|
289
289
|
//#endregion
|
|
290
|
-
export { DEFAULT_ACCOUNT_ID, LineChannelConfigSchema, LineConfigSchema, buildChannelConfigSchema, buildComputedAccountStatusSnapshot, buildTemplateMessageFromPayload, buildTokenChannelStatusSummary, cancelDefaultRichMenu, clearAccountEntryFields, convertCodeBlockToFlexBubble, convertLinksToFlexBubble, convertTableToFlexBubble, createActionCard, createAgendaCard, createAppleTvRemoteCard, createAudioMessage, createButtonMenu, createButtonTemplate, createCarousel, createCarouselColumn, createConfirmTemplate, createDefaultMenuConfig, createDeviceControlCard, createEventCard, createFlexMessage, createGridLayout, createImageCard, createImageCarousel, createImageCarouselColumn, createImageMessage, createInfoCard, createLineNodeWebhookHandler, createLineWebhookMiddleware, createLinkMenu, createListCard, createLocationMessage, createMediaPlayerCard, createNotificationBubble, createProductCarousel, createQuickReplyItems, createReceiptCard, createRichMenu, createRichMenuAlias, createTemplateCarousel, createTextMessageWithQuickReplies, createVideoMessage, createYesNoConfirm, datetimePickerAction, deleteRichMenu, deleteRichMenuAlias, downloadLineMedia, extractCodeBlocks, extractLinks, extractMarkdownTables, firstDefined, formatDocsLink, getDefaultRichMenuId, getRichMenu, getRichMenuIdOfUser, getRichMenuList, getUserDisplayName, getUserProfile, hasLineDirectives, hasMarkdownToConvert,
|
|
290
|
+
export { DEFAULT_ACCOUNT_ID, LineChannelConfigSchema, LineConfigSchema, buildChannelConfigSchema, buildComputedAccountStatusSnapshot, buildTemplateMessageFromPayload, buildTokenChannelStatusSummary, cancelDefaultRichMenu, clearAccountEntryFields, convertCodeBlockToFlexBubble, convertLinksToFlexBubble, convertTableToFlexBubble, createActionCard, createAgendaCard, createAppleTvRemoteCard, createAudioMessage, createButtonMenu, createButtonTemplate, createCarousel, createCarouselColumn, createConfirmTemplate, createDefaultMenuConfig, createDeviceControlCard, createEventCard, createFlexMessage, createGridLayout, createImageCard, createImageCarousel, createImageCarouselColumn, createImageMessage, createInfoCard, createLineNodeWebhookHandler, createLineWebhookMiddleware, createLinkMenu, createListCard, createLocationMessage, createMediaPlayerCard, createNotificationBubble, createProductCarousel, createQuickReplyItems, createReceiptCard, createRichMenu, createRichMenuAlias, createTemplateCarousel, createTextMessageWithQuickReplies, createVideoMessage, createYesNoConfirm, datetimePickerAction, deleteRichMenu, deleteRichMenuAlias, downloadLineMedia, extractCodeBlocks, extractLinks, extractMarkdownTables, firstDefined, formatDocsLink, getDefaultRichMenuId, getRichMenu, getRichMenuIdOfUser, getRichMenuList, getUserDisplayName, getUserProfile, hasLineDirectives, hasMarkdownToConvert, linkRichMenuToUser, linkRichMenuToUsers, listLineAccountIds, messageAction, monitorLineProvider, normalizeAccountId, normalizeAllowFrom, parseLineDirectives, parseLineWebhookBody, postbackAction, probeLineBot, processLineMessage, pushFlexMessage, pushImageMessage, pushLocationMessage, pushMessageLine, pushMessagesLine, pushTemplateMessage, pushTextMessageWithQuickReplies, readLineWebhookRequestBody, replyMessageLine, resolveDefaultLineAccountId, resolveExactLineGroupConfigKey, resolveLineAccount, resolveLineChannelAccessToken, resolveLineGroupConfigEntry, resolveLineGroupLookupIds, resolveLineGroupsConfig, sendMessageLine, setDefaultRichMenu, setLineRuntime, setSetupChannelEnabled, showLoadingAnimation, splitSetupEntries, startLineWebhook, stripMarkdown, toFlexMessage, unlinkRichMenuFromUser, unlinkRichMenuFromUsers, uploadRichMenuImage, uriAction, validateLineSignature };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/line",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.10-beta.2",
|
|
4
4
|
"description": "OpenClaw LINE channel plugin",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"openclaw": "workspace:*"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"openclaw": ">=2026.5.
|
|
18
|
+
"openclaw": ">=2026.5.10-beta.2"
|
|
19
19
|
},
|
|
20
20
|
"peerDependenciesMeta": {
|
|
21
21
|
"openclaw": {
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"minHostVersion": ">=2026.4.10"
|
|
46
46
|
},
|
|
47
47
|
"compat": {
|
|
48
|
-
"pluginApi": ">=2026.5.
|
|
48
|
+
"pluginApi": ">=2026.5.10-beta.2"
|
|
49
49
|
},
|
|
50
50
|
"build": {
|
|
51
|
-
"openclawVersion": "2026.5.
|
|
51
|
+
"openclawVersion": "2026.5.10-beta.2"
|
|
52
52
|
},
|
|
53
53
|
"release": {
|
|
54
54
|
"publishToClawHub": true,
|