enable logs

This commit is contained in:
Shihaam Abdul Rahman 2024-09-21 06:05:13 +05:00
parent a7917d7303
commit bf1c6688a8
Signed by: shihaam
GPG Key ID: 6DA2E87EBC227636

View File

@ -1,5 +1,6 @@
import os import os
import asyncio import asyncio
import logging
from aiosmtpd.controller import Controller from aiosmtpd.controller import Controller
from email.parser import BytesParser from email.parser import BytesParser
from email.policy import default from email.policy import default
@ -7,11 +8,17 @@ import telegram
import re import re
import httpx import httpx
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Configuration # Configuration
TELEGRAM_API_KEY = os.getenv('TELEGRAM_API_KEY') TELEGRAM_API_KEY = os.getenv('TELEGRAM_API_KEY')
DEFAULT_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID') # Fallback chat ID DEFAULT_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID') # Fallback chat ID
NTFY_TOKEN = os.getenv('NTFY_TOKEN') NTFY_TOKEN = os.getenv('NTFY_TOKEN')
NTFY_URL = os.getenv('NTFY_URL') NTFY_URL = os.getenv('NTFY_URL')
TELEGRAM_DOMAIN = os.getenv('TELEGRAM_DOMAIN', 'telegram.local')
NTFY_DOMAIN = os.getenv('NTFY_DOMAIN', 'ntfy.local')
# SMTP configuration # SMTP configuration
SMTP_HOST = '0.0.0.0' # Listen on all interfaces SMTP_HOST = '0.0.0.0' # Listen on all interfaces
@ -19,10 +26,12 @@ SMTP_PORT = 2525 # Alternative SMTP port
class SMTPHandler: class SMTPHandler:
async def handle_RCPT(self, server, session, envelope, address, rcpt_options): async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
logger.info(f"Received RCPT command for address: {address}")
envelope.rcpt_tos.append(address) envelope.rcpt_tos.append(address)
return '250 OK' return '250 OK'
async def handle_DATA(self, server, session, envelope): async def handle_DATA(self, server, session, envelope):
logger.info("Handling DATA command")
parser = BytesParser(policy=default) parser = BytesParser(policy=default)
message = parser.parsebytes(envelope.content) message = parser.parsebytes(envelope.content)
@ -30,36 +39,58 @@ class SMTPHandler:
body = message.get_body(preferencelist=('plain', 'html')).get_content() body = message.get_body(preferencelist=('plain', 'html')).get_content()
full_message = f"Subject: {subject}\n\n{body}" full_message = f"Subject: {subject}\n\n{body}"
logger.info(f"Parsed email - Subject: {subject}")
logger.debug(f"Email body: {body[:100]}...") # Log first 100 chars of body
# Extract destination from the recipient email address # Extract destination from the recipient email address
destination, service = self.extract_destination(envelope.rcpt_tos[0]) destination, service = self.extract_destination(envelope.rcpt_tos[0])
logger.info(f"Extracted destination: {destination}, service: {service}")
if service == 'telegram': if service == 'telegram':
await self.send_telegram(destination, full_message) await self.send_telegram(destination, full_message)
elif service == 'ntfy': elif service == 'ntfy':
await self.send_ntfy(destination, subject, body) await self.send_ntfy(destination, subject, body)
else: else:
print(f"Invalid service: {service}. Message not sent.") logger.error(f"Invalid service: {service}. Message not sent.")
return '250 Message accepted for delivery' return '250 Message accepted for delivery'
def extract_destination(self, email): def extract_destination(self, email):
match = re.match(r'(.+)@(telegram|ntfy)$', email) logger.info(f"Extracting destination from email: {email}")
if match: telegram_pattern = rf'^(.+)@{re.escape(TELEGRAM_DOMAIN)}$'
return match.group(1), match.group(2) ntfy_pattern = rf'^(.+)@{re.escape(NTFY_DOMAIN)}$'
print(f"Invalid email format: {email}. Using default Telegram chat ID.")
telegram_match = re.match(telegram_pattern, email)
if telegram_match:
logger.info(f"Matched Telegram pattern: {telegram_match.group(1)}")
return telegram_match.group(1), 'telegram'
ntfy_match = re.match(ntfy_pattern, email)
if ntfy_match:
logger.info(f"Matched ntfy pattern: {ntfy_match.group(1)}")
return ntfy_match.group(1), 'ntfy'
logger.warning(f"Invalid email format: {email}. Using default Telegram chat ID.")
return DEFAULT_CHAT_ID, 'telegram' return DEFAULT_CHAT_ID, 'telegram'
async def send_telegram(self, chat_id, message): async def send_telegram(self, chat_id, message):
logger.info(f"Sending message to Telegram chat ID: {chat_id}")
bot = telegram.Bot(TELEGRAM_API_KEY) bot = telegram.Bot(TELEGRAM_API_KEY)
try: try:
await bot.send_message(chat_id=chat_id, text=message) await bot.send_message(chat_id=chat_id, text=message)
print(f"Message sent to Telegram chat ID: {chat_id}") logger.info(f"Message sent successfully to Telegram chat ID: {chat_id}")
except telegram.error.BadRequest as e: except telegram.error.BadRequest as e:
print(f"Failed to send message to Telegram chat ID: {chat_id}. Error: {str(e)}") logger.error(f"Failed to send message to Telegram chat ID: {chat_id}. Error: {str(e)}")
print("Attempting to send to default Telegram chat ID.") logger.info("Attempting to send to default Telegram chat ID.")
try:
await bot.send_message(chat_id=DEFAULT_CHAT_ID, text=message) await bot.send_message(chat_id=DEFAULT_CHAT_ID, text=message)
logger.info(f"Message sent successfully to default Telegram chat ID: {DEFAULT_CHAT_ID}")
except telegram.error.BadRequest as e:
logger.error(f"Failed to send message to default Telegram chat ID. Error: {str(e)}")
async def send_ntfy(self, topic, subject, body): async def send_ntfy(self, topic, subject, body):
logger.info(f"Sending message to ntfy topic: {topic}")
headers = { headers = {
"Authorization": f"Bearer {NTFY_TOKEN}", "Authorization": f"Bearer {NTFY_TOKEN}",
"Title": subject, "Title": subject,
@ -69,16 +100,19 @@ class SMTPHandler:
try: try:
response = await client.post(f"{NTFY_URL}/{topic}", content=body, headers=headers) response = await client.post(f"{NTFY_URL}/{topic}", content=body, headers=headers)
response.raise_for_status() response.raise_for_status()
print(f"Message sent to ntfy topic: {topic}") logger.info(f"Message sent successfully to ntfy topic: {topic}")
except httpx.HTTPStatusError as e: except httpx.HTTPStatusError as e:
print(f"Failed to send message to ntfy topic: {topic}. Error: {str(e)}") logger.error(f"Failed to send message to ntfy topic: {topic}. Error: {str(e)}")
async def start_smtp_server(): async def start_smtp_server():
controller = Controller(SMTPHandler(), hostname=SMTP_HOST, port=SMTP_PORT) controller = Controller(SMTPHandler(), hostname=SMTP_HOST, port=SMTP_PORT)
controller.start() controller.start()
if __name__ == '__main__': if __name__ == '__main__':
logger.info(f"Starting SMTP server on {SMTP_HOST}:{SMTP_PORT}")
logger.info(f"Telegram domain: {TELEGRAM_DOMAIN}")
logger.info(f"ntfy domain: {NTFY_DOMAIN}")
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.create_task(start_smtp_server()) loop.create_task(start_smtp_server())
print(f"SMTP server started on {SMTP_HOST}:{SMTP_PORT}") logger.info("SMTP server started. Waiting for incoming messages...")
loop.run_forever() loop.run_forever()