1

I want to write a script that uses the Gmail API to download all attachments from all emails with labelID Label_41.

I completed the instruction at https://developers.google.com/gmail/api/quickstart/php

Using the API I expected listUsersMessages(...)->getMessages() to return all emails with label Label_41.

$client = getClient();
$service = new Google_Service_Gmail($client);

$user = 'me';
$labels = array('labelIds' => array('Label_41'));
$messagesResponse = $service->users_messages->listUsersMessages($user, $labels);
$messages = $messagesResponse->getMessages();

foreach ($messages as $message) {
    echo 'Message with ID: ' . $message->getId();

    echo $message->getLabelIds();

    if($message->getLabelIds() == null) echo " (NO LABEL) ";

    echo  "\n";
}

However, all the emails that I got here have no label assigned to them, as my terminal output shows. What have I done wrong here?

enter image description here

Adam
  • 25,960
  • 22
  • 158
  • 247
  • Try it with a string parameter, instead of array `$labels = array('labelIds' => 'Label_41');` Also the parameter should be Id, not a text, except some standard ones, like 'INBOX'. Check this example https://stackoverflow.com/a/41273594/4621324 – Axalix Aug 07 '17 at 18:38
  • @Axalix thx for the link. With the help of your referecned code-snipped I manged to get it working. The Google-API for PHP really needs some improvement lol. – Adam Aug 07 '17 at 22:19
  • 1
    Google API documentation is known as "garbage"... – Axalix Aug 07 '17 at 22:22

2 Answers2

1

The problem is that the $message object in the foreach loop almost contains no data. One needs to initiate the message object with a full parameter. This is the final code that downloaded all the attachments of the mails with label Label_41

client = getClient();
$service = new Google_Service_Gmail($client);

$user = 'me';
$optParams = [];
$optParams['labelIds'] = 'Label_41';

$messagesResponse = $service->users_messages->listUsersMessages($user, $optParams);
$messages = $messagesResponse->getMessages();

foreach ($messages as $message) {
    echo 'Message with ID: ' . $message->getId();

    $messageId = $message->getId();

    $optParamsGet = [];
    $optParamsGet['format'] = 'full'; // Display message in payload
    $message = $service->users_messages->get($user,$messageId,$optParamsGet);

    $messagePayload = $message->getPayload();
    $headers = $message->getPayload()->getHeaders();
    $parts = $message->getPayload()->getParts();

    $timestamp = ($message->internalDate) / 1000;

    $date = date('Y-m-d H-i-s', $timestamp);

    foreach ($parts as $part) {
      if($part->mimeType == 'application/pdf'){
          $attachmentId = $part['body']['attachmentId'];
      }
    }

    $data = $service->users_messages_attachments->get($user, $messageId, $attachmentId);
    $data = $data->data;
    $data = strtr($data, array('-' => '+', '_' => '/'));

    $filename = "Car2Go " . $date . ".pdf";

    if(!file_exists($filename)){
      $fh = fopen($filename, "w+");
      fwrite($fh, base64_decode($data));
      fclose($fh);
    }
    else{
      'File ' . $filename . 'already exists!';
    }

    echo  "\n";
}
Adam
  • 25,960
  • 22
  • 158
  • 247
1

maybe someone else will be searching for the simple solution. Please see below script code that can be used as Google Script (Java Script, see start tutorial here: https://script.google.com/home/start ):

// GLOBALS
//Array of file extension which you would like to extract to Drive
var fileTypesToExtract = ['sql','gz'];
//Name of the folder in google drive i which files will be put
var folderName = 'BACKUPS';
//Name of the label which will be applied after processing the mail message
var labelName = 'SavedToGDrive';



function GmailToDrive(){
  //build query to search emails
  var query = '';
  
  //uncomment to search by filetypes
  //filename:jpg OR filename:tif OR filename:gif OR fileName:png OR filename:bmp OR filename:svg'; //'after:'+formattedDate+
  //for(var i in fileTypesToExtract){
  // query += (query === '' ?('filename:'+fileTypesToExtract[i]) : (' OR filename:'+fileTypesToExtract[i]));
  //}
  //query = 'in:inbox has:nouserlabels ' + query;
  
  //search by label
  query = 'label:backups-real-estate-backup';
  //exclude already downloaded mails, so you can repeat running this script 
  if timeout happened
  query = query + ' AND NOT label:savedtogdrive';
  
  var threads = GmailApp.search(query);
  var label = getGmailLabel_(labelName);
  var parentFolder;
  if(threads.length > 0){
    parentFolder = getFolder_(folderName);
  }
  var root = DriveApp.getRootFolder();
  for(var i in threads){
    var mesgs = threads[i].getMessages();
 for(var j in mesgs){
      //get attachments
      var attachments = mesgs[j].getAttachments();
      for(var k in attachments){
        var attachment = attachments[k];
        var isDefinedType = checkIfDefinedType_(attachment);
     if(!isDefinedType) continue;
     var attachmentBlob = attachment.copyBlob();
        var file = DriveApp.createFile(attachmentBlob);
        parentFolder.addFile(file);
        root.removeFile(file);
      }
 }
 threads[i].addLabel(label);
  }
}

//This function will get the parent folder in Google drive
function getFolder_(folderName){
  var folder;
  var fi = DriveApp.getFoldersByName(folderName);
  if(fi.hasNext()){
    folder = fi.next();
  }
  else{
    folder = DriveApp.createFolder(folderName);
  }
  return folder;
}

//getDate n days back
// n must be integer
function getDateNDaysBack_(n){
  n = parseInt(n);
  var date = new Date();
  date.setDate(date.getDate() - n);
  return Utilities.formatDate(date, Session.getScriptTimeZone(), 'yyyy/MM/dd');
}

function getGmailLabel_(name){
  var label = GmailApp.getUserLabelByName(name);
  if(!label){
 label = GmailApp.createLabel(name);
  }
  return label;
}

//this function will check for filextension type.
// and return boolean
function checkIfDefinedType_(attachment){
  var fileName = attachment.getName();
  var temp = fileName.split('.');
  var fileExtension = temp[temp.length-1].toLowerCase();
  if(fileTypesToExtract.indexOf(fileExtension) !== -1) return true;
  else return false;
}

Thanks.

AndrewK
  • 345
  • 3
  • 9