#!/usr/bin/env python3
"""Dump all custom_emoji_ids of a Telegram custom emoji pack.

Usage:
  export BOT_TOKEN=123456:ABC...        (a normal bot token from @BotFather)
  python3 fetch_pack.py RestrictedEmoji
  python3 fetch_pack.py FestiveFlags RoundFlags --out flags_packs.json
  python3 fetch_pack.py --env MY_TOKEN_VAR SomePack

The pack name is the last part of the link t.me/addemoji/<name>.
No Telegram Premium is needed to read a pack with a bot token.
Only the Python standard library is used.
"""
import argparse
import json
import os
import sys
import urllib.error
import urllib.parse
import urllib.request


def call(token, method, params):
    url = "https://api.telegram.org/bot%s/%s" % (token, method)
    data = urllib.parse.urlencode(params).encode()
    try:
        with urllib.request.urlopen(urllib.request.Request(url, data=data), timeout=30) as r:
            return json.load(r)
    except urllib.error.HTTPError as e:
        try:
            return json.load(e)
        except Exception:
            return {"ok": False, "description": "HTTP %s" % e.code}


def fetch_pack(token, name):
    res = call(token, "getStickerSet", {"name": name})
    if not res.get("ok"):
        raise RuntimeError("%s: %s" % (name, res.get("description")))
    s = res["result"]
    items = []
    for st in s.get("stickers", []):
        cid = st.get("custom_emoji_id")
        if not cid:
            continue  # normal sticker, not a custom emoji
        items.append({
            "id": cid,
            "emoji": st.get("emoji", ""),
            "pack": s.get("name", name),
            "animated": bool(st.get("is_animated") or st.get("is_video")),
        })
    return s.get("title", name), s.get("sticker_type"), items


def main():
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("packs", nargs="+", help="pack name(s), from t.me/addemoji/<name>")
    ap.add_argument("--env", default="BOT_TOKEN", help="env var that holds the bot token (default BOT_TOKEN)")
    ap.add_argument("--out", help="write JSON to this file (default: print to screen)")
    a = ap.parse_args()
    token = os.environ.get(a.env)
    if not token:
        sys.exit("Set the %s environment variable to your bot token." % a.env)
    all_items = []
    for name in a.packs:
        try:
            title, kind, items = fetch_pack(token, name)
        except RuntimeError as e:
            print("skip", e, file=sys.stderr)
            continue
        print("%s (%s, %s): %d custom emoji" % (name, title, kind, len(items)), file=sys.stderr)
        all_items.extend(items)
    text = json.dumps(all_items, ensure_ascii=False, indent=1)
    if a.out:
        with open(a.out, "w", encoding="utf8") as f:
            f.write(text)
        print("wrote", a.out, file=sys.stderr)
    else:
        print(text)


if __name__ == "__main__":
    main()
