iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
Software Development

Laravel 新手初見 API系列 第 25

Day25-介接 API(三)Google Calendar(III)OAuth 憑證建立與用 Google Calendar API 建立 Google Meet 會議

大家好~
今天來實作如何用 Google Calendar API 建立 Google Meet 會議吧,
如果要建立 Google Meet 會議是不能用服務帳號當憑證的,
所以這邊我們改建立 OAuth 憑證來實作該功能喔~

OAuth 憑證建立

點擊建立憑證
選擇 OAuth 用戶端 ID

建立 OAuth 用戶端 ID

選擇應用程式類型,
並輸入自定義的名稱~

已授權的重新導向 URI

這邊重新導向的 URI 我們先用 http://127.0.0.1:8000/

建立後把 JSON 下載下來放到我們專案內吧~

OAuth 同意畫面

然後來到 OAuth 同意畫面頁面。

將等等要用的 Google 帳號加進測試使用者

取得 token.json

以下三個是等一下有用到的 env,
分別代表:

  • env('OAUTH_CLIENT_CREDENTIALS_PATH')
    • 剛剛下載下來的 json 檔案路徑
  • env('OAUTH_TOKEN_JSON_PATH')
    • 接下來實作取得的 token.json 的檔案路徑
  • env('GOOGLE_CALENDAR_ID')
    • 日曆 ID

下面實作過程參考自官方文件的 PHP Quickstart

use Illuminate\Http\Request;
use Google\Client;
use Google\Service\Calendar;
protected $client;
protected $tokenPath;

public function __construct()
{
    $this->tokenPath = env('OAUTH_TOKEN_JSON_PATH');
    $this->client = new Client();
    $this->client->setAuthConfig(env('OAUTH_CLIENT_CREDENTIALS_PATH'));
    $this->client->addScope(Calendar::CALENDAR_EVENTS);
}

public function tokenCheck()
{
    if (file_exists($this->tokenPath)) {
        $accessToken = json_decode(file_get_contents($this->tokenPath), true);
        $this->client->setAccessToken($accessToken);
    }

    // If there is no previous token or it's expired.
    if ($this->client->isAccessTokenExpired()) {
        // Refresh the token if possible, else fetch a new one.
        if ($this->client->getRefreshToken()) {
            $this->client->fetchAccessTokenWithRefreshToken($this->client->getRefreshToken());
        } else {
            // Request authorization from the user.
            $authUrl = $this->client->createAuthUrl();
            return $authUrl;
        }
    }

    return [
        'message' => 'success'
    ];
}

public function tokenInsert(Request $request)
{
    $authCode = $request->authCode;

    // Exchange authorization code for an access token.
    $accessToken = $this->client->fetchAccessTokenWithAuthCode($authCode);

    $this->client->setAccessToken($accessToken);

    // Check to see if there was an error.
    if (array_key_exists('error', $accessToken)) {
        throw new Exception(join(', ', $accessToken));
    }
    // Save the token to a file.
    if (!file_exists(dirname($this->tokenPath))) {
        mkdir(dirname($this->tokenPath), 0700, true);
    }
    file_put_contents($this->tokenPath, json_encode($this->client->getAccessToken()));

    return [
        'message' => 'success'
    ];
}
tokenCheck()

先試試 tokenCheck() 這個 function,
會取得一段 URL,
將這段 URL 貼到瀏覽器上。

選擇剛剛加到測試使用者的那個帳號。

點擊繼續

再點擊繼續

之後會重新導向到剛剛我們設定的 URI http://127.0.0.1:8000/
將 URI 內的 code 複製下來~

tokenInsert(Request $request)

將剛剛的 code 傳給 tokenInsert(Request $request) 這個 function。

就可以得到上圖這個 token.json 啦~

建立 Google Meet 會議

內容其實與建立 Google Calendar API 的 Event 差不多,
不過使用服務帳號的憑證無法建立 ConferenceData
以下範例是用 OAuth 的憑證實作的喔~

use Illuminate\Http\Request;
use Google\Client;
use Google\Service\Calendar;
use Google\Service\Calendar\Event;
use Google\Service\Calendar\EventDateTime;
use Google\Service\Calendar\ConferenceData;
use Google\Service\Calendar\ConferenceSolutionKey;
use Google\Service\Calendar\CreateConferenceRequest;
protected $client;
protected $calendar;
protected $calendarId;

public function __construct()
{
    $tokenPath = env('OAUTH_TOKEN_JSON_PATH');
    $this->client = new Client();
    $this->client->setAuthConfig(env('OAUTH_CLIENT_CREDENTIALS_PATH'));
    $this->client->addScope(Calendar::CALENDAR_EVENTS);
    $accessToken = json_decode(file_get_contents($tokenPath), true);
    $this->client->setAccessToken($accessToken);
    $this->calendar = new Calendar($this->client);
    $this->calendarId = env('GOOGLE_CALENDAR_ID');
}

public function insert(Request $request)
{
    $calendarEvent = new Event();

    $conferenceSolutionKey = new ConferenceSolutionKey();
    $conferenceSolutionKey->setType('hangoutsMeet');

    $createConferenceRequest = new CreateConferenceRequest();
    $createConferenceRequest->setRequestId(md5('ironman2021' . time()));
    $createConferenceRequest->setConferenceSolutionKey($conferenceSolutionKey);

    $conferenceData = new ConferenceData();
    $conferenceData->setCreateRequest($createConferenceRequest);
    $calendarEvent->setConferenceData($conferenceData);

    $calendarEvent->setSummary($request->summary);
    $calendarEvent->setDescription($request->description);

    $startTime = new EventDateTime();
    $startTime->setDateTime($request->startTime);
    $calendarEvent->setStart($startTime);

    $endTime = new EventDateTime();
    $endTime->setDateTime($request->endTime);
    $calendarEvent->setEnd($endTime);

    $event = $this->calendar->events->insert(
        $this->calendarId,
        $calendarEvent,
        [
            'conferenceDataVersion' => 1
        ]
    );

    return [
        'id' => $event->getId(),
        'link' => $event->getHtmlLink(),
        'hangoutLink' => $event->getHangoutLink(),
        'summary' => $event->getSummary(),
        'description' => $event->getDescription(),
        'start' => $event->getStart()->getDateTime(),
        'end' => $event->getEnd()->getDateTime(),
    ];
}

成果預覽:

用 Postman 測試一下,
將 Response 內的 hangoutLink 複製到瀏覽器上看一下~

成功建立一個有 Google Meet 的 Event 啦!

這個 Event 的建立者會是剛剛我們同意使用應用程式的帳號喔。

下圖是用服務帳號憑證建立的 Event,

建立者的帳號是服務帳戶的電子郵件。

今天就先這樣啦~
大家明天見!
若文章有任何問題,
還請大家不吝賜教!

參考資料:


上一篇
Day24-介接 API(二)Google Calendar(II)Events——Read、Update、Delete
下一篇
Day26-介接 API(番外篇 I)NLP 自然語言處理之初見 Dialogflow ES
系列文
Laravel 新手初見 API30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
arguskao
iT邦新手 4 級 ‧ 2023-07-26 12:22:00

請問一下,如果同一個時間被塞入第二個會議,也能建立嗎?
因為實務中,一個人不可能同時去參加兩個會議

我要留言

立即登入留言