Created
December 24, 2025 16:49
-
-
Save tanfwc/b9bbbabffd6af011679334bd53de01dd to your computer and use it in GitHub Desktop.
SmarterMail Search All Alias
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| # Script provided by SmarterTools Team | |
| # | |
| # DISCLAIMER: USE AT YOUR OWN RISK | |
| # | |
| # This script is provided for educational and sharing purposes only. | |
| # I make no guarantees about its correctness, safety, or suitability | |
| # for your environment. It may modify your SmarterMail aliases and | |
| # affect email delivery. Always test in a safe environment and | |
| # backup your data before use. You assume all responsibility for | |
| # any consequences arising from running this script. | |
| import requests | |
| import json | |
| import sys | |
| from datetime import datetime | |
| from urllib.parse import quote | |
| # Configuration | |
| SMARTERMAIL_URL = "" | |
| USERNAME = "" | |
| PASSWORD = "" | |
| USER_EMAIL = "" | |
| def authenticate(base_url, username, password): | |
| """Authenticate and return access token.""" | |
| auth_url = f"{base_url}/api/v1/auth/authenticate-user" | |
| payload = { | |
| "username": username, | |
| "password": password | |
| } | |
| response = requests.post(auth_url, json=payload, verify=False) | |
| if response.status_code != 200: | |
| print(f"Authentication failed: {response.status_code}") | |
| print(response.text) | |
| sys.exit(1) | |
| data = response.json() | |
| if not data.get("success") or not data.get("accessToken"): | |
| print(f"Login failed: {data.get('message')}") | |
| sys.exit(1) | |
| print("Authentication successful!") | |
| return data["accessToken"] | |
| def search_aliases_by_target(base_url, access_token, user_email): | |
| """Search for aliases containing the user.""" | |
| encoded_email = quote(user_email) | |
| search_url = f"{base_url}/api/v1/settings/domain/aliases/{encoded_email}" | |
| # Extract domain from email | |
| try: | |
| domain = user_email.split("@", 1)[1] | |
| except IndexError: | |
| raise ValueError(f"Invalid email address: {user_email}") | |
| headers = { | |
| "Authorization": f"Bearer {access_token}", | |
| "X-Smartermaildomain": domain | |
| } | |
| response = requests.get(search_url, headers=headers, verify=False) | |
| if response.status_code != 200: | |
| print(f"[search_aliases_by_target] Search failed: {response.status_code} {base_url}/api/v1/settings/domain/aliases/{encoded_email}") | |
| print(response.text) | |
| sys.exit(1) | |
| return response.json() | |
| def main(): | |
| print(f"Searching for aliases containing: {USER_EMAIL}") | |
| print("-" * 60) | |
| # Authenticate and get access token | |
| access_token = authenticate(SMARTERMAIL_URL, USERNAME, PASSWORD) | |
| # Search for aliases | |
| print("\nSearching aliases...") | |
| results = search_aliases_by_target(SMARTERMAIL_URL, access_token, USER_EMAIL) | |
| # Filter results | |
| matching_aliases = [] | |
| if "gridInfo" in results: | |
| for alias in results["gridInfo"]: | |
| targets = alias.get("targets", []) | |
| if any(target.lower() == USER_EMAIL.lower() for target in targets): | |
| matching_aliases.append(alias) | |
| if not matching_aliases: | |
| print(f"\nNo aliases found for {USER_EMAIL}") | |
| return | |
| # Display results | |
| print(f"\nFound {len(matching_aliases)} alias(es):") | |
| print("=" * 60) | |
| for i, alias in enumerate(matching_aliases, 1): | |
| print(f"\n{i}. {alias.get('name')}") | |
| print(f" Targets: {', '.join(alias.get('targets', []))}") | |
| print("\n" + "=" * 60) | |
| # Backup to JSON | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| backup_file = f"alias_backup_{timestamp}.json" | |
| with open(backup_file, "w", encoding="utf-8") as f: | |
| json.dump(matching_aliases, f, indent=2) | |
| print(f"\nBackup saved to: {backup_file}") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment