Professional Email Automation Tool for Business & Educational Use
Automate your business email campaigns with Microsoft Graph API. Perfect for educational institutions, businesses, and organizations that need to send personalized emails with attachments and company signatures.
- Overview
- Features
- Use Cases
- Prerequisites
- Quick Start
- Detailed Setup Guide
- Configuration
- Usage Examples
- Company Signature Setup
- PDF Attachment Guide
- Troubleshooting
- Security & Best Practices
- API Reference
- License
- Contributing
Microsoft Automation Emailing is a powerful Python application designed for businesses and educational institutions to automate email sending through Microsoft Graph API. This tool enables you to:
- Send personalized emails to multiple recipients
- Attach PDF documents (invoices, reports, certificates, etc.)
- Include professional company signatures with logos
- Automate business communications and educational notifications
- Track email delivery with detailed reporting
- Businesses: Marketing campaigns, invoice distribution, report sharing
- Educational Institutions: Course notifications, certificate distribution, announcements
- Organizations: Newsletter distribution, event invitations, document sharing
- ✅ One-by-One Sending: Prevents rate limiting and ensures reliable delivery
- ✅ HTML Email Templates: Create beautiful, professional email designs
- ✅ PDF Attachment Support: Attach documents, invoices, certificates, reports
- ✅ Company Signature: Automatically embed company logos and signatures
- ✅ Email Validation: Built-in validation using Disify API (removes invalid/disposable emails)
- ✅ Progress Tracking: Resume interrupted sending sessions
- ✅ Detailed Reporting: Comprehensive success/failure reports
- ✅ Error Handling: Automatic retry logic for throttled requests
- ✅ No User Interaction: Fully automated using Application permissions
- 🔄 Automatic Token Refresh: Handles Microsoft Graph API token expiration
- 📊 Real-time Progress: Live updates during email sending
- 🛡️ Duplicate Prevention: Tracks sent emails to prevent duplicates
- ⚡ Rate Limit Handling: Intelligent backoff for throttled requests
- 📝 Logging: Comprehensive logging for debugging
- Invoice Distribution: Automatically send invoices to clients
- Marketing Campaigns: Send promotional emails to customer lists
- Report Sharing: Distribute monthly/quarterly reports to stakeholders
- Document Delivery: Send contracts, proposals, and legal documents
- Certificate Distribution: Send course completion certificates to students
- Course Notifications: Notify students about new courses, assignments, or deadlines
- Announcements: Distribute institutional announcements to faculty/students
- Grade Reports: Send grade reports to students and parents
Before you begin, ensure you have:
-
Python 3.7 or higher installed
python3 --version
-
Microsoft Azure Account with Entra ID (Azure AD)
- Free tier available at azure.microsoft.com
-
Microsoft 365 Account (for sending emails)
- Can be Business, Education, or Enterprise plan
-
App Registration in Azure Portal with:
Mail.Send(Application) permission- Admin consent granted
git clone https://github.com/nabilW/Email-Sender.git
cd Email-Senderpip install -r requirements.txtcp .env.example .env
# Edit .env with your credentials# Create recipients.txt with one email per line
echo "client1@example.com" > recipients.txt
echo "client2@example.com" >> recipients.txtpython3 email_sender.pyThat's it! Your emails will start sending automatically.
- Go to Azure Portal
- Navigate to Azure Active Directory > App registrations
- Click New registration
- Name:
Email Automation App(or your preferred name) - Supported account types: Single tenant
- Click Register
- In your app, go to API permissions
- Click Add a permission
- Select Microsoft Graph
- Choose Application permissions
- Search for
Mail.Send - Select Mail.Send and click Add permissions
- Important: Click Grant admin consent (requires admin privileges)
- Go to Certificates & secrets
- Click New client secret
- Description:
Email Automation Secret - Expires: Choose appropriate duration (6 months, 12 months, or never)
- Click Add
- Copy the secret value immediately (you won't see it again!)
- Tenant ID: Go to Overview > Copy Tenant ID
- Client ID: Go to Overview > Copy Application (client) ID
- Client Secret: The value you copied from step above
Edit your .env file:
# Microsoft Graph API Credentials (Required)
TENANT_ID=your-tenant-id-here
CLIENT_ID=your-client-id-here
CLIENT_SECRET=your-client-secret-here
SENDER_EMAIL=your-email@yourdomain.com
# Email Template (Optional - can also be set in email_sender.py)
EMAIL_SUBJECT=Your Email Subject Here
EMAIL_BODY_HTML=<html><body><p>Your HTML email content here</p></body></html>
EMAIL_BODY_TEXT=Your plain text email content hereWhere to find these values:
- TENANT_ID: Azure Portal > Entra ID > Overview > Tenant ID
- CLIENT_ID: Azure Portal > App registrations > Your App > Overview > Application (client) ID
- CLIENT_SECRET: The secret value you created (from Certificates & secrets)
- SENDER_EMAIL: Your Microsoft 365 email address (must be in your tenant)
Create recipients.txt with one email address per line:
client1@example.com
client2@example.com
client3@example.com
Tips:
- Empty lines are ignored
- Comments starting with
#are ignored - The script automatically validates and filters invalid emails
- Place your PDF file in the project directory
- Update
attachment_pathinemail_sender.py(line ~850):attachment_path = Path("your-document.pdf")
Supported formats: PDF only (.pdf)
You can configure email templates in two ways:
EMAIL_SUBJECT=Welcome to Our Service
EMAIL_BODY_HTML=<html><body><h1>Welcome!</h1><p>Thank you for joining us.</p></body></html>
EMAIL_BODY_TEXT=Welcome! Thank you for joining us.Edit email_sender.py (lines 48-88) to customize templates directly.
Default: 5 seconds (to avoid rate limiting)
To change, modify delay_seconds in send_emails_one_by_one() function:
delay_seconds=10.0 # Wait 10 seconds between emailsThe script automatically validates emails using:
- Format validation (RFC 5322 compliant)
- Disify API (checks for disposable emails, invalid DNS)
To disable Disify validation:
recipients, stats = load_recipients_from_file(recipients_file, use_disify=False)-
Place logo file in the project directory with one of these names:
logo.pnglogo.jpgorlogo.jpeglogo_black.pnglogo.gif
-
Supported formats:
- PNG (automatically converted to JPEG for better compatibility)
- JPEG/JPG
- GIF
-
Logo will automatically be embedded in your email signature
Edit the email template in .env or email_sender.py to include your signature:
<div class="signature">
<img src="PLACEHOLDER_LOGO_URL" alt="Company Logo" />
<p><strong>Your Name</strong></p>
<p>Your Title</p>
<p>Company Name</p>
<p>Email: your@email.com</p>
<p>Phone: +1 (555) 123-4567</p>
</div>The script automatically replaces PLACEHOLDER_LOGO_URL with your embedded logo.
If you prefer to host your logo online:
- Upload logo to your website/CDN
- In
email_sender.py, set:logo_url = "https://yourdomain.com/logo.png"
- Place PDF file in the project directory
- Update attachment path in
email_sender.py:attachment_path = Path("invoice.pdf") # Your PDF filename
- Invoices:
invoice.pdf,invoice-2024.pdf - Certificates:
certificate.pdf,completion-certificate.pdf - Reports:
monthly-report.pdf,annual-report.pdf - Documents:
contract.pdf,proposal.pdf
Currently, the script supports one PDF attachment per email. For multiple attachments, you can:
- Combine PDFs into a single file
- Modify the code to support multiple attachments (see Contributing)
# 1. Configure .env with your credentials
# 2. Create recipients.txt with email addresses
# 3. Run the script
python3 email_sender.py# In email_sender.py, set:
attachment_path = Path("monthly-report.pdf")# Place logo.png in project directory
# Script automatically detects and embeds it
python3 email_sender.py# In .env file:
EMAIL_SUBJECT=Important Announcement
EMAIL_BODY_HTML=<html><body><h1>Important</h1><p>This is your message.</p></body></html>
EMAIL_BODY_TEXT=Important: This is your message.Error: Failed to acquire token
Solutions:
- Verify
TENANT_ID,CLIENT_ID, andCLIENT_SECRETare correct - Check that client secret hasn't expired
- Ensure app registration has
Mail.Send(Application) permission - Verify admin consent is granted
Error: 401 Unauthorized or 403 Forbidden
Solutions:
- Verify
SENDER_EMAILmatches an email in your tenant - Check that app registration has admin consent for Mail.Send
- Ensure the email account exists and is active
Error: ApplicationThrottled or 429 Too Many Requests
Solutions:
- Increase delay between emails (default: 5 seconds)
- The script automatically retries with exponential backoff
- Consider sending in smaller batches
Error: Attachment file not found
Solutions:
- Verify PDF file exists in project directory
- Check file path in
email_sender.py - Ensure file has
.pdfextension - Check file permissions
Solutions:
- Verify logo file exists with correct name (
logo.png,logo.jpg, etc.) - Check file format (PNG, JPG, or GIF)
- Ensure logo file is in project root directory
- Check file size (very large files may cause issues)
-
Never commit
.envfile- Already excluded in
.gitignore - Contains sensitive credentials
- Already excluded in
-
Rotate client secrets regularly
- Set expiration dates
- Create new secrets before old ones expire
-
Use environment variables in production
- Don't hardcode credentials
- Use secure secret management (Azure Key Vault, AWS Secrets Manager)
-
Limit permissions
- Only grant
Mail.Sendpermission (not full mailbox access) - Use application permissions (not delegated)
- Only grant
-
Monitor usage
- Review
send_results.jsonregularly - Check Azure Portal for unusual activity
- Review
- Test with small batches first: Send to 5-10 recipients before large campaigns
- Validate email lists: Use the built-in validation to remove invalid emails
- Monitor rate limits: Adjust delays if you encounter throttling
- Keep logs: Review
email_send_log.txtfor debugging - Backup progress: The script saves progress automatically
Endpoint:
POST https://graph.microsoft.com/v1.0/users/{SENDER_EMAIL}/sendMail
Required Permission:
Mail.Send(Application)- Admin consent required
Resource App ID:
a7f3d892-4c1e-4a5b-9d2f-8e6c3a1b4f7e
Permission ID:
c4e8a2d1-7b3f-4a9c-8e2d-5f1a9b3c7e4d
Main class for sending emails via Microsoft Graph API.
Methods:
get_access_token(): Acquires and refreshes access tokenssend_email(): Sends a single email with retry logicsend_emails_one_by_one(): Sends emails to multiple recipients
Loads and validates email addresses from a text file.
Parameters:
file_path: Path to recipients fileuse_disify: Enable/disable Disify API validation (default: True)
This project is licensed under the MIT License - see the LICENSE file for details.
This software is provided for educational and business purposes. Users are responsible for:
- Complying with email regulations (CAN-SPAM Act, GDPR, etc.)
- Obtaining proper consent from recipients
- Following Microsoft's Terms of Service
- Respecting recipient privacy and preferences
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Support for multiple attachments
- Email template builder
- GUI interface
- Additional email validation services
- Enhanced error handling
- Performance optimizations
- Issues: Open an issue on GitHub
- Documentation: Check this README and code comments
- Microsoft Graph API: Official Documentation
Q: Can I send to Gmail/Yahoo/other email providers?
A: Yes! The script works with any email address, not just Microsoft accounts.
Q: How many emails can I send per day?
A: Depends on your Microsoft 365 plan. Check your plan's limits in Azure Portal.
Q: Can I schedule emails?
A: Use a task scheduler (cron, Windows Task Scheduler) to run the script at specific times.
Q: Is this free?
A: The script is free and open source. Microsoft 365 subscription required for sending emails.
This project is designed for educational and business automation purposes. It demonstrates:
- Microsoft Graph API integration
- Email automation best practices
- Python application development
- API authentication and security
- Error handling and retry logic
Perfect for:
- Learning Microsoft Graph API
- Understanding email automation
- Business process automation
- Educational institution communications
Current Version: 1.0.0
Status: ✅ Production Ready
Maintenance: Active
Made with ❤️ for businesses and educational institutions