長話短說

讀完本文後,您將了解如何:

  • 透過使用 Cal.com 建立調度應用程式,將 AI 副駕駛整合到您的 Next.js 應用程式中。

  • 開發和管理自訂調度程序,以增強整個應用程式的使用者體驗。

另外,您將有一個很酷的專案可以在您的作品集中展示!

涼爽的


什麼是人工智慧副駕駛?

AI Copilot 是一款應用程式內人工智慧助手,可協助用戶在應用程式內回答問題並採取行動。它將LLMs知識帶入您的申請中。

以下是人工智慧副駕駛的一些潛在用例:

  • ChatBot :應用程式的上下文應用程式內訊息傳遞工具,可以幫助使用者進行查詢並在應用程式中執行一些特定操作。

  • AI 自動完成:智慧輸入控件,在使用者輸入訊息時提供與上下文相關的建議。

  • CoAgents :人工智慧助手,可以與您的應用程式和使用者一起實際工作,能夠獨立執行複雜的任務。

CopilotKit是領先、最強大且最易於使用的開源框架,用於建立應用內 AI 副駕駛。您可以在幾分鐘內讓完全自訂的 AI 副駕駛在您的應用程式中執行。

副駕駛

{% cta https://git.new/devtoarticle1 %} 查看 CopilotKit ⭐️ {% endcta %}


先決條件

要學習本教程,您需要具備以下條件。

以下是我們將在本教程中建立的演示:

演示1

建立新的 Next.js 專案

Next.js是用於建立可擴展和高效能 Web 應用程式的最廣泛使用的框架之一。它建立在 React 的核心功能之上,提供伺服器端渲染、靜態網站生成和更簡單的路由接口,有助於建立具有良好 SEO 的快速且可用於生產的網站。

為了讓我們能夠專注於學習如何將Cal.com和 Copilot 整合到您的客房預訂 Next.js 應用程式中,我為此應用程式建立了元件和 UI 介面。執行以下命令來克隆並執行應用程式:

git clone https://github.com/icode247/copilot-booking-app 
&& cd copilot-booking-app && npm install && npm run dev

螢幕截圖-1

整合Cal.com API 進行預訂

現在定義這些路線。在這些路線中,我們將向Cal.com APU 發出 API 請求以建立新預訂或取消預訂。在您的 API 資料夾中,建立一個新的bookings/route.ts檔案並新增以下程式碼:

import { NextRequest, NextResponse } from 'next/server';
import axios from 'axios';

export async function POST(request: NextRequest) {
  const { room, start, end, time, email } = await request.json();

  try {
    const [startDate] = start.split("T");
    const startDateTime = new Date(`${startDate}T${time}:00`);
    const formattedStart = startDateTime.toISOString();

    const endDateTime = new Date(startDateTime);
    endDateTime.setHours(endDateTime.getHours() + 1);
    const formattedEnd = endDateTime.toISOString();

    // Step 1: Create event-type
    const eventTypePayload = {
      length: 60,
      slug: `booking-${Date.now()}-${room.toLowerCase().replace(/\s+/g, "-")}`,
      title: `Booking for ${room}`,
      description: `Booking for ${room} from ${formattedStart} to ${formattedEnd}`,
      locations: [{ type: "inPerson", address: room }],
      disableGuests: false,
      slotInterval: 0,
      minimumBookingNotice: 0,
      beforeEventBuffer: 0,
      afterEventBuffer: 0,
    };

    const eventTypeResponse = await axios.post(
      `${CALCOM_API_BASE_URL}/event-types`,
      eventTypePayload,
      {
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${process.env.NEXT_PUBLIC_CALCOM_API_KEY}`,
        },
      }
    );

    const eventTypeId = eventTypeResponse.data.data.id;

    // Step 2: Create booking
    const bookingPayload = {
      end: formattedEnd,
      start: formattedStart,
      eventTypeId,
      eventTypeSlug: eventTypePayload.slug,
      timeZone: "Africa/Lagos",
      user: [email],
      language: "en",
      bookingUid: `booking-${Date.now()}`,
      metadata: {},
      responses: {
        name: email.split("@")[0],
        email,
        guests: [],
        notes: `Booking for ${room} from ${formattedStart} to ${formattedEnd}`,
      },
    };

    const bookingResponse = await axios.post(
      `${process.env.CALCOM_API_BASE_URL}/bookings`,
      bookingPayload,
      {
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${process.env.NEXT_PUBLIC_CALCOM_API_KEY}`,
        },
      }
    );

    return NextResponse.json({ booking: bookingResponse.data }, { status: 201 });
  } catch (error) {
    console.error("Error response status:", error.response?.status);
    return NextResponse.json(
      {
        error: "Failed to create booking",
        details: error.response?.data || error.message,
      },
      { status: 500 }
    );
  }
}

上述程式碼將在Cal.com中建立一個活動類型,其中包含預訂詳細訊息,包括房間和時間資訊。然後,使用新建立的事件類型的 ID,繼續在Cal.com上建立實際預訂。此程式碼處理日期格式,建立兩個 API 呼叫所需的有效負載,並使用 axios 將請求傳送到Cal.com API。

建立一個新的cancel/route.ts檔案並新增以下程式碼:

import { NextRequest, NextResponse } from "next/server";
import axios from "axios";

export async function POST(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  try {
    const body = await request.json();
    const bookingId = params.id;

    const cancelledBookingResponse = await axios.post(
      `${process.env.CALCOM_API_BASE_URL}/bookings/${bookingId}/cancel`,
      body,
      {
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${process.env.NEXT_PUBLIC_CALCOM_API_KEY}`,
        },
      }
    );

    return NextResponse.json(
      { booking: cancelledBookingResponse.data },
      { status: 201 }
    );
  } catch (error) {
    console.error("Error cancelling booking:", error);
    return NextResponse.json(
      { error: "Failed to cancel booking" },
      { status: 500 }
    );
  }
}

上面的程式碼實作了一個 API 路由處理程序,用於使用Cal.com API 取消預訂。

現在更新您的app/page.tsx檔案以使用我們建立的RoomBookingProvider

// app/page.tsx
'use client';

import Layout from "@/components/Layout";
import RoomBookingCard from "@/components/RoomBookingCard";
import { RoomBookingProvider } from "@/lib/hooks/use-room-booking";

export default function Home() {
  return (
    <RoomBookingProvider>
      <Layout>
        <RoomBookingCard />
      </Layout>
    </RoomBookingProvider>
  );
}

然後,更新 RoomBookingCard.tsx 檔案以使用 useRoomBooking 掛鉤來允許使用者預訂房間。

// components/RoomBookingCard.tsx
"use client";

import { FC, useEffect, useState } from "react";
import RoomList from "./RoomList";
import Notification from "./Notification";
import BookingForm from "./BookingForm";
import { useRoomBooking } from "@/lib/hooks/use-room-booking";

const RoomBookingCard: FC = () => {
  const [selectedRoom, setSelectedRoom] = useState<string | null>(null);
  const [notification, setNotification] = useState<string | null>(null);
  const [rooms, setRooms] = useState([]);
  const { addBooking } = useRoomBooking();

  useEffect(() => {
    async function fetchRooms() {
      const response = await fetch("/api/rooms");
      const data = await response.json();
      setRooms(data);
    }
    fetchRooms();
  }, []);

  const handleRoomSelect = (room: string) => {
    setSelectedRoom(room);
  };

  const handleBookingConfirm = async (
    sdate: string,
    time: string,
    edate: string,
    email: string
  ) => {
    try {
      if (selectedRoom) {
        await addBooking(selectedRoom, sdate, time, edate, email);
        setNotification("Booking confirmed!");
        setSelectedRoom(null);
      }
    } catch (error) {
      setNotification(error.message);
    }
  };

  return (
    <div>
      {notification && (
        <Notification
          message={notification}
          onClose={() => setNotification(null)}
        />
      )}
      {selectedRoom ? (
        <BookingForm room={selectedRoom} onConfirm={handleBookingConfirm} />
      ) : (
        <RoomList rooms={rooms} onSelectRoom={handleRoomSelect} />
      )}
    </div>
  );
};

export default RoomBookingCard;

現在您可以選擇任何房間,輸入您的詳細資料並預訂。

螢幕截圖-2

現在讓我們透過使用 CopilotKit 加入 AI 副駕駛來使應用程式變得更有趣。首先,造訪OpenAI 開發者平台並建立一個新的金鑰。

整合 Copilotkit 以實現 AI 驅動的交互

OpenAI 儀表板

設定 Copilotkit

Copilotkit 提供兩種整合選項:

  • Copilot Cloud:哪種最簡單的方式開始使用 CopilotKit 和

  • 自託管:這會在您自己的基礎架構上設定 Copilot Runtime 執行個體。

在本教程中,我們將使用Copilot Cloud。點擊此處免費取得您的 Copilot Cloud API 金鑰。然後,將<your-public-api-key>替換為您的實際 Open AI 金鑰以產生 Copilot 公鑰。

將您的 API 金鑰安全地新增到您的.env.local檔案中:

PUBLIC_API_KEY=<your-public-api-key>

更新您的app/page.tsx檔案以將<CopilotKit>提供者包裝在您的應用程式中:


// app/page.tsx
"use client";

import Layout from "@/components/Layout";
import RoomBookingCard from "@/components/RoomBookingCard";
import { RoomBookingProvider } from "@/lib/hooks/use-room-booking";
import { CopilotKit } from "@copilotkit/react-core";
import { CopilotPopup } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";

export default function Home() {
  return (
    <CopilotKit publicApiKey={process.env.PUBLIC_API_KEY}>
      <RoomBookingProvider>
        <Layout>
          <RoomBookingCard />
        </Layout>
      </RoomBookingProvider>
      <CopilotPopup />
    </CopilotKit>
  );
}

在上面的程式碼中,我們導入了<CopilotPopup />元件,並使用<CopilotKit>提供者包裝了頁面,兩者都來自@copilotkit/react-ui 。我們還從同一個包中匯入了可選的內建樣式來增強 UI。

現在您將在頁面右下角看到聊天彈出視窗。

彈出螢幕截圖

為了讓 Copilot 為我們提供正確的答案並執行任務,我們需要使用useCopilotReadable掛鉤讓它了解我們的應用程式狀態。更新lib/hooks/use-room-booking.tsx檔案中的程式碼,為副駕駛提供我們的預訂和房間的狀態:

// ...

import { useCopilotReadable } from "@copilotkit/react-core";
// ...

export function RoomBookingProvider({ children }: { children: ReactNode }) {
    // ... 
    const [rooms, setRooms] = useState([]);

    // ... 

    useCopilotReadable({
       description: "The state of the booking list",
       value: JSON.stringify(bookings),
    });

    useCopilotReadable({
       description: "The state of the rooms list",
       value: JSON.stringify(rooms),
    });
    //...
}

現在,您可以透過詢問您有多少預訂來測試 Copilot。

CopilotKit 聊天螢幕

處理預訂和取消

讓 Copilot 能夠執行更多任務,例如建立預訂、取消預訂以及獲取有關可用房間的資訊。為此,我們將使用Copilot useCopilotAction掛鉤。此掛鉤允許您向副駕駛提供操作。

更新您的lib/hooks/use-room-booking.tsx檔案並新增以下操作:

// ...

export function RoomBookingProvider({ children }: { children: ReactNode }) {
// ...

  useCopilotAction({
    name: "addBooking",
    description: "Adds a booking to the list",
    parameters: [
      {
        name: "room",
        type: "string",
        description: "The room to be booked",
        required: true,
      },
      {
        name: "date",
        type: "string",
        description: "The date of the booking",
        required: true,
      },
      {
        name: "time",
        type: "string",
        description: "The time of the booking",
        required: true,
      },
      {
        name: "end",
        type: "string",
        description: "The checkout time for booking",
        required: true,
      },
      {
        name: "email",
        type: "string",
        description: "Email address of the user booking the room",
        required: true,
      },
    ],
    handler: async ({ room, date, time, end, email }) => {
      await addBooking(room, date, time, end, email);
    },
  });

  useCopilotAction({
    name: "cancelBooking",
    description: "Cancels a booking from the list",
    parameters: [
      { name: "room", type: "string", description: "The room of the booking to be cancelled", required: true },
      { name: "date", type: "string", description: "The date of the booking to be cancelled", required: true },
      { name: "reason", type: "string", description: "The reason for cancellation", required: true },
    ],
    handler: async ({ room, date, reason }) => {
      await cancelBooking(room, date, reason);
    },
  });

  useCopilotAction({
    name: "fetchAvailableRooms",
    description: "Fetches available rooms for a given date",
    parameters: [
      {
        name: "date",
        type: "string",
        description: "The date to check room availability",
        required: true,
      },
    ],
    handler: async ({ date }) => {
      const availableRooms = await fetchAvailableRooms(date);
      setRooms(availableRooms);
    },
  });

  useCopilotAction({
    name: "setBookingStatus",
    description: "Sets the status of a booking",
    parameters: [
      {
        name: "id",
        type: "number",
        description: "The ID of the booking",
        required: true,
      },
      {
        name: "status",
        type: "string",
        description: "The status of the booking",
        enum: Object.values(BookingStatus),
        required: true,
      },
    ],
    handler: ({ id, status }) => {
      setBookingStatus(id, status);
    },
  });
  //...
 }

在上面的程式碼片段中,我們使用useCopilotAction掛鉤來建立操作來建立預訂、 addBookingcancelBookingfetchAvailableRoomssetBookingStatus 。這些操作中的每一個都需要一個具有以下屬性的物件。

name代表動作的名稱。

description是指描述動作的特徵。這非常重要,因為它可以讓我們的副駕駛選擇正確的行動。

parameters是操作所採用的參數集,它是一個陣列。它符合 JSON Schema 格式。

handler只是一個在執行操作時執行的函數。

現在,您可以使用副駕駛執行高級操作,例如查看可用房間清單、預訂和取消預訂。請隨意與副駕駛聊天以執行其他操作。

使用 CopilotKit 進行進階操作

太棒了,您現在有了一個人工智慧驅動的日程安排應用程式可以加入到您的作品集中。


總結一下

CopilotKit是一款創新且便利的工具,可將 AI 功能新增至您的產品。無論是建立語音互動系統還是為具有挑戰性的程式部署自動化,其適應性都將滿足任何想要將人工智慧融入其工作的軟體開發人員的需求。

如果您正在開發非常重視人工智慧的產品,或者正在尋找將其加入到您製作的應用程式中的方法,那麼您絕對應該考慮使用 CopilotKit。此介面簡單且可快速配置,從而減少了時間並提高了全局關注度。

您對 CopilotKit 等工具的好奇心可以幫助您跟上軟體產業快速變化的格局。

加入 CopilotKit 令人驚嘆的開發者社區,與我們一起建立!

不要忘記查看我們的GitHub並給我們一顆星來表達您的愛 ⭐️


原文出處:https://dev.to/copilotkit/how-i-built-the-worlds-best-nextjs-ai-scheduling-app-442c


共有 0 則留言