【Swift5】APIKitを使って Gmail API からメッセージ取得する

##前提
まず、Gmail API のそもそも使い方や、OAuth認証、メッセージのid/threadIdの取得、ユーザー情報（主にメールアドレス）の取得やキーチェーンへの保存は以下方がまとめてくださっているのでそちらを参照されたし。
https://qiita.com/ryokkkke/items/dd04bea2b579c16a9b19
https://qiita.com/ryokkkke/items/4c3da87b50d7a298e604

基本自分の備忘録の意味合いが強いのでコードや説明が雑です。あらかじめご了承ください。

```swift:Request.swift

import APIKit

struct MessageRequest: Request {
    typealias Response = Message
    
    let userId: String
    let messageId: String
    let token: String

    var baseURL: URL {
        return URL(string: "https://www.googleapis.com")!
    }

    var method: HTTPMethod {
        return .get
    }

    var path: String {
        return "/gmail/v1/users/\(userId)/messages/\(messageId)"
    }
    
    var headerFields: [String : String] {
        return ["Authorization" : "Bearer " + token]
    }

    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Message {
        print(urlResponse)
        return try Message(object: object)
    }
}

struct Message {
    let subject: String
    let date: String
    let from: String
    let parts: [[String: Any]]

    init(object: Any) throws {
        guard let dictionary = object as? [String: Any],
            let payload = dictionary["payload"] as? [String: Any],
            let headers = payload["headers"] as? [[String: String]],
            let subject = headers.filter({ (dics) -> Bool in
                dics["name"] == "Subject"
            }).first!["value"],
            let date = headers.filter({ (dics) -> Bool in
                dics["name"] == "Date"
            }).first!["value"],
            let from = headers.filter({ (dics) -> Bool in
                dics["name"] == "From"
            }).first!["value"],
            let parts = payload["parts"] as? [[String: Any]] else {
                throw ResponseError.unexpectedObject(object)
        }
        self.subject = subject
        self.date = date
        self.from = from
        self.parts = parts
    }
}
```

```swift:ViewController.swift

   func getGmailList(userId: String) { // ここのuserIdはメールアドレス
        let query = GTLRGmailQuery_UsersMessagesList.query(withUserId: userId)
        let service = GTLRGmailService()
        service.authorizer = GTMAppAuthFetcherAuthorization.init(fromKeychainForName: "kGTMAppAuthBylistStoryboardAuthorizerKey")
        service.executeQuery(
            query,
            delegate: self,
            didFinish: #selector(parseMessage)
        )
    }
    
    @objc func parseMessage(ticket: GTLRServiceTicket, finishedWithObject response: GTLRGmail_ListMessagesResponse, error: NSError?) {
        if let error = error {
            print("メッセージリストの取得に失敗しました。")
            print(error)
            return
        }
        print("メッセージリストの取得に成功しました。")
        print(response.messages!)
        print("nextPageToken: \(response.nextPageToken!)")
        print("resultSizeEstimate: \(response.resultSizeEstimate!)")
        
        guard let userId = self.userId, // ここのuserIdは先に取得しておいたユーザー情報の中のメールアドレスを代入しています
            let messages = response.messages else {
            return
        }
        
        let request = MessageRequest(userId: userId, messageId: messages.first!.identifier!, token: token!)
        print(messages.first!.identifier!)

        Session.send(request) { result in
            switch result {
            case .success(let response):
                print("subject: \(response.subject)")
                print("date: \(response.date)")
                print("from: \(response.from)")
                print("parts: \(response.parts)")

            case .failure(let error):
                print("error: \(error)")
            }
        }
    }
```