Developer Guide: Creating a New Module
Holehe is designed to be easily extensible. If you want to add support for a new website, you can create a new module file.
Module Structure
A module is a Python file (e.g., mysite.py) located in the appropriate subdirectory of holehe/modules/. It must contain an asynchronous function with a specific signature.
Function Signature
from holehe.core import *
from holehe.localuseragent import *
async def mysite(email, client, out):
name = "mysite"
domain = "mysite.com"
method = "register" # register, login, password recovery, or other
frequent_rate_limit = False
# ... Logic goes here ...
Inputs
- email (
str): The target email address to check. - client (
httpx.AsyncClient): The HTTP client provided by the core logic. Use this to make requests. - out (
list): A list where you append the result dictionary.
Logic Guidelines
- User Agents: Use
random.choice(ua["browsers"]["chrome"])(or firefox/safari) fromholehe.localuseragentto randomize headers. - Requests: Use
await client.get(...)orawait client.post(...). - Error Handling: Wrap requests in
try/exceptblocks to handle connection errors gracefully. If an exception occurs, append a result with"error": True. - Verification: Check the response status code, JSON content, or HTML text to determine if the email is in use.
Output Format
You must append a dictionary to the out list. Do not return values.
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": False, # True if rate limited
"exists": True, # True if account found
"emailrecovery": None, # String if found (e.g. "a*****@gmail.com")
"phoneNumber": None, # String if found
"others": None # Dict or String for extra info
})
Example Template
from holehe.core import *
from holehe.localuseragent import *
async def example_site(email, client, out):
name = "examplesite"
domain = "examplesite.com"
method = "register"
frequent_rate_limit = False
headers = {
'User-Agent': random.choice(ua["browsers"]["chrome"])
}
try:
# Example: Checking a registration API
req = await client.get(f"https://api.examplesite.com/check/{email}", headers=headers)
if req.status_code == 200 and "already_registered" in req.text:
exists = True
else:
exists = False
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": False,
"exists": exists,
"emailrecovery": None,
"phoneNumber": None,
"others": None
})
except Exception:
# Handle connection errors/timeouts
out.append({
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": True,
"exists": False,
"emailrecovery": None,
"phoneNumber": None,
"others": None
})