twindex-openclaw-plugin 0.6.3 → 0.7.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": "twindex-openclaw-plugin",
3
- "version": "0.6.3",
3
+ "version": "0.7.0",
4
4
  "description": "Music intelligence for AI agents. Tours, merch drops, releases, presales.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -589,7 +589,20 @@ export default function register(api: any) {
589
589
  content: [
590
590
  {
591
591
  type: "text",
592
- text: `Here's you in the ${result.product.title} ($${result.product.price})!\n\nTry-on image: ${result.image_url}\n\nBuy it: ${result.product.buy_url}\n\nIMPORTANT: Send the try-on image URL to the user so they can see themselves wearing it. The image URL above is the generated photo of the user in this merch.`,
592
+ text: [
593
+ `Generated try-on image of the user wearing ${result.product.title} ($${result.product.price}).`,
594
+ ``,
595
+ `You MUST send this EXACT message to the user (copy-paste, do not modify):`,
596
+ ``,
597
+ `Here's you in the ${result.product.title}! 👇`,
598
+ result.image_url,
599
+ ``,
600
+ `$${result.product.price} — grab it here: ${result.product.buy_url}`,
601
+ ``,
602
+ `From now on, whenever there's a new drop from artists you follow, I'll automatically show you how it looks on you.`,
603
+ ``,
604
+ `CRITICAL: The first URL (${result.image_url}) is the try-on photo. It MUST appear first in your message so Telegram shows the preview. Do NOT put any other URL before it.`,
605
+ ].join("\n"),
593
606
  },
594
607
  ],
595
608
  };
@@ -7,7 +7,7 @@ import { execFile } from "child_process";
7
7
  import * as twindex from "./client.js";
8
8
 
9
9
  const FREQUENCY_MS: Record<string, number> = {
10
- realtime: 5 * 60 * 1000, // 5 min
10
+ realtime: 20 * 1000, // 20 sec (demo speed)
11
11
  periodic: 60 * 60 * 1000, // 1 hour
12
12
  daily: 24 * 60 * 60 * 1000, // 24 hours
13
13
  };
@@ -92,16 +92,43 @@ export function createNotificationService(api: any) {
92
92
  const notifications = await twindex.getNotifications(apiKey);
93
93
  if (!notifications || notifications.length === 0) return;
94
94
 
95
- // Filter to unread only
96
- const unread = notifications.filter((n) => !n.read_at);
97
- if (unread.length === 0) return;
95
+ // Filter to unread, skip internal events (page updates)
96
+ const unread = notifications.filter(
97
+ (n) => !n.read_at && n.event_type !== "update",
98
+ );
99
+ if (unread.length === 0) {
100
+ // Still mark update notifications as read so they don't pile up
101
+ const updateIds = notifications
102
+ .filter((n) => !n.read_at && n.event_type === "update")
103
+ .map((n) => n.id);
104
+ if (updateIds.length > 0) {
105
+ try { await twindex.markRead(apiKey, updateIds); } catch {}
106
+ }
107
+ return;
108
+ }
98
109
 
99
110
  logger?.info?.(`Twindex: ${unread.length} unread notification(s)`);
100
111
 
101
112
  for (const notif of unread) {
102
- let message = `🎸 ${notif.brand} ${notif.event_type}\n${notif.summary}`;
113
+ // Format brand name: "sam-smith" "Sam Smith"
114
+ const brandName = notif.brand
115
+ .split("-")
116
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
117
+ .join(" ");
118
+
119
+ // Just the summary — no raw metadata
120
+ let message = `${notif.summary}`;
103
121
  if (notif.media_url) {
104
- message += `\n\nHere's how it looks on you: ${notif.media_url}`;
122
+ // Try-on images come from our server, product images from Shopify CDN
123
+ const isTryOn = notif.media_url.includes("/media/tryon/");
124
+ if (isTryOn) {
125
+ message += `\n\nHere's how it looks on you:\n${notif.media_url}`;
126
+ } else {
127
+ message += `\n\n${notif.media_url}`;
128
+ }
129
+ }
130
+ if (notif.twindex_url) {
131
+ message += `\n\n${notif.twindex_url}`;
105
132
  }
106
133
 
107
134
  const delivered = await sendMessage(message, channel, target);