Separate display snippet from raw_content: use actual message.content
for raw_content (which may be empty string) and only use the placeholder
string for the display snippet. This matches the precedent from Task 5's
ping.py where build_ping_embed must never substitute raw_content with a
placeholder, preserving the factual state of whether content was present.
- Remove 'or (empty)' fallback in build_ping_embed to preserve empty strings in raw_content
- Fix parse_ping_embed to use direct indexing for all required fields (modality, raw_content, captured_at)
- Remove unused timezone import
- Add test case for empty raw_content round-trip to catch future regressions
Fixes code review findings: empty raw_content was being converted to literal "(empty)" string,
breaking lossless round-trip requirement needed by Task 7's thread-open handler.