ใน Codelab นี้คุณจะได้เรียนรู้การสร้าง LINE Chatbot ให้สามารถโต้ตอบได้แบบ Generative AI ผ่านการเชื่อมต่อ PaLM API โดยใช้ Cloud Functions for Firebase 2nd Gen กัน

สิ่งที่คุณจะได้เรียนรู้


สิ่งที่คุณต้องเตรียมพร้อมก่อนเริ่ม Codelab

สมัครเป็น LINE Developer

จุดเริ่มขบวนสำหรับการพัฒนาแอปพลิเคชันต่างๆบนแพลตฟอร์มของ LINE คือคุณจะต้องสมัครเป็น LINE Developer ก่อน

  1. เข้าไปที่ https://developers.line.biz/console/ แล้วเลือก Log in with LINE account(สีเขียว) เพื่อเข้าสู่ระบบ

  1. เข้าสู่ระบบด้วยบัญชี LINE ของคุณให้เรียบร้อย
  2. กรอกชื่อและอีเมล พร้อมกดยอมรับ Agreement จากนั้นกดปุ่ม Create my account เป็นอันเสร็จสิ้นขั้นตอนการสมัครเป็น LINE Developer


สร้าง Provider

Provider คือชื่อผู้ให้บริการ ซึ่งจะไปแสดงตามหน้า consent ต่างๆ หรือเรียกได้ว่าเป็น superset ของแอปทั้งหลายที่เราจะพัฒนาขึ้นรวมถึง LIFF app ด้วย โดยการสร้างเพียงให้ระบุชื่อของ Provider ลงไป ซึ่งอาจจะตั้งเป็นชื่อตัวเอง, ชื่อบริษัท, ชื่อทีม หรือชื่อกลุ่มก็ได้


สร้าง Channel

Channel เปรียบเสมือนแอป หรือเรียกได้ว่าเป็น subset ของ Provider โดยมีอยู่ 3 รูปแบบ คือ LINE Login, Messaging API และ Clova Skill

  1. สำหรับการพัฒนา Chatbot เราจะต้องเลือก Create a Messaging API channel

  1. เมื่อกดเลือก Messaging API channel จะเข้าสู่หน้าที่ให้ระบุรายละเอียดต่างๆลงไป แล้วกดสร้าง


เพิ่ม Chatbot เป็นเพื่อนและตั้งค่า Channel

  1. หลังจากกดสร้าง Channel แล้ว ให้ไปที่ Tab ชื่อ Messaging API และทำการแสกน QR code ด้วยแอป LINE เพื่อเพิ่ม Chatbot เป็นเพื่อน

  1. ให้ปิด Auto-reply messages เนื่องจากฟีเจอร์นี้จะเป็น default การตอบกลับของ Chatbot ซึ่งไม่จำเป็นต้องใช้ฟีเจอร์นี้

  1. กลับมาที่ Channel ที่เราสร้างใน Tab ชื่อ Messaging API ตรงส่วนของ Channel access token ให้กดปุ่ม Issue

เบื้องหลังของ Chatbot ตัวนี้ เราจะใช้บริการใน Firebase อย่าง Cloud Functions for Firebase และ Cloud Firestore ดังนั้นขั้นตอนนี้เราจะมาสร้างโปรเจค Firebase เพื่อใช้งานกัน

สร้างโปรเจคใน Firebase

  1. ให้ Sign in ใน Firebase console ด้วย Google account
  2. ในหน้า Firebase console ให้คลิก Add project จากนั้นตั้งชื่อโปรเจคตามต้องการ

  1. เมื่อกด Continue แล้วให้ข้ามการตั้งค่า Google Analytics ไป เพราะคุณจะไม่ได้ใช้มันในโปรเจคนี้


เปลี่ยนแพลนจาก Spark ไปเป็น Blaze (Pay as you go)

เนื่องจาก Cloud Functions for Firebase มีเงื่อนไขว่า หากต้องการไป request ตัว APIs ที่อยู่ภายนอก Google คุณจำเป็นจะต้องใช้ Blaze plan(เราจะต้องไปเรียก Messaging API ของ LINE)

การติดตั้ง Firebase CLI

Firebase CLI เป็นเครื่องมือที่จำเป็นสำหรับการ deploy ตัวฟังก์ชันที่เราพัฒนาขึ้น อีกทั้งยังสามารถจำลองการทำงานฟังก์ชัน(Emulate) ภายในเครื่องที่เราพัฒนาอยู่(Locally) ได้

  1. เปิด Terminal ขึ้นมาแล้ว run คำสั่ง
npm install -g firebase-tools
  1. ตรวจสอบว่า Firebase CLI ได้ติดตั้งเรียบร้อยแล้วโดย run คำสั่ง (หากสำเร็จจะเห็นเลขเวอร์ชัน)
firebase --version


Initialize โปรเจค

  1. รันคำสั่งนี้ จากนั้นตัว browser จะเปิดขึ้นมาให้เราเข้าสู้ระบบด้วย Google account เดียวกันกับที่สร้างโปรดจคใน Firebase
firebase login
  1. สร้างโฟลเดอร์เปล่า(ตัวอย่างโฟลเดอร์ชื่อ bot) แล้วให้ shell เข้าไปในนั้น
mkdir bot
cd bot
  1. เมื่อเข้ามาในโฟลเดอร์แล้ว ให้ Initial โปรเจคด้วยคำสั่ง
firebase init functions
  1. เลือก Use an existing project จากนั้นจะเห็นเชื่อโปรเจคที่เราสร้างไว้ ก็กด enter ต่อไป

  1. ถัดไปจะมีตัวเลือกภาษา 2 ตัวคือ JavaScript และ TypeScript โดยตัวอย่างนี้ให้เลือก JavaScript
  2. จากนั้นมันจะถามว่าจะให้ติดตั้ง ESLint ไหม ตรงนี้แนะนำให้ตอบ N ไปก่อน(สำหรับมือใหม่)
  3. สุดท้ายมันจะถามว่าจะให้ติดตั้ง dependencies เลยไหมก็ให้ตอบว่า Y ไป

ขั้นตอนนี้เราจะสร้าง Webhook ขึ้นมาเพื่อให้ LINE Chatbot สามารถรับข้อมูลและโต้ตอบกับผู้ใช้งานได้ผ่าน Messaging API

ใน Codelab นี้เราจะใช้ axios มาเป็นตัวช่วยในการสร้าง request ซึ่งเราจะต้องทำการติดตั้ง dependency ตัวนี้ก่อน โดยให้เปิด command line แล้วเข้าไปที่ /functions จากนั้นใช้คำสั่ง

npm install axios --save

ถัดไปเราจะสร้าง Environment Variable โดยให้ไปสร้างไฟล์ .env ใน /functions แล้วให้ไป copy ค่า Channel Access Token ของ Messaging API Channel ที่ issue ไว้ก่อนหน้านี้มาระบุลงไป

CHANNEL_ACCESS_TOKEN=YOUR-CHANNEL-ACCESS-TOKEN

จากนั้นให้เปิดไฟล์ /functions/index.js แล้วให้ copy โค้ดด้านล่างนี้ไปแทนที่โค้ดเดิม เพื่อเตรียมรับ Webhook event ประเภท text จาก LINE และตอบกลับผู้ใช้งาน

// Import dependencies
const {onRequest} = require("firebase-functions/v2/https");
const axios = require("axios");

// Create a webhook via HTTP requests
exports.webhook = onRequest(async (req, res) => {
  if (req.method === "POST") {
    const events = req.body.events;
    for (const event of events) {
      switch (event.type) {
        case "message":
          if (event.message.type === "text") {
            const msg = event.message.text;
            await reply(event.replyToken, [{ type: "text", text: msg }]);
          }
          break;
      }
    }
  }
  res.send(req.method);
});

// Create a reply function with Messaging API
const reply = (token, payload) => {
  return axios({
    method: "post",
    url: `https://api.line.me/v2/bot/message/reply`,
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.CHANNEL_ACCESS_TOKEN}`
    },
    data: { replyToken: token, messages: payload }
  });
};

แล้วก็ให้เปิด command line ขึ้นมาอีกครั้ง และให้แน่ใจว่าเราอยู่ที่ functions/ จากนั้นใช้คำสั่งด้านล่างนี้เพื่อ deploy ตัว webhook ของเราขึ้น production

firebase deploy --only functions

เมื่อ deploy เสร็จเรียบร้อยเราจะเห็น Webhook URL โผล่อยู่ใน command line เลย ก็ให้เรา copy มา หรือกรณีที่ไม่พบก็ให้เข้าไปที่ Firebase console เลือกโปรเจคที่เราสร้างไว้ แล้วเลือกเมนู Build > Functions จะเจอชื่อฟังก์ชันและ Webhook URL ที่นั่น

เมื่อได้ Webhook URL มาแล้ว ก็ให้เอา URL นี้ไปอัพเดทที่ Messaging API Channel ใน LINE Developers console ตามที่ได้สร้างไว้ และให้มั่นใจว่าได้เปิดใช้ Use webhook แล้ว

ขั้นตอนนี้เราจะไปเปิดใช้งาน PaLM API พร้อมสร้าง API Key เพื่อนำไปเชื่อต่อกับ LINE Chatbot

ให้เข้าสู่เว็บไซต์ MakerSuite

จากนั้นให้กดปุ่ม Create an API key แล้วจะพบทางเลือกที่ให้เราสร้าง API key ด้วยการสร้างโปรเจคใหม่ หรือเลือกโปรเจคที่มีอยู่แล้วใน Google Cloud ก็ได้(ถ้ามี) ซึ่งเมื่อสร้างเสร็จ เราก็จะได้ API key มา

ให้เราเพิ่มตัวแปร API_KEY ใน Environment Variable โดยเปิดไฟล์ .env ใน /functions แล้วให้เอา API key ระบุลงไป

CHANNEL_ACCESS_TOKEN=YOUR-CHANNEL-ACCESS-TOKEN
API_KEY=YOUR-PALM-API-KEY

การใช้งาน Natural Language Processing(NLP) ใน PaLM API จะมีอยู่ 2 รูปแบบ ซึ่งใน Codelab นี้จะพาทุกท่านไปเขียนโปรแกรมเชื่อมต่อทั้ง 2 แบบ โดยเริ่มจากทำการติดตั้ง dependencies 2 ตัวที่ชื่อ google-auth-library และ @google-ai/generativelanguage ก่อน โดยให้เปิด command line แล้วเข้าไปที่ /functions จากนั้นใช้คำสั่ง

npm install google-auth-library @google-ai/generativelanguage --save

เพื่อให้โค้ดในไฟล์ /functions/index.js ไม่ยาวจนเกินไป ขั้นตอนนี้จึงขอแยก module ของ PaLM API ออกมาเป็นไฟล์ /functions/palm.js โดยจะมีทั้งฟังก์ชันสำหรับ Text และ Chat services อยู่ในนี้

// Import dependencies
const { TextServiceClient, DiscussServiceClient } = require("@google-ai/generativelanguage").v1beta2;
const { GoogleAuth } = require("google-auth-library");

// Get PaLM API key from Environment Variable
const API_KEY = process.env.API_KEY;

// Text service
const text = async (prompt) => {
  const client = new TextServiceClient({ authClient: new GoogleAuth().fromAPIKey(API_KEY) });
  return await client.generateText({
    model: "models/text-bison-001",
    prompt: { text: prompt }
  });
};

// Chat service
const chat = async (prompt) => {
  const client = new DiscussServiceClient({ authClient: new GoogleAuth().fromAPIKey(API_KEY) });
  return await client.generateMessage({
    model: "models/chat-bison-001",
    prompt: {
      context: "You are a Community Manager who works with many of developer communities in Thailand and want to help developers succeed by using LINE APIs.",
      examples: [
        {
          input: { content: "What APIs does LINE provide?" },
          output: { content: "Messaging API, LIFF, LINE Login, LINE Beacon, LINE Notify, LINE Things, and LINE MINI App."},
        },
        {
          input: { content: "What can I do with the Messaging API?" },
          output: { content: "Build a chatbot to interact with users on LINE."},
        },
        {
          input: { content: "What can I do with the LIFF?" },
          output: { content: "Build a web app that run within LINE."},
        },
        {
          input: { content: "How to get started with LINE APIs?" },
          output: { content: "You can go to LINE Developers Thailand website at https://linedevth.line.me and explore APIs that fit with your use case."},
        }
      ],
      messages: [{ content: prompt }]
    }
  });
};

module.exports = { text, chat };

แล้วก็ให้เราไปอัพเดทโค้ดในไฟล์ /functions/index.js เพื่อดึงเอา module ดังกล่าวมาใช้งาน

const {onRequest} = require("firebase-functions/v2/https");
const axios = require("axios");
const palm = require("./palm"); // import palm module


Text service

จะเป็นการโต้ตอบแบบครั้งเดียว ไม่ต้องการบริบทก่อนหน้า ถามมาตอบไปแล้วจบ ซึ่งตัว AI จะใช้ความรู้ที่เรียนมาหาคำตอบมาให้เรา เช่น "Please tell me how to cook Tom Yum Kung"

ให้ปรับโค้ดในส่วนที่เช็คเงื่อนไขข้อความประเภท text เป็น

if (event.message.type === "text") {
  const result = await palm.text(event.message.text);
  const msg = result[0].candidates[0].output;
  await reply(event.replyToken, [{ type: "text", text: msg }]);
}

จากนั้นก็ deploy ผ่าน command line ด้วยคำสั่ง

firebase deploy --only functions

เสร็จแล้วก็มาทดสอบกันดูหน่อย...ผลคือ มันตอบได้ถูก ละเอียด โดยเฉพาะโค้ดก็สามารถเอาไปใช้ได้เลย


Chat service

จะเป็นการโต้ตอบไปมาแบบสนทนา สามารถระบุบริบทให้กับ AI และสามารถยกตัวอย่างบทสนทนาเพื่อให้ AI ได้เรียนรู้และเข้าใจคำตอบที่เฉพาะเจาะจงกับ use case นั้นๆได้ เช่น กำหนด context ให้ AI เป็น "You are a Community Manager who works with many of developer communities in Thailand and want to help developers succeed by using LINE APIs."

ให้ปรับโค้ดในส่วนที่เช็คเงื่อนไขข้อความประเภท text เป็น

if (event.message.type === "text") {
  const result = await palm.chat(event.message.text);
  const msg = result[0].candidates[0].content;
  await reply(event.replyToken, [{ type: "text", text: msg }]);
}

จากนั้นก็ deploy ผ่าน command line ด้วยคำสั่ง

firebase deploy --only functions

เสร็จแล้วก็มาทดสอบกันดูหน่อย...ผลคือมันเข้าใจบริบทที่เราป้อนให้ โดยมีการสร้างความรู้เกี่ยวกับเรื่องนั้นๆเสริมเข้าไปด้วย

ยินดีด้วยครับ ถึงตรงนี้คุณก็มี LINE Chatbot สำหรับการรายงานราคาทองคำเป็นของคุณเองแล้ว!!!

สิ่งที่คุณได้เรียนรู้ใน Codelab นี้

เรียนรู้เพิ่มเติม

Reference docs

บอกเราหน่อยว่า Codelab ชุดนี้เป็นอย่างไรบ้าง