@alfe.ai/openclaw-google-chat 0.0.4 → 0.0.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/plugin2.cjs CHANGED
@@ -161,6 +161,37 @@ async function listRecentMessages(token, spaceName, limit) {
161
161
  return (await request(token, `/${spaceName}/messages?${new URLSearchParams({ pageSize: String(limit) }).toString()}`)).messages ?? [];
162
162
  }
163
163
  //#endregion
164
+ //#region src/markdown-to-gchat.ts
165
+ /**
166
+ * Convert standard Markdown to Google Chat text formatting.
167
+ *
168
+ * Google Chat supports: *bold*, _italic_, ~strikethrough~, `code`,
169
+ * ```code blocks```, but NOT standard Markdown syntax like **bold**,
170
+ * ## headings, or - bullet lists.
171
+ */
172
+ const CODE_BLOCK_RE = /```[\s\S]*?```/g;
173
+ const INLINE_CODE_RE = /`[^`]+`/g;
174
+ function markdownToGChat(text) {
175
+ const preserved = [];
176
+ const placeholder = (i) => `\x00CODE${String(i)}\x00`;
177
+ let result = text.replace(CODE_BLOCK_RE, (match) => {
178
+ preserved.push(match);
179
+ return placeholder(preserved.length - 1);
180
+ });
181
+ result = result.replace(INLINE_CODE_RE, (match) => {
182
+ preserved.push(match);
183
+ return placeholder(preserved.length - 1);
184
+ });
185
+ result = result.replace(/^#{1,6}\s+(.+)$/gm, "*$1*");
186
+ result = result.replace(/\*\*(.+?)\*\*/g, "*$1*");
187
+ result = result.replace(/__(.+?)__/g, "*$1*");
188
+ result = result.replace(/~~(.+?)~~/g, "~$1~");
189
+ result = result.replace(/^[\s]*[-*]\s+/gm, "• ");
190
+ result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1 ($2)");
191
+ for (let i = preserved.length - 1; i >= 0; i--) result = result.replace(placeholder(i), () => preserved[i]);
192
+ return result;
193
+ }
194
+ //#endregion
164
195
  //#region src/gchat-poller.ts
165
196
  const INTERVAL_ACTIVE_MS = 1e3;
166
197
  const INTERVAL_WARM_MS = 5e3;
@@ -355,7 +386,9 @@ var GChatPoller = class {
355
386
  return;
356
387
  }
357
388
  const conversationId = `alfe:gchat:${state.spaceName}`;
358
- const peerLabel = state.peerDisplayName ?? "User";
389
+ const senderName = message.sender.name || state.peerUserId;
390
+ const senderDisplayName = message.sender.displayName;
391
+ const peerLabel = senderDisplayName || state.peerDisplayName || "User";
359
392
  this.log.info(`Dispatching message from ${peerLabel} in ${state.spaceName}`);
360
393
  try {
361
394
  const cfg = this.runtime.config.loadConfig();
@@ -367,10 +400,10 @@ var GChatPoller = class {
367
400
  accountId: "default",
368
401
  peer: {
369
402
  kind: "direct",
370
- id: `gchat:${state.peerUserId}:conv:${conversationId}`
403
+ id: `gchat:${senderName}:conv:${conversationId}`
371
404
  },
372
- senderId: `gchat:${state.peerUserId}`,
373
- senderAddress: `user:gchat:${state.peerUserId}`,
405
+ senderId: `gchat:${senderName}`,
406
+ senderAddress: `user:gchat:${senderName}`,
374
407
  recipientAddress: "agent",
375
408
  conversationLabel: `[Google Chat] ${peerLabel}`,
376
409
  rawBody: message.text,
@@ -379,11 +412,12 @@ var GChatPoller = class {
379
412
  extraContext: {
380
413
  ChannelMode: "gchat",
381
414
  ConversationId: conversationId,
382
- ...state.peerDisplayName ? { SenderName: state.peerDisplayName } : {}
415
+ ...senderDisplayName ? { SenderName: senderDisplayName } : {}
383
416
  },
384
417
  deliver: async (payload) => {
385
- const text = payload.text ?? "";
386
- if (!text) return;
418
+ const raw = payload.text ?? "";
419
+ if (!raw) return;
420
+ const text = markdownToGChat(raw);
387
421
  try {
388
422
  await sendMessage(await this.tokenManager.getAccessToken(), state.spaceName, text);
389
423
  } catch (err) {
package/dist/plugin2.js CHANGED
@@ -161,6 +161,37 @@ async function listRecentMessages(token, spaceName, limit) {
161
161
  return (await request(token, `/${spaceName}/messages?${new URLSearchParams({ pageSize: String(limit) }).toString()}`)).messages ?? [];
162
162
  }
163
163
  //#endregion
164
+ //#region src/markdown-to-gchat.ts
165
+ /**
166
+ * Convert standard Markdown to Google Chat text formatting.
167
+ *
168
+ * Google Chat supports: *bold*, _italic_, ~strikethrough~, `code`,
169
+ * ```code blocks```, but NOT standard Markdown syntax like **bold**,
170
+ * ## headings, or - bullet lists.
171
+ */
172
+ const CODE_BLOCK_RE = /```[\s\S]*?```/g;
173
+ const INLINE_CODE_RE = /`[^`]+`/g;
174
+ function markdownToGChat(text) {
175
+ const preserved = [];
176
+ const placeholder = (i) => `\x00CODE${String(i)}\x00`;
177
+ let result = text.replace(CODE_BLOCK_RE, (match) => {
178
+ preserved.push(match);
179
+ return placeholder(preserved.length - 1);
180
+ });
181
+ result = result.replace(INLINE_CODE_RE, (match) => {
182
+ preserved.push(match);
183
+ return placeholder(preserved.length - 1);
184
+ });
185
+ result = result.replace(/^#{1,6}\s+(.+)$/gm, "*$1*");
186
+ result = result.replace(/\*\*(.+?)\*\*/g, "*$1*");
187
+ result = result.replace(/__(.+?)__/g, "*$1*");
188
+ result = result.replace(/~~(.+?)~~/g, "~$1~");
189
+ result = result.replace(/^[\s]*[-*]\s+/gm, "• ");
190
+ result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1 ($2)");
191
+ for (let i = preserved.length - 1; i >= 0; i--) result = result.replace(placeholder(i), () => preserved[i]);
192
+ return result;
193
+ }
194
+ //#endregion
164
195
  //#region src/gchat-poller.ts
165
196
  const INTERVAL_ACTIVE_MS = 1e3;
166
197
  const INTERVAL_WARM_MS = 5e3;
@@ -355,7 +386,9 @@ var GChatPoller = class {
355
386
  return;
356
387
  }
357
388
  const conversationId = `alfe:gchat:${state.spaceName}`;
358
- const peerLabel = state.peerDisplayName ?? "User";
389
+ const senderName = message.sender.name || state.peerUserId;
390
+ const senderDisplayName = message.sender.displayName;
391
+ const peerLabel = senderDisplayName || state.peerDisplayName || "User";
359
392
  this.log.info(`Dispatching message from ${peerLabel} in ${state.spaceName}`);
360
393
  try {
361
394
  const cfg = this.runtime.config.loadConfig();
@@ -367,10 +400,10 @@ var GChatPoller = class {
367
400
  accountId: "default",
368
401
  peer: {
369
402
  kind: "direct",
370
- id: `gchat:${state.peerUserId}:conv:${conversationId}`
403
+ id: `gchat:${senderName}:conv:${conversationId}`
371
404
  },
372
- senderId: `gchat:${state.peerUserId}`,
373
- senderAddress: `user:gchat:${state.peerUserId}`,
405
+ senderId: `gchat:${senderName}`,
406
+ senderAddress: `user:gchat:${senderName}`,
374
407
  recipientAddress: "agent",
375
408
  conversationLabel: `[Google Chat] ${peerLabel}`,
376
409
  rawBody: message.text,
@@ -379,11 +412,12 @@ var GChatPoller = class {
379
412
  extraContext: {
380
413
  ChannelMode: "gchat",
381
414
  ConversationId: conversationId,
382
- ...state.peerDisplayName ? { SenderName: state.peerDisplayName } : {}
415
+ ...senderDisplayName ? { SenderName: senderDisplayName } : {}
383
416
  },
384
417
  deliver: async (payload) => {
385
- const text = payload.text ?? "";
386
- if (!text) return;
418
+ const raw = payload.text ?? "";
419
+ if (!raw) return;
420
+ const text = markdownToGChat(raw);
387
421
  try {
388
422
  await sendMessage(await this.tokenManager.getAccessToken(), state.spaceName, text);
389
423
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/openclaw-google-chat",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "OpenClaw Google Chat plugin — DM polling and auto-reply via connected Google account",
5
5
  "type": "module",
6
6
  "main": "./dist/plugin.js",