Created
August 8, 2025 09:12
-
-
Save aaronedev/9d8b0076357882adc4742fd6df1f9702 to your computer and use it in GitHub Desktop.
json to vcf contact creation designed for telegram export contact feature
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
############################################################################## | |
# Script to convert a JSON file to VCF format | |
# was originally created for Telegram contacts when using | |
# export contact feature | |
############################################################################## | |
# Author: https://github.com/aaronedev | |
# Version: 1.0 | |
# License: MIT | |
# 2025-08-08 | |
# Dependencies: jq | |
# Usage: ./json2vcf.sh <input_json_file> [output_directory] | |
# Example: ./json2vcf.sh contacts.json | |
# Output: ./vcf_contacts/ | |
############################################################################## | |
# Check if jq is installed | |
if ! command -v jq &>/dev/null; then | |
echo "Error: jq is required but not installed. Install with: pacman -S jq" | |
exit 1 | |
fi | |
# Check if input file is provided | |
if [ $# -eq 0 ]; then | |
echo "Usage: $0 <json_file> [output_directory]" | |
echo "Example: $0 telegram_contacts.json ./vcf_contacts/" | |
exit 1 | |
fi | |
JSON_FILE="$1" | |
OUTPUT_DIR="${2:-./vcf_contacts}" | |
# Check if JSON file exists | |
if [ ! -f "$JSON_FILE" ]; then | |
echo "Error: File '$JSON_FILE' not found" | |
exit 1 | |
fi | |
# Create output directory | |
mkdir -p "$OUTPUT_DIR" | |
# Function to generate UID (using sha256 hash of contact info) | |
generate_uid() { | |
local first_name="$1" | |
local last_name="$2" | |
local phone="$3" | |
echo -n "${first_name}${last_name}${phone}" | sha256sum | cut -d' ' -f1 | |
} | |
# Function to format phone number (convert to international format) | |
format_phone() { | |
local phone="$1" | |
# Remove leading zeros and add + if it starts with country code | |
if [[ $phone =~ ^00([0-9]+)$ ]]; then | |
echo "+${BASH_REMATCH[1]}" | |
else | |
echo "$phone" | |
fi | |
} | |
# Function to create safe filename from name | |
safe_filename() { | |
local name="$1" | |
# Replace spaces and special chars with underscores, remove multiple underscores | |
echo "$name" | sed 's/[^a-zA-Z0-9]/_/g' | sed 's/__*/_/g' | sed 's/^_\|_$//g' | |
} | |
# Parse JSON and create VCF files | |
jq -r '.contacts.list[] | @base64' "$JSON_FILE" | while read -r contact_b64; do | |
# Decode base64 and extract contact info | |
contact=$(echo "$contact_b64" | base64 --decode) | |
first_name=$(echo "$contact" | jq -r '.first_name // ""') | |
last_name=$(echo "$contact" | jq -r '.last_name // ""') | |
phone_number=$(echo "$contact" | jq -r '.phone_number // ""') | |
# Skip if no phone number | |
if [ -z "$phone_number" ]; then | |
echo "Warning: Skipping contact with no phone number" | |
continue | |
fi | |
# Create full name (FN field) | |
if [ -n "$first_name" ] && [ -n "$last_name" ]; then | |
full_name="$first_name $last_name" | |
elif [ -n "$first_name" ]; then | |
full_name="$first_name" | |
elif [ -n "$last_name" ]; then | |
full_name="$last_name" | |
else | |
full_name="Unknown Contact" | |
fi | |
# Create structured name (N field: Last;First;;;) | |
structured_name="${last_name};${first_name};;;" | |
# Generate UID | |
uid=$(generate_uid "$first_name" "$last_name" "$phone_number") | |
# Format phone number | |
formatted_phone=$(format_phone "$phone_number") | |
# Create safe filename | |
safe_name=$(safe_filename "$full_name") | |
filename="${OUTPUT_DIR}/${safe_name}_${uid:0:8}.vcf" | |
# Generate VCF content | |
cat >"$filename" <<EOF | |
BEGIN:VCARD | |
VERSION:3.0 | |
UID:$uid | |
FN:$full_name | |
N:$structured_name | |
TEL;TYPE=CELL:$formatted_phone | |
CATEGORIES:myContacts | |
END:VCARD | |
EOF | |
echo "Created: $filename" | |
done | |
echo "VCF conversion completed. Files saved to: $OUTPUT_DIR" | |
# Optional: Create a combined VCF file | |
read -r -p "Create a single combined VCF file? (y/n): " create_combined | |
if [[ $create_combined =~ ^[Yy]$ ]]; then | |
combined_file="${OUTPUT_DIR}/all_contacts.vcf" | |
cat "${OUTPUT_DIR}"/*.vcf >"$combined_file" | |
echo "Combined VCF created: $combined_file" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment