How to Add a New Social Media Module to holehe: A Step-by-Step Guide
To add a new social media module to holehe, create an async coroutine in the holehe/modules/medias/ directory that accepts email, client, and out parameters, implement the required metadata structure, and register the function in the category's __init__.py file.
holehe is an open-source email OSINT tool that checks for account existence across hundreds of platforms using an extensible plugin architecture. Its modular design allows developers to add support for new services by implementing standardized async functions that the core engine automatically discovers. This guide walks you through the exact process to add a new social media module to holehe, referencing the actual source code structure from the megadose/holehe repository.
Understanding the Module Architecture in holehe
holehe employs a dynamic plugin system where each service is implemented as a standalone async function. The central engine in holehe/core.py discovers available modules by importing the MODULES dictionary exposed through __init__.py files across category folders. Each module follows a strict contract: it receives an email string, an httpx.AsyncClient instance, and a shared output list, then appends a standardized result dictionary containing nine mandatory keys.
Step-by-Step Guide to Adding a Social Media Module
Choose the Correct Category Directory
Social media platforms belong in holehe/modules/medias/. If your target service requires a new sub-category, create a dedicated folder and ensure it exposes a MODULES list via its own __init__.py so the core loader can discover it.
Create the Module File with the Standard Async Signature
Create a Python file (e.g., instagram.py) inside the chosen directory. Define a single coroutine with this exact signature:
async def instagram(email, client, out):
The client parameter provides a reusable httpx.AsyncClient for HTTP requests, while out is a list where you must append the result dictionary.
Implement the Coroutine with Required Metadata
First, declare the static metadata variables: name, domain, method, and frequent_rate_limit. For request headers, reuse the ua helper imported from holehe/localuseragent.py, following the pattern established in existing modules like Blablacar (holehe/modules/transport/blablacar.py).
Wrap all HTTP calls in a try/except block to catch connectivity or rate-limit errors. Append a dictionary to the out list containing these mandatory keys: name, domain, method, frequent_rate_limit, rateLimit, exists, emailrecovery, phoneNumber, and others. Set rateLimit=True when exceptions occur.
Register the Module in init.py
Edit holehe/modules/medias/__init__.py to import your function and append it to the MODULES list:
from .instagram import instagram
MODULES.append(instagram)
The core loader iterates over this list in holehe/core.py and invokes each coroutine during execution.
Test Your Implementation
Run the project's test suite using python -m unittest to verify that your new module integrates correctly without breaking existing functionality.
Complete Implementation Example
The following example demonstrates a minimal Instagram module following the holehe architectural pattern:
from holehe.core import *
from holehe.localuseragent import *
async def instagram(email, client, out):
name = "instagram"
domain = "instagram.com"
method = "register"
frequent_rate_limit = False
headers = {
"User-Agent": random.choice(ua["browsers"]["firefox"]),
"Accept": "application/json",
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
}
try:
resp = await client.get(
f"https://www.instagram.com/web/accounts/web_signup_ajax/",
params={"email": email},
headers=headers,
)
data = resp.json()
except Exception:
out.append(
{
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": True,
"exists": False,
"emailrecovery": None,
"phoneNumber": None,
"others": None,
}
)
return None
exists = data.get("email")
out.append(
{
"name": name,
"domain": domain,
"method": method,
"frequent_rate_limit": frequent_rate_limit,
"rateLimit": False,
"exists": bool(exists),
"emailrecovery": None,
"phoneNumber": None,
"others": None,
}
)
Register the module in holehe/modules/medias/__init__.py:
from .instagram import instagram
MODULES.append(instagram)
Summary
- Create async function: Define
async def servicename(email, client, out)in the appropriate subdirectory underholehe/modules/. - Implement metadata: Include
name,domain,method, andfrequent_rate_limitvariables at the function start. - Handle errors: Wrap HTTP calls in
try/exceptblocks and setrateLimit=Truewhen catching exceptions. - Standardize output: Append dictionaries containing all nine required keys (
name,domain,method,frequent_rate_limit,rateLimit,exists,emailrecovery,phoneNumber,others) to theoutlist. - Register module: Import and append the function to
MODULESin the category's__init__.pyfile. - Use helpers: Import
uafromholehe/localuseragent.pyfor realistic user-agent headers, as demonstrated inholehe/modules/transport/blablacar.py.
Frequently Asked Questions
What is the exact function signature required for a holehe module?
The function must be an async coroutine named after the service, accepting three parameters: email (string), client (httpx.AsyncClient), and out (list). The loader in holehe/core.py calls each module with these exact arguments during the OSINT enumeration process.
How does holehe automatically discover new modules?
The core engine imports the MODULES list from package __init__.py files throughout the holehe/modules/ directory tree. When you append your coroutine to MODULES in holehe/modules/medias/__init__.py, the discovery system automatically includes it in the execution cycle without requiring central registry edits.
What fields are mandatory in the result dictionary appended to the out list?
Every result must contain nine specific keys: name, domain, method, frequent_rate_limit, rateLimit, exists, emailrecovery, phoneNumber, and others. The exists field indicates account presence as a boolean, while rateLimit signals whether the service blocked the request.
How should I handle rate limiting in my social media module?
Wrap all external HTTP requests in a try/except block. If an exception occurs or the response indicates throttling, immediately append a result with rateLimit=True and exists=False, then return. Refer to lines 30-38 of holehe/modules/transport/blablacar.py for the standard error-handling pattern used across the codebase.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →