LargeTuna
LargeTuna

Reputation: 2824

Gmail API PHP - Request Entity Too Large Error 413

I need help understanding Gmails API and how I can fix my script below. I have gone through every post on Stack and all the documentation on Gmail to try and figure out how to send an email using the api with attachments over 5 Mb.

Here is my script. This works fine if the attachments are less than 5Mb. The instant it goes over, I get the 413 error.

Request Entity Too Large Error 413

    # set up the google client...
    $client = new Google_Client();
    $client->setApplicationName("My App");
    $client->setAuthConfig($array['credentials']);
    
    # create new gmail service...
    $gmail = new \Google_Service_Gmail($client);
    
    # set the content...
    $strRawMessage = "";
    $boundary = uniqid(rand(), true);
    $subjectCharset = $charset = 'utf-8';
    $strMailContent = 'Test Message Body...';
    $strMailContent = quoted_printable_encode( $strMailContent );
    $strSubject = 'Test Message Subject...';
    
    # set up who the message is being sent to...
    $to[] = $this->encodeRecipients('You' . " <[email protected]>");
    $strRawMessage .= "To: " . implode(", ", $to) . "\r\n";
    
    # set the subject...
    $strRawMessage .= 'Subject: =?' . $subjectCharset . '?B?' . base64_encode($strSubject) . "?=\r\n";
    $strRawMessage .= 'MIME-Version: 1.0' . "\r\n";
    $strRawMessage .= 'Content-type: Multipart/Mixed; boundary="' . $boundary . '"' . "\r\n";
    
    # set the body...
    $strRawMessage .= "\r\n--{$boundary}\r\n";
    $strRawMessage .= 'Content-Type: text/html; charset=' . $charset . "\r\n";
    $strRawMessage .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n\r\n";
    $strRawMessage .= $strMailContent . "\r\n";
    
    # loop over the attachments...
    $attachments[] = [
        'url'=>'https://s3-us-west-2.amazonaws.com/xyz/bugfiles/Pizigani_1367_Chart_10MB.jpg',
        'name'=>'Pizigani_1367_Chart_10MB.jpg',
        'size'=>'10Mb'
    ];
    foreach($attachments as $attachment){
    
        # get the file info...
        $url = $attachment['url'];
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_exec($ch);
        $mimeType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
        $fileSize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
        $path = parse_url($url, PHP_URL_PATH);
        $filename = substr($path, strrpos($path, '/') + 1); # $attachment['name'];
    
        # add it as an attachment to the email...
        $strRawMessage .= "\r\n--{$boundary}\r\n";
        $strRawMessage .= 'Content-Type: '. $mimeType .'; name="'. $filename .'";' . "\r\n";
        $strRawMessage .= 'Content-Description: ' . $filename . ';' . "\r\n";
        $strRawMessage .= 'Content-Disposition: attachment; filename="' . $attachment['name'] . '-' . $filename . '"; size=' . $fileSize. ';' . "\r\n";
        $strRawMessage .= 'Content-Transfer-Encoding: base64' . "\r\n\r\n";
        $strRawMessage .= chunk_split(base64_encode(file_get_contents($url)), 76, "\n") . "\r\n";
        $strRawMessage .= '--' . $boundary . "\r\n";
    }
    
    try {
    
        # Prepare the message in message/rfc822
        $mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');
        $msg = new \Google_Service_Gmail_Message();
        $msg->setRaw($mime);
    
        # send the message...
        $message = $gmail->users_messages->send("me", $msg);
    
        echo '<pre>';
        print_r($message);
        echo '</pre>';
        die;
    
    } catch (\Exception $e) {
        echo '<pre>';
        print_r($e->getMessage());
        echo '</pre>';
        die;
    }

What I do not understand is that in Gmails docs it says to use this url when uploading attachments.

 POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=multipart

Or it says to use this URL to be more reliable...

 POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=resumable

What I dont see is where I would even use that URL at all. No where in the classes (Google_Client, Google_Service_Gmail, Google_Service_Gmail_Message) is that option even available to use.

Upvotes: 3

Views: 3180

Answers (2)

Shaggyrd
Shaggyrd

Reputation: 29

You have a similar error as found here in the google documentations Try using: Multipart upload: uploadType=multipart or Resumable upload: uploadType=resumable

and supposedly this is how should work

# send the message...
$message = $gmail->users_messages->send("me", $msg, ['uploadType' => 'multipart']);

if needed here the api reference link

Upvotes: 1

Optiroot
Optiroot

Reputation: 164

Google API is strict for some things. The limit for the method you're using (users/SendMessage) which is the right one, is limited to 35MB as per documentation. Actually posting with MIME TYPE multipart, in certain cases (almost all) extends the file size to the double. For example, if you upload a file of 20MB, it can end up to be almost 40MB so Google returns that error because in the end they're getting a file bigger than the file size limit.

Upvotes: 0

Related Questions