Real-Time Location Sharing with Telegram Bots

    Recently, I embarked on developing a Telegram bot featuring a unique task: receiving live location updates from a user's device. This bot was designed with a specific function in mind - users could input tasks associated with certain geographical locations. Once a user entered the designated area (within a specified radius), the bot would automatically send a message and relevant task notifications to the user.

As of the time this article was written, Telegram has a limitation regarding continuous location sharing - the maximum duration for live location sharing is capped at 8 hours. This presents a challenge as users are required to refresh their live location every 8 hours to maintain continuity.

Now, let's delve into how we can capture live location updates in our Telegram bot. For this project, I utilized the telebot API, and all the subsequent code examples are based on this library. The process begins when a user opts to share their live location, triggering a message with their geographical coordinates sent to the bot. This live location is then updated periodically, and each update edits the original message. We can track these updates using the edited_message_handler in the bot, which captures all modifications to the message. To further refine this, specifying the content type as 'location' enables us to monitor every live location update received from the user.

@bot.edited_message_handler(content_types=['location'])
def handle_live_location(message):
user_latitude = message.location.latitude
user_longitude = message.location.longitude

    Live location sharing is over.

    An important consideration in our project is handling the scenario when the live location-sharing period expires. Currently, there isn't a straightforward method to continuously receive a user's location data. However, I've devised a workaround that effectively addresses this challenge.

The core idea involves monitoring the moment when the live location sharing ceases and subsequently prompting the user with a notification. This notification serves as a reminder for the user to reshare their location if they continue to require the services of our bot. Let's explore the implementation details of this approach.

We know that the location-sharing process involves the periodic editing of a message. To leverage this, we can set up a function within a separate thread that monitors when the last message update occurred. If there is no edit to the message after a certain duration, this function will then send a prompt to the user and terminate the separate thread. This method ensures that we maintain user engagement while working within the constraints of Telegram's location-sharing features.

def refresh_live_location_notifier(chat_id, message, bot_object):

"""
if the user's location has stopped arriving
and there has been no more than a minute,
the function sends a notification to the user,
that he needs to share his location with the bot again
"""

continue_loop_flag = True
chat_id_cache[chat_id]["thread"] = True
while continue_loop_flag:
if "last_live_location_share_time" in chat_id_cache[chat_id]:
last_location_share_time = (chat_id_cache[chat_id]
["last_live_location_share_time"])
else:
chat_id_cache[chat_id]["last_live_location_share_time"] = datetime.now()
time.sleep(300)
continue

now = datetime.now()
if (now - last_location_share_time) > timedelta(minutes=5):
bot_object.send_message(chat_id,"%s, it looks like live "
"location period is over,"
"please share your live location, "
"to continue monitoring your tasks."
% message.chat.first_name)
continue_loop_flag = False
chat_id_cache[chat_id]["thread"] = False
logger.info("For chat_id=%s live location period was over, "
"message sended." % chat_id)

else:
time.sleep(300)

We can initiate this function in a separate thread as soon as we receive the initial message containing the user's location coordinates.:

thread = threading.Thread(target=refresh_live_location_notifier, 
                          args=[chat_id, message, bot])
thread.start()

Admittedly, this approach is more of a workaround rather than a direct solution, and future updates to the Telegram API may offer a more streamlined method. If you're interested in exploring the complete code for LocationReminder, you can find it here

28 Dec 2021
Switch Theme