Day30-用 LINEBot、Google Calendar、Dialogflow ES 做个开会机器人当结尾!

大家好~
今天是最後一天了,
来将这几天所学结合成一个小作品吧!

功能部分就是当使用者跟 LINEBot 说什麽时候要开会,
LINEBot 会回应一个 Google Meet 的会议连结。

功能满简单的,
所以我决定用 Dialogflow 这个架构。

LINEBot Channel 申请可以参考 Day12
Dialogflow 与 LINEBot Channel 连动设定可以参考 Day26
Dialogflow Intent 的训练也可以参考 Day26
Google Calendar 会用 Oauth 的凭证,
可以参考 Day25

底下就是程序的实作啦~

Route::post('/dialogflow', [DialogflowController::class, 'intent']);

开个 Webhook 给 Dialogflow。

GoogleMeetController
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;

class GoogleMeetController extends Controller
{
    protected $client;
    protected $calendar;
    protected $calendarId;

    public function __construct()
    {
        $this->client = new Client();
        $this->client->setAuthConfig(env('OAUTH_CLIENT_CREDENTIALS_PATH'));
        $this->client->addScope(Calendar::CALENDAR_EVENTS);
        $tokenPath = env('OAUTH_TOKEN_JSON_PATH');
        $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 create($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']);

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

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

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

        return $response->getHangoutLink();
    }
}

GoogleMeetController 会在指定时间建立一个 Google Calendar Event,
然後回传 Google Meet 连结。

env 的设定也是和 Day25 一样喔~

DialogflowController
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\GoogleMeetController;

class DialogflowController extends Controller
{
    public function intent(Request $request)
    {
        $queryText = $request->queryResult['queryText'];

        $datetime = $request->queryResult['outputContexts'][0]['parameters']['date-time'];

        $meetData['summary'] = "开会";

        switch ($datetime) {
            case is_string($datetime):
                $meetData['startTime'] = $datetime;
                $meetData['endTime'] = Carbon::parse($datetime)->addHour()->toRfc3339String();
                break;
            case is_array($datetime):
                if (isset($datetime['date_time'])) {
                    $startTime = $datetime['date_time'];
                    $meetData['startTime'] = $startTime;
                    $meetData['endTime'] = Carbon::parse($startTime)->addHour()->toRfc3339String();
                } elseif (isset($datetime['startDateTime'])) {
                    $startTime = $datetime['startDateTime'];
                    $endTime = $datetime['endDateTime'];
                    $meetData['startTime'] = $startTime;
                    $meetData['endTime'] = $endTime;
                } else {
                    $startTime = $datetime['startTime'];
                    $endTime = $datetime['endTime'];
                    $meetData['startTime'] = $startTime;
                    $meetData['endTime'] = $endTime;
                }
                break;
            default:
                return response('400', Response::HTTP_BAD_REQUEST);
        }

        $googleMeetController = new GoogleMeetController;
        $url = $googleMeetController->create($meetData);

        $jsonResponse = [
            "fulfillmentMessages" => [
                [
                    "text" => [
                        "text" => [
                            $url
                        ]
                    ]
                ]
            ]
        ];
        return $jsonResponse;
    }
}

DialogflowController 会将 Google Meet 连结传给 Dialogflow。

这样就差不多完成啦~
以下开始成果预览!

成果预览:

测试结果#1

测试结果#2

功能测试成功!

以上程序码仅仅只是可动而已,
还有许多的不足,
例外处理以及一些安全上的问题都还没完善,
像是 Dialogflow 发送的 Request 没在 Headers 加入验证相关的讯息,
DialogflowController 也没有对 Request 做验证。

之後还有更多要加强的地方,
这只是个起点。

感谢30天来收看的你~

若文章有任何问题,
还请不吝赐教!
也欢迎一起讨论~
谢谢大家!


<<:  #30-用Tailwind&Gulp做个动态菜单网站(完赛!)

>>:  【课程推荐】UiPath Studio 基础实作2日课 (中文教学)

PHP 正则相关函数

PHP Regular expression 本来 PHP 支援两类 regular express...

安装 + 最最最基本的Hello world

简介 什麽是Python Python本意是指蟒蛇,是一种面相对象的解释型语言 人生苦短,我学Pyt...

从 JavaScript 角度学 Python(30) - 爬虫

前言 前面我们也已经学了不少的知识点,而这边也进入了铁人赛的最後一天,所以就来试着写一个简单的 it...

[Day - 26] - Spring Swagger之我的SeaFood API 手册配制方法

Abstract 我们前面讲了许多Spring应用开发,但当我们开发好一套系统,势必要有一套API手...

产品设计框架 - 双钻石产品设计法 Double Diamond

双钻石产品设计法,是由英国设计协会(Design Council)在2005年提出的设计流程,主要有...