Email Hippo
This is the Email Hippo integration used to verify email sources as fake emails that were used as part of phishing attacks.
Data Enrichment & Threat Intelligence · Email Hippo
Details
| ID | Email Hippo |
|---|---|
| Provider | EmailHippo |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.9.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
This is the Email Hippo integration used to verify email sources as fake emails that were used as part of phishing attacks.
.
This integration was integrated and tested with version 2.0.1551 of Email Hippo.
Configure Email Hippo in Cortex
| Parameter | Description | Required |
|---|---|---|
| MORE Server URL (e.g., https://api.hippoapi.com) | True | |
| Email Hippo WHOIS Server URL (e.g., https://api.whoishippo.com) | True | |
| MORE API Key | True | |
| WHOIS API Key | True | |
| Source Reliability | Reliability of the source providing the intelligence data. | False |
| Create relationships | Create relationships between indicators as part of enrichment. | False |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
email-hippo-email-quota-get
Get the email quota from the API.
Base Command
email-hippo-email-quota-get
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| EmailHippo.Quota.quotaUsed | String | Total quota used. |
| EmailHippo.Quota.quotaRemaining | String | The remaining quota. |
Command example
#### Context Example
```json
{
"EmailHippo": {
"Quota": {
"accountId": 7031,
"errorSummary": "Valid",
"nextQuotaResetDate": "2023-12-28T00:00:00",
"quotaRemaining": 99,
"quotaUsed": 1,
"reportedDate": "2023-11-28T12:49:16.0260781Z"
}
}
}
Human Readable Output
Email quota
Email Quota remaining Email Quota used 99 1
Return email information and reputation.
Base Command
email
Input
| Argument Name | Description | Required |
|---|---|---|
| A comma-separated list of email addresses to validate. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| Email.Address | String | The email address of the indicator. |
| Email.Domain | string | The email domain. |
| EmailHippo.Email.Address | String | The email address of the indicator. |
Command example
!email email=test@example.com
Context Example
{
"DBotScore": {
"Indicator": "test@example.com",
"Reliability": "C - Fairly reliable",
"Score": 1,
"Type": "email",
"Vendor": "Email Hippo"
},
"Email": {
"Address": "test@example.com",
"Domain": "example.com"
},
"EmailHippo": {
"Email": {
"Address": "test@example.com",
"diagnostic": {
"key": "e4ddf797-f25b-410b-a753-58234759a67a"
},
"disposition": {
"isFreeMail": false,
"isRole": true
},
"domain": null,
"emailVerification": {
"dnsVerification": {
"isDomainHasDnsRecord": true,
"isDomainHasMxRecords": true,
"mxRecords": [
{
"exchange": ".",
"ipAddresses": null,
"preference": 0
}
],
"recordRoot": {
"ipAddresses": [
"93.184.216.34"
]
},
"recordWww": {
"ipAddresses": [
"93.184.216.34"
]
},
"txtRecords": [
"\"wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn\"",
"\"v=spf1 -all\""
]
},
"mailboxVerification": {
"reason": "DomainIsWellKnownDea",
"result": "Unverifiable"
},
"syntaxVerification": {
"isSyntaxValid": true,
"reason": "Success"
}
},
"hippoTrust": {
"level": "Low",
"score": 0
},
"infrastructure": {
"mail": {
"mailServerLocation": null,
"serviceTypeId": "Other",
"smtpBanner": null
},
"web": {
"hasAliveWebServer": true
}
},
"meta": {
"domain": "example.com",
"email": "test@example.com",
"emailHashMd5": "55502f40dc8b7c769880b10874abc9d0",
"emailHashSha1": "567159d622ffbb50b11b0efd307be358624a26ee",
"emailHashSha256": "973dfe463ec85785f5f95af5ba3906eedb2d931c24e69824a89ea65dba4e813b",
"expires": "Sat, 24 Feb 2024 23:31:57 GMT",
"lastModified": "Mon, 28 Aug 2023 23:31:57 GMT",
"subDomain": null,
"tld": "com",
"user": "test"
},
"performance": {
"dnsLookup": 740,
"mailboxVerification": 0,
"other": 0,
"overallExecutionTime": 818,
"spamAssessment": 0,
"syntaxCheck": 0,
"webInfrastructurePing": 78
},
"sendAssess": {
"inboxQualityScore": 0.1,
"sendRecommendation": "DoNotSend"
},
"social": {
"gravatar": {
"imageUrl": "//www.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0",
"profileUrl": "//www.gravatar.com/55502f40dc8b7c769880b10874abc9d0"
}
},
"spamAssess": {
"actionRecomendation": "Block",
"blockLists": [
{
"blockListName": "spamhaus",
"isListed": false,
"listedMoreInfo": null,
"listedReason": null
}
],
"domainRiskScore": 10,
"formatRiskScore": 0,
"isDarkWebEmailAddress": false,
"isDisposableEmailAddress": true,
"isGibberishDomain": false,
"isGibberishUser": false,
"overallRiskScore": 10,
"profanityRiskScore": 0
},
"spamTrapAssess": {
"isSpamTrap": false,
"spamTrapDescriptor": null
},
"version": {
"doc": "https://api-docs.emailhippo.com/en/latest/",
"v": "More-(1.2.1091)"
}
}
}
}
Human Readable Output
Email test@example.com
Hippo Trust Score Inbox quality score Result Spam risk score Low DoNotSend result: Unverifiable
reason: DomainIsWellKnownDeaBlock
domain
Returns domain information and reputation.
Base Command
domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The domain to query (CSV). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | The reliability score of the vendor. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| Domain.Name | String | The name of the domain that was checked. |
| Domain.NameServers | String | Name of the servers of the domain. |
| Domain.UpdatedDate | Date | The date that the domain was last updated. |
| Domain.CreationDate | Date | The creation date of the domain. Format is ISO8601 (i.e.,’2020-04-30T10:35:00.000Z’). |
| Domain.Registrar.Name | String | The name of the registrar. |
| Domain.Registrar.AbuseEmail | String | The email address of the contact for reporting abuse. |
| Domain.Registrar.AbusePhone | String | The phone number of the contact for reporting abuse. |
| Domain.Admin.Country | String | The country of the domain administrator. |
| Domain.Admin.Email | String | The email address of the domain administrator. |
| Domain.Admin.Name | String | The name of the domain administrator. |
| Domain.Admin.Phone | String | The phone number of the domain administrator. |
| Domain.Tech.Country | String | The country of tech administrator. |
| Domain.Tech.Name | String | The name of the tech administrator. |
| Domain.Tech.Email | String | The email of the tech administrator. |
| Domain.Tech.Organization | String | The organization of the tech administrator. |
| Domain.WHOIS.NameServers | String | A CSV string of name servers, for example ‘ns1.bla.com, ns2.bla.com’. |
| Domain.WHOIS.CreationDate | Date | The creation date of the domain. Format is ISO8601 (i.e., ‘2020-04-30T10:35:00.000Z’). |
| Domain.WHOIS.UpdatedDate | Date | The date when the domain was last updated. Format is ISO8601 (i.e., ‘2020-04-30T10:35:00.000Z’). |
| Domain.WHOIS.ExpirationDate | Date | The expiration date of the domain. |
Command example
!domain domain=example.com
Context Example
{
"DBotScore": {
"Indicator": "example.com",
"Reliability": "C - Fairly reliable",
"Score": 0,
"Type": "domain",
"Vendor": "Email Hippo"
},
"Domain": {
"CreationDate": "2018-08-21T14:02:43.000Z",
"Name": "example.com",
"NameServers": [
{
"Address": "A.example.NET"
},
{
"Address": "B.example.NET"
}
],
"UpdatedDate": "2018-08-21T14:02:43.000Z",
"WHOIS": {
"CreationDate": "2018-08-21T14:02:43.000Z",
"NameServers": [
{
"Address": "A.example.NET"
},
{
"Address": "B.example.NET"
}
],
"UpdatedDate": "2018-08-21T14:02:43.000Z"
}
},
"EmailHippo": {
"Domain": {
"creation_date": "2018-08-21T14:02:43.000Z",
"domain": "example.com",
"meta": {
"domain": "example.com",
"domainAge": "0 year(s), 0 month(s), 0 week(s), 0 day(s)",
"domainAgeIso8601": "P0D",
"domainAgeSeconds": 0,
"executionTime": 2092,
"parseCode": "Success",
"recordAge": "5 year(s), 3 months, 0 week(s), 6 day(s), 22 hour(s), 46 minute(s)",
"recordAgeIso8601": "P5Y3M6DT22H46M23.4811208S",
"recordCreatedDate": "2018-08-21T14:02:43Z",
"recordUpdatedDate": "2018-08-21T14:02:43Z",
"timeToExpiry": "0 year(s), 0 months, 0 week(s), 0 day(s)",
"timeToExpiryIso8601": "P0D",
"timeToExpirySeconds": 0,
"tld": "com"
},
"updated_date": "2018-08-21T14:02:43.000Z",
"version": {
"doc": "https://emailhippo.github.io/whois-developers",
"v": "1.0.511"
},
"whoisServerRecord": {
"adminContact": {
"city": "",
"country": "",
"email": "",
"faxNumber": "",
"faxNumberExt": "",
"name": "",
"organization": "",
"phoneNumber": "",
"phoneNumberExt": "",
"postalCode": "",
"state": "",
"street1": "",
"street2": null,
"street3": null,
"street4": null,
"userId": ""
},
"billingContact": {
"city": null,
"country": null,
"email": null,
"faxNumber": null,
"faxNumberExt": null,
"name": null,
"organization": null,
"phoneNumber": null,
"phoneNumberExt": null,
"postalCode": null,
"state": null,
"street1": null,
"street2": null,
"street3": null,
"street4": null,
"userId": null
},
"changed": null,
"created": null,
"customFields": null,
"dnsSec": "",
"domainHandle": "",
"domainName": "example.com",
"domainOwnerContact": {
"city": "",
"country": "",
"email": "",
"faxNumber": "",
"faxNumberExt": "",
"name": "",
"organization": "",
"phoneNumber": "",
"phoneNumberExt": "",
"postalCode": "",
"state": "",
"street1": "",
"street2": null,
"street3": null,
"street4": null,
"userId": ""
},
"domainStati": null,
"expiry": null,
"nameServers": [
{
"Address": "A.example.NET"
},
{
"Address": "B.example.NET"
}
],
"recordFound": true,
"registrar": {
"abuseEmail": "",
"abusePhone": "",
"name": "",
"registrarId": "",
"url": "",
"whois": "--UNSPECIFIED--"
},
"registrarContact": {
"city": null,
"country": null,
"email": null,
"faxNumber": null,
"faxNumberExt": null,
"name": null,
"organization": null,
"phoneNumber": null,
"phoneNumberExt": null,
"postalCode": null,
"state": null,
"street1": null,
"street2": null,
"street3": null,
"street4": null,
"userId": null
},
"remarks": null,
"reseller": "",
"techContact": {
"city": "",
"country": "",
"email": "",
"faxNumber": "",
"faxNumberExt": "",
"name": "",
"organization": "",
"phoneNumber": "",
"phoneNumberExt": "",
"postalCode": "",
"state": "",
"street1": "",
"street2": null,
"street3": null,
"street4": null,
"userId": ""
},
"tld": "com",
"zoneContact": {
"city": null,
"country": null,
"email": null,
"faxNumber": null,
"faxNumberExt": null,
"name": null,
"organization": null,
"phoneNumber": null,
"phoneNumberExt": null,
"postalCode": null,
"state": null,
"street1": null,
"street2": null,
"street3": null,
"street4": null,
"userId": null
}
}
}
}
}
Human Readable Output
Domain example.com
Domain Age Expires On Name servers Registered On Registrar Status Time To Expiry Updated On 0 year(s), 0 month(s), 0 week(s), 0 day(s) {‘Address’: ‘A.example.NET’},
{‘Address’: ‘B.example.NET’}0 year(s), 0 months, 0 week(s), 0 day(s)
Configuration parameters
more_server_url— MORE Server URL (e.g., https://api.hippoapi.com) (required)whois_server_url— Email Hippo WHOIS Server URL (e.g., https://api.whoishippo.com) (required)more_credentials— (required)whois_credentials— (required)integrationReliability— Source Reliabilitycreate_relationships— Create relationshipsinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (3)
-
domainReturns domain information and reputation.
-
emailReturn email information and reputation.
-
email-hippo-email-quota-getGet the email quota from the API.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import urllib3 import dateparser from requests import Response from functools import partial from typing import Any # Disable insecure warnings urllib3.disable_warnings() DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" TRUST_LEVEL_TO_DBOT_SCORE_MAPPING = { "None": Common.DBotScore.NONE, "High": Common.DBotScore.GOOD, "Medium": Common.DBotScore.SUSPICIOUS, "Low": Common.DBotScore.BAD, } class Client(BaseClient): """Client class to interact with the service API This Client implements API calls, and does not contain any Demisto logic. Should only do requests and return data. It inherits from BaseClient defined in CommonServer Python. Most calls use _http_request() that handles proxy, SSL verification, etc. """ def __init__(self, more_api_key, whois_api_key, more_server_url, whois_server_url, **kwargs): self._more_api_key = more_api_key self._whois_api_key = whois_api_key self._more_server_url = more_server_url.rstrip("/") self._whois_server_url = f'{whois_server_url.rstrip("/")}/v1/{whois_api_key}' super().__init__(base_url="", **kwargs) def get_email_reputation(self, email: str) -> dict[str, Any]: """Gets the Email reputation using the hippoapi '/email' API endpoint Args: email (str): Email address to get the reputation for. Returns: dict: dict containing the Email reputation as returned from the API """ return self._http_request( method="GET", full_url=f"{self._more_server_url}/v3/more/json/{self._more_api_key}/{email}", with_metrics=True, ) def get_domain_reputation(self, domain: str) -> dict[str, Any]: """ Gets the Domain reputation using the whoishippo '/domain' API endpoint. Args: domain (str): Domain name to get the reputation for. Returns: dict: dict containing the domain reputation as returned from the API. """ return self._http_request( method="GET", full_url=f"{self._whois_server_url}/{domain}", with_metrics=True, ) def get_email_quota(self) -> dict[str, Any]: """ Get the email quota remaining for the API key """ return self._http_request( method="GET", full_url=f"{self._more_server_url}/customer/reports/v3/quota/{self._more_api_key}", with_metrics=True, ) def determine_error_type(self, res: Response): """Determines the error type based on response. Args: res (Response): The response object from the http request. Returns: (ErrorTypes): The error type determined. """ if "Insufficient quota" in res.text: return ErrorTypes.QUOTA_ERROR return super().determine_error_type(res) def parse_domain_date(domain_date: list[str] | str, date_format: str = "%Y-%m-%dT%H:%M:%S.000Z") -> str | None: """ Converts whois date format to an ISO8601 string. Converts the domain WHOIS date (YYYY-mm-dd HH:MM:SS) format in a datetime. If a list is returned with multiple elements, takes only the first one. Args: domain_date (str/list): a string or list of strings with the format 'YYYY-mm-DD HH:MM:SS' date_format (int): The format date to which the function will convert the given date. Returns: str: Parsed time, default in ISO8601 format. """ if isinstance(domain_date, str): # if str parse the value domain_date_dt = dateparser.parse(domain_date) if domain_date_dt: return domain_date_dt.strftime(date_format) elif isinstance(domain_date, list) and len(domain_date) > 0 and isinstance(domain_date[0], str): # if list with at least one element, parse the first element domain_date_dt = dateparser.parse(domain_date[0]) if domain_date_dt: return domain_date_dt.strftime(date_format) # in any other case return nothing return None """ COMMAND FUNCTIONS """ def test_module(client: Client) -> str: """ Tests API connectivity and authentication for both, EmailHippo and WHOIS. When 'ok' is returned it indicates the integration works like it is supposed to and connection to the service is successful. Raises exceptions if something goes wrong. Args: client (Client): EmailHippo client to use. Returns: str: 'ok' if test passed, anything else will raise an exception and will fail the test. """ test_methods: dict[str, Any] = { "MORE": partial(client.get_email_reputation, "test@test.com"), "WHOIS": partial(client.get_domain_reputation, "google.com"), } for key_vendor in test_methods: try: test_methods[key_vendor]() except DemistoException as e: if "Unauthorized" in str(e): return f"Authorization Error: make sure {key_vendor} API Key is correctly set" else: raise e return "ok" def get_email_quota_command(client: Client) -> CommandResults: """ email-hippo-email-quota-get command: Returns the email quota. Args: client (Client): EmailHippo client to use. Returns: CommandResults: A ``CommandResults`` object that is then passed to ``return_results``. """ quota = client.get_email_quota() quota.pop("licenseKey", None) # delete the licenseKey as this are secret readable_output = tableToMarkdown( "Email quota", {"Email Quota used": quota.get("quotaUsed"), "Email Quota remaining": quota.get("quotaRemaining")} ) return CommandResults( readable_output=readable_output, outputs_prefix="EmailHippo.Quota", outputs_key_field="accountId", outputs=quota ) def email_reputation_command( client: Client, args: dict[str, Any], reliability: DBotScoreReliability, create_relationships: bool = False ) -> list[CommandResults]: """ email command: Returns Email reputation for a list of Emails Args: client (Client): EmailHippo client to use. args (dict): all command arguments, usually passed from ``demisto.args()``. reliability (DBotScoreReliability): reliability of the source providing the intelligence data. create_relationships (bool): whether to create relationships between the email and domain. Returns: CommandResults: A ``CommandResults`` object that is then passed to ``return_results``, that contains Emails. """ emails = argToList(args.get("email")) if len(emails) == 0: raise ValueError("Email(s) not specified") command_results: list[CommandResults] = [] for email in emails: email_data = client.get_email_reputation(email) email_data["Address"] = email domain = demisto.get(email_data, "meta.domain") level = demisto.get(email_data, "hippoTrust.level") reputation = TRUST_LEVEL_TO_DBOT_SCORE_MAPPING.get(level, Common.DBotScore.NONE) dbot_score = Common.DBotScore( indicator=email, indicator_type=DBotScoreType.EMAIL, integration_name="Email Hippo", score=reputation, malicious_description=f"Email Hippo returned reputation {reputation}", reliability=reliability, ) relationships = [] if create_relationships: relationships.append( EntityRelationship( entity_a=email, entity_a_type=FeedIndicatorType.Email, name="related-to", entity_b=domain, entity_b_type=FeedIndicatorType.Domain, brand="Email Hippo", ) ) email_indicator = Common.EMAIL(address=email, dbot_score=dbot_score, domain=domain, relationships=relationships) email_readable = { "Result": demisto.get(email_data, "emailVerification.mailboxVerification"), "Hippo Trust Score": demisto.get(email_data, "hippoTrust.level"), "Inbox quality score": demisto.get(email_data, "sendAssess.sendRecommendation"), "Spam risk score": demisto.get(email_data, "spamAssess.actionRecomendation"), } readable_output = tableToMarkdown(f"Email {email}", email_readable) command_results.append( CommandResults( readable_output=readable_output, outputs_prefix="EmailHippo.Email", outputs_key_field="Address", outputs=email_data, indicator=email_indicator, relationships=relationships, ) ) return command_results def domain_reputation_command(client: Client, args: dict[str, Any], reliability: DBotScoreReliability) -> list[CommandResults]: """ domain command: Returns domain reputation for a list of domains. Args: client (Client): EmailHippo client to use. args (dict): all command arguments, usually passed from ``demisto.args()``. reliability (DBotScoreReliability): reliability of the source providing the intelligence data. Returns: CommandResults: A ``CommandResults`` object that is then passed to ``return_results``, that contains Domains. """ domains = argToList(args.get("domain")) if len(domains) == 0: raise ValueError("domain(s) not specified") command_results: list[CommandResults] = [] for domain in domains: domain_data = client.get_domain_reputation(domain) domain_data["domain"] = domain # convert the dates to ISO8601 as Cortex XSOAR customers use this format by default if creation_date := demisto.get(domain_data, "meta.recordCreatedDate"): domain_data["creation_date"] = parse_domain_date(creation_date) if updated_date := demisto.get(domain_data, "meta.recordUpdatedDate"): domain_data["updated_date"] = parse_domain_date(updated_date) dbot_score = Common.DBotScore( indicator=domain, integration_name="Email Hippo", indicator_type=DBotScoreType.DOMAIN, score=Common.DBotScore.NONE, reliability=reliability, ) domain_indicator = Common.Domain( domain=domain, creation_date=domain_data.get("creation_date", None), updated_date=domain_data.get("updated_date", None), # organization=domain_data.get('org', None), name_servers=demisto.get(domain_data, "whoisServerRecord.nameServers"), registrar_name=demisto.get(domain_data, "whoisServerRecord.registrar.name"), registrar_abuse_phone=demisto.get(domain_data, "whoisServerRecord.registrar.abusePhone"), registrar_abuse_email=demisto.get(domain_data, "whoisServerRecord.registrar.abuseEmail"), admin_name=demisto.get(domain_data, "whoisServerRecord.adminContact.name"), admin_country=demisto.get(domain_data, "whoisServerRecord.adminContact.country"), admin_email=demisto.get(domain_data, "whoisServerRecord.adminContact.email"), admin_phone=demisto.get(domain_data, "whoisServerRecord.adminContact.phoneNumber"), tech_country=demisto.get(domain_data, "whoisServerRecord.techContact.country"), tech_name=demisto.get(domain_data, "whoisServerRecord.techContact.name"), tech_organization=demisto.get(domain_data, "whoisServerRecord.techContact.organization"), tech_email=demisto.get(domain_data, "whoisServerRecord.techContact.email"), dbot_score=dbot_score, ) domain_readable = { "Registrar": demisto.get(domain_data, "whoisServerRecord.registrar.name"), "Registered On": demisto.get(domain_data, "whoisServerRecord.created"), "Domain Age": demisto.get(domain_data, "meta.domainAge"), "Expires On": demisto.get(domain_data, "whoisServerRecord.expiry"), "Time To Expiry": demisto.get(domain_data, "meta.timeToExpiry"), "Updated On": demisto.get(domain_data, "whoisServerRecord.changed"), "Status": demisto.get(domain_data, "whoisServerRecord.domainStati"), "Name servers": demisto.get(domain_data, "whoisServerRecord.nameServers"), } readable_output = tableToMarkdown(f"Domain {domain}", domain_readable) # delete the rawResponse key from the output domain_data.get("whoisServerRecord", {}).pop("rawResponse", None) command_results.append( CommandResults( readable_output=readable_output, outputs_prefix="EmailHippo.Domain", outputs_key_field="domain", outputs=domain_data, indicator=domain_indicator, ) ) return command_results """ MAIN FUNCTION """ def main() -> None: # pragma: no cover """ main function, parses params and runs command functions """ params = demisto.params() args = demisto.args() command = demisto.command() more_api_key = params.get("more_credentials", {}).get("password") whois_api_key = params.get("whois_credentials", {}).get("password") more_server_url = params.get("more_server_url", "https://api.hippoapi.com") whois_server_url = params.get("whois_server_url", "https://api.whoishippo.com") reliability = params.get("integrationReliability", DBotScoreReliability.C) verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) demisto.debug(f"Command being called is {command}") res: list[CommandResults] = [] client = None try: client = Client( more_api_key=more_api_key, whois_api_key=whois_api_key, more_server_url=more_server_url, whois_server_url=whois_server_url, verify=verify_certificate, proxy=proxy, ) if command == "test-module": return_results(test_module(client)) elif command == "email": res = email_reputation_command(client, args, reliability) elif command == "domain": res = domain_reputation_command(client, args, reliability) elif command == "email-hippo-email-quota-get": res = [get_email_quota_command(client)] else: raise NotImplementedError(f"Command {command} is not implemented") if res: return_results(res) # Log exceptions and return errors except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{str(e)}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()