After authenticating with Google using GoogleSignIn, one of the next steps I wanted to tackle in my app was retrieving a list of messages. Here is the reference on this part of the API. What we see is that it requires a userId (which is your email address… or alternatively just the value “me”).
It has some optional query parameters such as indicating if you want to also include trash and spam folders, as well as filtering on labels. You can also pass in a query string in exactly the same format as you would the Google Search Box on email. Such as “from:[email protected]”, or just by keyword or phrase, etc…
On the right of the page there is also a way to test this out. In userId put in your email address and in labelIds, put in the word INBOX in CAPS.
If you hit the Execute button at the bottom of the right sidebar, a window will pop open asking you to authenticate. Enter your credentials if needed, and when done, you should get a response showing message id’s and thread id’s of all messages in your inbox. An example JSON response is found below. We won’t actually be using the JSON response in our app, but it does help when trying to troubleshoot why you can’t access particular information, such as when something you expect to be there is not.
{
"messages": [
{
"id": "168a916e41b77b38",
"threadId": "168a916e41b77b38"
},
{
"id": "168a091bda5b39da",
"threadId": "168a091bda5b39da"
}
],
"resultSizeEstimate": 2
}
Integrating the Gmail SDK in to the Test App
We will start off by using the test app from the previous tutorial. You can download it here.
If you haven’t been through that tutorial yet I recommend you do so. Although the starter project you just downloaded is complete, you’ll need to get a key from Google and put it in the credentials .plist file as well as in the URL Types, as well as update the clientID in the app delegate. Unfortunately I can’t share my IDs with you.
Getting the First MessageID
Rather than walk you through creating a whole UI to display all of the individual message IDs, instead, we’ll just check to see if there is at least 1 message, and if so, we’ll print that message Id to the console.
Step 1
In the ViewController.swift class, add the following IBAction:
@IBAction func fetchLatestMessageID(_ sender: Any) {
}
Connect it up to a UIButton on the Storyboard.
When the user is signed in, we can tap this button to get the latest message ID. We will implement that now.
func listInboxMessages() {
}
Create a method, and then call that from the IBAction for the Fetch Latest Message ID button, as follows:
@IBAction func fetchLatestMessageID(_ sender: Any) {
listInboxMessages()
}
Step 2
Ensure that the following imports are found up top:
import UIKit
import GoogleAPIClientForREST
import GoogleSignIn
import GTMSessionFetcher
You will see an error for the GoogleAPIClientForREST import. To fix that, we need to edit our podfile. You can open that up from the Pods section of the project navigator. Add a new line just below the GoogleSignIn pod as follows:
pod 'GoogleSignIn'
pod 'GoogleAPIClientForREST/Gmail'
Open up the Terminal and navigate to the project folder and run “pod install”. When this command completes, the error should be gone.
Step 3
To use the list command, add the following to “listInboxMessages()”:
func listInboxMessages() {
let gmailService = GTLRGmailService.init()
let listQuery = GTLRGmailQuery_UsersMessagesList.query(withUserId: "me")
listQuery.labelIds = ["INBOX"]
let authorizer = GIDSignIn.sharedInstance()?.currentUser?.authentication?.fetcherAuthorizer()
gmailService.authorizer = authorizer
gmailService.executeQuery(listQuery) { (ticket, response, error) in
if response != nil {
print("Response: ")
print(response)
} else {
print("Error: ")
print(error)
}
}
}
On line 2 we create the GmailService.
Line 4 is where we create a query. The GTLRGmailQuery_UsersMessagesList class has just one query type that requires a user ID. In this field you can simply specify the String “me”. Alternatively, you can specify your email address fetched from the GIDSignIn as seen in the inWillDispach method further down the class.
Line 5 we are specifying the optional labelIds we are interested in querying. In this example, we put one string in the Array of “INBOX”.
Lines 7 and 8 are where we get the authoriser. Because we used GoogleSignIn, we need to fetch the authoriser from there and let the gmailService know that we have a valid authoriser. These two lines are where this happens.
On line 10 we execute the query. We pass in the listQuery we created, and also use the completion handler which provides a ticket, a response, and an error.
Lines 11 to 17 we are simply checking if there’s an error or not. If not, we print the response which logs this to the console:
GTLRGmail_ListMessagesResponse 0x282ebf570: {messages:[3] resultSizeEstimate:3}
If there is an error, it will inform you what that error is so that you can act accordingly. One example of an error is when you forget to copy the authoriser over. It simply tells you that you need to login.
Step 4
With a valid response in place we can now extract the messageID from the first item.
Just after line 13, add the following:
self.getFirstMessageIdFromMessages(response: response as! GTLRGmail_ListMessagesResponse)
Create a new method as follows:
func getFirstMessageIdFromMessages(response: GTLRGmail_ListMessagesResponse) {
}
To access the messages in the ListMessagesResponse you can modify the method above as follows:
func getFirstMessageIdFromMessages(response: GTLRGmail_ListMessagesResponse) {
let messagesResponse = response as GTLRGmail_ListMessagesResponse
print("Latest Message: ")
print(messagesResponse.messages![0].identifier)
}
Line 2, we create the messagesResponse constant and store the response “as” GTLRGmail_ListMessagesResponse.
Line 4, we access the messages property of the messagesResponse, and then access item 0 in that array and then access the identifier key.
Running the code, assuming you have an item in your inbox, you will see the following in the console:
Latest Message:
Optional("168a916e41b77b38")
Please note that this code alone is very unstable. If there are no messages in the inbox, it will cause problems. If you are to implement this code in a project then I strongly recommend that you implement all error checking as best practice.
In our next tutorial we’ll look at using that ID logged so that we can use “get” to get the contents of the message.
The project can be downloaded from here, although remember to insert your own client ID and other information as described in the previous tutorial.
James says
What should I use instead of “authoriser” if I have not a Google Sign in? I’ve implemented AppAuth so I have token response, is there any way to do this?