Skip to content

Latest commit

 

History

History
245 lines (180 loc) · 10.8 KB

1_Workshop_1.md

File metadata and controls

245 lines (180 loc) · 10.8 KB

Workshop 1: สร้างบอตอ่อนๆ

ใน Workshop นี้ เราจะสร้างบอตที่สามารถทำนายอนาคตของคุณ โดยการสุ่มคำทำนายจากข้อมูลที่เรากำหนดไว้

Step 0: Copy โปรเจค

  1. ไปที่ https://codesandbox.io/p/devbox/fortune-teller-template-th-6kzpwn
  2. กดปุ่ม "Fork" ที่มุมขวาบนของหน้า

หลังจาก Fork แล้ว โปรเจคที่เห็นในจอจะเปลี่ยนเป็นโปรเจคที่เป็นของคุณเอง และสามารถแก้ไขได้ตามต้องการ

  1. กดปุ่ม "Share" ที่มุมขวาบนของหน้า
  2. ที่ "Change permissions" ให้เลือก "Unlisted" เพื่อทำให้โปรเจคสามารถเข้าถึงได้
  3. กดที่กล่องสี่เหลี่ยมที่มุมซ้ายบน แล้วกด "Restart Devbox"

Step 1: ตั้งค่าบอต

  1. สร้างบอตใหม่ตามขั้นตอนในไฟล์นี้
  2. หลังจากสร้างบอตเสร็จแล้ว ไปที่หน้า "Basic settings" ของบอต
  3. คัดลอก Channel secret ไปแทนที่คำว่า CHANNEL_SECRET ในไฟล์ index.js
  4. ไปที่หน้า "Messaging API" ของบอต
  5. คัดลอก Channel access token ไปแทนที่คำว่า CHANNEL_ACCESS_TOKEN ในไฟล์เดียวกัน
  6. ใน Codesandbox, กด Save (Ctrl + S), โปรแกรมจะเริ่มใหม่โดยอัตโนมัติ

Step 1.5: อธิบายโค้ดเล็กน้อยก่อนเริ่ม (ข้ามได้ถ้าเทพแล้ว)

โปรเจคที่เพิ่งก็อปไปประกอบไปด้วยไฟล์สำคัญ 2 ไฟล์ คือ

  • index.js ไฟล์หลักของโปรเจค ที่เราจะเขียนโค้ดของบอต โปรแกรมจะเริ่มทำงานจากไฟล์นี้
  • fortune.json เก็บข้อมูลคำทำนายเพื่อใช้ส่งกลับไปยังผู้ใช้

Step 2: ทำให้ "ดูดวง Bot" ตอบข้อความได้

  1. ในไฟล์ index.js, เพิ่มโค้ดต่อไปนี้ใต้ตัวแปร lineConfig
const messagingClient = new line.messagingApi.MessagingApiClient(lineConfig);

messagingClient ที่เพิ่งสร้างนี้เป็นตัวช่วยในการใช้งาน LINE เพื่อส่งข้อความกลับไปยังผู้ใช้

  1. เพิ่มโค้ดต่อไปนี้ที่ล่างสุดของไฟล์ index.js
function reply(event, ...messages) {
  return messagingClient.replyMessage({
    replyToken: event.replyToken,
    messages: messages.map(message => ({
      type: "text",
      text: message,
    })),
  });
}

ฟังก์ชั่น reply เรียกใช้ตัวช่วย messagingClient ให้เราส่งข้อความกลับไปยังผู้ใช้ได้ง่ายขึ้น

  1. และเพิ่มโค้ดต่อไปนี้ที่ล่างสุดของไฟล์ index.js ต่อจากโค้ดที่เพิ่งเพิ่มไป
function handleLineEvent(event) {
  return reply(event, "สวัสดีจากดูดวง Bot");
}
  1. กด Save
  2. ใน Codesandbox จอครึ่งขวาจะเป็น Browser ที่มีลิงค์อยู่ด้านบน ให้ Copy ลิงค์นั้นไปวางในหน้า "Messaging API" ของบอต ในช่อง "Webhook URL"
  3. กด "Update" แล้วกด "Verify" เพื่อทดสอบการเชื่อมต่อระหว่าง LINE กับบอต; ถ้าทดสอบผ่านจะขึ้นคำว่า "Success"
  4. กดเปิด "Use webhook" ถ้าหากยังไม่ได้เปิด
  5. ตั้งค่าบอทเพิ่มเล็กน้อยตามไฟล์นี้
  6. ลองส่งอะไรก็ได้ใน LINE ดู

Step 3: สุ่มคำทำนาย

  1. สร้าง constant แทนค่าดวงแต่ละประเภทเพื่อความสะดวกในการใช้งาน
const FortuneCategory = {
  Love: "love",
  Career: "career",
  Finance: "finance",
  Health: "health",
};
  1. สร้างฟังก์ชั่น getFortune สำหรับการสุ่มดวงในประเภทนั้นๆ
function getFortune(category) {
  const index = Math.floor(Math.random() * fortunes[category].length);
  return fortunes[category][index];
}
  1. สร้างตัวแปร counter ไว้เช็คว่าเราดูดวงไปกี่รอบแล้ว
let count = 1;
  1. สร้างฟังก์ชัน getAllFortuneMessages สำหรับสุ่มดวงประเภทละอัน แล้วเอามาทำเป็นข้อความ Line
function getAllFortuneMessages() {
  const fortuneMessages = [
    `ดูดวงประจำวันครั้งที่ ${count++}`,
    `ด้านความรัก\n${getFortune(FortuneCategory.Love)}`,
    `ด้านการงาน\n${getFortune(FortuneCategory.Career)}`,
    `ด้านการเงิน\n${getFortune(FortuneCategory.Finance)}`,
    `ด้านสุขภาพ\n${getFortune(FortuneCategory.Health)}`,
  ];

  return fortuneMessages;
}
  1. เปลี่ยนฟังก์ชั่น handleLineEvent ให้ตอบข้อความด้วยดวงที่เราพึ่งสุ่มมา
function handleLineEvent(event) {
  return reply(event, ...getAllFortuneMessages());
}
  1. กด Save แล้วลองส่งอะไรก็ได้ใน LINE ดู

Step 4: ส่งดวงกลับมาแค่ตอนที่เราพิมพ์ไปว่า "ดูดวง"

ถึงตอนนี้ บอตจะให้ดวงกลับมาทุกครั้งที่เราส่งข้อความไป แต่เราต้องการให้บอตตอบดวงกลับมาเฉพาะเมื่อเราพิมพ์ไปว่า "ดูดวง" เท่านั้น

  1. เปลี่ยนฟังก์ชั่น handleLineEvent ให้เช็คก่อนว่าข้อความที่ถูกส่งมาคือคำว่า "ดูดวง" รึเปล่า
function handleLineEvent(event) {
  // หยิบเอา text จาก message ใน event ออกมา
  const text = event.message.text;

  if (text === "ดูดวง") {
    return reply(event, ...getAllFortuneMessages());
  }
}
  1. กด Save แล้วลองส่งอะไรก็ได้ใน LINE ดู; ถ้าไม่ได้ส่ง "ดูดวง" บอตจะไม่ตอบอะไรกลับมา

  2. เปลี่ยนฟังก์ชั่น handleLineEvent อีกครั้งให้ส่งอย่างอื่นกลับไปถ้าข้อความที่ถูกส่งมาไม่ใช่คำว่า "ดูดวง"

function handleLineEvent(event) {
  // หยิบเอา text จาก message ใน event ออกมา
  const text = event.message.text;

  if (text === "ดูดวง") {
    return reply(event, ...getAllFortuneMessages());
  } else {
    return reply(event, "???"); // << ใส่ข้อความตรง ???
  }
}
  1. กด Save แล้วลองส่งอะไรก็ได้ใน LINE ดู

Step 99: Cheat code

สำหรับคนที่ตามไม่ทัน ก็อปโค้ดนี้ไปแทนที่โค้ดในไฟล์ index.js, เปลี่ยน CHANNEL_SECRET และ CHANNEL_ACCESS_TOKEN แล้วกด Save แล้วลองส่งอะไรก็ได้ใน LINE ดู

โค้ดเต็ม index.js
const line = require("@line/bot-sdk");
const express = require("express");
const fortunes = require("./fortune.json");

const lineConfig = {
  channelSecret: "CHANNEL_SECRET",
  channelAccessToken: "CHANNEL_ACCESS_TOKEN",
};
const messagingClient = new line.messagingApi.MessagingApiClient(lineConfig);

const app = express();
app.post("/", line.middleware(lineConfig), handlePostRequest);
app.listen(3000);

async function handlePostRequest(req, res) {
  const { events } = req.body;

  const eventHandledPromises = events.map(handleLineEvent);

  const result = await Promise.all(eventHandledPromises);

  return res.send(result);
}

function reply(event, ...messages) {
  return messagingClient.replyMessage({
    replyToken: event.replyToken,
    messages: messages.map((message) => ({
      type: "text",
      text: message,
    })),
  });
}

function handleLineEvent(event) {
  const text = event.message.text;

  if (text === "ดูดวง") {
    return reply(event, ...getAllFortuneMessages());
  } else {
    return reply(event, "ไม่เข้าใจจ้า พิมพ์ 'ดูดวง' เพื่อดูดวง");
  }
}

const FortuneCategory = {
  Love: "love",
  Career: "career",
  Finance: "finance",
  Health: "health",
};

function getFortune(category) {
  const index = Math.floor(Math.random() * fortunes[category].length);
  return fortunes[category][index];
}

let count = 1;

function getAllFortuneMessages() {
  const fortuneMessages = [
    `ดูดวงประจำวันครั้งที่ ${count++}`,
    `ด้านความรัก\n${getFortune(FortuneCategory.Love)}`,
    `ด้านการงาน\n${getFortune(FortuneCategory.Career)}`,
    `ด้านการเงิน\n${getFortune(FortuneCategory.Finance)}`,
    `ด้านสุขภาพ\n${getFortune(FortuneCategory.Health)}`,
  ];

  return fortuneMessages;
}