@@ -293,6 +293,30 @@ def extract_direct_thread(data):
293293 data ["last_activity_at" ] = datetime .datetime .fromtimestamp (
294294 data ["last_activity_at" ] // 1_000_000
295295 )
296+
297+ # Convert last_seen_at timestamps
298+ last_seen_at = data .get ("last_seen_at" , {})
299+ for user_id , seen_info in last_seen_at .items ():
300+ if "timestamp" in seen_info :
301+ seen_info ["timestamp" ] = datetime .datetime .fromtimestamp (
302+ int (seen_info ["timestamp" ]) // 1_000_000
303+ )
304+ if "created_at" in seen_info :
305+ seen_info ["created_at" ] = datetime .datetime .fromtimestamp (
306+ int (seen_info ["created_at" ]) // 1_000_000
307+ )
308+ # Convert disappearing messages seen state timestamps
309+ disappearing_state = seen_info .get ("disappearing_messages_seen_state" )
310+ if disappearing_state :
311+ if "timestamp" in disappearing_state :
312+ disappearing_state ["timestamp" ] = datetime .datetime .fromtimestamp (
313+ int (disappearing_state ["timestamp" ]) // 1_000_000
314+ )
315+ if "created_at" in disappearing_state :
316+ disappearing_state ["created_at" ] = datetime .datetime .fromtimestamp (
317+ int (disappearing_state ["created_at" ]) // 1_000_000
318+ )
319+
296320 return DirectThread (** data )
297321
298322
@@ -352,12 +376,54 @@ def extract_direct_message(data):
352376 if xma_media_share :
353377 data ["xma_share" ] = extract_media_v1_xma (xma_media_share [0 ])
354378
379+ # Convert main timestamp
355380 data ["timestamp" ] = datetime .datetime .fromtimestamp (
356381 int (data ["timestamp" ]) // 1_000_000
357382 )
358383 data ["user_id" ] = str (data .get ("user_id" , "" ))
359384 data ["client_context" ] = data .get ("client_context" , "" )
360385
386+ # Convert reaction timestamps
387+ reactions = data .get ("reactions" , {})
388+ if reactions and "emojis" in reactions :
389+ for emoji_reaction in reactions ["emojis" ]:
390+ if "timestamp" in emoji_reaction :
391+ emoji_reaction ["timestamp" ] = datetime .datetime .fromtimestamp (
392+ int (emoji_reaction ["timestamp" ]) // 1_000_000
393+ )
394+
395+ # Convert visual media timestamps
396+ visual_media = data .get ("visual_media" , {})
397+ if visual_media and "media" in visual_media :
398+ media = visual_media ["media" ]
399+ if "expiring_media_action_summary" in media and media ["expiring_media_action_summary" ]:
400+ media ["expiring_media_action_summary" ]["timestamp" ] = datetime .datetime .fromtimestamp (
401+ int (media ["expiring_media_action_summary" ]["timestamp" ]) // 1_000_000
402+ )
403+
404+ # Convert image candidates URL expiration timestamps
405+ if "image_versions2" in media and media ["image_versions2" ]:
406+ candidates = media ["image_versions2" ].get ("candidates" , [])
407+ for candidate in candidates :
408+ if "url_expiration_timestamp_us" in candidate and candidate ["url_expiration_timestamp_us" ]:
409+ candidate ["url_expiration_timestamp_us" ] = datetime .datetime .fromtimestamp (
410+ int (candidate ["url_expiration_timestamp_us" ]) // 1_000_000
411+ )
412+
413+ # Convert video versions URL expiration timestamps
414+ if "video_versions" in media and media ["video_versions" ]:
415+ for video_version in media ["video_versions" ]:
416+ if "url_expiration_timestamp_us" in video_version and video_version ["url_expiration_timestamp_us" ]:
417+ video_version ["url_expiration_timestamp_us" ] = datetime .datetime .fromtimestamp (
418+ int (video_version ["url_expiration_timestamp_us" ]) // 1_000_000
419+ )
420+
421+ # Convert top-level visual media expiring action summary timestamp
422+ if visual_media and "expiring_media_action_summary" in visual_media and visual_media ["expiring_media_action_summary" ]:
423+ visual_media ["expiring_media_action_summary" ]["timestamp" ] = datetime .datetime .fromtimestamp (
424+ int (visual_media ["expiring_media_action_summary" ]["timestamp" ]) // 1_000_000
425+ )
426+
361427 return DirectMessage (** data )
362428
363429
0 commit comments