yukee1992 commited on
Commit
3f4e033
·
verified ·
1 Parent(s): 1c4069d

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +217 -154
main.py CHANGED
@@ -98,7 +98,174 @@ class ApprovalAction(BaseModel):
98
  action: str
99
  admin_id: str
100
 
101
- # ============ NEW: MAP DIRECTION PARSING ============
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
  def parse_map_directions(text):
104
  """Parse Google Maps/Apple Maps/Waze directions link"""
@@ -161,6 +328,8 @@ def parse_map_directions(text):
161
  if from_info:
162
  result["from"] = from_info["place_name"]
163
  logger.info(f"From location: {result['from']} (from coordinates)")
 
 
164
  else:
165
  result["from"] = urllib.parse.unquote(from_place_raw).replace('+', ' ')
166
 
@@ -171,6 +340,8 @@ def parse_map_directions(text):
171
  if to_info:
172
  result["to"] = to_info["place_name"]
173
  logger.info(f"To location: {result['to']} (from coordinates)")
 
 
174
  else:
175
  result["to"] = urllib.parse.unquote(to_place_raw).replace('+', ' ')
176
 
@@ -255,151 +426,19 @@ def parse_map_directions(text):
255
 
256
  return None
257
 
258
- # Add this new function near your other parsing functions (around line 150)
259
-
260
- def follow_google_maps_redirect(url):
261
- """Follow Google Maps shortened URL to get the full URL and extract destination"""
262
- try:
263
- import requests
264
-
265
- logger.info(f"Following Google Maps redirect: {url}")
266
-
267
- # Follow the redirect
268
- response = requests.get(url, timeout=10, allow_redirects=True)
269
- full_url = response.url
270
- logger.info(f"Redirected to: {full_url}")
271
-
272
- # Try to extract destination from the full URL
273
- result = {
274
- "to": None,
275
- "from": None,
276
- "to_lat": None,
277
- "to_lon": None,
278
- "from_lat": None,
279
- "from_lon": None
280
  }
281
-
282
- # ============ NEW: Extract from /dir/ pattern ============
283
- # Pattern: /dir/from/to or /dir/from+place/to+place
284
- dir_match = re.search(r'/dir/([^/]+)/([^/]+)', full_url)
285
- if dir_match:
286
- from_place_raw = dir_match.group(1)
287
- to_place_raw = dir_match.group(2)
288
-
289
- # Check if from is a coordinate
290
- coord_pattern = r'^(-?\d+\.\d+),(-?\d+\.\d+)$'
291
- from_coord_match = re.match(coord_pattern, from_place_raw)
292
- to_coord_match = re.match(coord_pattern, to_place_raw)
293
-
294
- if from_coord_match:
295
- result["from_lat"] = float(from_coord_match.group(1))
296
- result["from_lon"] = float(from_coord_match.group(2))
297
- # Reverse geocode to get place name
298
- from_info = reverse_geocode_enhanced(result["from_lat"], result["from_lon"])
299
- if from_info:
300
- result["from"] = from_info["place_name"]
301
- logger.info(f"From location: {result['from']} (from coordinates)")
302
- else:
303
- result["from"] = urllib.parse.unquote(from_place_raw).replace('+', ' ')
304
- logger.info(f"From location: {result['from']}")
305
-
306
- if to_coord_match:
307
- result["to_lat"] = float(to_coord_match.group(1))
308
- result["to_lon"] = float(to_coord_match.group(2))
309
- to_info = reverse_geocode_enhanced(result["to_lat"], result["to_lon"])
310
- if to_info:
311
- result["to"] = to_info["place_name"]
312
- logger.info(f"To location: {result['to']} (from coordinates)")
313
- else:
314
- result["to"] = urllib.parse.unquote(to_place_raw).replace('+', ' ')
315
- logger.info(f"To location: {result['to']}")
316
-
317
- return result
318
-
319
- # ============ Extract coordinates from the URL ============
320
- # Pattern: @lat,lon or /@lat,lon
321
- coord_pattern = r'[@/](-?\d+\.\d+),(-?\d+\.\d+)'
322
- coord_matches = re.findall(coord_pattern, full_url)
323
-
324
- if coord_matches:
325
- logger.info(f"Found coordinates in URL: {coord_matches}")
326
- if len(coord_matches) >= 2:
327
- # First set is start, second is destination
328
- result["from_lat"] = float(coord_matches[0][0])
329
- result["from_lon"] = float(coord_matches[0][1])
330
- result["to_lat"] = float(coord_matches[1][0])
331
- result["to_lon"] = float(coord_matches[1][1])
332
-
333
- # Reverse geocode to get place names
334
- if result["from_lat"] and result["from_lon"]:
335
- from_info = reverse_geocode_enhanced(result["from_lat"], result["from_lon"])
336
- if from_info:
337
- result["from"] = from_info["place_name"]
338
- logger.info(f"From location: {result['from']}")
339
-
340
- if result["to_lat"] and result["to_lon"]:
341
- to_info = reverse_geocode_enhanced(result["to_lat"], result["to_lon"])
342
- if to_info:
343
- result["to"] = to_info["place_name"]
344
- logger.info(f"To location: {result['to']}")
345
-
346
- if result["from"] and result["to"]:
347
- return result
348
- elif len(coord_matches) == 1:
349
- # Only one coordinate set - this is a single location
350
- result["to_lat"] = float(coord_matches[0][0])
351
- result["to_lon"] = float(coord_matches[0][1])
352
-
353
- to_info = reverse_geocode_enhanced(result["to_lat"], result["to_lon"])
354
- if to_info:
355
- result["to"] = to_info["place_name"]
356
- logger.info(f"Destination location: {result['to']}")
357
-
358
- # ============ Try other methods if we still don't have both locations ============
359
- if not result["to"]:
360
- # Try to get from 'q' parameter (search query)
361
- q_match = re.search(r'[?&]q=([^&]+)', full_url)
362
- if q_match:
363
- result["to"] = urllib.parse.unquote(q_match.group(1)).replace('+', ' ')
364
- logger.info(f"Extracted from 'q' parameter: {result['to']}")
365
-
366
- # Try to get from 'daddr' parameter (destination address)
367
- daddr_match = re.search(r'[?&]daddr=([^&]+)', full_url)
368
- if daddr_match:
369
- result["to"] = urllib.parse.unquote(daddr_match.group(1)).replace('+', ' ')
370
- logger.info(f"Extracted from 'daddr' parameter: {result['to']}")
371
-
372
- # Try to get from '/place/' pattern
373
- place_match = re.search(r'/place/([^/]+)/', full_url)
374
- if place_match:
375
- result["to"] = urllib.parse.unquote(place_match.group(1)).replace('+', ' ')
376
- logger.info(f"Extracted from '/place/': {result['to']}")
377
-
378
- # If we still don't have a "from" location, try to get from the URL
379
- if not result["from"] and not result["from_lat"]:
380
- # Try to extract "saddr" (source address) parameter
381
- saddr_match = re.search(r'[?&]saddr=([^&]+)', full_url)
382
- if saddr_match:
383
- result["from"] = urllib.parse.unquote(saddr_match.group(1)).replace('+', ' ')
384
- logger.info(f"Extracted from 'saddr' parameter: {result['from']}")
385
-
386
- # If we have coordinates for from but no name, try to reverse geocode
387
- if not result["from"] and result["from_lat"] and result["from_lon"]:
388
- from_info = reverse_geocode_enhanced(result["from_lat"], result["from_lon"])
389
- if from_info:
390
- result["from"] = from_info["place_name"]
391
- logger.info(f"From location from coordinates: {result['from']}")
392
-
393
- logger.info(f"Final result: from={result['from']}, to={result['to']}")
394
- return result
395
-
396
- except Exception as e:
397
- logger.error(f"Error following redirect: {e}")
398
- import traceback
399
- traceback.print_exc()
400
- return None
401
 
402
- # ============ NEW: REVERSE GEOCODING ============
403
 
404
  def reverse_geocode_enhanced(lat, lon):
405
  """Enhanced reverse geocoding with better Malaysian address parsing"""
@@ -465,7 +504,7 @@ def reverse_geocode_enhanced(lat, lon):
465
  logger.error(f"Reverse geocoding error: {e}")
466
  return None
467
 
468
- # ============ NEW: AUTO TRIP FUNCTIONS ============
469
 
470
  async def auto_start_trip_with_direction(user_id, direction_info, chat_id, username, purpose=None):
471
  """Auto-start trip from shared direction with optional purpose"""
@@ -482,9 +521,11 @@ async def auto_start_trip_with_direction(user_id, direction_info, chat_id, usern
482
  # Set the purpose
483
  trip_purpose = purpose or "Service"
484
 
 
 
485
  # If we have both from and to coordinates, we can complete the trip directly
486
  if from_lat and to_lat:
487
- # We have both locations - complete the trip directly
488
  pending_actions[user_id] = "waiting_for_start_location"
489
 
490
  user_sessions[user_id] = {
@@ -505,6 +546,7 @@ async def auto_start_trip_with_direction(user_id, direction_info, chat_id, usern
505
 
506
  # If we have a destination but no from location, ask user to share location
507
  elif to_lat and not from_lat:
 
508
  user_sessions[user_id] = {
509
  "direction_info": direction_info,
510
  "to_place": to_place,
@@ -585,7 +627,7 @@ async def complete_trip_automatically(user_id, chat_id, username):
585
  end_lat = session.get("end_gps_lat")
586
  end_lon = session.get("end_gps_lon")
587
  place_name = session.get("place_name", end_place)
588
- trip_purpose = session.get("trip_purpose", "Service") # Get purpose from session
589
 
590
  # Calculate distance
591
  distance = 0
@@ -664,7 +706,7 @@ async def complete_trip_automatically(user_id, chat_id, username):
664
  "chat_id": chat_id
665
  }
666
 
667
- # ============ NEW: QUICK TRIP COMMANDS ============
668
 
669
  async def quick_trip_with_purpose(user_id, purpose, chat_id, username):
670
  """Quick trip with a specific purpose"""
@@ -2501,9 +2543,7 @@ async def admin_test_sync(admin_key: str = None):
2501
  import traceback
2502
  result["traceback"] = traceback.format_exc()
2503
 
2504
- return result
2505
-
2506
- @app.get("/admin/debug-user/{telegram_id}")
2507
  async def admin_debug_user(telegram_id: str, admin_key: str = None):
2508
  """Debug endpoint to check user registration status"""
2509
  if admin_key != ADMIN_KEY:
@@ -2987,7 +3027,32 @@ async def start_trip(data: dict):
2987
 
2988
  # If we have a destination name, use it
2989
  to_place = direction_info.get("to")
2990
- if to_place and to_place != "Destination (Google Maps link detected)":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2991
  # We have a valid destination
2992
  logger.info(f"Destination detected: {to_place}")
2993
 
@@ -3081,8 +3146,6 @@ async def start_trip(data: dict):
3081
  purpose
3082
  )
3083
 
3084
- # ... rest of your existing start_trip function ...
3085
-
3086
  # Check if user is registered
3087
  if not is_registered(user_id):
3088
  return {
 
98
  action: str
99
  admin_id: str
100
 
101
+ # ============ MAP DIRECTION PARSING ============
102
+
103
+ def follow_google_maps_redirect(url):
104
+ """Follow Google Maps shortened URL to get the full URL and extract destination"""
105
+ try:
106
+ import requests
107
+
108
+ logger.info(f"Following Google Maps redirect: {url}")
109
+
110
+ # Follow the redirect
111
+ response = requests.get(url, timeout=15, allow_redirects=True)
112
+ full_url = response.url
113
+ logger.info(f"Redirected to: {full_url}")
114
+
115
+ # Try to extract destination from the full URL
116
+ result = {
117
+ "to": None,
118
+ "from": None,
119
+ "to_lat": None,
120
+ "to_lon": None,
121
+ "from_lat": None,
122
+ "from_lon": None
123
+ }
124
+
125
+ # ============ Extract from /dir/ pattern ============
126
+ # Pattern: /dir/from/to or /dir/from+place/to+place
127
+ dir_match = re.search(r'/dir/([^/]+)/([^/]+)', full_url)
128
+ if dir_match:
129
+ from_place_raw = dir_match.group(1)
130
+ to_place_raw = dir_match.group(2)
131
+ logger.info(f"From raw: {from_place_raw}, To raw: {to_place_raw}")
132
+
133
+ # Check if from is a coordinate
134
+ coord_pattern = r'^(-?\d+\.\d+),(-?\d+\.\d+)$'
135
+ from_coord_match = re.match(coord_pattern, from_place_raw)
136
+ to_coord_match = re.match(coord_pattern, to_place_raw)
137
+
138
+ if from_coord_match:
139
+ result["from_lat"] = float(from_coord_match.group(1))
140
+ result["from_lon"] = float(from_coord_match.group(2))
141
+ logger.info(f"From coordinates: {result['from_lat']}, {result['from_lon']}")
142
+ # Reverse geocode to get place name
143
+ from_info = reverse_geocode_enhanced(result["from_lat"], result["from_lon"])
144
+ if from_info:
145
+ result["from"] = from_info["place_name"]
146
+ logger.info(f"From location: {result['from']} (from coordinates)")
147
+ else:
148
+ result["from"] = f"{result['from_lat']}, {result['from_lon']}"
149
+ else:
150
+ result["from"] = urllib.parse.unquote(from_place_raw).replace('+', ' ')
151
+ logger.info(f"From location: {result['from']}")
152
+
153
+ if to_coord_match:
154
+ result["to_lat"] = float(to_coord_match.group(1))
155
+ result["to_lon"] = float(to_coord_match.group(2))
156
+ logger.info(f"To coordinates: {result['to_lat']}, {result['to_lon']}")
157
+ to_info = reverse_geocode_enhanced(result["to_lat"], result["to_lon"])
158
+ if to_info:
159
+ result["to"] = to_info["place_name"]
160
+ logger.info(f"To location: {result['to']} (from coordinates)")
161
+ else:
162
+ result["to"] = f"{result['to_lat']}, {result['to_lon']}"
163
+ else:
164
+ result["to"] = urllib.parse.unquote(to_place_raw).replace('+', ' ')
165
+ logger.info(f"To location: {result['to']}")
166
+
167
+ if result["from"] and result["to"]:
168
+ logger.info(f"✅ Extracted both from and to: {result['from']} -> {result['to']}")
169
+ return result
170
+
171
+ # ============ Extract coordinates from the URL ============
172
+ # Pattern: @lat,lon or /@lat,lon
173
+ coord_pattern = r'[@/](-?\d+\.\d+),(-?\d+\.\d+)'
174
+ coord_matches = re.findall(coord_pattern, full_url)
175
+
176
+ if coord_matches:
177
+ logger.info(f"Found coordinates in URL: {coord_matches}")
178
+ if len(coord_matches) >= 2:
179
+ # First set is start, second is destination
180
+ result["from_lat"] = float(coord_matches[0][0])
181
+ result["from_lon"] = float(coord_matches[0][1])
182
+ result["to_lat"] = float(coord_matches[1][0])
183
+ result["to_lon"] = float(coord_matches[1][1])
184
+
185
+ # Reverse geocode to get place names
186
+ if result["from_lat"] and result["from_lon"]:
187
+ from_info = reverse_geocode_enhanced(result["from_lat"], result["from_lon"])
188
+ if from_info:
189
+ result["from"] = from_info["place_name"]
190
+ logger.info(f"From location: {result['from']}")
191
+ else:
192
+ result["from"] = f"{result['from_lat']}, {result['from_lon']}"
193
+
194
+ if result["to_lat"] and result["to_lon"]:
195
+ to_info = reverse_geocode_enhanced(result["to_lat"], result["to_lon"])
196
+ if to_info:
197
+ result["to"] = to_info["place_name"]
198
+ logger.info(f"To location: {result['to']}")
199
+ else:
200
+ result["to"] = f"{result['to_lat']}, {result['to_lon']}"
201
+
202
+ if result["from"] and result["to"]:
203
+ return result
204
+ elif len(coord_matches) == 1:
205
+ # Only one coordinate set - this is a single location
206
+ result["to_lat"] = float(coord_matches[0][0])
207
+ result["to_lon"] = float(coord_matches[0][1])
208
+
209
+ to_info = reverse_geocode_enhanced(result["to_lat"], result["to_lon"])
210
+ if to_info:
211
+ result["to"] = to_info["place_name"]
212
+ logger.info(f"Destination location: {result['to']}")
213
+
214
+ # ============ Try other methods if we still don't have both locations ============
215
+ if not result["to"]:
216
+ # Try to get from 'q' parameter (search query)
217
+ q_match = re.search(r'[?&]q=([^&]+)', full_url)
218
+ if q_match:
219
+ result["to"] = urllib.parse.unquote(q_match.group(1)).replace('+', ' ')
220
+ logger.info(f"Extracted from 'q' parameter: {result['to']}")
221
+
222
+ # Try to get from 'daddr' parameter (destination address)
223
+ daddr_match = re.search(r'[?&]daddr=([^&]+)', full_url)
224
+ if daddr_match:
225
+ result["to"] = urllib.parse.unquote(daddr_match.group(1)).replace('+', ' ')
226
+ logger.info(f"Extracted from 'daddr' parameter: {result['to']}")
227
+
228
+ # Try to get from '/place/' pattern
229
+ place_match = re.search(r'/place/([^/]+)/', full_url)
230
+ if place_match:
231
+ result["to"] = urllib.parse.unquote(place_match.group(1)).replace('+', ' ')
232
+ logger.info(f"Extracted from '/place/': {result['to']}")
233
+
234
+ # If we still don't have a "from" location, try to get from the URL
235
+ if not result["from"] and not result["from_lat"]:
236
+ # Try to extract "saddr" (source address) parameter
237
+ saddr_match = re.search(r'[?&]saddr=([^&]+)', full_url)
238
+ if saddr_match:
239
+ result["from"] = urllib.parse.unquote(saddr_match.group(1)).replace('+', ' ')
240
+ logger.info(f"Extracted from 'saddr' parameter: {result['from']}")
241
+
242
+ # If we have coordinates for from but no name, try to reverse geocode
243
+ if not result["from"] and result["from_lat"] and result["from_lon"]:
244
+ from_info = reverse_geocode_enhanced(result["from_lat"], result["from_lon"])
245
+ if from_info:
246
+ result["from"] = from_info["place_name"]
247
+ logger.info(f"From location from coordinates: {result['from']}")
248
+ else:
249
+ result["from"] = f"{result['from_lat']}, {result['from_lon']}"
250
+
251
+ # If we have coordinates for to but no name, try to reverse geocode
252
+ if not result["to"] and result["to_lat"] and result["to_lon"]:
253
+ to_info = reverse_geocode_enhanced(result["to_lat"], result["to_lon"])
254
+ if to_info:
255
+ result["to"] = to_info["place_name"]
256
+ logger.info(f"To location from coordinates: {result['to']}")
257
+ else:
258
+ result["to"] = f"{result['to_lat']}, {result['to_lon']}"
259
+
260
+ logger.info(f"Final result: from={result['from']}, to={result['to']}")
261
+ return result
262
+
263
+ except Exception as e:
264
+ logger.error(f"Error following redirect: {e}")
265
+ import traceback
266
+ traceback.print_exc()
267
+ return None
268
+
269
 
270
  def parse_map_directions(text):
271
  """Parse Google Maps/Apple Maps/Waze directions link"""
 
328
  if from_info:
329
  result["from"] = from_info["place_name"]
330
  logger.info(f"From location: {result['from']} (from coordinates)")
331
+ else:
332
+ result["from"] = f"{result['from_lat']}, {result['from_lon']}"
333
  else:
334
  result["from"] = urllib.parse.unquote(from_place_raw).replace('+', ' ')
335
 
 
340
  if to_info:
341
  result["to"] = to_info["place_name"]
342
  logger.info(f"To location: {result['to']} (from coordinates)")
343
+ else:
344
+ result["to"] = f"{result['to_lat']}, {result['to_lon']}"
345
  else:
346
  result["to"] = urllib.parse.unquote(to_place_raw).replace('+', ' ')
347
 
 
426
 
427
  return None
428
 
429
+ def extract_coordinates_from_text(text):
430
+ """Extract GPS coordinates from text"""
431
+ coord_pattern = r'(-?\d+\.\d+)\s*[,,]\s*(-?\d+\.\d+)'
432
+ match = re.search(coord_pattern, text)
433
+
434
+ if match:
435
+ return {
436
+ "lat": float(match.group(1)),
437
+ "lon": float(match.group(2))
 
 
 
 
 
 
 
 
 
 
 
 
 
438
  }
439
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
 
441
+ # ============ REVERSE GEOCODING ============
442
 
443
  def reverse_geocode_enhanced(lat, lon):
444
  """Enhanced reverse geocoding with better Malaysian address parsing"""
 
504
  logger.error(f"Reverse geocoding error: {e}")
505
  return None
506
 
507
+ # ============ AUTO TRIP FUNCTIONS ============
508
 
509
  async def auto_start_trip_with_direction(user_id, direction_info, chat_id, username, purpose=None):
510
  """Auto-start trip from shared direction with optional purpose"""
 
521
  # Set the purpose
522
  trip_purpose = purpose or "Service"
523
 
524
+ logger.info(f"Auto trip: from={from_place} ({from_lat}, {from_lon}), to={to_place} ({to_lat}, {to_lon})")
525
+
526
  # If we have both from and to coordinates, we can complete the trip directly
527
  if from_lat and to_lat:
528
+ logger.info(f"✅ Both from and to coordinates found, completing trip automatically")
529
  pending_actions[user_id] = "waiting_for_start_location"
530
 
531
  user_sessions[user_id] = {
 
546
 
547
  # If we have a destination but no from location, ask user to share location
548
  elif to_lat and not from_lat:
549
+ logger.info(f"✅ Only destination found, asking for current location")
550
  user_sessions[user_id] = {
551
  "direction_info": direction_info,
552
  "to_place": to_place,
 
627
  end_lat = session.get("end_gps_lat")
628
  end_lon = session.get("end_gps_lon")
629
  place_name = session.get("place_name", end_place)
630
+ trip_purpose = session.get("trip_purpose", "Service")
631
 
632
  # Calculate distance
633
  distance = 0
 
706
  "chat_id": chat_id
707
  }
708
 
709
+ # ============ QUICK TRIP COMMANDS ============
710
 
711
  async def quick_trip_with_purpose(user_id, purpose, chat_id, username):
712
  """Quick trip with a specific purpose"""
 
2543
  import traceback
2544
  result["traceback"] = traceback.format_exc()
2545
 
2546
+ return result@app.get("/admin/debug-user/{telegram_id}")
 
 
2547
  async def admin_debug_user(telegram_id: str, admin_key: str = None):
2548
  """Debug endpoint to check user registration status"""
2549
  if admin_key != ADMIN_KEY:
 
3027
 
3028
  # If we have a destination name, use it
3029
  to_place = direction_info.get("to")
3030
+ from_place = direction_info.get("from")
3031
+ from_lat = direction_info.get("from_lat")
3032
+ from_lon = direction_info.get("from_lon")
3033
+ to_lat = direction_info.get("to_lat")
3034
+ to_lon = direction_info.get("to_lon")
3035
+
3036
+ # If we have both from and to, complete the trip automatically
3037
+ if from_lat and to_lat:
3038
+ logger.info(f"✅ Both from and to coordinates found, completing trip automatically")
3039
+ pending_actions[user_id] = "waiting_for_start_location"
3040
+
3041
+ user_sessions[user_id] = {
3042
+ "start_place": from_place or "Current Location",
3043
+ "start_gps_lat": from_lat,
3044
+ "start_gps_lon": from_lon,
3045
+ "end_place": to_place,
3046
+ "place_name": to_place,
3047
+ "trip_purpose": purpose,
3048
+ "status": "start_location_received",
3049
+ "auto_trip": True,
3050
+ "direction_shared": True
3051
+ }
3052
+
3053
+ return await complete_trip_automatically(user_id, chat_id, username)
3054
+
3055
+ elif to_place and to_place != "Destination (Google Maps link detected)":
3056
  # We have a valid destination
3057
  logger.info(f"Destination detected: {to_place}")
3058
 
 
3146
  purpose
3147
  )
3148
 
 
 
3149
  # Check if user is registered
3150
  if not is_registered(user_id):
3151
  return {