Created
May 3, 2025 14:36
-
-
Save hridaydutta123/4cdefdb19b82b5345545881ff20ce428 to your computer and use it in GitHub Desktop.
Download chrome extensions from Chrome Web Store
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
#!/usr/bin/env bash | |
# | |
# Download multiple Chrome extensions from the webstore using a CSV file of extension IDs. | |
# | |
# Author: Hridoy Sankar Dutta (modified) | |
set -e | |
# ========================================================================== | |
usage() { | |
echo "Usage: $0 [-h|--help] <extensionIdsFile> [outputDir] [extensionVersion]" | |
echo | |
echo "Download multiple Chrome extensions (.crx) from a file with extension IDs." | |
echo | |
echo "Options:" | |
echo " -h, --help Show this help message and exit" | |
echo | |
echo "Arguments:" | |
echo " extensionIdsFile File containing Chrome extension IDs (one per line)" | |
echo " outputDir (Optional) Directory to save the .crx files (default: ./original_crx)" | |
echo " extensionVersion (Optional) Specific version to download" | |
} | |
# Check arguments | |
if [ $# -lt 1 ]; then | |
usage | |
exit 1 | |
fi | |
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then | |
usage | |
exit 0 | |
fi | |
extensionIdsFile="$1" | |
outputPath="${2:-original_crx}" | |
extensionVersion="$3" | |
if [ ! -f "$extensionIdsFile" ]; then | |
echo "Error: Extension IDs file not found: $extensionIdsFile" | |
exit 1 | |
fi | |
# Create output directory if it doesn't exist | |
mkdir -p "$outputPath" | |
# Use a default or hardcoded version of Chrome if google-chrome not found | |
if command -v google-chrome &> /dev/null; then | |
CHROME_VERSION=$(google-chrome --version | cut -d ' ' -f 3) | |
else | |
echo "Warning: google-chrome not found, using hardcoded version." | |
CHROME_VERSION="123.0.6312.86" | |
fi | |
# Detect OS | |
[ -n "$platformOs" ] || case "$OSTYPE" in | |
*darwin*) platformOs="mac" ;; | |
*linux*) platformOs="linux" ;; | |
*) echo "Unsupported platform: $OSTYPE"; exit 1 ;; | |
esac | |
# Detect architecture | |
arch="x86-64" | |
ARCH="$(uname -m)" | |
case "$ARCH" in | |
*arm*) arch="arm" ;; | |
"x86_64") arch="x86-64" ;; | |
esac | |
# Function to download a single extension | |
download_extension() { | |
local extensionId="$1" | |
echo "Downloading extension: $extensionId" | |
# Construct download URL | |
crxDownloadUrl='https://clients2.google.com/service/update2/crx?response=redirect' | |
crxDownloadUrl="${crxDownloadUrl}&os=${platformOs}" | |
crxDownloadUrl="${crxDownloadUrl}&arch=${arch}" | |
crxDownloadUrl="${crxDownloadUrl}&os_arch=${arch}" | |
crxDownloadUrl="${crxDownloadUrl}&prod=chromecrx" | |
crxDownloadUrl="${crxDownloadUrl}&prodchannel=unknown" | |
crxDownloadUrl="${crxDownloadUrl}&prodversion=${CHROME_VERSION}" | |
crxDownloadUrl="${crxDownloadUrl}&acceptformat=crx3" | |
# Add version string if provided | |
if [ -n "$extensionVersion" ]; then | |
crxDownloadUrl="${crxDownloadUrl}&x=id%3D${extensionId}%26uc%26v%3D${extensionVersion}" | |
else | |
crxDownloadUrl="${crxDownloadUrl}&x=id%3D${extensionId}%26uc" | |
fi | |
# Prepare output | |
downloadFilePath="$outputPath/$extensionId.crx" | |
# Download the CRX - continue on error | |
if ! wget \ | |
--quiet \ | |
--referer="https://chrome.google.com/webstore/detail/${extensionId}?hl=en" \ | |
--user-agent="Mozilla/5.0 Chrome/$CHROME_VERSION" \ | |
-O "$downloadFilePath" "$crxDownloadUrl" 2>/dev/null; then | |
echo "⚠️ Warning: Could not download extension $extensionId" | |
return 1 | |
fi | |
if [ ! -s "$downloadFilePath" ]; then | |
echo "❌ Error: Downloaded file for $extensionId has 0 bytes." | |
return 1 | |
else | |
echo "✅ Extension $extensionId downloaded to: $downloadFilePath" | |
return 0 | |
fi | |
} | |
# Print info header | |
echo "=== Chrome Extension Downloader ===" | |
echo "Output directory: $outputPath" | |
echo "Chrome version: $CHROME_VERSION" | |
echo "Platform: $platformOs ($arch)" | |
echo "===============================" | |
# Read the CSV file line by line and download each extension | |
total_extensions=$(wc -l < "$extensionIdsFile") | |
success_count=0 | |
fail_count=0 | |
current=0 | |
while IFS= read -r extensionId || [ -n "$extensionId" ]; do | |
# Skip empty lines | |
if [ -z "$extensionId" ]; then | |
continue | |
fi | |
# Remove any whitespace or carriage returns | |
extensionId=$(echo "$extensionId" | tr -d '[:space:]') | |
# Only process if we have a valid extension ID | |
if [ ${#extensionId} -eq 32 ]; then | |
current=$((current + 1)) | |
echo "[$current/$total_extensions] Processing extension ID: $extensionId" | |
if download_extension "$extensionId"; then | |
success_count=$((success_count + 1)) | |
else | |
fail_count=$((fail_count + 1)) | |
echo "⏩ Skipping and continuing to next extension..." | |
fi | |
else | |
echo "Warning: Skipping invalid extension ID: $extensionId (not 32 characters)" | |
fail_count=$((fail_count + 1)) | |
fi | |
done < "$extensionIdsFile" | |
echo "===============================" | |
echo "Download summary:" | |
echo "Total extensions processed: $total_extensions" | |
echo "Successful downloads: $success_count" | |
echo "Failed downloads: $fail_count" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment