I've created an API which will take first name, last name and email and generate all possible combinations of emails and returns the valid emails(Which are exist in this world). It works for innofied but doesn't works gmail. For gmail it says all the valid emails. I'm using gmail SMTP for this
The following is the code in api.php
Route::post('/validate-emails', [EmailValidationController::class, 'validateEmails']);
The following is the code in EmailValidationController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Services\Integrations\Email\EmailServiceInterface;
class EmailValidationController extends Controller
{
public function __construct(
private EmailServiceInterface $emailValidationService
) {}
public function validateEmails(Request $request)
{
$validator = Validator::make($request->all(), [
'first_name' => 'required|string',
'last_name' => 'required|string',
'domain' => 'required|string'
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors()], 422);
}
$first = strtolower($request->first_name);
$last = strtolower($request->last_name);
$domain = strtolower($request->domain);
$emails = $this->emailValidationService->generateEmailPermutations($first, $last, $domain);
$validEmails = $this->emailValidationService->validateEmails($emails);
return response()->json([
'all_combinations' => $emails,
'valid_combinations' => array_values($validEmails),
]);
}
}
The following is the code EmailService
<?php
namespace App\Services\Integrations\Email;
use App\Services\Integrations\Email\EmailServiceInterface;
use Illuminate\Support\Facades\Log;
class EmailService implements EmailServiceInterface
{
/**
* Generate all possible email permutations.
*
* @param string $firstName
* @param string $lastName
* @param string $domain
* @return array
*/
public function generateEmailPermutations(
string $firstName,
string $lastName,
string $domain
): array {
$first = strtolower($firstName);
$last = strtolower($lastName);
$f = substr($first, 0, 1);
$l = substr($last, 0, 1);
return [
"$first@$domain",
"$last@$domain",
"$first$last@$domain",
"$first.$last@$domain",
"$f$last@$domain",
"$f.$last@$domain",
"$first$l@$domain",
"$first.$l@$domain",
"$f$l@$domain",
"$f.$l@$domain",
"$last$first@$domain",
"$last.$first@$domain",
"$last$f@$domain",
"$last.$f@$domain",
"$l$first@$domain",
"$l.$first@$domain",
"$l$f@$domain",
"$l.$f@$domain",
"$first-$last@$domain",
"$f-$last@$domain",
"$first-$l@$domain",
"$f-$l@$domain",
"$last-$first@$domain",
"$last-$f@$domain",
"$l-$first@$domain",
"$l-$f@$domain",
"{$first}_{$last}@$domain",
"{$f}_{$last}@$domain",
"{$first}_{$l}@$domain",
"{$f}_{$l}@$domain",
"{$last}_{$first}@$domain",
"{$last}_{$f}@$domain",
"{$l}_{$first}@$domain",
"{$l}_{$f}@$domain",
];
}
/**
* Validate email addresses using MX and SMTP verification.
*/
public function validateEmails(array $emails): array
{
return array_filter($emails, fn($email) => $this->validateEmailSMTP($email));
}
private function getMXRecord($domain)
{
$mxRecords = dns_get_record($domain, DNS_MX);
return $mxRecords ? $mxRecords[0]['target'] : null;
}
private function validateEmailSMTP($email)
{
$domain = explode('@', $email)[1];
$mxServer = $this->getMXRecord($domain);
if (!$mxServer) {
return false; // No mail server found
}
$from = config('mail.from.address');
$mailServerDomain = config('mail.mailers.smtp.mail_server_domain');
$sock = fsockopen($mxServer, 25, $errno, $errstr, 5);
if (!$sock) {
return false;
}
stream_set_timeout($sock, 5);
$this->getSMTPResponse($sock); // Read initial 220 response
fwrite($sock, "HELO $mailServerDomain\r\n");
$this->getSMTPResponse($sock); // Read HELO response
fwrite($sock, "MAIL FROM:<$from>\r\n");
$this->getSMTPResponse($sock); // Read MAIL FROM response
fwrite($sock, "RCPT TO:<$email>\r\n");
$response = $this->getSMTPResponse($sock); // Read RCPT TO response
fwrite($sock, "QUIT\r\n");
fclose($sock);
return strpos($response, "250") !== false && !strpos($response, "550");
}
private function getSMTPResponse($sock)
{
$response = '';
while ($line = fgets($sock, 1024)) {
$response .= $line;
if (substr($line, 3, 1) == " ") { // End of response
break;
}
}
return $response;
}
}
It works for the following input Input
{
"first_name": "deep",
"last_name": "jajodia",
"domain": "innofied"
}
Output
{
"all_combinations": [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
],
"valid_combinations": [
"[email protected]",
"[email protected]"
]
}
Here [email protected],[email protected] are valid and exist. It works for innofied but for gmail it doesn't work
Input for gmail
{
"first_name": "sourav",
"last_name": "saha964",
"domain": "gmail"
}
Output
{
"all_combinations": [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
],
"valid_combinations": [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
]
}
Here only [email protected] is valid and others are not