The above answer from @trajchevska is pretty nice and I am glad that I found it (!) - but it will not "reveal the full truth". So I tried to put together my insights to create a snippet that should work as-it-is.
$user = 'me'; // or user@example.com
$emailId = 12301839123180983123;
$from = 'johndoe@foobar.com';
$fromName = 'John Doe';
// this is for first authentification of this app to the Google-universe in general
$client = getClient();
// an this is to actually start working with Gmail
$googleService = new Google_Service_Gmail($client);
try {
// receive the message body and extract it's headers
$message = $googleService->users_messages->get($user, $emailId);
$messageDetails = $message->getPayload();
$messageHeaders = $messageDetails->getHeaders();
// get the subject from the original message header
$subject = 'Re:'.$getMessageHeaderValue($messageHeaders, 'Subject');
// if you use the from header, this may contain the complete email address like John Doe <john.doe@foobar.com> - phpMailer will not accept that, the tricky thing is: you will not notice it, because it will be left blank and the Gmail API will return an "Recipient address required"
preg_match('/.*<(.*@.*)>/', $getMessageHeaderValue($messageHeaders, 'From'),$to);
// now use the PHPMailer to build a valid email-body
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->From = $from;
$mail->FromName = $fromName;
$mail->addAddress($to[1]);
$mail->Subject = $subject;
$mail->Body = $body;
// preSend will build and verify the email
$mail->preSend();
$mime = $mail->getSentMIMEMessage();
// the base64-url-encode is important, otherwise you'll receive an "Invalid value for ByteString" error
$raw = base64url_encode($mime);
// now use the Gmail-Message object to actually
// for me it is not clear, why we cannot use Class Google_Service_Gmail for this
$message = new Google_Service_Gmail_Message();
$message->setRaw($raw);
$message->setThreadId($emailId);
// and finally provide encoded message and user to our global google service object - this will send the email
$response = $googleService->users_messages->send($user, $message);
} catch (Exception $e) {
print($e->getMessage());
}
function getMessageHeaderValue($headers, $headerName) {
foreach ($headers as $header) {
if ($header->name == $headerName) {
return $header->value;
}
}
return NULL;
}
// this function comes from https://developers.google.com/people/quickstart/php
/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function getClient()
{
// first get a credentials.json from here:
// https://console.developers.google.com/apis/
//
// if you change scope or before first use, run the script on CLI
// it will return an URL that you need to call
// which will return an access token that you can use for future use
$client = new Google_Client();
$client->setApplicationName('Gmail API');
// see scopes: https://developers.google.com/gmail/api/auth/scopes
$client->setScopes(array(Google_Service_Gmail::GMAIL_READONLY,Google_Service_GMail::GMAIL_COMPOSE));
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = 'token.json';
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if (!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}
function base64url_encode($mime) {
return rtrim(strtr(base64_encode($mime), '+/', '-_'), '=');
}