Directory:
0.0--Overview of the Chrome extension development (Gmail Accessory Management Assistant) series
1.One of the chrome extensions development--chrome Extended file Structure
2.Chrome Extensions development of the--chrome extension script in the operation mechanism and communication methods
3.data Local storage and download in the three--chrome extensions developed by Chrome
4.Chrome Extension Development Four--the core function realization idea
If you're interested in gmailassist, you can search for "Gmail assistant" in the Chrome store, or click here direct access to the store to install the trial;
If you are interested in the source code of Gmailassist, you can View its source code on my GitHub.
The original plan specifically used a blog post to briefly introduce the Gmail API, but think about the official documents have been very clear, there is no good understanding of the place, I will no longer write a special article to say it. Introducing the Gmailassist feature implementation process, I will add if there is a need to explain the Gmail API.
first, authorization and interface display
After the user clicks on the Address bar icon, call the previous one mentioned in the library for the Chrome extension for OAUTH2 authorization function authorize to complete the authorization (details can see its source code, very intuitive). and sends a message to the content script of the current page to display the Gmailassist UI by modifying the DOM element of the page.
You need to listen for the click Icon event in the background script, so the code is as follows:
Chrome.pageAction.onClicked.addListener (function () {google.authorize (function () {chrome.tabs.query ({active: True, Currentwindow: True}, function (tabs) {chrome.tabs.sendMessage (tabs[0].id, {Token:google.getAccessToken ()}, function (response) { // can write points to handle response logic. In addition, the above Google.getaccesstoken () is a function in the library.
}); }); });})
Ii. Get the list of attachments
This is a very good word.
Let's look at some of the relevant Gmail APIs:
First, almost all of the methods in the Gmail API need to provide authorization information, which is the token obtained through OAuth2. Almost all methods also require a parameter to specify the mailbox (USERID) to be manipulated, and this parameter can be assigned a value of "me" to indicate that the current user is completing the authorized mailbox. The call to the Gmail API can be done via HTTP requests.
1.Users.messages:list
The user clicks the "Get Attachment List" button and invokes the Users.messages:list method in the Gmail API to get all the messages that meet the criteria (the method can take parameters to get a specific collection of messages). But each message in the result returned by the method defaults to only MessageId and threadId two fields (later learned that it should be possible to return more fields by specifying parameters), such as:
{ "messages" : [{ "id": "152a445862514939" , "threadId": "152a445862514939 "
}, {
"id": "152a348995acc143" , "threadId": "152a348995acc143 "
}, ... {
"id": "14956AB84ABC30C8" , "threadId": "14956ab84abc30c8 "
" Nextpagetoken": "16041633375627414246 " , "Resultsizeestimate": 103
}
In Gmailassist, all we want is a message with an attachment, so you can specify q=has:attachment in the parameters of the list method to get all the message information that contains the attachment.
What is this argument about? You can specify the Q field in the URL of the request. For example:
GET https://www.googleapis.com/gmail/v1/users/me/messages?q=has:attachment
can I specify a different search criteria? Make q equal to other content? OK. The value of this parameter is supported by Gmail's built-in search filter syntax, details can be found here .
It is not difficult to see from the above example of the HTTP request results that there is a field in the return message: Nextpagetoken. As the name implies, this is the token that gets the next page of the list result. The results returned by the list method are paginated for a long while, with a default limit of 100 mail messages per page, so you need to return a page and use this token to take a page. The last page does not have this field, so you can
if (list.nextpagetoken) { fetchnextlist (list.nextpagetoken);}
To get the complete mailing list recursively.
2.Users.messages:get
Through the list method to get the ID of all messages with attachments, and then in order to get the inside of the attachment, you have to use Get method, get a specific message, and extract the information from the attachment. Get the details of the method, you can look at Google's documents, no more mention.
among them, the download of attachments, there is no direct API available, nor need. According to their own many times manually in the mailbox operation of the experiment, found the rules of the attachment, in the program to spell out, in the user to download the corresponding attachment, the content script from the background can be sent. If you are interested in what you look like, you can see the source code .
3.Users.drafts:list,Users.drafts:get,Users.drafts:update
(add: If you're familiar with Gmail, or have already played with those APIs, it's easy to see that Gmail's letters are all message types except drafts, and the draft is the draft type that wraps a message.) )
To finish inserting the selected attachment into the latest draft , there is no direct API available, it can only make the program a little more troublesome. I now use the following ideas:
First get the latest draft, that is, call drafts first. The list method returns the draft listing, because the result is in chronological order, so we'll get the first draft ID to call the Get method and get the full text of the draft.
Take the full text of the message that contains the attachment that you want to insert in the Messages.get, capture the selected attachment, insert these (if there are multiple) attachments into a queue, and then go out of the team to the end of the original draft that you previously received. (This requires a bit of action, primarily to ensure that the format is correct.) Details can refer to the RFC822 protocol, or you get a few RAW format of the message, in the Base64urlsafe format to transcode to see the format is clear)
After the good, with the Drafts.update method directly to the whole new draft of the BASE64URLSAFE format transcoding results, as raw field back to the server to complete the draft update, that is, the completion of the attachment insert.
The three methods are similar to the above Messages.list and Messages.get. It is important to note that, based on the above idea, when getting drafts through get, it is necessary to specify in the parameters the draft content that returns the RAW type. The raw field obtained is Base64 encoded, the local operation needs to be decoded first, the operation is finished before encoding, and then sent back to the server. This codec can be used with the JS function Atob (), Btoa ():
decodedmsg = Atob (Raw.replace (/-/g, ' + '). Replace (/_/g, '/'))); //Raw refers to the full text of the message returned by the server in RAW format (is a string)
// the above sentence is the first to complete the '-' and ' _ ' replaced with ' + ' and '/' (that is, the Base64urlsafe into Base64), and then base64 decoding //
The reason for this substitution is that ' + ' and '/' appear in the URI meaning
= Btoa (newdraft). Replace (/\//g, ' _ '). Replace (/\+/g, '-')); // Newdraft is a string, that is, what you want to encode
// The above sentence is similar to the first sentence, Base64 code First, then complete the replacement, and become Base64urlsafe
Of course, although this idea can achieve the desired function, but not good. I think there can be an optimization on the basis of this idea:
When you get an attachment, instead of getting the full message through the Messages.get method, you get the Attachmentid field for each attachment, with the corresponding fields combined with messageId, to get the contents of the attachment through the Messages.attachments.get method. This gets the MIME some comments and the Base64 encoded attachment content.
Further consideration can be given to the local cache wave, which is to store the used attachment content (including the corresponding MIME field) with the Chrome.storage interface. It is important to note that if this is the case, you need to declare a unlimited storage permission in manifest, otherwise you will be constrained by the storage limit of 5MB.
Or another way of thinking, upload attachments directly. But this idea requires the attachment file to download, and then use the Drafts.update method to complete the attachment upload.
In short, several ideas are a core idea: to download the attachment first, and then upload to the draft, but our program is to complete this set of work automatically to liberate the user. Why does it have to be this whole thing? Download again upload, how much trouble ah? Can do Because the format of the message itself is so limited, the attachment is written as MIME part in the message, not as I originally imagined-leaving a URI in the message that points to the attachment, separated by the attachment and the message body.
third, the Gmail APIUsage Restrictions
It's critical!
Click the link to see the official documents, the details are very clear. I'll say a few things here:
1. There are two types of restrictions: total limit and rate limit .
The former is for your entire program , meaning that different Gmail users share the quotas that your program has. Your program to use the Gmail API is required to register with Google (the process is not complicated, according to official documents a little bit), and then your program is equivalent to have a own account, the so-called "total limit" is the "account" of your program. The specific is: free users (you, developers) can send 1 billion units a day request. Note that it is your program that has so many quotas per day. As far as gmailassist is concerned, when different Gmail users use it, they are consuming the total of this 1 billion unit/day quota for my developer account. Your quota will refresh every day. So how do you see your program? How many quotas are consumed this day?
Go to Google Developer Console, select the item you want to view, and click Next. Then you can see the quota on the right, the amount of information.
The latter is for specific Gmail users , and the maximum request rate supported for free projects is limited to 250 units per second/user . But this limit is not absolute, Google allows a short burst, that your program can temporarily break through this limit, but if you continue to break it, you will receive HTTP 429 or 403 or 502 errors, indicating that the server is not enough, you are too fierce. (What happens now?) An exponential backoff algorithm is used to try to re-send requests. Specifically I will say in the next Article blog post. )
2. What are the units that describe the limitations or descriptions of usage?
What I said above is how many units. the so-called quota unit in the official documentation, which is the smallest unit to measure and describe your API usage, each time you invoke the different methods in the API, you will consume a different number of quota units, ranging from 5 to 100, depending on the official documentation.
3. Limitations other than the Gmail API itself
These are the limitations of the Gmail API itself, but users are also subject to the rate limits used by Gmail itself when using your program, but you don't have to think about it in your program development, and you can hardly do anything about that limitation.
4. Batch request is not a trick of breaking limits
The Gmail API encourages developers to use batch request to improve program performance. As the name implies, multiple requests are merged into one request. But in this way, the quota consumed by each individual request in this synthesized request is still calculated separately .
Chrome extension Development Four--the implementation of core functions