Skip to content

Instantly share code, notes, and snippets.

@vphantom
Created March 25, 2025 12:21
Show Gist options
  • Save vphantom/152865f885ca190b4aae28c7fe6497ac to your computer and use it in GitHub Desktop.
Save vphantom/152865f885ca190b4aae28c7fe6497ac to your computer and use it in GitHub Desktop.
Convert OpenRouter chat JSON archive into Markdown
#!/usr/bin/env python3
"""
OpenRouter Chat Transcript Converter
This script converts JSON chat data from OpenRouter to a markdown format.
It reads a JSON file and outputs a markdown file with the chat transcript.
Usage: openrouter2md input_file1.json [input_file2.json ...]
Output: input_file1.md [input_file2.md ...]
Origin: version 1.6 of
https://creativecommons.org/publicdomain/zero/1.0/
https://gist.github.com/wujipu0/6fb3b9ead828f9c88642763e7dea960f
"""
import json
import sys
import os
from datetime import datetime
def format_timestamp(timestamp: str) -> str:
"""Convert ISO format timestamp to a more readable format in local timezone."""
dt = datetime.fromisoformat(timestamp.replace("Z", "+00:00")).astimezone()
return dt.strftime("%Y-%m-%d %H:%M:%S")
def format_message(message: dict, characters: dict) -> str:
"""Format a single message for markdown output."""
character = 'User'
quoted = True
try:
character = characters.get(message['characterId']).get('name')
quoted = False
except AttributeError:
pass
content = f"{'> ' if quoted else ''}{message['content']}"
return (f"### {character}\n\n"
f"{format_timestamp(message['updatedAt'])}\n\n"
f"{content}\n\n")
def json_to_markdown(json_data: str) -> str:
"""Convert JSON chat data to markdown format."""
data = json.loads(json_data)
characters = data['characters']
messages = data['messages']
markdown = "# OpenRouter Chat\n\n"
markdown += "## Characters\n\n"
for character_id, character in characters.items():
markdown += f"### {character['name']}\n\n"
markdown += f"**Model:** {character['modelInfo']['name']}\n\n"
markdown += f"{character['description']}\n\n"
markdown += "## Conversation\n\n"
sorted_messages = sorted(messages.values(), key=lambda x: x['updatedAt'])
markdown += ''.join(format_message(message, characters) for message in sorted_messages)
return markdown
def main():
"""Main function to handle file I/O and conversion process."""
if len(sys.argv) < 2:
print("Usage: python3 openrouter2md input_file1.json [input_file2.json ...]")
sys.exit(1)
input_files = sys.argv[1:]
for input_filename in input_files:
output_filename = os.path.splitext(input_filename)[0] + '.md'
try:
with open(input_filename, 'r') as file:
json_data = file.read()
markdown_output = json_to_markdown(json_data)
with open(output_filename, 'w') as file:
file.write(markdown_output)
print(f"Markdown file '{output_filename}' has been created.")
except FileNotFoundError:
print(f"Error: The file '{input_filename}' was not found.")
except json.JSONDecodeError:
print(f"Error: The file '{input_filename}' does not contain valid JSON data.")
except Exception as e:
print(f"An error occurred with '{input_filename}': {str(e)}")
continue
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment