Chapter 7: Gmail Libraries

I n the previous chapters, you discovered how Gmail works: how it loads into your browser, and how it handles your mail through a series of JavaScript tricks and the passing of data in the background. You can use this newfound knowledge to take control of the application from within your own programs. To do that, you need to use a library— a piece of code that encapsulates the nitty gritty of the interaction between your program and Gmail itself in such a way that it makes writing that program very easy. Instead of, for example, having to write code that requests the Inbox’s JavaScript array, parses it, finds the message identity, requests the thread, parses that, and finally displays it on the screen, you can simply run the function to download the next unread mail. This approach, of wrapping complex activities up into their own simpler-to-use functions, is one of the bases of software engineering, so it’s not surprising that there are already many such modules for Gm

Chapter 7: Gmail Libraries

PHP — Gmailer

Yin Hung Gan’s Gmailer library is the obvious choice for PHP coders. Gan wrote
it so that he could build a simplified interface for Gmail, and check his mail from
his PDA. It is really two projects: the Gmailer library and Gmail-Lite, which uses
the library to give Gan his simple HTML interface.

Getting and Installing the Library

Gmailer can be downloaded from http://gmail-lite.sourceforge.net/. At
the time of this writing, Gmailer is at version 0.6.9a. The Gmailer homepage
looks like Figure 7-1.
FIGURE 7-1: The Gmailer homepage
Once downloaded, you need only unpack it into the directory your script will run
in. You will also need cURL, from http://curl.haxx.se/, and the OpenSSL
package from www.openssl.org/, but it is very likely that you will already have
those installed as a matter of course. If not, follow the instructions on their websites to download and install them properly. To save time, worry about those only
if any error messages tell you to.

How to Use It

Gmailer provides a series of methods that can be used to log in to Gmail and perform the usual functions. Table 7-1 gives the complete rundown of the methods.
Table 7-1 Gmailer’s Methods
Method Function
void setSessionMethod To set the session handling method before connect. If you want 
(GM_CONSTANT method) PHP to handle it with cookies, set it to GM_USE_PHPSESSION|
[0.6.4] GM_USE_COOKIE; if you want PHP to handle it but without
using cookies, set it to !GM_USE_COOKIE|GM_USE_
PHPSESSION; if you do not want PHP to handle it, set it to
GM_USE_COOKIE|!GM_USE_PHPSESSION. It will set to
GM_USE_PHPSESSION|GM_USE_COOKIE by default.
void setLoginInfo To set the login information before connect.
string name,
string password,
int GMT_timezone)
void setProxy(string To set the proxy information if necessary. If your proxy server
hostname, string does not require login, set both username and password to “”
username, string
password) [0.6.4]
bool connect() To connect to Gmail. It will use header() to set cookies at the
client-side browser. So you shouldn’t output anything before
calling this method, or use connectNoCookie() otherwise. It
returns 1 if it succeeds, 0 otherwise.
bool connectNoCookie() To connect to Gmail without storing any cookies at the client-side
browser. It returns 1 if it succeeds, 0 otherwise.
bool isConnected() To check if connected.
bool fetch(string query) To fetch the URL query result from Gmail. It is intended to be
used internally (private method). Use fetchBox() instead.
bool fetchBox To fetch a result from Gmail by given:
GM_CONSTANT type, type: Gmailer constant, such as GM_LABEL.
string box, int position) box: name of box (such as Inbox, your_label)
position: cursor for paged result.
bool fetchContact() To fetch the contact list.
Continued
12_59611x ch07.qxp 11/28/05 11:01 PM Page 119
120 Part II — Getting Inside Gmail
Table 7-1 (continued)
Method Function
GMailSnapshot get To get a snapshot, an object (see GMailSnapshot below) for you
Snapshot(GM_CONSTANT to access the query result at ease.
type)
bool getAttachment To download an attachment of a message.
(string attachment_id,
string message_id,
string filename)
array getAttachmentsOf To download all files attached to a conversation. The full path of
(array GMailSnapshot-> downloaded files will be returned (as array).
conv, string path_to_
store_files)
bool send(string to, To send Gmail. to, cc, and bcc are comma-separated addresses.
string subject, attachments is an array of names of files to be attached.
string body, string cc,
string bcc,
string message_replying,
string thread_replying,
array attachments)
bool performAction To perform an action on a message. message_id can be a string 
(GM_CONSTANT action_ if only one message is to be acted.
type, array message_id,
string label)
void disconnect() To disconnect from Gmail. Any cookies set at the client-side
browser by libgmailer will be removed.
string dump(string query) To dump all it gets from the URL query string, including headers.
array getStandardBox() To get an array of names of the standard box (Inbox, Starred, and
so on).

Logging in with Gmailer

Logging into Gmail with the Gmailer library is very simple. First you point your
script to the library itself:
require(“libgmailer.php”);
Then you invoke the new Gmailer object:
$gm = new GMailer();
12_59611x ch07.qxp 11/28/05 11:02 PM Page 120
Chapter 7 — Gmail Libraries 121
Then you set the setLoginInfo method, giving the username, password, and
time zone from GMT:
$gm->setLoginInfo($name, $pwd, $tz);
Finally, you tell Gmailer to connect:
$gm->connect();
You need to use setLoginInfo only once — Gmailer saves your Gmail cookies,
so once you’ve logged in, you only need to use the connect() method to pass
more commands.
Putting that all together, then, you arrive at Listing 7-1, which gets you logged in
to Gmail, ready for some more code.
Listing 7-1: Logging in to Gmail with PHP
<?php 
require(“libgmailer.php”);
$gm = new GMailer();
$name = “username”;
$pwd = “password”;
$tz = “0”;
$gm->setLoginInfo($name, $pwd, $tz);
if ($gm->connect()) {
/** THE REST OF YOUR CODE GOES IN HERE **/
}
$gm->disconnect();
?>
The disconnect() method logs you out again.

Retrieving the Inbox

Once you are logged in, retrieving a thread is simple and is a good example to
show the deeper functions available from the Gmailer library.
12_59611x ch07.qxp 11/28/05 11:02 PM Page 121
122 Part II — Getting Inside Gmail
Assuming you’re logged in, request the Inbox like so:
$gm->fetchBox(GM_STANDARD, Inbox, 0);
Then parse it into an object called a Snapshot, like so:
$snapshot = $gm->getSnapshot(GM_STANDARD);
Once you have the Inbox loaded into a Snapshot, you can query that Snapshot
and get all of the information out of it. You’ll have noticed, however, two things
not yet covered: the phrase GM_STANDARD and the properties that Snapshots
themselves have.

The Constants

GM_STANDARD is a constant. Gmailer has 20 constants available, each representing
a different feature of the Gmail system: the Inbox, the Labels, the Contacts, and
so on. To work with Gmail, you need to use a method to retrieve one of the constants, and then you create a Snapshot of it, and finally query that Snapshot.
This two-stage process is really all there is to the Gmailer library, so once you
understand it, you are good to go.
Table 7-2 gives the constants available to the programmer.
Table 7-2 Gmailer’s Constants
Constant Description
GM_STANDARD All the information about a standard box (Inbox, Sent, All,
Starred, Spam, Trash).
GM_LABEL All the information about the labels.
GM_CONVERSATION All the information about a particular conversation.
GM_QUERY All about a search query.
GM_CONTACT All about the contact list.
GM_ACT_APPLYLABEL Apply or remove label from message.
GM_ACT_REMOVELABEL
GM_ACT_STAR Star or unstar a message.
GM_ACT_UNSTAR
GM_ACT_SPAM Mark or unmark a message as spam.
GM_ACT_UNSPAM
GM_ACT_READ Mark a message as read or unread.
GM_ACT_UNREAD
GM_ACT_ARCHIVE Move a message away from or to the Inbox.
GM_ACT_INBOX
12_59611x ch07.qxp 11/28/05 11:02 PM Page 122
Chapter 7 — Gmail Libraries 123
Constant Description
GM_ACT_TRASH Move message to or away from the Trash.
GM_ACT_UNTRASH
GM_ACT_DELFOREVER Delete message forever.
GM_USE_PHPSESSION Use PHP session to handle Gmail-lite session.
[0.6.4]
GM_USE_COOKIE [0.6.4] Use cookie to handle Gmail-lite session.
Table 7-3 gives special properties available for each constant’s Snapshot.
Table 7-3 The Data Available via a Snapshot
Properties available to all Snapshot types except GM_CONTACT
Property Description
gmail_ver Version of Gmail JavaScript core program.
quota_mb Mailbox quota in MB.
quota_per Mailbox quota in percentage.
std_box_new Number-indexed array. Number of unread mails in each standard box. You
may call GMailer::getStandardBox() to get an array of names of
standard boxes.
have_invit Number of invites you have. 0 = no invitation, and so forth.
label_list Number-indexed array. An array of label names.
label_new Number-indexed array. Number of unread mails in each label. (A 1-to-1
mapping of label_list.)
Properties available to Snapshot types GM_STANDARD, GM_LABEL, and GM_QUERY
Property Description
box_name Name of the standard box or label, or query string currently viewing.
box_total Total number of conversations in current mailbox.
box_pos Current starting position (for paged results).
Number-indexed array. An array of conversations in the current mailbox.
Each conversation is a text-indexed array of the following:
Continued
12_59611x ch07.qxp 11/28/05 11:02 PM Page 123
124 Part II — Getting Inside Gmail
Table 7-3 (continued)
Index Description
Id Conversation ID.
is_read 0 = read; 1 = not read yet.
is_starred 0 = not starred; 1 = starred.
Date Arrival date/time of the most recent message.
sender Senders of message in this conversation.
Flag Flag.
Subj Subject of this conversation.
snippet Snippet, or preview, of this conversation.
Labels Number-indexed array. Name of labels that this
conversation is bearing.
attachment Number-indexed array. Name of all attaching files of
this conversation.
Msgid Message ID of the most recently received message of
this conversation.
For example, in order to get the subject of the sixth conversation of the
current viewing box you write $snapshot->box[5][“subj”].
Properties available to Snapshot type GM_CONVERSATION
Property Description
conv_title Subject (title) of this conversation.
conv_total Total number of messages in this conversation.
conv_id Conversation ID.
conv_labels Number-indexed array. Name of labels that this conversation is bearing.
conv_starred Is the conversation starred? This is true if any of the messages of a
[0.6.4] conversation are starred.
Number-indexed array. An array of messages of the current conversation.
Each message is a text-indexed array of the following:
Index Description
index Index.
id Message ID.
sender Name of sender of this message.
sender_email E-mail address of the sender.
recv Name of receiver of this message.
12_59611x ch07.qxp 11/28/05 11:02 PM Page 124
Chapter 7 — Gmail Libraries 125
Index Description
recv_email E-mail address of the receiver.
reply_email Replying address of this message.
dt_easy Arrival date/time of this message in easy format, such
as 9 Aug (2 days ago).
dt Arrival date/time of this message in long format, such
as Mon, 9 Aug 2004 19:34:03 +0800.
subj Subject of this message.
is_starred Is the message starred?
[0.6.4]
snippet Snippet, or preview, of this message.
body Message body.
attachment Number-indexed array. An array of attachment
information, which is a text-indexed array of the
following:
Index Description
id Attachment ID.
filename Filename of this attaching file.
type File type (such as JPG, GIF, PDF) of
this attaching file.
size Size in bytes of this file.
Example: $snapshot-
>conv[3][“attachment”][1][“size”]
(size of the 2nd attaching file of the 4th
messages of current conversation)
Properties available to Snapshot type GM_CONTACT
Property Description
contacts_all Number-indexed array. Array of entries (see the table that follows) of your
All address book.
contacts_freq Number-indexed array. Array of entries of your frequently mailed address
book:
Index Description.
name Name (nickname).
email E-mail address.
notes Notes.
is_freq 0 = not frequently mailed; 1 = frequently mailed.
12_59611x ch07.qxp 11/28/05 11:02 PM Page 125
126 Part II — Getting Inside Gmail
Once you’ve requested the Inbox and created a Snapshot, you can query that
Snapshot for details. To print out the number of threads within the Inbox, you
can say this:
echo “Threads in the inbox:” . $snapshot->box_total;
In order to get the Thread ID of the first thread in the Inbox, you can do this:
$threaded = $snapshot->box[0][“id”];
As you can see from the code and the preceding tables, it’s really quite a straightforward interface. You’ll be using the interface in later chapters, but to finish,
Listing 7-2 shows PHP code using the Gmailer library to log in and display the
contents of the first message in the first thread in the Inbox.
Listing 7-2: Reading the First Message in the Inbox
<?php
require(“libgmailer.php”);
$gm = new GMailer();
$name = “username”;
$pwd = “password”;
$tz = “0”;
$gm->setLoginInfo($name, $pwd, $tz);
if ($gm->connect()) {
$gm->fetchBox(GM_STANDARD, Inbox, 0);
$snapshot = $gm->getSnapshot(GM_STANDARD);
$threaded = $snapshot->box[0][“id”];
$gm->fetchBox(GM_CONVERSATION, $threaded, 0);
$snapshot = $gm->getSnapshot(GM_CONVERSATION);
echo “The first message reads” . $snapshot-
>conv[0][“body”];
}
$gm->disconnect();
?>
You return to this library in later chapters.

Perl — Mail::Webmail::Gmail

CPAN, the directory of Perl modules, lists quite a few Gmail-related modules,
one of which is shown in Figure 7-2. But at time of this writing, the only one
working is Allen Holman’s Mail::Webmail::Gmail.
FIGURE 7-2: A CPAN search resulting in a Gmail module

Getting and Installing the Library

Mail::Webmail::Gmail is available from CPAN. You can download it directly
from http://search.cpan.org/~mincus/ or use the command line like this:
sudo perl -MCPAN -e ‘install Mail::Webmail::Gmail’
However installed, the module has a few dependencies that you will need to have
installed already:
 LWP::UserAgent
 HTTP::Headers
 HTTP::Cookies
 HTTP::Request::Common
 Crypt::SSLeay
 Exporter

Using the Library

The Mail::Webmail::Gmail module is remarkably simple to use and very thorough. You’ll be using it extensively in the next few chapters, so here we shall just
summarize the options

Logging In

The standard call for logging into Gmail session is:
my $gmail = Mail::Webmail::Gmail->new(username => ‘username’,
password => ‘password’, );
That call can also take some optional arguments. If given the details, you can use a
proxy server, and you can also encrypt the entire session as opposed to just the
login sequence. Call them all like so:
my $gmail = Mail::Webmail::Gmail->new(
username => ‘username’, 
password => ‘password’, 
proxy_username => ‘proxy_username’,
proxy_password => ‘proxy_password’,
proxy_name => ‘proxy_server’,
encrypt_session => 1 
);
Once logged in, you can make requests for data and pass methods on the Gmail
Inbox. There are lots of methods that you can use.

The Other Functions

This chapter provides only a table of the available functions (see Table 7-4). They
are more fully explained as you use them in the rest of the book.
Table 7-4 The Functions Within Mail::Gmail::Webmail
Function What It Does
get_labels() Retrieves an array of the labels in the account.
edit_labels (label=> Creates the label ‘label name’.
’label_name’, action =>
‘create’);
edit_labels( label => Renames the label ‘label_name’ to ‘renamed_label’.
‘label_name’, action =>
‘rename’, new_name =>
‘renamed_label’ );
12_59611x ch07.qxp 11/28/05 11:02 PM Page 128
Chapter 7 — Gmail Libraries 129
Function What It Does
edit_labels( label => Deletes the label ‘label_name’.
‘label_name’, action =>
‘delete’ );
edit_labels( label => Adds a label to a message.
‘label_name’, action =>
‘add’, msgid =>
$message_id );
$gmail->edit_labels Removes a label from a message.
( label => ‘label_name’,
action => ‘remove’,
msgid => $message_id );
update_prefs Sets preferences inside Gmail. The available options are:
( indicators => 0, keyboard_shortcuts = ( 0, 1 )
reply_to => indicators = ( 0, 1 )
[email protected]’ ); snippets = ( 0, 1 )
max_page_size = ( 25, 50, 100 )
display_name = ( ‘’, string value up to 96
characters )
reply_to = ( ‘’, string value up to 320
characters )
signature = ( ‘’, string value up to 1000
characters )
edit_star( action => Stars a message.
‘add’, ‘msgid’ =>
$msgid );
edit_star( action => Unstars the message.
‘remove’, ‘msgid’ =>
$msgid );
edit_archive( action => Archives the message.
‘archive’, ‘msgid’ =>
$msgid );
edit_archive( action => Unarchives the message.
‘unarchive’, ‘msgid’ =>
$msgid );
Continued
12_59611x ch07.qxp 11/28/05 11:02 PM Page 129
130 Part II — Getting Inside Gmail
Table 7-4 (continued)
Function What It Does
$gmail->get_messages Retrieves a reference to an array of hashes for the messages
( label => ‘work’ ); within the stated label. Or you can use the Gmail standard folder
names ‘INBOX’, ‘STARRED’, ‘SPAM’, or ‘TRASH’
get_messages( label => $Mail::Webmail::Gmail::FOLDERS{
‘INBOX’ } );
The array of hashes looks like this:
$indv_email{ ‘id’ }
$indv_email{ ‘new’ }
$indv_email{ ‘starred’ }
$indv_email{ ‘date_received’ }
$indv_email{ ‘sender_email’ }
$indv_email{ ‘subject’ }
$indv_email{ ‘blurb’ }
@{ $indv_email{ ‘labels’ } }
@{ $indv_email{ ‘attachments’ } }
size_usage(); Returns a scalar value with the amount of megabytes remaining
to use.
get_indv_email( id => Retrieves a hash of hashes containing an individual message in 
$msgid) this format:
$indv_email{ ‘id’ }
$indv_email{ ‘sender_email’ }
$indv_email{ ‘sent’ }
$indv_email{ ‘to’ }
$indv_email{ ‘read’ }
$indv_email{ ‘subject’ }
@{ $indv_email{ ‘attachments’ } }
get_mime_email( msg => Retrieves the message as a string, in MIME format.
$msgid )
get_contacts( ); Retrieves an array of hashes containing the Gmail address book.
The array of hashes is in the following format:
$indv_contact{ ‘id’ }
$indv_contact{ ‘name1’ }
$indv_contact{ ‘name2’ }
$indv_contact{ ‘email’ }
$indv_contact{ ‘note’ }
12_59611x ch07.qxp 11/28/05 11:02 PM Page 130
Chapter 7 — Gmail Libraries 131
Function What It Does
send_message( to => Sends a message to a single recipient.
[email protected]’, To send to multiple users, send an arrayref containing all of the 
subject => ‘Test Message’, users:
msgbody => ‘This is
a test.’ );
my $email_addrs = [
[email protected]’,
[email protected]’,
[email protected]’, ];
$gmail->send_message( to => $email_addrs,
subject => ‘Test Message’, msgbody => ‘This is a
test.’ );
send_message( to => Sends a message with an attachment.
[email protected]’,
subject => ‘Test Message’,
msgbody => ‘This is a
test.’, file0 => [“/tmp/
foo”], file1 => [“/tmp/
bar”] );
delete_message Sends a message to the Trash.
( msgid => $msgid, del_
message => 0 );
delete_message( msgid => Permanently deletes the message.
$msgid );
The rest of this module is covered in Chapter 8 onwards.

Python — Libgmail

The trifecta of scripting languages beginning with P ends with ython, and is completed by Libgmail, the Python bindings for Gmail access

Getting and Installing the Library

Libgmail is hosted on Sourceforge at http://Libgmail.sourceforge.net/
and can be downloaded directly from there. The authors of Libgmail advise using
the version from CVS if possible, as it is more likely to work with whatever
changes Google has made to the service lately. Figure 7-3 gives the traditional
screenshot of the project’s homepage.
12_59611x ch07.qxp 11/28/05 11:02 PM Page 131
132 Part II — Getting Inside Gmail
FIGURE 7-3: Python’s Libgmail binding
You should follow the instructions on their website to install the latest version. As
mentioned before, if Libgmail stops working, it may just be a matter of time
before a new version restores functionality

How to Use It

Libgmail comes with some sample code, but no real documentation at the
moment. There are currently 15 methods available, which offer the vast majority
of the functionality that Gmail can give. Start by logging in

login

To log in, import the Libgmail bindings, create a new GmailAccount object, and
use the login method on it, like so:
import Libgmail
ga = Libgmail.GmailAccount(“[email protected]”,
“mymailismypass”)
ga.login()
Now that you’re logged in, you want to retrieve the messages from a folder

getMessagesByFolder

The getMessagesByFolder method takes the name of the folder, and an
optional True/False flag to indicate selecting every page of that folder’s listing.
(Remember that these libraries interact with Gmail by scraping the pages it
returns, effectively, so you still have to consider the information as it is meant for
the real Gmail interface, not just yours).
Leaving the flag off sets it to the default False. To place the details of the Inbox
into an object called folder, you do the following:
folder= ga.getMessagesByFolder(‘inbox’)
This returns a GmailSearchResult instance that you can query

getMessageByLabel

The getMessageByLabel method works in exactly the same way as
getMessagesByFolder but replaces the folder with a label. It returns a
GmailSearchResult instance, which is examined in two paragraphs’ time.

getMessagesByQuery

The getMessagesByQuery method works in exactly the same way as
getMessagesByFolder but does so with a search query instead of the name of
the mailbox. For example:
messages = ga.getMessagesByQuery(‘ransom note’)
This query will also return a GmailSearchResult instance.
All this talk of GmailSearchResult instances begs the question: What exactly is
a GmailSearchResult instance? A GmailSearchResult instance is a thread
object. This contains details of the thread, plus one or more msg objects, corresponding to the messages within. These can be queried like so:
for thread in folder:
print thread.id # the id of the thread
print len(thread) # the number of messages
print thread.subject # the subject of the thread
for msg in thread:
print msg.id # the id of the message
print msg.number # the number within the thread
print msg.subject # the message subject
print msg.source # the raw source of the message

getQuotaInfo

The getQuotaInfo method allows you to retrieve information on how much
storage you are taking up inside Gmail. It returns an array of megabytes used,
total megabytes available, and percentage of storage used

getUnreadMsgCount

When invoked, the getUnreadMsgCount method returns an integer equal to the
number of unread messages within the Inbox:
new_messages = ga.getUnreadMsgCount()

Reading the First Message in the Inbox

Putting together the methods discussed so far, you can display the messages in the
Inbox, and information about the amount of storage you have left, with the code
in Listing 7-3.
Listing 7-3: Using Python to Display the First Message in the Inbox
#!/usr/bin/python2.3
import Libgmail
ga = Libgmail.GmailAccount(“[email protected]”,
“mymailismypass”)
ga.login()
folder = ga.getMessagesByFolder(‘inbox’)
for thread in folder:
print thread.id, len(thread), thread.subject
for msg in thread:
print “Message ID:”, msg.id
print “Message Number:”, msg.number
print “Message Subject:”, msg.subject
print msg.source
Keeping Your Powder Dry
The remaining methods —sendMessage, trashMessage, trashThread, getLabelNames,
createLabel, deleteLabel, renameLabel, and storeFile— are, apart from being selfexplanatorily named, covered in great detail in the remainder of this book.
12_59611x ch07.qxp 11/28/05 11:03 PM Page 134
Chapter 7 — Gmail Libraries 135
quotaInfo = ga.getQuotaInfo()
quotaMbUsed = quotaInfo[QU_SPACEUSED]
quotaMbTotal = quotaInfo[QU_QUOTA]
quotaPercent = quotaInfo[QU_PERCENT]
print “%s of %s used. (%s)\n” % (quotaMbUsed, quotaMbTotal,
quotaPercent

Setting Yourselves Up for the Remaining Chapters

To aid you in your coding over the next few chapters, you shall also need a small Perl module of your own, which tidies up the boring things such as logging in. Listing 7-4 gives the script Utils.pm, which you should place within the directory in which you wish to work. You will need to place your own username and password in the place indicated. Listing 7-4: Utils.pm package Utils; require Mail::Webmail::Gmail; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(login strip_bold); sub login { return Mail::Webmail::Gmail->new( username => “USERNAME”, password => “PASSWORD” ); } # get rid of and in subjects sub strip_bold { my $str = shift; $str =~ s/(.*)<\/b>/$1/; return $str; } 1; 12_59611x ch07.qxp 11/28/05 11:03 PM Page 135 136 Part II — Getting Inside Gmail You will also need the following Perl modules installed:  libwww-perl: http://search.cpan.org/~gaas/libwww-perl-5.803/  MIME-Base64: http://search.cpan.org/~gaas/MIME-Base64-3.05/  MIME-tools: http://search.cpan.org/~dskoll/MIME-tools-5.417/  MailFolder: http://search.cpan.org/~kjohnson/MailFolder-0.07/  MD5: http://search.cpan.org/~gaas/MD5-2.03/

And Now . . .

In this chapter, you worked through a quick overview of the most popular Gmail
libraries available for the most popular scripting languages. As you have seen, the
libraries are at varying stages of completeness and simplicity but are nevertheless
extremely useful.
In the next few chapters, you will use the Perl library to perform the basic Gmail
functions and start to produce Gmail-based applications of your own.

What's Your Reaction?

like

dislike

love

funny

angry

sad

wow