antenna-openclaw-plugin 1.2.22 → 1.2.24

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/index.ts CHANGED
@@ -100,9 +100,18 @@ function extractWords(profile: Partial<Profile>): string[] {
100
100
  return text.split(/[\s,,。.!!??、;;::]+/).filter((w) => w.length > 1);
101
101
  }
102
102
 
103
- function deriveDeviceId(senderId: string, channel: string): string {
103
+ function deriveDeviceId(senderId: string, channel: string, chatId?: string): string {
104
104
  const id = `${channel}:${senderId}`;
105
105
  _knownDeviceIds.add(id);
106
+ if (chatId) {
107
+ _channelContext.set(id, chatId);
108
+ // Persist to DB async
109
+ try {
110
+ const cfg = getConfig(api);
111
+ const sb = getSupabase(cfg);
112
+ sb.rpc("upsert_profile", { p_device_id: id, p_last_chat_id: chatId }).then(() => {}).catch(() => {});
113
+ } catch {}
114
+ }
106
115
  return id;
107
116
  }
108
117
 
@@ -167,12 +176,6 @@ async function notifyUser(
167
176
  logger.warn(`Antenna: notify failed for ${channel}:${userId}: ${err.message}`);
168
177
  }
169
178
  }
170
- }
171
- logger.info(`Antenna: notified ${channel}:${userId} (chat=${chatId || 'deliver'})`);
172
- } catch (err: any) {
173
- logger.warn(`Antenna: notify failed for ${channel}:${userId}: ${err.message}`);
174
- }
175
- }
176
179
 
177
180
  function startFollowUpCron(
178
181
  deviceId: string,
@@ -262,14 +265,15 @@ export default function register(api: any) {
262
265
  lng: { type: "number", description: "Longitude (optional if location was shared via web)" },
263
266
  radius_m: { type: "number", description: "Search radius in meters (default 500, max 1000)" },
264
267
  sender_id: { type: "string", description: "The sender's user ID (from message context)" },
265
- channel: { type: "string", description: "The channel name (telegram, whatsapp, etc.)" },
268
+ channel: { type: "string", description: "The channel name" },
269
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
266
270
  },
267
271
  required: ["sender_id", "channel"],
268
272
  },
269
273
  async execute(_id: string, params: any) {
270
274
  const cfg = getConfig(api);
271
275
  const supabase = getSupabase(cfg);
272
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
276
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
273
277
  const radius = params.radius_m ?? cfg.defaultRadiusM ?? 500;
274
278
 
275
279
  if (isRateLimited(deviceId)) {
@@ -376,6 +380,7 @@ export default function register(api: any) {
376
380
  action: { type: "string", enum: ["get", "set"], description: "'get' to view profile, 'set' to update it" },
377
381
  sender_id: { type: "string", description: "The sender's user ID" },
378
382
  channel: { type: "string", description: "The channel name" },
383
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
379
384
  display_name: { type: "string", description: "Display name" },
380
385
  emoji: { type: "string", description: "Profile emoji" },
381
386
  line1: { type: "string", description: "First line (who you are / what you do)" },
@@ -388,7 +393,7 @@ export default function register(api: any) {
388
393
  async execute(_id: string, params: any) {
389
394
  const cfg = getConfig(api);
390
395
  const supabase = getSupabase(cfg);
391
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
396
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
392
397
 
393
398
  if (params.action === "get") {
394
399
  const { data, error } = await supabase.rpc("get_profile", { p_device_id: deviceId });
@@ -434,6 +439,7 @@ export default function register(api: any) {
434
439
  lng: { type: "number", description: "Longitude" },
435
440
  sender_id: { type: "string", description: "The sender's user ID" },
436
441
  channel: { type: "string", description: "The channel name" },
442
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
437
443
  place_name: { type: "string", description: "Optional: name of the place (for confirmation message)" },
438
444
  },
439
445
  required: ["lat", "lng", "sender_id", "channel"],
@@ -441,7 +447,7 @@ export default function register(api: any) {
441
447
  async execute(_id: string, params: any) {
442
448
  const cfg = getConfig(api);
443
449
  const supabase = getSupabase(cfg);
444
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
450
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
445
451
  const fuzzy = fuzzyCoords(params.lat, params.lng);
446
452
 
447
453
  // Check if user has a profile first
@@ -479,6 +485,7 @@ export default function register(api: any) {
479
485
  properties: {
480
486
  sender_id: { type: "string" },
481
487
  channel: { type: "string" },
488
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
482
489
  ref: { type: "string", description: "Ref number from scan results (e.g. '1')" },
483
490
  target_device_id: { type: "string", description: "Device ID (use ref instead when possible)" },
484
491
  contact_info: { type: "string", description: "Optional contact info to share" },
@@ -488,7 +495,7 @@ export default function register(api: any) {
488
495
  async execute(_id: string, params: any) {
489
496
  const cfg = getConfig(api);
490
497
  const supabase = getSupabase(cfg);
491
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
498
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
492
499
 
493
500
  // Resolve ref to device_id — try DB first, then memory fallback
494
501
  let targetId = params.target_device_id;
@@ -555,6 +562,7 @@ export default function register(api: any) {
555
562
  properties: {
556
563
  sender_id: { type: "string", description: "The sender's user ID" },
557
564
  channel: { type: "string", description: "The channel name" },
565
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
558
566
  purpose: { type: "string", description: "'profile' (default) or 'event'" },
559
567
  event_code: { type: "string", description: "Event code (required when purpose=event)" },
560
568
  },
@@ -563,7 +571,7 @@ export default function register(api: any) {
563
571
  async execute(_id: string, params: any) {
564
572
  const cfg = getConfig(api);
565
573
  const supabase = getSupabase(cfg);
566
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
574
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
567
575
 
568
576
  const { data, error } = await supabase.rpc("create_bind_token", {
569
577
  p_device_id: deviceId,
@@ -597,13 +605,14 @@ export default function register(api: any) {
597
605
  properties: {
598
606
  sender_id: { type: "string", description: "The sender's user ID" },
599
607
  channel: { type: "string", description: "The channel name" },
608
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
600
609
  },
601
610
  required: ["sender_id", "channel"],
602
611
  },
603
612
  async execute(_id: string, params: any) {
604
613
  const cfg = getConfig(api);
605
614
  const supabase = getSupabase(cfg);
606
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
615
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
607
616
 
608
617
  const { data: globalData } = await supabase.rpc("global_discover", {
609
618
  p_device_id: deviceId, p_limit: 1,
@@ -677,6 +686,7 @@ export default function register(api: any) {
677
686
  name: { type: "string", description: "Event name" },
678
687
  sender_id: { type: "string" },
679
688
  channel: { type: "string" },
689
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
680
690
  lat: { type: "number", description: "Event latitude" },
681
691
  lng: { type: "number", description: "Event longitude" },
682
692
  starts_at: { type: "string", description: "Start time ISO" },
@@ -691,7 +701,7 @@ export default function register(api: any) {
691
701
  async execute(_id: string, params: any) {
692
702
  const cfg = getConfig(api);
693
703
  const supabase = getSupabase(cfg);
694
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
704
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
695
705
  const { data, error } = await supabase.rpc("create_event", {
696
706
  p_name: params.name,
697
707
  p_lat: params.lat || null,
@@ -721,13 +731,14 @@ export default function register(api: any) {
721
731
  code: { type: "string", description: "Event code" },
722
732
  sender_id: { type: "string" },
723
733
  channel: { type: "string" },
734
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
724
735
  },
725
736
  required: ["code", "sender_id", "channel"],
726
737
  },
727
738
  async execute(_id: string, params: any) {
728
739
  const cfg = getConfig(api);
729
740
  const supabase = getSupabase(cfg);
730
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
741
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
731
742
  const { data, error } = await supabase.rpc("end_event", {
732
743
  p_code: params.code,
733
744
  p_device_id: deviceId,
@@ -749,6 +760,7 @@ export default function register(api: any) {
749
760
  code: { type: "string", description: "Event code" },
750
761
  sender_id: { type: "string" },
751
762
  channel: { type: "string" },
763
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
752
764
  lat: { type: "number", description: "Latitude (optional, for auto-checkin)" },
753
765
  lng: { type: "number", description: "Longitude (optional, for auto-checkin)" },
754
766
  application_context: { type: "string", description: "Application context from screening conversation" },
@@ -758,7 +770,7 @@ export default function register(api: any) {
758
770
  async execute(_id: string, params: any) {
759
771
  const cfg = getConfig(api);
760
772
  const supabase = getSupabase(cfg);
761
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
773
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
762
774
 
763
775
  // Profile gate
764
776
  const { data: profile } = await supabase.rpc("get_profile", { p_device_id: deviceId });
@@ -833,13 +845,14 @@ export default function register(api: any) {
833
845
  code: { type: "string", description: "Event code" },
834
846
  sender_id: { type: "string" },
835
847
  channel: { type: "string" },
848
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
836
849
  },
837
850
  required: ["code", "sender_id", "channel"],
838
851
  },
839
852
  async execute(_id: string, params: any) {
840
853
  const cfg = getConfig(api);
841
854
  const supabase = getSupabase(cfg);
842
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
855
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
843
856
 
844
857
  const { data, error } = await supabase.rpc("event_participants_list", { p_code: params.code, p_device_id: deviceId });
845
858
  if (error) return ok({ error: error.message });
@@ -870,6 +883,7 @@ export default function register(api: any) {
870
883
  properties: {
871
884
  sender_id: { type: "string", description: "The sender's user ID" },
872
885
  channel: { type: "string", description: "The channel name" },
886
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
873
887
  ref: { type: "string", description: "Ref number from scan/discover results" },
874
888
  target_device_id: { type: "string", description: "Device ID (use ref instead when possible)" },
875
889
  },
@@ -878,7 +892,7 @@ export default function register(api: any) {
878
892
  async execute(_id: string, params: any) {
879
893
  const cfg = getConfig(api);
880
894
  const supabase = getSupabase(cfg);
881
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
895
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
882
896
 
883
897
  let targetId = params.target_device_id;
884
898
  if (!targetId && params.ref) {
@@ -906,6 +920,7 @@ export default function register(api: any) {
906
920
  code: { type: "string", description: "Event code" },
907
921
  sender_id: { type: "string" },
908
922
  channel: { type: "string" },
923
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
909
924
  lat: { type: "number", description: "Latitude (optional)" },
910
925
  lng: { type: "number", description: "Longitude (optional)" },
911
926
  },
@@ -914,7 +929,7 @@ export default function register(api: any) {
914
929
  async execute(_id: string, params: any) {
915
930
  const cfg = getConfig(api);
916
931
  const supabase = getSupabase(cfg);
917
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
932
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
918
933
  const fuzzy = (params.lat != null && params.lng != null) ? fuzzyCoords(params.lat, params.lng) : { lat: null, lng: null };
919
934
  const { data, error } = await supabase.rpc("event_checkin", {
920
935
  p_code: params.code,
@@ -966,13 +981,14 @@ export default function register(api: any) {
966
981
  properties: {
967
982
  sender_id: { type: "string" },
968
983
  channel: { type: "string" },
984
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
969
985
  },
970
986
  required: ["sender_id", "channel"],
971
987
  },
972
988
  async execute(_id: string, params: any) {
973
989
  const cfg = getConfig(api);
974
990
  const supabase = getSupabase(cfg);
975
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
991
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
976
992
 
977
993
  const { data: allMatches } = await supabase.rpc("get_my_matches", { p_device_id: deviceId });
978
994
 
@@ -1048,6 +1064,7 @@ export default function register(api: any) {
1048
1064
  code: { type: "string", description: "Event code" },
1049
1065
  sender_id: { type: "string" },
1050
1066
  channel: { type: "string" },
1067
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
1051
1068
  name: { type: "string", description: "New event name" },
1052
1069
  description: { type: "string", description: "New event description" },
1053
1070
  og_image: { type: "string", description: "New OG image URL" },
@@ -1061,7 +1078,7 @@ export default function register(api: any) {
1061
1078
  async execute(_id: string, params: any) {
1062
1079
  const cfg = getConfig(api);
1063
1080
  const supabase = getSupabase(cfg);
1064
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
1081
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
1065
1082
  const { data, error } = await supabase.rpc("update_event", {
1066
1083
  p_code: params.code, p_device_id: deviceId,
1067
1084
  p_name: params.name || null, p_description: params.description || null,
@@ -1085,6 +1102,7 @@ export default function register(api: any) {
1085
1102
  code: { type: "string", description: "Event code" },
1086
1103
  sender_id: { type: "string" },
1087
1104
  channel: { type: "string" },
1105
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
1088
1106
  ref: { type: "string", description: "Ref number of the participant to approve" },
1089
1107
  },
1090
1108
  required: ["code", "sender_id", "channel", "ref"],
@@ -1092,7 +1110,7 @@ export default function register(api: any) {
1092
1110
  async execute(_id: string, params: any) {
1093
1111
  const cfg = getConfig(api);
1094
1112
  const supabase = getSupabase(cfg);
1095
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
1113
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
1096
1114
  const { data, error } = await supabase.rpc("approve_participant", {
1097
1115
  p_code: params.code, p_device_id: deviceId, p_target_ref: params.ref,
1098
1116
  });
@@ -1113,6 +1131,7 @@ export default function register(api: any) {
1113
1131
  code: { type: "string", description: "Event code" },
1114
1132
  sender_id: { type: "string" },
1115
1133
  channel: { type: "string" },
1134
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
1116
1135
  ref: { type: "string", description: "Ref number of the participant to reject" },
1117
1136
  },
1118
1137
  required: ["code", "sender_id", "channel", "ref"],
@@ -1120,7 +1139,7 @@ export default function register(api: any) {
1120
1139
  async execute(_id: string, params: any) {
1121
1140
  const cfg = getConfig(api);
1122
1141
  const supabase = getSupabase(cfg);
1123
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
1142
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
1124
1143
  const { data, error } = await supabase.rpc("reject_participant", {
1125
1144
  p_code: params.code, p_device_id: deviceId, p_target_ref: params.ref,
1126
1145
  });
@@ -1141,6 +1160,7 @@ export default function register(api: any) {
1141
1160
  code: { type: "string", description: "Event code" },
1142
1161
  sender_id: { type: "string" },
1143
1162
  channel: { type: "string" },
1163
+ chat_id: { type: "string", description: "Chat/channel ID for notifications (from message context)" },
1144
1164
  ref: { type: "string", description: "Ref number of the participant to make co-host" },
1145
1165
  },
1146
1166
  required: ["code", "sender_id", "channel", "ref"],
@@ -1148,7 +1168,7 @@ export default function register(api: any) {
1148
1168
  async execute(_id: string, params: any) {
1149
1169
  const cfg = getConfig(api);
1150
1170
  const supabase = getSupabase(cfg);
1151
- const deviceId = deriveDeviceId(params.sender_id, params.channel);
1171
+ const deviceId = deriveDeviceId(params.sender_id, params.channel, params.chat_id);
1152
1172
  const { data, error } = await supabase.rpc("add_cohost", {
1153
1173
  p_code: params.code, p_device_id: deviceId, p_target_ref: params.ref,
1154
1174
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antenna-openclaw-plugin",
3
- "version": "1.2.22",
3
+ "version": "1.2.24",
4
4
  "description": "Antenna — agent-mediated nearby people discovery for OpenClaw",
5
5
  "openclaw": {
6
6
  "extensions": ["./index.ts"]
@@ -12,6 +12,7 @@ You have access to Antenna for location-based social discovery.
12
12
  - If you have Antenna plugin tools registered (antenna_scan, antenna_profile, etc.) — use them directly.
13
13
  - If not, use CLI: `antenna <command> [flags]`. Example: `antenna scan --id telegram:123`. The CLI supports all the same features.
14
14
  - All tool names map to CLI commands: `antenna_scan` → `antenna scan`, `antenna_event_create` → `antenna event --create`, etc.
15
+ - **Always pass `chat_id`** when calling any Antenna tool. This is the chat/channel ID from your message context (e.g. Discord channel ID, Telegram chat ID). Antenna uses it to send you notifications about matches and event approvals.
15
16
 
16
17
  ## Onboarding — 装上之后主动引导
17
18