@ebowwa/channel-telegram 1.17.1 → 1.17.2

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/types.d.ts CHANGED
@@ -223,4 +223,100 @@ export interface ConversationMessage {
223
223
  role: 'user' | 'assistant';
224
224
  content: string;
225
225
  }
226
+ /**
227
+ * Extended location interface that includes all Telegram Bot API properties.
228
+ * The @types/node-telegram-bot-api only includes latitude/longitude.
229
+ * @see https://core.telegram.org/bots/api#location
230
+ */
231
+ export interface TelegramLocation {
232
+ /** Longitude as defined by sender */
233
+ longitude: number;
234
+ /** Latitude as defined by sender */
235
+ latitude: number;
236
+ /** Optional. The radius of uncertainty for the location, measured in meters; 0-1500 */
237
+ horizontal_accuracy?: number;
238
+ /** Optional. Time relative to the message sending date, during which the location can be updated, in seconds */
239
+ live_period?: number;
240
+ /** Optional. The direction in which the user is moving, in degrees; 1-360 */
241
+ heading?: number;
242
+ /** Optional. The maximum distance for proximity alerts about approaching another chat member, in meters */
243
+ proximity_alert_radius?: number;
244
+ }
245
+ /**
246
+ * Represents a venue (location + name/address).
247
+ * @see https://core.telegram.org/bots/api#venue
248
+ */
249
+ export interface TelegramVenue {
250
+ /** The location of the venue */
251
+ location: TelegramLocation;
252
+ /** Name of the venue */
253
+ title: string;
254
+ /** Address of the venue */
255
+ address: string;
256
+ /** Optional. Foursquare identifier of the venue */
257
+ foursquare_id?: string;
258
+ /** Optional. Foursquare type of the venue */
259
+ foursquare_type?: string;
260
+ /** Optional. Google Places identifier of the venue */
261
+ google_place_id?: string;
262
+ /** Optional. Google Places type of the venue */
263
+ google_place_type?: string;
264
+ }
265
+ /**
266
+ * Live location state for tracking active live locations.
267
+ */
268
+ export interface LiveLocationState {
269
+ /** Chat ID where the live location was shared */
270
+ chatId: number;
271
+ /** Message ID of the location message */
272
+ messageId: number;
273
+ /** User ID who shared the location */
274
+ userId: number;
275
+ /** Current location data */
276
+ location: TelegramLocation;
277
+ /** When the live location was first received */
278
+ startedAt: Date;
279
+ /** When the live location expires (calculated from live_period) */
280
+ expiresAt?: Date;
281
+ /** Number of updates received */
282
+ updateCount: number;
283
+ }
284
+ /**
285
+ * Options for sending a location.
286
+ */
287
+ export interface SendLocationOptions {
288
+ /** Unique identifier for the target message thread (topic) of the forum */
289
+ message_thread_id?: number;
290
+ /** Period in seconds for which the location will be updated (see Live Locations) */
291
+ live_period?: number;
292
+ /** Latitude of the location */
293
+ latitude: number;
294
+ /** Longitude of the location */
295
+ longitude: number;
296
+ /** The radius of uncertainty for the location, measured in meters; 0-1500 */
297
+ horizontal_accuracy?: number;
298
+ /** Direction in which the location moves, in degrees; 1-360 */
299
+ heading?: number;
300
+ /** Maximum distance for proximity alerts, in meters; 1-100000 */
301
+ proximity_alert_radius?: number;
302
+ /** Sends the message silently */
303
+ disable_notification?: boolean;
304
+ /** Protects the contents of the sent message from forwarding and saving */
305
+ protect_content?: boolean;
306
+ }
307
+ /**
308
+ * Options for editing a live location.
309
+ */
310
+ export interface EditLiveLocationOptions {
311
+ /** Latitude of new location */
312
+ latitude: number;
313
+ /** Longitude of new location */
314
+ longitude: number;
315
+ /** The radius of uncertainty for the location, measured in meters; 0-1500 */
316
+ horizontal_accuracy?: number;
317
+ /** Direction in which the location moves, in degrees; 1-360 */
318
+ heading?: number;
319
+ /** Maximum distance for proximity alerts, in meters; 1-100000 */
320
+ proximity_alert_radius?: number;
321
+ }
226
322
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebowwa/channel-telegram",
3
- "version": "1.17.1",
3
+ "version": "1.17.2",
4
4
  "description": "Pure Telegram protocol adapter implementing ChannelConnector",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/index.ts CHANGED
@@ -24,12 +24,51 @@ import {
24
24
  type MessageSender,
25
25
  type MessageContext,
26
26
  type MessageHandler,
27
+ type MediaAttachment,
28
+ type ChannelLocation,
27
29
  createChannelId,
28
30
  } from "@ebowwa/channel-types";
29
31
 
30
32
  import { ConversationMemory } from "./conversation-memory.js";
31
33
  import { registerAllCommands, isQuiet } from "./commands/index.js";
32
- import type { Tool } from "./types.js";
34
+ import type { Tool, TelegramLocation, TelegramVenue, LiveLocationState, SendLocationOptions, EditLiveLocationOptions } from "./types.js";
35
+
36
+ /**
37
+ * Extended Telegram Location type that includes all Bot API properties.
38
+ * The node-telegram-bot-api types only include latitude/longitude.
39
+ */
40
+ interface TelegramLocationExtended {
41
+ latitude: number;
42
+ longitude: number;
43
+ horizontal_accuracy?: number;
44
+ live_period?: number;
45
+ heading?: number;
46
+ proximity_alert_radius?: number;
47
+ }
48
+
49
+ /**
50
+ * Location data storage for message metadata.
51
+ */
52
+ interface LocationData {
53
+ type: "location" | "location_update";
54
+ location: TelegramLocation;
55
+ isLive: boolean;
56
+ venue?: TelegramVenue;
57
+ updateNumber?: number;
58
+ }
59
+
60
+ /**
61
+ * Extended Telegram Location type that includes all Bot API properties.
62
+ * The node-telegram-bot-api types only include latitude/longitude.
63
+ */
64
+ interface TelegramLocationExtended {
65
+ latitude: number;
66
+ longitude: number;
67
+ horizontal_accuracy?: number;
68
+ live_period?: number;
69
+ heading?: number;
70
+ proximity_alert_radius?: number;
71
+ }
33
72
 
34
73
  // ============================================================
35
74
  // PLUGIN EXPORTS (ChannelPlugin Pattern)
@@ -76,6 +115,12 @@ export type {
76
115
  SetChatMemberTagParams,
77
116
  PromoteChatMemberParams,
78
117
  LinkPreviewOptions,
118
+ // Location Types
119
+ TelegramLocation,
120
+ TelegramVenue,
121
+ LiveLocationState,
122
+ SendLocationOptions,
123
+ EditLiveLocationOptions,
79
124
  } from "./types.js";
80
125
 
81
126
  // Normalization utilities
@@ -149,6 +194,11 @@ export class TelegramChannel {
149
194
  private connected = false;
150
195
  // Streaming state
151
196
  private activeStreams: Map<string, { messageId?: number; lastText: string; lastUpdate: number; pendingPromise?: Promise<void> }> = new Map();
197
+ // Live location tracking state
198
+ private liveLocations: Map<string, LiveLocationState> = new Map();
199
+ private liveLocationCleanupInterval?: NodeJS.Timeout;
200
+ // Location data storage for message metadata
201
+ private locationData: Map<string, LocationData> = new Map();
152
202
 
153
203
  constructor(config: TelegramConfig) {
154
204
  this.config = config;
@@ -172,6 +222,9 @@ export class TelegramChannel {
172
222
  reactions: true,
173
223
  editing: true,
174
224
  streaming: this.nativeStreaming,
225
+ locations: true,
226
+ liveLocations: true,
227
+ venues: true,
175
228
  },
176
229
  media: {
177
230
  maxFileSize: 50 * 1024 * 1024, // 50MB
@@ -202,6 +255,9 @@ export class TelegramChannel {
202
255
  },
203
256
  });
204
257
 
258
+ // Start live location cleanup interval (every 5 minutes)
259
+ this.startLiveLocationCleanupTimer();
260
+
205
261
  // NOTE: Commands are NOT registered here with bot.onText() handlers.
206
262
  // Instead, all messages (including commands) flow through the message event
207
263
  // to the daemon's messageHandler, which uses @ebowwa/channel-command for unified handling.
@@ -220,6 +276,13 @@ export class TelegramChannel {
220
276
 
221
277
  async stop(): Promise<void> {
222
278
  console.log("[TelegramChannel] Stopping...");
279
+ // Stop live location cleanup timer
280
+ if (this.liveLocationCleanupInterval) {
281
+ clearInterval(this.liveLocationCleanupInterval);
282
+ this.liveLocationCleanupInterval = undefined;
283
+ }
284
+ // Clear all live locations
285
+ this.liveLocations.clear();
223
286
  await this.bot.stopPolling();
224
287
  this.connected = false;
225
288
  }
@@ -501,6 +564,389 @@ export class TelegramChannel {
501
564
  return false;
502
565
  }
503
566
 
567
+ // ============================================================
568
+ // Live Location Methods
569
+ // ============================================================
570
+
571
+ /**
572
+ * Send a static or live location.
573
+ * If live_period is set, the location can be updated with editLiveLocation.
574
+ */
575
+ async sendLocation(chatId: number, options: SendLocationOptions): Promise<TelegramBot.Message> {
576
+ const result = await this.bot.sendLocation(chatId, options.latitude, options.longitude, {
577
+ live_period: options.live_period,
578
+ disable_notification: options.disable_notification,
579
+ });
580
+
581
+ // Track live location if live_period is set
582
+ if (options.live_period && result.location) {
583
+ const key = `${chatId}:${result.message_id}`;
584
+ const expiresAt = options.live_period
585
+ ? new Date(Date.now() + options.live_period * 1000)
586
+ : undefined;
587
+
588
+ const locationData: TelegramLocationExtended = {
589
+ latitude: result.location.latitude,
590
+ longitude: result.location.longitude,
591
+ live_period: options.live_period,
592
+ heading: options.heading,
593
+ horizontal_accuracy: options.horizontal_accuracy,
594
+ proximity_alert_radius: options.proximity_alert_radius,
595
+ };
596
+
597
+ this.liveLocations.set(key, {
598
+ chatId,
599
+ messageId: result.message_id,
600
+ userId: result.from?.id || 0,
601
+ location: locationData,
602
+ startedAt: new Date(),
603
+ expiresAt,
604
+ updateCount: 0,
605
+ });
606
+
607
+ console.log(`[TelegramChannel] Started tracking live location: ${key}, expires in ${options.live_period}s`);
608
+ }
609
+
610
+ return result;
611
+ }
612
+
613
+ /**
614
+ * Edit a live location message.
615
+ * Updates the location and returns the edited message.
616
+ */
617
+ async editLiveLocation(
618
+ chatId: number,
619
+ messageId: number,
620
+ options: EditLiveLocationOptions
621
+ ): Promise<TelegramBot.Message | boolean> {
622
+ const result = await this.bot.editMessageLiveLocation(options.latitude, options.longitude, {
623
+ chat_id: chatId,
624
+ message_id: messageId,
625
+ });
626
+
627
+ // Update tracked state
628
+ const key = `${chatId}:${messageId}`;
629
+ const state = this.liveLocations.get(key);
630
+ if (state) {
631
+ state.location = {
632
+ ...state.location,
633
+ latitude: options.latitude,
634
+ longitude: options.longitude,
635
+ horizontal_accuracy: options.horizontal_accuracy,
636
+ heading: options.heading,
637
+ proximity_alert_radius: options.proximity_alert_radius,
638
+ };
639
+ state.updateCount++;
640
+ console.log(`[TelegramChannel] Updated live location: ${key} (update #${state.updateCount})`);
641
+ }
642
+
643
+ return result;
644
+ }
645
+
646
+ /**
647
+ * Stop a live location message.
648
+ * The location will no longer update.
649
+ */
650
+ async stopLiveLocation(chatId: number, messageId: number): Promise<TelegramBot.Message | boolean> {
651
+ const result = await this.bot.stopMessageLiveLocation({
652
+ chat_id: chatId,
653
+ message_id: messageId,
654
+ });
655
+
656
+ // Remove from tracking
657
+ const key = `${chatId}:${messageId}`;
658
+ const state = this.liveLocations.get(key);
659
+ if (state) {
660
+ console.log(`[TelegramChannel] Stopped live location: ${key} (had ${state.updateCount} updates)`);
661
+ this.liveLocations.delete(key);
662
+ }
663
+
664
+ return result;
665
+ }
666
+
667
+ /**
668
+ * Get live location state for a specific message.
669
+ */
670
+ getLiveLocation(chatId: number, messageId: number): LiveLocationState | undefined {
671
+ const key = `${chatId}:${messageId}`;
672
+ return this.liveLocations.get(key);
673
+ }
674
+
675
+ /**
676
+ * Get all active live locations being tracked.
677
+ */
678
+ getActiveLiveLocations(): LiveLocationState[] {
679
+ // Clean up expired locations first
680
+ this.cleanupExpiredLiveLocations();
681
+ return Array.from(this.liveLocations.values());
682
+ }
683
+
684
+ /**
685
+ * Get live locations shared by a specific user.
686
+ */
687
+ getLiveLocationsByUser(userId: number): LiveLocationState[] {
688
+ this.cleanupExpiredLiveLocations();
689
+ return Array.from(this.liveLocations.values()).filter(
690
+ (state) => state.userId === userId
691
+ );
692
+ }
693
+
694
+ /**
695
+ * Clean up expired live locations.
696
+ */
697
+ private cleanupExpiredLiveLocations(): void {
698
+ const now = new Date();
699
+ for (const [key, state] of this.liveLocations) {
700
+ if (state.expiresAt && state.expiresAt < now) {
701
+ console.log(`[TelegramChannel] Cleaned up expired live location: ${key}`);
702
+ this.liveLocations.delete(key);
703
+ }
704
+ }
705
+ }
706
+
707
+ /**
708
+ * Start the live location cleanup timer (runs every 5 minutes).
709
+ */
710
+ private startLiveLocationCleanupTimer(): void {
711
+ // Clean up every 5 minutes
712
+ this.liveLocationCleanupInterval = setInterval(() => {
713
+ this.cleanupExpiredLiveLocations();
714
+ }, 5 * 60 * 1000);
715
+ console.log("[TelegramChannel] Started live location cleanup timer");
716
+ }
717
+
718
+ /**
719
+ * Start periodic cleanup of expired live locations.
720
+ */
721
+ private startLiveLocationCleanup(): void {
722
+ // Clean up every 5 minutes
723
+ this.liveLocationCleanupInterval = setInterval(() => {
724
+ this.cleanupExpiredLiveLocations();
725
+ }, 5 * 60 * 1000);
726
+ }
727
+
728
+ /**
729
+ * Stop live location cleanup interval.
730
+ */
731
+ private stopLiveLocationCleanup(): void {
732
+ if (this.liveLocationCleanupInterval) {
733
+ clearInterval(this.liveLocationCleanupInterval);
734
+ this.liveLocationCleanupInterval = undefined;
735
+ }
736
+ }
737
+
738
+ /**
739
+ * Handle incoming location message (static or live).
740
+ * Updates internal tracking and routes to message handler.
741
+ */
742
+ private handleLocationMessage(msg: TelegramBot.Message): ChannelMessage | null {
743
+ if (!msg.location) return null;
744
+
745
+ // Cast to extended location type that includes all Telegram properties
746
+ const rawLocation = msg.location as TelegramLocation;
747
+ const location: TelegramLocation = {
748
+ latitude: rawLocation.latitude,
749
+ longitude: rawLocation.longitude,
750
+ horizontal_accuracy: rawLocation.horizontal_accuracy,
751
+ live_period: rawLocation.live_period,
752
+ heading: rawLocation.heading,
753
+ proximity_alert_radius: rawLocation.proximity_alert_radius,
754
+ };
755
+
756
+ // Track live locations from users
757
+ if (location.live_period) {
758
+ const key = `${msg.chat.id}:${msg.message_id}`;
759
+ const expiresAt = new Date(Date.now() + location.live_period * 1000);
760
+
761
+ this.liveLocations.set(key, {
762
+ chatId: msg.chat.id,
763
+ messageId: msg.message_id,
764
+ userId: msg.from?.id || 0,
765
+ location,
766
+ startedAt: new Date(),
767
+ expiresAt,
768
+ updateCount: 0,
769
+ });
770
+
771
+ console.log(`[TelegramChannel] Tracking user live location: ${key}, expires in ${location.live_period}s`);
772
+ }
773
+
774
+ // Create ChannelMessage
775
+ const sender: MessageSender = {
776
+ id: msg.from?.id?.toString() || msg.chat.id.toString(),
777
+ username: msg.from?.username,
778
+ displayName: msg.from?.first_name || msg.from?.username || "User",
779
+ isBot: msg.from?.is_bot || false,
780
+ };
781
+
782
+ const context: MessageContext = {
783
+ isDM: msg.chat.type === "private",
784
+ groupName: msg.chat.type !== "private" ? msg.chat.title : undefined,
785
+ };
786
+
787
+ const chatChannelId = createChannelId("telegram", msg.chat.id.toString());
788
+
789
+ // Build text representation for location
790
+ const locationText = location.live_period
791
+ ? `[Live Location] ${location.latitude.toFixed(6)}, ${location.longitude.toFixed(6)} (live for ${Math.floor(location.live_period / 60)}m)`
792
+ : `[Location] ${location.latitude.toFixed(6)}, ${location.longitude.toFixed(6)}`;
793
+
794
+ // Store location info in a separate map for retrieval
795
+ const locationKey = `${chatChannelId.accountId}:${msg.message_id}`;
796
+ this.locationData.set(locationKey, {
797
+ type: "location",
798
+ location,
799
+ isLive: !!location.live_period,
800
+ venue: msg.venue,
801
+ });
802
+
803
+ // Build media attachment with location data
804
+ const media: MediaAttachment[] = [];
805
+
806
+ if (location.live_period) {
807
+ // Live location
808
+ media.push({
809
+ type: "location",
810
+ location: {
811
+ type: "live",
812
+ latitude: location.latitude,
813
+ longitude: location.longitude,
814
+ accuracy: location.horizontal_accuracy,
815
+ heading: location.heading,
816
+ sessionId: `live_${msg.chat.id}_${msg.message_id}`,
817
+ startedAt: new Date(msg.date * 1000),
818
+ expiresAt: new Date(Date.now() + location.live_period * 1000),
819
+ livePeriod: location.live_period,
820
+ updateCount: 0,
821
+ status: "active",
822
+ },
823
+ });
824
+ } else {
825
+ // Static location
826
+ media.push({
827
+ type: "location",
828
+ location: {
829
+ type: "static",
830
+ latitude: location.latitude,
831
+ longitude: location.longitude,
832
+ accuracy: location.horizontal_accuracy,
833
+ heading: location.heading,
834
+ timestamp: new Date(msg.date * 1000),
835
+ },
836
+ });
837
+ }
838
+
839
+ // Add venue info if present
840
+ if (msg.venue) {
841
+ media.push({
842
+ type: "venue",
843
+ location: {
844
+ type: "static",
845
+ latitude: location.latitude,
846
+ longitude: location.longitude,
847
+ timestamp: new Date(msg.date * 1000),
848
+ label: msg.venue.title,
849
+ address: msg.venue.address,
850
+ },
851
+ });
852
+ }
853
+
854
+ return {
855
+ messageId: msg.message_id.toString(),
856
+ channelId: chatChannelId,
857
+ timestamp: new Date(msg.date * 1000),
858
+ sender,
859
+ text: locationText,
860
+ media,
861
+ context,
862
+ };
863
+ }
864
+
865
+ /**
866
+ * Handle live location update (edited_message with location).
867
+ */
868
+ private handleLocationUpdate(msg: TelegramBot.Message): ChannelMessage | null {
869
+ if (!msg.location) return null;
870
+
871
+ const key = `${msg.chat.id}:${msg.message_id}`;
872
+ const state = this.liveLocations.get(key);
873
+
874
+ // Cast to extended location type
875
+ const rawLocation = msg.location as TelegramLocation;
876
+
877
+ if (state) {
878
+ // Update tracked location
879
+ state.location = {
880
+ latitude: rawLocation.latitude,
881
+ longitude: rawLocation.longitude,
882
+ horizontal_accuracy: rawLocation.horizontal_accuracy,
883
+ heading: rawLocation.heading,
884
+ proximity_alert_radius: rawLocation.proximity_alert_radius,
885
+ live_period: rawLocation.live_period,
886
+ };
887
+ state.updateCount++;
888
+
889
+ console.log(`[TelegramChannel] Live location update: ${key} (update #${state.updateCount})`);
890
+ }
891
+
892
+ // Create ChannelMessage for the update
893
+ const sender: MessageSender = {
894
+ id: msg.from?.id?.toString() || msg.chat.id.toString(),
895
+ username: msg.from?.username,
896
+ displayName: msg.from?.first_name || msg.from?.username || "User",
897
+ isBot: msg.from?.is_bot || false,
898
+ };
899
+
900
+ const context: MessageContext = {
901
+ isDM: msg.chat.type === "private",
902
+ groupName: msg.chat.type !== "private" ? msg.chat.title : undefined,
903
+ };
904
+
905
+ const chatChannelId = createChannelId("telegram", msg.chat.id.toString());
906
+
907
+ // Store location update info
908
+ const locationKey = `${chatChannelId.accountId}:${msg.message_id}`;
909
+ this.locationData.set(locationKey, {
910
+ type: "location_update",
911
+ location: {
912
+ latitude: rawLocation.latitude,
913
+ longitude: rawLocation.longitude,
914
+ horizontal_accuracy: rawLocation.horizontal_accuracy,
915
+ heading: rawLocation.heading,
916
+ proximity_alert_radius: rawLocation.proximity_alert_radius,
917
+ },
918
+ isLive: true,
919
+ updateNumber: state?.updateCount || 0,
920
+ });
921
+
922
+ // Build media attachment with live location update data
923
+ const media: MediaAttachment[] = [{
924
+ type: "location",
925
+ location: {
926
+ type: "live",
927
+ latitude: rawLocation.latitude,
928
+ longitude: rawLocation.longitude,
929
+ accuracy: rawLocation.horizontal_accuracy,
930
+ heading: rawLocation.heading,
931
+ sessionId: `live_${msg.chat.id}_${msg.message_id}`,
932
+ startedAt: state?.startedAt || new Date(msg.date * 1000),
933
+ expiresAt: state?.expiresAt,
934
+ updateCount: state?.updateCount || 0,
935
+ status: "active",
936
+ },
937
+ }];
938
+
939
+ return {
940
+ messageId: msg.message_id.toString(),
941
+ channelId: chatChannelId,
942
+ timestamp: new Date(msg.date * 1000),
943
+ sender,
944
+ text: `[Live Location Update] ${rawLocation.latitude.toFixed(6)}, ${rawLocation.longitude.toFixed(6)}`,
945
+ media,
946
+ context,
947
+ };
948
+ }
949
+
504
950
  // ============================================================
505
951
  // Message Routing (Internal)
506
952
  // ============================================================
@@ -509,6 +955,25 @@ export class TelegramChannel {
509
955
  // Text messages - all go to the daemon's messageHandler (including commands)
510
956
  // The daemon uses @ebowwa/channel-command for unified command handling with full context
511
957
  this.bot.on("message", async (msg) => {
958
+ // Check for location messages first
959
+ if (msg.location) {
960
+ if (!this.isAllowed(msg.from?.id, msg.chat.id)) return;
961
+
962
+ const message = this.handleLocationMessage(msg);
963
+ if (message && this.messageHandler) {
964
+ console.log(`[TelegramChannel] Location from ${message.sender.displayName}: ${message.text}`);
965
+ try {
966
+ const response = await this.messageHandler(message);
967
+ if (response) {
968
+ await this.send(response);
969
+ }
970
+ } catch (error) {
971
+ console.error("[TelegramChannel] Location handler error:", error);
972
+ }
973
+ }
974
+ return;
975
+ }
976
+
512
977
  if (!msg.text) return;
513
978
  // All messages flow to the daemon, including commands
514
979
  if (!this.isAllowed(msg.from?.id, msg.chat.id)) return;
@@ -530,8 +995,27 @@ export class TelegramChannel {
530
995
  }
531
996
  });
532
997
 
533
- // Edited messages
998
+ // Edited messages (includes live location updates)
534
999
  this.bot.on("edited_message", async (msg) => {
1000
+ // Handle live location updates
1001
+ if (msg.location) {
1002
+ if (!this.isAllowed(msg.from?.id, msg.chat.id)) return;
1003
+
1004
+ const message = this.handleLocationUpdate(msg);
1005
+ if (message && this.messageHandler) {
1006
+ console.log(`[TelegramChannel] Live location update from ${message.sender.displayName}`);
1007
+ try {
1008
+ const response = await this.messageHandler(message);
1009
+ if (response) {
1010
+ await this.send(response);
1011
+ }
1012
+ } catch (error) {
1013
+ console.error("[TelegramChannel] Location update handler error:", error);
1014
+ }
1015
+ }
1016
+ return;
1017
+ }
1018
+
535
1019
  if (!msg.text) return;
536
1020
  if (!this.isAllowed(msg.from?.id, msg.chat.id)) return;
537
1021