Viblo Learning
+8

Laravel + Google API: Nghịch thử ứng dụng đặt lịch thông qua Calendar API và hmm... mấy thứ linh tinh

Bài viết này sẽ hướng dẫn các bạn tự tạo ra một ứng dụng đặt lịch từ A đến Y thông qua Calendar API do Google cung cấp. Nếu có gì sai sót hoặc chưa tối ưu mong các bạn góp ý để mình chỉnh sửa lại tốt hơn 😄

Chuẩn bị:

Chỉ cần chuẩn bị một bộ project "Goravel" như bài viết trước đó của mình là đủ rồi 😄

Bắt đầu

Controller

Hãy khởi động nhẹ nhàng với một controller đơn giản thế này, chúng ta sẽ dần hoàn thiện nó ở bên dưới.

CalendarController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Components\GoogleClient;
use Google_Service_Calendar;

class CalendarController extends Controller
{
    protected $client;

    public function __construct(GoogleClient $client)
    {
        $this->client = $client->getClient();
    }

    public function index()
    {
        return view('calendar');
    }
}

View

Có controller rồi, hãy tạo ra một view đơn giản để fill các thông số cho event mà chúng ta muốn tạo ra.

Mình dùng một package có tên flatpickr để làm phần chọn ngày giờ, các bạn có thể tham khảo hoặc dùng package khác cũng được.

Calendar.blade.php

Quay lại Controller

Thêm function createEvent :

public function createEvent(Request $request)
{
    $calendarService = new Google_Service_Calendar($this->client);

    $event = new \Google_Service_Calendar_Event([
        'summary' => $request->title,
        'description' => $request->description,
        'start' => [
            'dateTime' => $this->convertTime($request->start)
        ],
        'end' => [
            'dateTime' => $this->convertTime($request->end)
        ]
    ]);
    dd($calendarService->events->insert('primary', $event));
}

Các bạn sẽ thấy có một function tên convertTime, giải thích qua chút.

Thời gian mà Calendar chấp nhận phải có dạng: 2018-12-14T04:09:29+00:00

Đại loại vậy đó, nên các bạn cần convert thời gian sao cho trông giống như thế, ở đây mình dùng package Carbon để convert, nếu bạn chưa dùng bao giờ thì có thể tham khảo cách cài đặt tại đây

Và từ đó chúng ta tạo ra một function tên convertTime như sau:

private function convertTime($time, $min = 0)
{
    return Carbon::parse($time, 'Asia/Bangkok')->addMinutes($min)->toIso8601String();
}

Ờm thế là xong rồi đấy 😄 không tin đặt thử xem, dễ đúng không? :v

Sau khi bấm Create, lịch được tạo thành công, các bạn sẽ nhận được response là một object, trong đó có chứa một số thông tin mà có thể bạn sẽ cần dùng lại, ví dụ như: id, event_link, ...

Làm app là dễ nhở 😄

Đùa xíu thôi, chứ một app đặt lịch đâu phải chỉ có như thế, chúng ta sẽ còn những yêu cầu khác nữa, lần lượt mình sẽ thử giải quyết vài option nữa xem thế nào.

Nghĩ xem nhé, đặt lịch mà có mỗi một mình thì hơi buồn nhỉ? Giờ bạn muốn đặt một lịch đi chơi chẳng hạn, và muốn rủ vài người bạn nữa đi cùng cho vui, bạn muốn thêm những người bạn đó vào làm khách mời trong lịch muốn đặt thì làm thế nào?

OK, hãy thử đặt một lịch hẹn và mời thêm những người khác nữa.

Thêm khách mời cho lịch

Để thêm được các khách mời cho lịch thì Calendar API cung cấp sẵn một option gọi là attendees, việc của chúng ta là đưa một danh sách các email cần mời vào option này là xong. Bắt tay vào làm nào, đầu tiên là sửa lại giao diện một chút:

(làm vội nên chỉ được thế này thôi :> )

Thêm một function nữa gọi là getAttendees :

private function getAttendees($emails)
{
    $attendees = [];

    foreach ($emails as $email) {
        if ($email) {
            $attendees[] = [
                'email' => $email
            ];
        }
    }

    return $attendees;
}

Trong hàm createEvent thêm option attendees cho $event như sau:

$event = new \Google_Service_Calendar_Event([
    'summary' => $request->title,
    'description' => $request->description,
    'start' => [
        'dateTime' => $this->convertTime($request->start)
    ],
    'end' => [
        'dateTime' => $this->convertTime($request->end)
    ],
    // thêm attendees
    'attendees' => $this->getAttendees($request->attendees)
]);

Sau khi xong, chúng ta test lại sẽ được kết quả như vậy:

Feels good, right? 😄

Ô sờ kê :v giờ đặt lịch được tương đối rồi, nhưng mà giả sử bạn đặt xong lịch đó, nhưng không muốn quay lại calendar để kiểm tra lịch mà muốn tổng hợp một danh sách lịch hiện luôn trước mặt mình, ngay trên ứng dụng này để tiện theo dõi thì sao?

Thì phải code tiếp chứ sao 😄 Hãy thử làm một danh sách các lịch của bạn theo ngày xem như nào nhé 😄

Xem lại danh sách lịch

Đầu tiên vẫn là giao diện, mình thích nó hiện luôn lên trang đặt lịch để cho tiện theo dõi, vừa vào cái là xem được, đặt được, khỏi phải click nhiều 😄

Tạm như vậy đi :v dữ liệu thật sẽ được fill vào ngay bây giờ đây.

Trong function index của CalendarController chúng ta sẽ lấy ra danh sách các events và sắp xếp chúng lại theo ngày để tiện theo dõi:

CalendarController

public function index()
{
    $calendarService = new Google_Service_Calendar($this->client);
    // lấy danh sách tất cả events
    $events = $calendarService->events->listEvents('primary')->getItems();

    if ($events) {
        $start = array_column($events, 'start');
        $startTime = array_column($start, 'dateTime');

        foreach ($startTime as $k => $item) {
            $orderByTime[] = Carbon::parse($item)->toDateString();
            $startTime[$k] = Carbon::parse($item)->toDateString();
        }

        $orderByTime = array_unique($orderByTime);
        krsort($orderByTime);

        foreach ($orderByTime as $item) {
            foreach ($events as $event) {
                if ($item == Carbon::parse($event->start->dateTime)->toDateString()) {
                    $finalItems[$item][] = $event;
                }
            }
        }
    } else {
        $finalItems = [];
    }

    $data['events'] = $finalItems;

    return view('welcome', $data);
}

Đoạn code trên là mình tự nghĩ ra để fill vào giao diện bên dưới:

Tất nhiên là bạn cũng có thể code kiểu khác để phù hợp với ứng dụng của bạn, nhưng cơ bản là bạn vẫn sẽ phải lấy ra được list các events đã, ở trên là dòng lệnh lấy toàn bộ events, bạn cũng có thể thêm một vài options như thế này để lấy ra các events trong một khoảng thời gian giới hạn nào đó chẳng hạn:

$optParams = [
    'timeMin' => [
        'dateTime' => $this->convertTime($request->start)
    ],
    'timeMax' => [
        'dateTime' => $this->convertTime($request->end)
    ],
];
$events = $calendarService->events->listEvents('primary', $optParams)->getItems();

Lời kết

Và đó là cách tạo ra một ứng dụng Google Calendar cơ bản, ngoài ra còn nhiều vấn đề nữa, ví dụ như là insert thêm file vào event vừa tạo ra và share file đó đến các khách mời mình sẽ đề cập trong các bài viết kế tiếp.

Cám ơn đã theo dõi bài viết này!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.