選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

58 行
1.5 KiB

  1. #!/usr/bin/env python3
  2. import asyncio
  3. import base64
  4. import datetime
  5. import json
  6. import os
  7. import re
  8. import sys
  9. import telethon
  10. API_ID = os.environ['TELEGRAM_API_ID']
  11. API_HASH = os.environ['TELEGRAM_API_HASH']
  12. BOT_TOKEN = os.environ['TELEGRAM_BOT_TOKEN']
  13. URL_PATTERN = re.compile(r'^https?://t\.me/(?:s/)?(?P<channel>[^/]+)/(?P<message>\d+)$')
  14. def stuff_to_json(o):
  15. if isinstance(o, datetime.datetime):
  16. return o.isoformat()
  17. if isinstance(o, bytes):
  18. return f'binary data: {base64.b64encode(o).decode("ascii")}'
  19. raise TypeError(f'Object of type {type(o)} is not JSON serializable')
  20. async def main():
  21. # Parse URLs
  22. targets = []
  23. for url in sys.argv[1:]:
  24. m = URL_PATTERN.match(url)
  25. if not m:
  26. print(f'Error: {url} is not a recognised Telegram URL', file = sys.stderr)
  27. sys.exit(1)
  28. targets.append((m['channel'], int(m['message'])))
  29. if not targets:
  30. print(f'Usage: telegram-dl.py URL [URL...]', file = sys.stderr)
  31. sys.exit(1)
  32. channelName = targets[0][0]
  33. if not all(x[0] == channelName for x in targets[1:]):
  34. print(f'Error: all URLs must be of the same channel', file = sys.stderr)
  35. sys.exit(1)
  36. ids = [x[1] for x in targets]
  37. # Let's go...
  38. client = telethon.TelegramClient('telegram-dl', API_ID, API_HASH)
  39. await client.start(bot_token = BOT_TOKEN)
  40. messages = await client.get_messages(channelName, ids = ids)
  41. for message in messages:
  42. if not message:
  43. continue
  44. with open(f'{channelName}_{message.id}.json', 'x') as fp:
  45. json.dump(message.to_dict(), fp, default = stuff_to_json)
  46. await client.download_media(message)
  47. asyncio.run(main())