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,

建立者的帐号是服务帐户的电子邮件。

今天就先这样啦~
大家明天见!
若文章有任何问题,
还请大家不吝赐教!

参考资料:


<<:  顺着藏宝图的指示,可以寻获庞大的财富

>>:  Re: 新手让网页 act 起来: Day25 - useMemo 和 useCallback

【Day19】导航元件 - Dropdown

元件介绍 Dropdown 是一个下拉选单元件,当页面上的选项过多时,可以用这个元件来收纳选项,透过...

[Day9] ORM Injection

前言 :你有听过SQL Injection吗? :有阿 :那你知道怎麽防范吗? :参数化查询、ORM...

[Day - 30] 不完美的结束

最後,还是到了这最後一天,这第 30 天不完美的完赛,有时候时常都会想,上班就很忙了,开的 Tick...

Blazor 开发入门系列

2022 新的一年降临了,回首望望过去,原本用 Blog 方式写下技术文, 後来尝试用 youtub...

MacOS读取蓝牙摇杆讯号,利用python修改pynput程序码实现 - 1.起始

1. 前言: 之前想要实现在几公尺外遥控 mac book,於是就在虾皮上找到了这个蓝牙摇杆,虽然怀...