first commit
This commit is contained in:
17
gmail-to-tryton/Dockerfile
Normal file
17
gmail-to-tryton/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Installer dépendances
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copier scripts
|
||||
COPY run.py .
|
||||
COPY entrypoint.sh .
|
||||
|
||||
# Rendre le script exécutable
|
||||
RUN chmod +x entrypoint.sh
|
||||
|
||||
# Entrypoint
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
3
gmail-to-tryton/entrypoint.sh
Executable file
3
gmail-to-tryton/entrypoint.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
python3 /app/run.py
|
||||
1
gmail-to-tryton/requirements.txt
Normal file
1
gmail-to-tryton/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
requests
|
||||
100
gmail-to-tryton/run.py
Normal file
100
gmail-to-tryton/run.py
Normal file
@@ -0,0 +1,100 @@
|
||||
import imaplib
|
||||
import time
|
||||
import requests
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
IMAP_SERVER = "imap.gmail.com"
|
||||
IMAP_PORT = 993
|
||||
|
||||
EMAIL_ACCOUNT = os.getenv("EMAIL_ACCOUNT")
|
||||
EMAIL_PASSWORD = os.getenv("EMAIL_PASSWORD")
|
||||
TRYTON_ENDPOINT = os.getenv("TRYTON_ENDPOINT")
|
||||
INTERVAL = int(os.getenv("INTERVAL", "30")) # secondes
|
||||
|
||||
LOG_FILE = "/app/logs/app.log"
|
||||
|
||||
|
||||
def log(msg):
|
||||
timestamp = datetime.now().isoformat()
|
||||
line = f"[{timestamp}] {msg}"
|
||||
print(line, flush=True)
|
||||
with open(LOG_FILE, "a") as f:
|
||||
f.write(line + "\n")
|
||||
|
||||
|
||||
def connect_imap():
|
||||
log("Connexion à Gmail via IMAP...")
|
||||
mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
|
||||
mail.login(EMAIL_ACCOUNT, EMAIL_PASSWORD)
|
||||
mail.select("INBOX")
|
||||
log("Connexion IMAP réussie.")
|
||||
return mail
|
||||
|
||||
|
||||
def fetch_unread_messages(mail):
|
||||
status, data = mail.search(None, '(UNSEEN)')
|
||||
if status != "OK":
|
||||
log("Erreur lors de la recherche de mails non lus.")
|
||||
return []
|
||||
msg_ids = data[0].split()
|
||||
log(f"{len(msg_ids)} mails non lus récupérés.")
|
||||
return msg_ids
|
||||
|
||||
|
||||
def get_raw_message(mail, msg_id):
|
||||
status, data = mail.fetch(msg_id, '(RFC822)')
|
||||
if status != "OK":
|
||||
log(f"Erreur récupération message {msg_id}")
|
||||
return None
|
||||
raw = data[0][1]
|
||||
log(f"Mail {msg_id.decode()} récupéré ({len(raw)} bytes)")
|
||||
return raw
|
||||
|
||||
|
||||
def post_to_tryton(raw_message):
|
||||
headers = {"Content-Type": "message/rfc822"}
|
||||
log(f"Envoi du mail vers Tryton : {TRYTON_ENDPOINT}")
|
||||
|
||||
try:
|
||||
r = requests.post(TRYTON_ENDPOINT, data=raw_message, headers=headers)
|
||||
except Exception as e:
|
||||
log(f"❌ Erreur réseau lors de l'envoi à Tryton : {e}")
|
||||
return False
|
||||
|
||||
log(f"Réponse HTTP Tryton : {r.status_code}")
|
||||
if r.status_code != 200:
|
||||
log(f"Corps de la réponse Tryton : {r.text[:500]}")
|
||||
return False
|
||||
|
||||
log("✔ Mail envoyé à Tryton avec succès.")
|
||||
return True
|
||||
|
||||
|
||||
def main_loop():
|
||||
log("🚀 Worker Gmail → Tryton démarré.")
|
||||
|
||||
while True:
|
||||
try:
|
||||
mail = connect_imap()
|
||||
unread_ids = fetch_unread_messages(mail)
|
||||
|
||||
if not unread_ids:
|
||||
log("Aucun nouvel email à traiter.")
|
||||
|
||||
for msg_id in unread_ids:
|
||||
raw = get_raw_message(mail, msg_id)
|
||||
if raw and post_to_tryton(raw):
|
||||
mail.store(msg_id, '+FLAGS', '\\Seen')
|
||||
log(f"Mail {msg_id.decode()} marqué comme lu.")
|
||||
|
||||
mail.logout()
|
||||
except Exception as e:
|
||||
log(f"❌ Erreur générale : {e}")
|
||||
|
||||
log(f"⏳ Pause {INTERVAL} secondes avant la prochaine vérification...")
|
||||
time.sleep(INTERVAL)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main_loop()
|
||||
Reference in New Issue
Block a user