APRS to Email

import socket
import smtplib
import re
from email.mime.text import MIMEText

# APRS credentials
APRS_CALLSIGN = 'CALLSIGN'
APRS_PASSCODE = 'PASSCODE'
APRS_SERVER = 'rotate.aprs2.net'
APRS_PORT = 14580

# Initialize the socket
aprs_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Email configuration
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
SENDER_EMAIL = 'EMAIL@gmail.com'
SENDER_PASSWORD = 'APP-PASSWORD-NOT-ACTUAL'

# Alias dictionary
alias_email_map = {
    'NAME': 'EMAIL ADDRESS',
    'NAME': 'EMAIL ADDRESS',
    'NAME': 'EMAIL ADDRESS',
    # Add more aliases and their corresponding email addresses here
}

def send_ack_message(sender, message_id):
    if message_id.isdigit():
        ack_message = 'ack{}'.format(message_id)
        sender_length = len(sender)
        spaces_after_sender = ' ' * max(1, 9 - sender_length)
        ack_packet_format = '{}>APRS::{}{}:{}\r\n'.format(APRS_CALLSIGN, sender, spaces_after_sender, ack_message)
        ack_packet = ack_packet_format.encode()
        aprs_socket.sendall(ack_packet)
        print("Sent ACK to {}: {}".format(sender, ack_message))
        print("Outgoing ACK packet: {}".format(ack_packet.decode()))

def send_email(subject, body, recipient_email):
    message = MIMEText(body)
    message['From'] = SENDER_EMAIL
    message['To'] = recipient_email
    message['Subject'] = subject

    try:
        server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        server.starttls()
        server.login(SENDER_EMAIL, SENDER_PASSWORD)
        server.sendmail(SENDER_EMAIL, recipient_email, message.as_string())
        server.quit()
        print('Email sent successfully!')
    except smtplib.SMTPException as e:
        print('Email could not be sent:', e)

def receive_aprs_messages():
    # Connect to the APRS server
    aprs_socket.connect((APRS_SERVER, APRS_PORT))
    print("Connected to APRS server with callsign: {}".format(APRS_CALLSIGN))

    # Send login information with APRS callsign and passcode
    login_str = 'user {} pass {} vers Python-APRS 1.0\r\n'.format(APRS_CALLSIGN, APRS_PASSCODE)
    aprs_socket.sendall(login_str.encode())
    print("Sent login information.")

    buffer = ""
    try:
        while True:
            data = aprs_socket.recv(1024)
            if not data:
                break
            
            # Add received data to the buffer
            buffer += data.decode()

            # Split buffer into lines
            lines = buffer.split('\n')

            # Process each line
            for line in lines[:-1]:
                if line.startswith('#'):
                    continue

                # Process APRS message
                print("Received raw APRS packet: {}".format(line.strip()))
                parts = line.strip().split(':')
                if len(parts) >= 2:
                    from_callsign = parts[0].split('>')[0].strip()
                    message_text = ':'.join(parts[1:]).strip()

                    # Check if the message contains "{"
                    if "{" in message_text:
                        message_id = message_text.split('{')[1].strip('}')
                        
                        # Remove the first 11 characters from the message to exclude the "Callsign :" prefix
                        verbose_message = message_text[11:].split('{')[0].strip()

                        # Display verbose message content
                        print("From: {}".format(from_callsign))
                        print("Message: {}".format(verbose_message))
                        print("Message ID: {}".format(message_id))

                        # Use regular expression to extract the alias and message body
                        match = re.match(r'@(\w+) (.+)', verbose_message)
                        if match:
                            alias = match.group(1)
                            message_body = match.group(2)

                            # Get the email address for the alias from the alias_email_map
                            recipient_email = alias_email_map.get(alias)
                            if recipient_email:
                                # Send email to the corresponding email address for the alias
                                send_email(from_callsign, message_body, recipient_email)
                            else:
                                print("Alias '{}' not found in the alias_email_map. Email not sent.".format(alias))

                        send_ack_message(from_callsign, message_id)

            # The last line might be an incomplete packet, so keep it in the buffer
            buffer = lines[-1]

    except Exception as e:
        print("Error receiving APRS messages: {}".format(e))

    finally:
        # Close the socket connection when done
        aprs_socket.close()


if __name__ == '__main__':
    print("APRS bot is running. Waiting for APRS messages...")
    receive_aprs_messages()