import argparse import logging import time import requests from tqdm import tqdm from typing import List, Tuple, Any, Dict http: requests.Session = requests.Session() def read_recipients(file_path: str) -> List[str]: with open(file_path, 'r') as f: return [r.strip() for r in f.readlines()] def read_mail_content(file_path: str) -> Tuple[str, bool]: with open(file_path, 'r') as f: content = f.read() return content, file_path.lower().endswith('.html') def send(recipient: str, subject: str, content: str, is_html: bool = False, base_url: str = 'https://mailwhale.dev'): payload: Dict[str, Any] = { 'to': [recipient], 'subject': subject, } if is_html: payload['html'] = content else: payload['text'] = content r = http.post(f'{base_url}/api/mail', json=payload) r.raise_for_status() def run(args): content, is_html = read_mail_content(args.content) for recipient in tqdm(read_recipients(args.recipients)): try: send(recipient, args.subject, content, is_html, args.mw_url) time.sleep(args.throttle) except Exception as e: logging.warning(f'failed to send to {recipient}, {e}') def parse_arguments(): parser = argparse.ArgumentParser(description='Script to send mass mail to a list of recipients through MailWhale') parser.add_argument('-r', '--recipients', required=True, type=str, help='path to line-separated file containing list of recipient addresses') parser.add_argument('-c', '--content', required=True, type=str, help='path to text- or html file containing the mail content') parser.add_argument('-s', '--subject', required=True, type=str, help='mail subject') parser.add_argument('--mw_client_id', required=True, type=str, help='mailwhale client id') parser.add_argument('--mw_client_secret', required=True, type=str, help='mailwhale client secret') parser.add_argument('--mw_url', default='https://mailwhale.dev', type=str, help='mailwhale base url') parser.add_argument('-t', '--throttle', default=5, type=int, help='seconds to wait between every mail') return parser.parse_args() if __name__ == '__main__': args = parse_arguments() http.auth = (args.mw_client_id, args.mw_client_secret) run(args)