Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save iamniels/1cf24540a4d96afac98cfd04ecd0b5ef to your computer and use it in GitHub Desktop.
Save iamniels/1cf24540a4d96afac98cfd04ecd0b5ef to your computer and use it in GitHub Desktop.
Server side printing with Google Cloud Print API from a PHP application

Server side printing with Google Cloud Print API from a PHP application

It took me quite some time to figure out how to print properly from a web application. I will explain here how I did it, so you don't have to spend the same time.

Authorization

Google Cloud Print API uses OAuth 2.0 for authorization.

As explained here on the Google Developer page, the best way to use OAuth with the Google API is with a Google service account. Create a service account as explained on the Google Developer page.

To use OAuth a library is required. Google has published the Google API PHP client library. If you want to use the examples from the Developer pages, you need to use version 1 of the library. In this article I use version 2 of the library.

➡️ Tip
If you need to run Google API PHP client library on PHP 5.4, make sure you use Guzzle Http version 5 instead of version 6, because the latter is not compatible with PHP 5.4. You can configure the right version in the composer.json file of the API Client library.

Make sure the private key of your service account is accessible by your web application and that you include the library. Then you can use the following code to setup a request to the API with authorization.

    $service_account_email = 'SERVICE ACCOUNT EMAIL';
    $key_file_location = 'PRIVATE KEY FILE LOCATION';

    $client = new Google_Client();
    $client->setAuthConfig($key_file_location);
    $client->setApplicationName("APPLICATION NAME");
    $client->setScopes(array('https://www.googleapis.com/auth/cloudprint'));

    $httpClient = $client->authorize();

Making a request

Now we can send a first request to the API. We start with a search request to see which printers are available.

    $params = array();
    /* Use form_params instead of body for version 6 of Guzzle Http */
    $response = $httpClient->post('https://www.google.com/cloudprint/search', array('body'=>$params));
    echo $response->getBody();

The response will be a list with available printers. One printer will be available, the Google Drive printer.

Making printers available to the service account

We need to share the printer with the service account and the printer needs to be accepted by the service account. The Google Cloud Print management interface is not available for the service account, so we need another way to accept the printer.

This Stackoverflow post documents a way to accept printers with the API, but I didn't get this to work.

I managed to share the printer with the following steps:

  1. Make a Google discussion group and add the service account to the group as member
  2. Add a second user to the group as administrator (explicitly select the user, do not use "all users")
  3. Share the printer with the group (by e-mail address)
  4. Now the administrator of the group can accept the printer for all members in the group

You can check with the search request whether the printer is available to the service account. You can find the printer id in the management interface or in the search response.

Printing

Now we have authorized access to a printer, we can print.

$params = array(
    'printerid' => 'PRINTER ID',
    'title' => 'TITLE',
    'ticket' => '{"version":"1.0","print":{}}',
    'content' => 'data:application/pdf;base64,' . base64_encode(file_get_contents('PDF FILE PATH')),
    'contentType' => 'dataUrl'
);

/* Use form_params instead of body for version 6 of Guzzle Http */
$response = $httpClient->post('https://www.google.com/cloudprint/submit', array('body'=>$params));
echo $response->getBody();

The ticket parameter contains printer instructions like media size and number of copies. If you would like to have an example of valid ticket contents, print the document with Chrome to Cloud Print and capture the API request with Fiddler (Windows only).

Document alignment

When I printed PDFs, the documents were not properly aligned on the paper. When I printed the same document with Chrome and Cloud Print, the document was properly aligned. Chrome modifies the PDF with PDFium before sending it to Cloud Print.

I still have to figure out the exact issues with the PDF files which cause this issue, but pre-processing the PDFs with the following GhostScript command solves at least the alignment issue for now.

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dBATCH  -dQUIET -sOutputFile=OUTPUT.pdf INPUT.pdf

Thank you for reading this tutorial. I hope it is helpful to you, if it was, please leave behind a comment. If you have any tips, questions or remarks, you are also welcome to comment.

@cbfx
Copy link

cbfx commented Feb 20, 2018

thanks for the example of the b64 dataUrl. i’ve been attempting to use an application/pdf mime type.

@jabbon
Copy link

jabbon commented Nov 5, 2018

For sharing the printer for the service account in the dashboard

  1. Share
  2. Copy de Service account ID (internal email) and Share

In PHP create a page with the following after auth

`$params = array(
'printerid' => 'ID_PRINTER',
'accept' => 'true',
);
$response = $httpClient->post('https://www.google.com/cloudprint/processinvite', array('body' => $params));

echo $response->getBody();`

@Enigmatec
Copy link

Enigmatec commented Sep 3, 2019

Really appreciate it.. Am a beginner, But i want to develop a website that will allow user to register there printer on my website. The user can choose to share add printer to my website for their personal use while another users might choose to share his printer in which anybody can print job to.. Can i achieve the task using google cloud print,if yes how..

@mantico91
Copy link

You're a master.. Thanks!

@jomofcw
Copy link

jomofcw commented Nov 5, 2019

THANKS !

EDIT : well it is a bite more complicated... I can print test from "https://www.google.com/cloudprint/simulate.html" with the user so share process is OK. But when I try the code above I get a false return with erro code 8 "unauthorized user"... dunno what's wrong... any help, please ?

@JeffersonDavidFerreiradaSilva

Any video tutorials? I'm not getting.

@iamniels
Copy link
Author

Google cloud printing is being abandoned by Google. GCP will be shut down by the end of 2020.

@Enigmatec
Copy link

Enigmatec commented Dec 10, 2019 via email

@hansallis
Copy link

Any suggestion as to alternatives? MS just announced Universal Print which seems to at least allow server side printing.

@iamniels
Copy link
Author

@hansallis PrintNode

@hansallis
Copy link

@iamniels thanks, I found them earlier today. If you're looking to silently print from the browser, qz.io also seems like a nice solution. It also allows access to local filesystem, usb and serial devices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment