@badgerclaw/connect 1.2.0 → 1.3.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@badgerclaw/connect",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "BadgerClaw channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -0,0 +1,5 @@
1
+ {
2
+ "!oVrHNyMFgnOCfmjlLU:badger.signout.io": {
3
+ "autoReply": true
4
+ }
5
+ }
@@ -31,13 +31,35 @@ function resolveMatrixRoomConfigForGroup(params: ChannelGroupContext) {
31
31
  export function resolveMatrixGroupRequireMention(params: ChannelGroupContext): boolean {
32
32
  // Check per-room config first (set by /bot talk on|off)
33
33
  try {
34
- const { getRoomAutoReply } = require("./matrix/monitor/bot-commands.js");
35
- const roomId = params.groupId?.trim() ?? "";
36
- const roomAutoReply = getRoomAutoReply(roomId);
37
- if (roomAutoReply === true) return false;
38
- if (roomAutoReply === false) return true;
39
- } catch {
40
- // bot-commands module not available, fall through
34
+ const fs = require("fs");
35
+ const path = require("path");
36
+ const configPath = path.join(
37
+ process.env.HOME || "/tmp",
38
+ ".openclaw/extensions/badgerclaw/room-config.json"
39
+ );
40
+ const raw = fs.readFileSync(configPath, "utf-8");
41
+ const roomConfig = JSON.parse(raw) as Record<string, { autoReply?: boolean }>;
42
+ const rawGroupId = params.groupId?.trim() ?? "";
43
+ // Try multiple formats: raw, stripped prefixes, just the room ID part
44
+ const variants = [
45
+ rawGroupId,
46
+ rawGroupId.replace(/^badgerclaw:/, ""),
47
+ rawGroupId.replace(/^channel:/, ""),
48
+ rawGroupId.replace(/^room:/, ""),
49
+ ];
50
+ for (const variant of variants) {
51
+ if (variant && roomConfig[variant]?.autoReply === true) {
52
+ console.log(`[badgerclaw] room-config autoReply=true for ${variant}`);
53
+ return false;
54
+ }
55
+ if (variant && roomConfig[variant]?.autoReply === false) {
56
+ console.log(`[badgerclaw] room-config autoReply=false for ${variant}`);
57
+ return true;
58
+ }
59
+ }
60
+ console.log(`[badgerclaw] room-config: no match for groupId="${rawGroupId}", keys=${Object.keys(roomConfig).join(",")}`);
61
+ } catch (err) {
62
+ console.log(`[badgerclaw] room-config error: ${err}`);
41
63
  }
42
64
 
43
65
  const resolved = resolveMatrixRoomConfigForGroup(params);
@@ -39,6 +39,24 @@ export function registerMatrixAutoJoin(params: {
39
39
  const { AutojoinRoomsMixin } = loadMatrixSdk();
40
40
  AutojoinRoomsMixin.setupOnClient(client);
41
41
  logVerbose("badgerclaw: auto-join enabled for all invites");
42
+
43
+ // Also join any rooms with pending invites from before startup
44
+ (async () => {
45
+ try {
46
+ const syncData = await client.doRequest("GET", "/_matrix/client/v3/sync", { timeout: "0" });
47
+ const invitedRooms = Object.keys(syncData?.rooms?.invite ?? {});
48
+ for (const roomId of invitedRooms) {
49
+ try {
50
+ await client.joinRoom(roomId);
51
+ logVerbose(`badgerclaw: joined pending invite room ${roomId}`);
52
+ } catch (err) {
53
+ logVerbose(`badgerclaw: failed to join pending invite ${roomId}: ${err}`);
54
+ }
55
+ }
56
+ } catch {
57
+ // Ignore sync errors
58
+ }
59
+ })();
42
60
  return;
43
61
  }
44
62
 
@@ -7,6 +7,12 @@ const ROOM_CONFIG_PATH = path.join(
7
7
  ".openclaw/extensions/badgerclaw/room-config.json"
8
8
  );
9
9
 
10
+ // Session store path for core groupActivation
11
+ const SESSION_STORE_PATH = path.join(
12
+ process.env.HOME || "/tmp",
13
+ ".openclaw/agents/main/sessions/sessions.json"
14
+ );
15
+
10
16
  function loadRoomConfig(): Record<string, { autoReply?: boolean }> {
11
17
  try {
12
18
  return JSON.parse(fs.readFileSync(ROOM_CONFIG_PATH, "utf-8"));
@@ -19,6 +25,22 @@ function saveRoomConfig(config: Record<string, { autoReply?: boolean }>): void {
19
25
  fs.writeFileSync(ROOM_CONFIG_PATH, JSON.stringify(config, null, 2));
20
26
  }
21
27
 
28
+ function setGroupActivation(roomId: string, activation: "always" | "mention"): void {
29
+ try {
30
+ const store = JSON.parse(fs.readFileSync(SESSION_STORE_PATH, "utf-8"));
31
+ // Session key format: agent:main:badgerclaw:channel:!roomid (lowercase)
32
+ const sessionKey = `agent:main:badgerclaw:channel:${roomId.toLowerCase()}`;
33
+ if (!store[sessionKey]) {
34
+ store[sessionKey] = {};
35
+ }
36
+ store[sessionKey].groupActivation = activation;
37
+ fs.writeFileSync(SESSION_STORE_PATH, JSON.stringify(store, null, 2));
38
+ console.log(`[badgerclaw] set groupActivation=${activation} for ${sessionKey}`);
39
+ } catch (err) {
40
+ console.error(`[badgerclaw] failed to set groupActivation: ${err}`);
41
+ }
42
+ }
43
+
22
44
  export function getRoomAutoReply(roomId: string): boolean | undefined {
23
45
  const config = loadRoomConfig();
24
46
  return config[roomId]?.autoReply;
@@ -108,6 +130,7 @@ export async function handleBotCommand(params: {
108
130
  const config = loadRoomConfig();
109
131
  config[roomId] = { ...config[roomId], autoReply: true };
110
132
  saveRoomConfig(config);
133
+ setGroupActivation(roomId, "always");
111
134
  await client.sendMessage(roomId, {
112
135
  msgtype: "m.text",
113
136
  body: "✅ Auto-reply enabled — I'll respond to every message in this room.",
@@ -118,6 +141,7 @@ export async function handleBotCommand(params: {
118
141
  const config = loadRoomConfig();
119
142
  config[roomId] = { ...config[roomId], autoReply: false };
120
143
  saveRoomConfig(config);
144
+ setGroupActivation(roomId, "mention");
121
145
  await client.sendMessage(roomId, {
122
146
  msgtype: "m.text",
123
147
  body: "✅ Auto-reply disabled — I'll only respond when @mentioned.",