warn('No output file found — nothing to upsert.'); return; } $data = json_decode(file_get_contents($path), true); foreach ($data['threads'] ?? [] as $thread) { DirectThread::updateOrCreate( ['thread_id' => $thread['thread_id']], [ 'thread_key' => $thread['thread_key'], 'thread_title' => $thread['thread_title'], 'is_group' => $thread['is_group'], 'participants' => $thread['participants'], 'last_activity_at' => $thread['last_activity_at'], 'muted' => $thread['muted'], ] ); } foreach ($data['messages'] ?? [] as $message) { DirectMessage::updateOrCreate( ['id' => $message['id']], [ 'thread_id' => $message['thread_id'], 'user_id' => $message['user_id'], 'username' => $message['username'], 'full_name' => $message['full_name'], 'item_type' => $message['content_type'], 'text' => $message['text'], 'timestamp' => $message['timestamp_ms'], 'shared_url' => $message['share']['url'] ?? null, 'shared_preview_image' => $message['share']['preview_image'] ?? null, 'shared_title' => $message['share']['title'] ?? null, 'shared_caption' => $message['share']['caption'] ?? null, 'attachments' => $message['attachments'] ?? null, 'reactions' => $message['reactions'], 'replied_to_id' => $message['replied_to_id'], 'replied_to_text' => $message['replied_to_text'], ] ); } $this->info(sprintf( 'Upserted %d threads and %d messages.', count($data['threads'] ?? []), count($data['messages'] ?? []) )); } }