Use volume for authentication with docker

This commit is contained in:
Baruch Odem 2020-04-24 12:35:53 +03:00
parent a3ca648cf6
commit 9285c74d66
6 changed files with 95 additions and 28 deletions

5
.gitignore vendored
View file

@ -1,2 +1,7 @@
.vscode
.venv
.env
*.session
__pycache__

View file

@ -1,6 +1,6 @@
FROM python:3
COPY telegram-download-daemon.py /
COPY *.py /
RUN pip install telethon cryptg

View file

@ -35,3 +35,23 @@ You need to configure these values:
You can define the as Environment Variables, or put them as a commend line arguments, for example:
python telegram-download-deamon.py --api-ip <your-id> --api-hash <your-hash> --channel <channel-number>
# Docker
Using
When we use the [`TelegramClient`](https://docs.telethon.dev/en/latest/quick-references/client-reference.html#telegramclient) method, it requires us to interact with the `Console` to give it our phone number and confirm with a security code.
To do this, when using *Docker*, you need to **interactively** run the container for the first time.
When you use `docker-compose`, the `.session` file, where the login is stored is kept in *Volume* outside the container. Therefore, when using docker-compose you are required to:
```bash
$ docker-compose run --rm telegram-download-deamon
# Interact with the console to authenticate yourself.
# See the message "Signed in successfully as {youe name}"
# Close the container
$ docker-compose up -d
```
See the `sessions` volume in the [docker-compose.yml](docker-compose.yml) file.

View file

@ -9,9 +9,12 @@ services:
TELEGRAM_DEAMON_API_HASH: "YOUR API HASH HERE"
TELEGRAM_DEAMON_CHANNEL: "YOUR CHANNEL ID HERE"
TELEGRAM_DEAMON_DEST: "/downloads"
TELEGRAM_DEAMON_SESSION_PATH: "/session"
volumes:
- downloads:/downloads
- sessions:/session
restart: unless-stopped
volumes:
downloads:
downloads:
sessions:

28
sessionManager.py Normal file
View file

@ -0,0 +1,28 @@
from os import getenv, path
from telethon.sessions import StringSession
TELEGRAM_DEAMON_SESSION_PATH = getenv("TELEGRAM_DEAMON_SESSION_PATH")
sessionName = "DownloadDaemon"
stringSessionFilename = f"{sessionName}.session"
def _getStringSessionIfExists():
sessionPath = path.join(TELEGRAM_DEAMON_SESSION_PATH, stringSessionFilename)
if path.isfile(sessionPath):
with open(sessionPath, 'r') as file:
session = file.read()
print(f"Session loaded from {sessionPath}")
return session
return None
def getSession():
if TELEGRAM_DEAMON_SESSION_PATH == None:
return sessionName
return StringSession(_getStringSessionIfExists())
def saveSession(session):
if TELEGRAM_DEAMON_SESSION_PATH != None:
sessionPath = path.join(TELEGRAM_DEAMON_SESSION_PATH, stringSessionFilename)
with open(sessionPath, 'w') as file:
file.write(StringSession.save(session))
print(f"Session saved in {sessionPath}")

View file

@ -5,6 +5,8 @@
from os import getenv
from sessionManager import getSession, saveSession
from telethon import TelegramClient, events
from telethon.tl.types import PeerChannel
import logging
@ -12,11 +14,14 @@ import logging
logging.basicConfig(format='[%(levelname) 5s/%(asctime)s]%(name)s:%(message)s',level=logging.WARNING)
import argparse
import asyncio
TELEGRAM_DEAMON_API_ID = getenv("TELEGRAM_DEAMON_API_ID")
TELEGRAM_DEAMON_API_HASH = getenv("TELEGRAM_DEAMON_API_HASH")
TELEGRAM_DEAMON_CHANNEL = getenv("TELEGRAM_DEAMON_CHANNEL")
TELEGRAM_DEAMON_SESSION_PATH = getenv("TELEGRAM_DEAMON_SESSION_PATH")
parser = argparse.ArgumentParser(description="Script to download files from Telegram Channel.")
parser.add_argument("--api-id", required=TELEGRAM_DEAMON_API_ID == None, type=int, default=TELEGRAM_DEAMON_API_ID, help='api_id from https://core.telegram.org/api/obtaining_api_id (default is TELEGRAM_DEAMON_API_ID env var)')
parser.add_argument("--api-hash", required=TELEGRAM_DEAMON_API_HASH == None, type=str, default=TELEGRAM_DEAMON_API_HASH, help='api_hash from https://core.telegram.org/api/obtaining_api_id (default is TELEGRAM_DEAMON_API_HASH env var)')
@ -31,34 +36,40 @@ downloadFolder = args.dest
# Edit these lines:
proxy = None
# End of interesting parameters
# End of interesting parameters
session = "DownloadDaemon"
async def sendHelloMessage(client, peerChannel):
entity = await client.get_entity(peerChannel)
await client.send_message(entity, "Hi! Ready for you files!")
client = TelegramClient(session, api_id, api_hash, proxy=proxy).start()
async def log_respond(event, respond):
print(respond)
await event.respond(respond)
@client.on(events.NewMessage())
async def handler(event):
with TelegramClient(getSession(), api_id, api_hash, proxy=proxy).start() as client:
saveSession(client.session)
peerChannel = PeerChannel(channel_id)
@client.on(events.NewMessage())
async def handler(event):
if event.to_id != peerChannel:
return
print(event)
if event.media:
filename=event.media.document.attributes[0].file_name
await log_respond(event, f"Downloading file {filename} ({event.media.document.size} bytes)")
await client.download_media(event.message, downloadFolder)
await log_respond(event, f"{filename} ready")
async def log_respond(respond):
print(respond)
await event.respond(respond)
if event.to_id != PeerChannel(channel_id):
return
async def start():
await sendHelloMessage(client, peerChannel)
await client.run_until_disconnected()
print(event)
if event.media:
filename=event.media.document.attributes[0].file_name
log_respond(f"Downloading file {filename} ({event.media.document.size} bytes)")
await client.download_media(event.message, downloadFolder)
log_respond(f"{filename} ready")
with client:
client.run_until_disconnected()
client.loop.run_until_complete(start())