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 +45 -25
- package/package.json +1 -1
- package/skills/antenna/SKILL.md +1 -0
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
|
|
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
package/skills/antenna/SKILL.md
CHANGED
|
@@ -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
|
|