Skip to content

add an email relay #3

Open
Open

Description

@divinity76
No description provided.

Activity

  1. divinity76 commented on May 27, 2017

    @divinity76
    OwnerAuthor

    here's some code i wrote to send email through gmail for another project... (without the gmail api)

    function gmail_email(string $username, string $password, string $to, string $subject, string $message, string $from = NULL): bool {
    	if ($from === NULL) {
    		$from = $username;
    	}
    	require_once ('hhb_.inc.php');
    	$hc = new hhb_curl ();
    	$hc->_setComfortableOptions ();
    	$hc->setopt_array ( array (
    			CURLOPT_CONNECTTIMEOUT => 10,
    			CURLOPT_TIMEOUT => 20 
    	) );
    	$hc->setopt ( CURLOPT_HTTPHEADER, [ 
    			'Accept-Language: en-US,en;q=0.5' 
    	] );
    	$hc->exec ( 'https://gmail.com/' );
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	$url = $domd->getElementById ( "gaia_loginform" )->getAttribute ( "action" );
    	$inputs_raw = getDOMDocumentFormInputs ( $domd, true ) ['gaia_loginform'];
    	$inputs = [ ];
    	foreach ( $inputs_raw as $name => $ele ) {
    		$inputs [$name] = $ele->getAttribute ( "value" );
    	}
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getResponseBody () );
    	unset ( $name, $ele, $inputs_raw, $domd );
    	$inputs ['Email'] = $username;
    	
    	$hc->setopt_array ( array (
    			CURLOPT_POST => true,
    			CURLOPT_POSTFIELDS => http_build_query ( $inputs ),
    			CURLOPT_URL => $url 
    	) );
    	unset ( $inputs, $url );
    	$hc->setopt ( CURLOPT_HTTPHEADER, [ 
    			'Accept-Language: en-US,en;q=0.5' 
    	] );
    	$hc->exec ();
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	$inputs_raw = getDOMDocumentFormInputs ( $domd, true ) ['gaia_loginform'];
    	$inputs = [ ];
    	$url = $domd->getElementById ( "gaia_loginform" )->getAttribute ( "action" );
    	foreach ( $inputs_raw as $name => $ele ) {
    		$inputs [$name] = $ele->getAttribute ( "value" );
    	}
    	unset ( $name, $ele, $inputs_raw, $domd );
    	$inputs ['Passwd'] = $password;
    	$hc->setopt_array ( array (
    			CURLOPT_POST => true,
    			CURLOPT_POSTFIELDS => http_build_query ( $inputs ),
    			CURLOPT_URL => $url 
    	) );
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getResponseBody () );
    	$hc->setopt ( CURLOPT_HTTPHEADER, [ 
    			'Accept-Language: en-US,en;q=0.5' 
    	] );
    	$hc->exec ();
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	foreach ( $domd->getElementsByTagName ( "form" ) as $form ) {
    		// MAINTENANCE WARNING: ?ui=mobile&zyp=c
    		// https://mail.google.com/mail/u/0/
    		if ($form->getAttribute ( "action" ) !== '?ui=mobile&zyp=c') {
    			$form->textContent = 'deleted';
    			$form->parentNode->removeChild ( $form );
    		}
    	}
    	$inputs_raw = getDOMDocumentFormInputs ( $domd, true ) [1];
    	// hhb_var_dump($inputs_raw);die();
    	$inputs = [ ];
    	foreach ( $inputs_raw as $name => $ele ) {
    		$inputs [$name] = $ele->getAttribute ( "value" );
    	}
    	$url = $domd->getElementsByTagName ( "form" )->item ( 1 )->getAttribute ( "action" );
    	if (null === parse_url ( $url, PHP_URL_HOST )) {
    		$url = $hc->getinfo ( CURLINFO_EFFECTIVE_URL ) . $url;
    	}
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getResponseBody () );
    	// die ();
    	$hc->setopt_array ( array (
    			CURLOPT_POST => true,
    			CURLOPT_POSTFIELDS => http_build_query ( $inputs ),
    			CURLOPT_URL => $url 
    	) );
    	$hc->setopt ( CURLOPT_HTTPHEADER, [ 
    			'Accept-Language: en-US,en;q=0.5' 
    	] );
    	$hc->exec ();
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getResponseBody () );
    	// die ();
    	$url = NULL;
    	foreach ( $domd->getElementsByTagName ( "a" ) as $a ) {
    		if ($a->textContent === 'Compose') {
    			$url = $a->getAttribute ( "href" );
    			if (null === parse_url ( $url, PHP_URL_HOST )) {
    				$urlinfo = parse_url ( $hc->getinfo ( CURLINFO_EFFECTIVE_URL ) );
    				// we actually just want to remove $urlinfo['query']...
    				$url = $urlinfo ['scheme'] . '://' . $urlinfo ['host'] . $urlinfo ['path'] . $url;
    			}
    			break;
    		}
    	}
    	// hhb_var_dump ( $url );
    	// die ();
    	$hc->setopt ( CURLOPT_HTTPGET, true );
    	$hc->setopt ( CURLOPT_HTTPHEADER, [ 
    			'Accept-Language: en-US,en;q=0.5' 
    	] );
    	$hc->exec ( $url );
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	$inputs_raw = getDOMDocumentFormInputs ( $domd, true ) ['cp'];
    	$inputs = [ ];
    	foreach ( $inputs_raw as $name => $ele ) {
    		$inputs [$name] = $ele->getAttribute ( "value" );
    	}
    	// not sure how they're doing it, but they have inputs in the HTML that they manage not to send, even with javascript disabled...
    	// heres a list of inputs to keep...
    	$toKeep = array (
    			'redir',
    			'at',
    			'from',
    			'to',
    			'subject',
    			'body',
    			'nvp_bu_send' 
    	);
    	foreach ( $inputs as $key => $unused ) {
    		if (! in_array ( $key, $toKeep, true )) {
    			unset ( $inputs [$key] );
    		}
    	}
    	$inputs ['from'] = $from;
    	$inputs ['to'] = $to;
    	$inputs ['subject'] = $subject;
    	$inputs ['body'] = $message;
    	$url = $domd->getElementsByTagName ( "form" )->item ( 0 )->getAttribute ( "action" );
    	if (null === parse_url ( $url, PHP_URL_HOST )) {
    		$urlinfo = parse_url ( $hc->getinfo ( CURLINFO_EFFECTIVE_URL ) );
    		// we actually just want to remove $urlinfo['query']...
    		$url = $urlinfo ['scheme'] . '://' . $urlinfo ['host'] . $urlinfo ['path'] . $url;
    	}
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getStdOut () );
    	$hc->setopt_array ( array (
    			CURLOPT_POST => true,
    			CURLOPT_POSTFIELDS => http_build_query ( $inputs ),
    			CURLOPT_URL => $url 
    	) );
    	$hc->setopt ( CURLOPT_HTTPHEADER, [ 
    			'Accept-Language: en-US,en;q=0.5' 
    	] );
    	$hc->exec ();
    	$sentResponseBody = $hc->getResponseBody ();
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getStdOut () );
    	$hc->setopt ( CURLOPT_HTTPHEADER, [ 
    			'Accept-Language: en-US,en;q=0.5' 
    	] );
    	$hc->exec ( 'https://mail.google.com/mail/logout?hl=en-GB' ); // logout.
    	if (false !== strpos ( preg_replace ( '/\s+/', '', $sentResponseBody ), 'Yourmessagehasbeensent' )) {
    		return true;
    	} else {
    		return false;
    	}
    }
    • and here's an older version, using a slightly different interface:
    function gmail_email(string $username, string $password, string $to, string $subject, string $message, string $from = NULL): bool {
    	if ($from === NULL) {
    		$from = $username;
    	}
    	require_once ('hhb_.inc.php');
    	$hc = new hhb_curl ();
    	$hc->_setComfortableOptions ();
    	$hc->setopt_array ( array (
    			CURLOPT_CONNECTTIMEOUT => 10,
    			CURLOPT_TIMEOUT => 20 
    	) );
    	$hc->exec ( 'https://gmail.com/' );
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	$url = $domd->getElementById ( "gaia_loginform" )->getAttribute ( "action" );
    	$inputs_raw = getDOMDocumentFormInputs ( $domd, true ) ['gaia_loginform'];
    	$inputs = [ ];
    	foreach ( $inputs_raw as $name => $ele ) {
    		$inputs [$name] = $ele->getAttribute ( "value" );
    	}
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getResponseBody () );
    	unset ( $name, $ele, $inputs_raw, $domd );
    	$inputs ['Email'] = $username;
    	
    	$hc->setopt_array ( array (
    			CURLOPT_POST => true,
    			CURLOPT_POSTFIELDS => http_build_query ( $inputs ),
    			CURLOPT_URL => $url 
    	) );
    	unset ( $inputs, $url );
    	$hc->exec ();
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	$inputs_raw = getDOMDocumentFormInputs ( $domd, true ) ['gaia_loginform'];
    	$inputs = [ ];
    	$url = $domd->getElementById ( "gaia_loginform" )->getAttribute ( "action" );
    	foreach ( $inputs_raw as $name => $ele ) {
    		$inputs [$name] = $ele->getAttribute ( "value" );
    	}
    	unset ( $name, $ele, $inputs_raw, $domd );
    	$inputs ['Passwd'] = $password;
    	$hc->setopt_array ( array (
    			CURLOPT_POST => true,
    			CURLOPT_POSTFIELDS => http_build_query ( $inputs ),
    			CURLOPT_URL => $url 
    	) );
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getResponseBody () );
    	$hc->exec ();
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	foreach ( $domd->getElementsByTagName ( "form" ) as $form ) {
    		// MAINTENANCE WARNING: ?ui=html&zy=c
    		// https://mail.google.com/mail/u/0/
    		if ($form->getAttribute ( "action" ) !== '?ui=html&zy=c') {
    			$form->parentNode->removeChild ( $form );
    		}
    	}
    	$inputs_raw = getDOMDocumentFormInputs ( $domd, true ) [0];
    	$inputs = [ ];
    	foreach ( $inputs_raw as $name => $ele ) {
    		$inputs [$name] = $ele->getAttribute ( "value" );
    	}
    	$url = $domd->getElementsByTagName ( "form" )->item ( 0 )->getAttribute ( "action" );
    	if (null === parse_url ( $url, PHP_URL_HOST )) {
    		$url = $hc->getinfo ( CURLINFO_EFFECTIVE_URL ) . $url;
    	}
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getResponseBody () );
    	$hc->setopt_array ( array (
    			CURLOPT_POST => true,
    			CURLOPT_POSTFIELDS => http_build_query ( $inputs ),
    			CURLOPT_URL => $url 
    	) );
    	$hc->exec ();
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	// hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getResponseBody () );
    	$url = $hc->getinfo ( CURLINFO_EFFECTIVE_URL );
    	$urlinfo = parse_url ( $url );
    	// we actually just want to remove $urlinfo['query']...
    	$url = $urlinfo ['scheme'] . '://' . $urlinfo ['host'] . $urlinfo ['path'];
    	foreach ( $domd->getElementsByTagName ( "a" ) as $a ) {
    		// INVESTIGATE ME: evil utf8 'Compose Mail' string? its not just the nbsp..
    		if (bin2hex ( $a->textContent ) === '436f6d706f7365c2a04d61696c') {
    			$url .= $a->getAttribute ( "href" );
    			break;
    		}
    	}
    	$hc->exec ( $url );
    	$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
    	$inputs_raw = getDOMDocumentFormInputs ( $domd, true );
    	unset ( $inputs_raw ['sbf'] );
    	$inputs_raw = $inputs_raw ['f'];
    	$inputs = [ ];
    	foreach ( $inputs_raw as $name => $ele ) {
    		$inputs [$name] = $ele->getAttribute ( "value" );
    	}
    	$url = NULL;
    	foreach ( $domd->getElementsByTagName ( "form" ) as $form ) {
    		if ($form->getAttribute ( "name" ) === 'f') {
    			$url = $form->getAttribute ( "action" );
    			break;
    		}
    	}
    	if ($url === NULL) {
    		throw new \RuntimeException ( 'failed to extract url!' );
    	}
    	if (null === parse_url ( $url, PHP_URL_HOST )) {
    		$url = $hc->getinfo ( CURLINFO_EFFECTIVE_URL ) . $url;
    	}
    	// not sure how gmail does it, but gmail manages to drop a lot of input fields.. without javascript,
    	// whilst still keeping them in the HTML source (as far as DOMDocument is concerned...)
    	$toKeep = array (
    			'redir',
    			'at',
    			'to',
    			'cc',
    			'bcc',
    			'file0',
    			'body',
    			'nvp_bu_send' 
    	);
    	foreach ( $inputs as $key => $unused ) {
    		if (! in_array ( $key, $toKeep, true )) {
    			unset ( $inputs [$key] );
    		}
    	}
    	$inputs ['to'] = $to;
    	$inputs ['body'] = $message;
    	$inputs ['subject'] = $subject;
    	$input ['from'] = $from;
    	$hc->setopt_array ( array (
    			CURLOPT_POST => true,
    			CURLOPT_POSTFIELDS => $inputs  // Note! use multipart/form-data here, gmail explicitly uses it in the html code, instead of the normal application/x-www-form-urlencoded
    	) );
    	$hc->exec ( $url );
    	$sentResponseBody = $hc->getResponseBody ();
    	//hhb_var_dump ( $url, $inputs, $hc->getStdErr (), $hc->getStdOut () );
    	$hc->setopt ( CURLOPT_HTTPGET, true );
    	$hc->exec ( 'https://mail.google.com/mail/logout?hl=en-GB' ); // logout.
    	if (false !== strpos ( preg_replace ( '/\s+/', '', $sentResponseBody ), 'Yourmessagehasbeensent' )) {
    		return true;
    	} else {
    		return false;
    	}
    
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions