Initial commit: Outlook Web Inbox Count extension v1.4

Chrome/Firefox extension that displays the total inbox item count next
to the Inbox label in Outlook Web. Includes build+publish automation
via the Chrome Web Store API (see PUBLISHING.md).
This commit is contained in:
Giorgio Gilestro 2026-04-09 07:56:37 +01:00
commit 922d520f02
9 changed files with 641 additions and 0 deletions

113
publish.sh Executable file
View file

@ -0,0 +1,113 @@
#!/usr/bin/env bash
# Build and publish the extension to the Chrome Web Store.
#
# Reads the version from manifest.json, builds outlook_web_inbox_count_v<VERSION>.zip
# (overwriting if present), then uploads and publishes it via the Chrome Web Store API.
#
# Usage:
# ./publish.sh # build from manifest.json, upload, and publish
# ./publish.sh --no-publish # upload only (leave in Draft state in the dashboard)
# ./publish.sh path/to/extension.zip # skip build, upload a specific zip
#
# Requires a .env file in the project root with:
# CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, EXTENSION_ID
# See PUBLISHING.md for how to obtain these.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# --- Parse arguments ---
PUBLISH=true
ZIP_ARG=""
for arg in "$@"; do
case "$arg" in
--no-publish) PUBLISH=false ;;
-h|--help)
sed -n '2,15p' "$0"
exit 0
;;
*) ZIP_ARG="$arg" ;;
esac
done
# --- Load credentials ---
if [[ ! -f .env ]]; then
echo "Error: .env file not found (see PUBLISHING.md)" >&2
exit 1
fi
set -a
# shellcheck disable=SC1091
source .env
set +a
for var in CLIENT_ID CLIENT_SECRET REFRESH_TOKEN EXTENSION_ID; do
if [[ -z "${!var:-}" ]]; then
echo "Error: $var is not set in .env" >&2
exit 1
fi
done
# --- Determine / build zip ---
if [[ -n "$ZIP_ARG" ]]; then
ZIP="$ZIP_ARG"
if [[ ! -f "$ZIP" ]]; then
echo "Error: $ZIP not found" >&2
exit 1
fi
else
VERSION=$(python3 -c "import json; print(json.load(open('manifest.json'))['version'])")
ZIP="outlook_web_inbox_count_v${VERSION}.zip"
echo "Building $ZIP from manifest version $VERSION..."
rm -f "$ZIP"
zip -q "$ZIP" manifest.json content.js icon16.png icon64.png icon128.png
fi
echo "Package: $ZIP"
# --- Get a fresh access token ---
echo "Fetching access token..."
ACCESS_TOKEN=$(curl -s "https://oauth2.googleapis.com/token" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}" \
-d "refresh_token=${REFRESH_TOKEN}" \
-d "grant_type=refresh_token" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('access_token',''))")
if [[ -z "$ACCESS_TOKEN" ]]; then
echo "Error: failed to obtain access token. Refresh token may have expired." >&2
echo "See PUBLISHING.md 'Refreshing credentials' section." >&2
exit 1
fi
# --- Upload ---
echo "Uploading to extension $EXTENSION_ID..."
UPLOAD_RESPONSE=$(curl -s \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "x-goog-api-version: 2" \
-X PUT \
-T "$ZIP" \
"https://www.googleapis.com/upload/chromewebstore/v1.1/items/$EXTENSION_ID")
echo "Upload response: $UPLOAD_RESPONSE"
UPLOAD_STATE=$(echo "$UPLOAD_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('uploadState',''))" 2>/dev/null || echo "")
if [[ "$UPLOAD_STATE" != "SUCCESS" ]]; then
echo "Error: upload did not succeed (state: $UPLOAD_STATE)" >&2
exit 1
fi
# --- Publish ---
if [[ "$PUBLISH" == "true" ]]; then
echo "Publishing..."
PUBLISH_RESPONSE=$(curl -s \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "x-goog-api-version: 2" \
-H "Content-Length: 0" \
-X POST \
"https://www.googleapis.com/chromewebstore/v1.1/items/$EXTENSION_ID/publish")
echo "Publish response: $PUBLISH_RESPONSE"
else
echo "Skipping publish step (--no-publish). The upload is in Draft state in the dashboard."
fi
echo "Done."