2-in-1 ดูราคาหุ้น Stock Token ผ่าน Google Sheet และส่งไปไลน์บอท
เราสามารถดูราคาหุ้นที่ขายอยู่ใน Stock Token ผ่าน Google Sheet ด้วย Google Finance ได้นะ แบบง่ายๆเลยหล่ะ สำหรับ developer เราจะมาเรียนรู้ในการดึงข้อมูลจาก Google Sheet เข้าไลน์บอทของเราอีกรอบนึง
แรงบันดาลใจมาจากคลิป พี่ต้า แห่ง Skooldio ที่ไปออก Mao-Investor แล้วเขาใช้ Google Finance บน Google Sheet ก็เลยนึกถึง Stock Token ใน Binance เลยลองทำดูดีกว่า
.
เนื้อหาเอาใจหลายกลุ่มมาก ทั้งอ่ะคนลงทุนในหุ้นก็ได้ ลงทุนในคริปโตก็ได้ develop ก็ได้ ชาวบ้านอ่านแล้วก็ได้ประโยชน์ แต่บางอย่างอาจจะแบบต้องมีความรู้หน่อย พยายามอธิบายให้เข้าใจง่ายที่สุดเนอะ
Stock Token คืออะไร?
Stock Token เป็นหนึ่งในบริการของเว็บไซต์เทรด cryptocurrency ชื่อดัง นามว่า Binance ใน feature นี้จะเป็นการซื้อขายหุ้นในสหรัฐอเมริกา โดยที่เราไม่ต้องไปมีบัญชีหุ้นที่โน้น และสามารถเข้าไปเทรดหุ้นได้เลย ผ่านเหรียญ BUSD (เหรียญ stable coin ของ Binance มีมูลค่าคํ้าประกันด้วยดอลลาร์สหรัฐในอัตราส่วน 1:1)
หุ้นตัวแรกที่ให้เราซื้อกันในนี้คือ TSLA (Tesla) นั่นเอง ตัวถัดมาก็คือ COIN (Coinbase) จากนั้นก็มี Microstrategy (MSTR), Apple (AAPL) และ Microsoft (MSFT) ตามลำดับ
ทั้ง 5 ตัวที่กล่าวมานี้ จะอยู่ใน NASDAQ (National Association of Securities Dealers Automated Quotations) หรือ ตลาดหุ้นแนสแด็ก เป็นตลาดหุ้นที่ใหญ่เป็นอันดับที่ 2 ในสหรัฐอเมริกา และบริษัทเทคโนโลยีชั้นนำต่างๆของโลก มักจะจดทะเบียนตลาดหลักทรัพย์ที่นี่
และหน่วยตํ่าสุดที่เราซื้อได้ก็คือ 0.01 นั่นเอง โดยระบบจะเอาเงิน BUSD ที่เราซื้อผ่านทางนี้ไปลงทุนให้ และได้ผลปันผลออกมาจ้า ในที่นี้เราไม่ได้เป็นผู้ถือหุ้นโดยตรงนะ
ความเสี่ยง เราให้เท่ากับตลาดหุ้น เนื่องจาก feature นี้กดซื้อได้ที่ราคา market เท่านั้น บวกกับเวลาคนละซีกโลกกัน ทำให้เราดอยไปแล้วทั้งสองตัวจ้า น่าจะรีบขายตัวที่ได้กำไรเนอะ ฮือออออออ แบบตลาดเปิดตอนเราจะนอนงี้
ส่วนตัวเหรียญ BUSD ไม่ได้เสี่ยงมากเท่าไหร่ เนื่องจากเป็น stable coin
การซื้อเหรียญนี้ ถ้าง่ายสุดคือซื้อผ่านระบบ P2P ใน Binance เอง หรือต้องซื้อจาก exchange ในไทยที่มีเหรียญนี้แล้วโอนเข้ามาก็ได้ โดยมีค่าธรรมเนียมการโอนอยู่ หรือซื้อเหรียญอื่นแล้วโอนเข้า Binance เพื่อเอาไปซื้อ BUSD ต่อก็ย่อมได้ แต่มันจะยากไปไหมนะนั่นสำหรับมือใหม่อ่ะ ... เอาเป็นว่ามันจะประมาณนี้แล้วกันเนอะ
แน่นอนว่าการซื้อหุ้นแบบ Stock Token นี้ จะต้องมีบัญชี Binance เสียก่อนนะ
ซึ่งมันจะต่างจากตลาดหลักทรัพย์ปกติตรงที่ เราสามารถซื้อเป็นหน่วยย่อยได้โดยไม่จำเป็นต้องซื้อหน่วยเต็มงี้ ในโลกคริปโตมันทำได้ เพื่อให้เราเข้าถึงการถือหุ้นได้ง่ายขึ้นนั่นเอง
ใช้ Google Finance บน Google Sheet กันเถอะ
จากเมื่อกี้ เราจะสรุปได้ว่า หุ้นทั้ง 5 ตัว อยู่ในตลาด NASDAQ เนอะ
เราสามารถเข้าไปส่องใน Google Finance เพื่อดูก่อนได้เลยจ้า
เข้าไปดูสักหนึ่งตัว เช่น Tesla เราก็จะเห็น detail ของหุ้นนั้นๆ ไม่ว่าจะเป็นราคา ข่าว และ stat ต่างๆ
จากนั้นเปิด Google Sheet เราจะอ้างอิงตามคลิปพี่ต้าข้างบนบางส่วนเลยว่ามีอะไรบ้าง
syntax ของตัว GOOGLEFINANCE จะเป็นดังนี้
GOOGLEFINANCE(ticker, [attribute], [start_date], [end_date|num_days], [interval])
มาดูกันทีละตัวกันนะ
ticker
: ชื่อหุ้น อันนี้จะบังคับใส่ทุกตัวเนอะ ซึ่งแน่นอนว่าจะต้องมีชื่อหุ้นเนอะ โดยจะ syntax ก็คือ{ตลาดหลักทรัพย์}:{ชื่อย่อหลักทรัพย์}
นั่นเอง ลอกจากช่องที่เราค้นหาใน Google Finance ได้เลยยยattribute
: ค่าต่างๆที่เราอยากรู้เกี่ยวกับหุ้นนั้นๆ เช่น ราคาจะใช้price
ค่าอัตราส่วนราคาต่อกำไร จะใช้pe
ค่าการเปลี่ยนแปลงราคาตั้งแต่ปิดตลาดก่อนหน้าใช้change
ถ้าอยากได้เป็นเปอร์เซ็นต์คือchangepct
นั่นเองstart_date
: วันเริ่มต้นend_date
: วันสิ้นสุดinterval
: ความถี่ในการแสดงข้อมูล ถ้าใช้รายวันให้ระบุเป็น 1 ถ้าใช้รายสัปดาห์ให้ระบุเป็น 7 โดยใส่ได้แค่ 2 ค่านี้เท่านั้น
ตัวอย่างในแต่ละช่องใน Google Sheet ชุดนี้กันเถอะ
- ราคาหุ้น :
=GOOGLEFINANCE({ticker},"price")
- ค่า PE หรือ ค่าอัตราส่วนราคาต่อกำไร :
=GOOGLEFINANCE({ticker},"pe")
ค่าสามารถเป็น N/A ได้ ถ้ามันติดลบงี้ - ค่าการเปลี่ยนแปลงราคาตั้งแต่ปิดตลาดก่อนหน้า:
=GOOGLEFINANCE({ticker},"change")
- เปอร์เซ็นต์ของค่าการเปลี่ยนแปลงราคาตั้งแต่ปิดตลาดก่อนหน้า:
=GOOGLEFINANCE({ticker},"changepct")
สามารถดูตัว document ของ GOOGLEFINANCE ได้ที่นี่เลยจ้า ซึ่งก็แล้วแต่เราว่าจะใช้สูตรสำนักไหนในการดูเนอะ
Disclammer : คือเขาบอกว่า
ข้อมูลราคาไม่ได้มาจากทุกตลาด และอาจล่าช้าได้ถึง 20 นาที ข้อมูลนี้มีให้ "ตามสภาพ" และมีวัตถุประสงค์เพื่อแจ้งให้ทราบเท่านั้น ไม่ใช่เพื่อการซื้อขายหรือเสนอแนะ ข้อจำกัดความรับผิด
ก็คือมันไม่ได้มา realtime ทันทีนะ สามารถดูว่าแต่ละตลาด delay ไปเท่าไหร่ใน document นี้นะ
ถ้าเราอยากรู้ว่าตอนนี้มีการ delay ไปเท่าไหร่ : =GOOGLEFINANCE({ticker},"datadelay")
แล้วใช้กับราคาหุ้นไทยได้ไหมนะ?
ไม่ได้อ่ะ ลองแล้ว
ทั้งๆที่ใส่ตามนี้นะ
ถ้าเจอวิธีที่ทำได้บอกด้วยเน้อ (แต่ของตลาดหลักทรัพย์แห่งประเทศไทยเขาก็มี API แหละ ใช้อันนั้นน่าจะดีกว่า)
แล้วพวกราคาของ Cryptocurrency หล่ะ?
ใช้ได้ โดยมัน reference จาก coinbase มานั่นเอง แต่ในแต่ละกระดานของ exchange นั้นมีราคาซื้อขายไม่เท่ากัน ตามแต่คนซื้อขายในกระดานนั้นๆ และตัว syntax จะสั้นมากๆเลย คือ GOOGLEFINANCE({ชื่อเหรียญ}{สกุลเงิน})
เส้นกราฟหล่ะ?
เราจะใช้สิ่งที่เรียกว่า SPARKLINE
ในการเพราะกราฟ โดย default จะเป็นกราฟเส้น ซึ่งก็เหมาะกับหุ้นเลยหล่ะ
syntax จะเป็นแบบนี้
SPARKLINE(ข้อมูล, [options])
syntax ของเขาจะประกอบด้วย 2 ส่วน คือ
- ข้อมูล : เราจะเอาอะไรมาเพาะกราฟ อันนี้ต้องใส่เนอะ โดยเราจะเอาข้อมูล
- options : การแสดงผลของกราฟ สามารถกราฟในรูปแบบต่างๆที่เราต้องการได้
สามารถอ่าน document ได้ที่นี่
ในที่นี้เราจะแสดงกราฟของราคาหุ้น ในรอบ 1 วันแล้วกันเนอะ ก่อนหน้านี้เราอยากรู้ว่าแต่ละวันราคาหุ้นเป็นเท่าไหร่
=GOOGLEFINANCE({ticket}, "price", TODAY(), TODAY()-1)
มาดูข้อมูลข้างในกันก่อน โดยจะเลือกดูหุ้นของ Apple เนื่องจากเพิ่งซื้อใน Stock Token ไป แหะๆ เพราะดูแล้วราคาไม่ได้เปลี่ยนแปลงเยอะมาก (ถ้าอ่านกราฟเป็นจะดีมากๆเลยหล่ะ) และมีให้ดู 30 วันล่าสุด
แล้วถ้าเราเพาะกราฟ เราก็จะใช้คำสั่ง SPARKLINE
ครอบข้อมูลชุดนี้นั่นเอง
=SPARKLINE(GOOGLEFINANCE({ticket}, "price", TODAY(), TODAY()-1))
ผลที่ได้จะได้กราฟมาแบบนี้
ถามว่าทำกับราคาคริปโตได้ไหม? ได้สิ ทำเหมือนกันเลย จะได้แบบนี้
แต่ด้วยตลาด cryptocurrency เป็นตลาดที่ไม่มีวันปิด ไม่เหมือนตลาดหุ้นที่มีเวลาเปิดปิด ดังนั้นจะได้ข้อมูลในทุกวัน และปิดที่เวลาจบวันนั่นเอง
ส่งข้อมูลใน Google Sheet ไปออกยัง LINE chatbot
ถามจีงงง ให้จะมาเปิด Google Sheet ตลอดเวลากันหล่ะ ไปจ้องกราฟในตลาดน่าจะดีกว่าไหม แต่เราจะใช้บอทเพื่อความสะดวกของเราเอง แหะๆ จะได้ลองทำบอทเชื่อมข้อมูลจาก Google Sheet ไปยัง LINE Bot ด้วยเนอะ
เราจะข้ามวิธีการสร้างบอทไปใน LINE OA ไปเนอะ
flow การทำงานจะเป็นประมาณนี้
เมื่อ user ถามบอท เราจะทำการนำเสนอข้อมูล 2 แบบ คือ ถ้า user พิมพ์คำว่า #stock_token
ให้แสดงข้อมูลหุ้นทุกตัวออกมาเลยในรูปแบบ carousel ของ Flex Message และเมื่อถามเพราะหุ้นตัวนั้นๆ เช่น $TSLA
หุ้น Tesla ให้แสดงข้อมูลตัวเดียวพอเป็น Flex Message
โดยเราจะใช้ webhook ที่ได้จากการสร้าง function ที่ exports มาจาก Firebase Cloud Function ไปใส่ใน LINE OA เพื่อเป็นการเชื่อมต่อ
บอทจะทำงานตาม condition ที่เราได้วางไว้ และทำการอ่านข้อมูลจาก Google Sheet ออกมาเพื่อส่งกลับออกไปให้ user
ออกแบบ Flex Message
ก่อนอื่น เราไปทำ UI การแสดงผลที่เป็น Flex Message ที่ LINE Bot Designer ก่อนเนอะ หน้าตาจะประมาณนี้
สำหรับทีมชาวบ้าน อาจจะอ่านจบแค่ตรงนี้ก็ได้แหละ เนื่องจากเนื้อหาต่อไปนี้ เป็นเนื้อหาการเขียนโปรแกรมที่มีพื้นฐานประมาณนึงแล้ว และจะไปแบบไวๆหน่อย แต่ทีมชาวบ้านสามารถออกแบบตัวหน้าตาข้อความตรงนี้ได้นะ แล้วเอาส่วน json ส่งให้ developer แล้ว define กันว่าตรงไหนอยากให้แสดงผลแบบไหน เพื่อความเข้าใจที่ตรงกันเนอะ
จากนั้นทำการดึงข้อมูลที่เราต้องการ จากใน Google Sheet กันเลย โดยเราจะไม่ใช้ inline editor ใน DialogFlow เนื่องจากเราต้องการใช้ Google Sheet API ในการดึงข้อมูลมาแสดงจ้า ตอนอ่าน document ก็เหวอเหมือนกัน แล้วฉันจะเพิ่มมันไปยังง้ายยย
ขั้นตอนการเตรียมของต่างๆ
ก่อนอื่นไปสร้างโปรเจก Firebase ก่อนนะ แล้วทำการ init project ให้เรียบร้อย~~
จากนั้นเพิ่ม Google Sheet API เข้ามาในโปรเจก โดยไปที่นี่เลย
เลือกชื่อโปรเจกที่เราสร้างมะกี้
แล้วทำการเพิ่ม Google Sheet API เข้ามาในโปรเจก โดยการเข้าไปค้นหา
เมื่อพบแล้ว กดปุ่ม enable เพื่อใช้งานมัน
พอ enable เสร็จปุ๊ปก็มีมาให้เราใช้เลยอ่ะ เอ้อมันดีย์
ก้อปปี้ชื่อ email ที่เป็น @{project_id}.iam.gserviceaccount.com
แล้วไปที่ Google Sheet ของเขา เอา email นี้เพิ่ม permission ของ Google Sheet ที่เราสร้างขึ้นมามะกี้ เป็น editor
จากนั้นทำการเตรียม sheet id เตรียมไว้ โดยดูจาก url ประมาณนี้
https://docs.google.com/spreadsheets/d/{sheet_id}/edit#gid=0
สามารถดูได้ตามนี้เลยจ้า
ไปกันต่อที่ Firebase ไปที่ฟันเฟือง setting และไปที่ Service accounts เพื่อไป download key ที่เป็น json ลงมา ชื่อว่า service-account.json
พร้อมเปลี่ยนชื่อไฟล์ เพื่อนำไปใช้ต่อไปจ้า
และสุดท้าย อย่าลืม import library ต่างๆเพิ่มเติมใน folder functions
อันเป็นที่อยู่ของ Firebase Cloud Function นะเออ มีดังนี้
- axios
- firebase-admin
- firebase-functions
- googleapis
ทำการเขียนบอทเบื้องต้น
ในที่นี้จะเป็นการเขียน bot โดยจะเขียนบน Firebase Cloud Function เนอะ เนื่องจากบอทตัวนี้จะมีหลายๆฟังก์ชั่นด้วยกัน และการรวมไว้ใน inline editor อาจจะไม่สะดวกสักเท่าไหร่เนอะ
ก่อนอื่นเรามาเขียน echo bot กันก่อน
.
- เราจะต้องดักก่อนว่า message ที่ได้มานั้น มี type เป็น
text
ถึงจะทำงานต่อ เพราะถ้าเราไม่ได้ดักไว้ อาจจะมีข้อความ type อื่นเช่น sticker จะทำให้โค้ดที่เราเขียนนั้น crash ได้จ้า
โดยตัว request.body.event[0]
ที่ได้ จะเป็นประมาณนี้ จากการทดลองรันใน Firebase Emulator นะ
- เรานำข้อความที่ได้จากการที่ user พิมพ์เข้ามา ซึ่งก็คือ
request.body.events[0].message.text
ทำการส่งกลับให้เป็น echo bot ซะ - ทำการปั้นข้อความ แล้ว reply ส่งไปให้ user โดยจะส่ง
replyToken
ไปกับตัว json ที่เป็น message
ดึงไฟล์ Google Sheet มาเข้าบอทของเรา
เนื่องจากเราเองทำหลายรอบอยู่ในการจัดโค้ด ด้วยความที่เราจะให้บอทตัวนี้มีหลาย feature เลยจะทำการแยก function ออกมาให้เป็น modular architecture ให้มากที่สุด
ดังนั้นในตอนนี้ สร้างไฟล์ google_sheet.js
ซึ่งเราจะให้มันอยู่ใน folder ที่ชื่อว่า service
นั่นเอง
ก่อนอื่น ทำการ import Google Sheet เข้ามาในโปรเจกก่อน พร้อมกับ Google Sheet ID ที่ได้มาก่อนหน้านี้
const { google } = require("googleapis");
const sheets = google.sheets("v4");
const GOOGLE_SHEET_ID = "YOUR_GOOGLE_SHEET_ID";
ทำการนำเข้าไฟล์ service-account.json
เข้ามา พร้อมทำการ create JWT เพื่อทำการ login เข้าไปอ่านเจ้า Google Sheet ด้านใน (ในส่วนนี้สามารถทำ Firebase Environment ทีหลังได้นะเออ เพราะไม่ควรอัพ key ขึ้น Github โดยตรง)
var serviceAccount = require("../service-account.json");
const jwtClient = new google.auth.JWT({
email: serviceAccount.client_email,
key: serviceAccount.private_key,
scopes: ["https://www.googleapis.com/auth/spreadsheets"]
});
ต่อมาทำการอ่านไฟล์จาก Google Sheet ของเรากันเลยจ้า โดยสร้าง function ใหม่ขึ้นมา
- ใส่ sheet id ให้เรียบร้อย
- syntax ของ
range
คือ{sheet_name}!{start}:{end}
function stockToken() {
sheets.spreadsheets.values.get({
auth: jwtClient,
spreadsheetId: GOOGLE_SHEET_ID,
range: "stock token!A2:H6"
}).then((response) => {
var data = response.data.values;
var length = data.length
console.log(data);
console.log(`${length} rows retrieved.`);
});
}
ผลที่ได้ตัว data
ของตัว sheet ออกมา โดยจะได้เป็นประมาณนี้
[
[
'NASDAQ:TSLA',
'Tesla Inc.',
'656.57',
'661.65',
'32.8',
'5.27',
'',
'0'
],
[
'NASDAQ:COIN',
'Coinbase Global, Inc.',
'226.01',
'96.69',
'3.54',
'1.59',
'',
'0'
],
[
'NASDAQ:MSTR',
'MicroStrategy Incorporated..',
'553',
'#N/A',
'-0.72',
'-0.13,
'',
'0'
],
[
'NASDAQ:AAPL’,
'Apple Inc.',
'133.7',
'30',
'-0.28',
-0.21',
'',
'0'
],
[
'NASDAQ:MSFT',
'Microsoft Corporation',
'265.27',
'26.1',
'-0.24,
'-0.09',
'',
'0'
]
]
โดยมี length
ทั้งหมดเป็น 5 นั่นเอง
สามารถอ่านเพิ่มเติมใน document ได้ดังนี้
เนื่องด้วยตัวเส้น sparkline ได้ออกมาเป็น string เปล่า จึงไม่สามารถนำมาแสดงในบอทของเราได้จ้า ;_; แต่มีปุ่มกดไป Google Finance แล้วน่าจะโอเคอยู่แหละ
ปั้นตัว Flex Message ขึ้นมา
ก่อนอื่นต้องทำความเข้าใจรูปแบบการนำ Flex Message ไปใช้ก่อนนะ
โดย format ที่ได้จาก LINE Bot Designer นั้น ถ้านำไปใส่ปั้นเป็น message เพื่อส่งออกทาง LINE จะมีหน้าตาตามนี้
จากนั้นสร้างไฟล์ line_template.js
ไว้ใน folder ที่ชื่อว่า template
เพราะอนาคาอาจจะมีของ Discord งี้ เพื่อสร้าง Flex Message และ Carousel Flex Message ตาม format ที่ถูกต้อง ดังนี้
.
output ที่เราต้องการ มี 2 แบบ คือ
- ถ้า user พิมพ์คำว่า
#stock_token
จะให้แสดงหุ้นทั้งหมดขึ้นมาในรูปแบบของ Carousel Flex Message - ถ้า user อยากดูข้อมูลหุ้นตัวเดียว เช่น
$AAPL
ก็ให้แสดงเป็น Flex Message มาตัวเดียวพอ
เราจะเริ่มจากแบบที่แก้ไขได้ง่ายแล้วกันเนอะ ที่การแสดง Flex Message อันเดียวก่อน
สร้าง function ใหม่ใน stock_token.js
ชื่อว่า setStockTokenFlexMessageJson
เป็น function เอาไว้ปั้น Flex Message ออกมานั่นเอง
ก่อนอื่น เรามากำหนดสีกันก่อน ว่าจะให้แสดงสีเขียวแบบไหน สีแดงแบบไหน ซึ่งทางเราจิ้มจาก Color Tool ของทาง Material Design นั่นเอง โดยเราให้สีของ title จะมีความเข้มกว่าสีที่เป็น body เนอะ
function setStockTokenFlexMessageJson(stock) {
//color code
const greenTextTitle = "#00701a";
const greenTextBody = "#43a047";
const redTextTitle = "#ab000d";
const redTextBody = "#e53935";
}
โดย stock
คือข้อมูลในแต่ละแถว ของหุ้นนั้นๆ เอามาปั้นเป็น Flex Message นั่นเอง
ตัดกลับไปที่ Google Sheet หวังว่าเราจะจำได้อยู่เนอะ ว่าแต่ละช่อง คือค่าอะไรบ้างนะ ซึ่ง stock
เป็น array เนอะ ดังนั้นสร้างตัวแปรให้สอดคล้องกันกับแถวของ Google Sheet
function setStockTokenFlexMessageJson(stock) {
//color code
//stock data
const stockId = stock[0];
const stockName = stock[1];
const stockPrice = stock[2];
const stockPe = stock[3];
const stockChange = stock[4];
const stockChangepct = stock[5];
const stockButtonUrl = `https://www.google.com/finance/quote/${stockId.split(":")[1]}:${stockId.split(":")[0]}`;
}
ในส่วนของ stockButtonUrl
นั้น คือ url ของ Google Finance นั่นเอง เพื่อสามารถดูกราฟหรืออะไรต่างๆเกี่ยวกับหุ้นตัวนั้นต่อไปได้นั่นเอง
ขั้นตอนต่อมาคือการแสดงสีของราคาในปัจจุบัน และการเปลี่ยนแปลงของราคา โดยราคาบวกเป็นสีเขียว ราคาลบเป็นสีแดง ตามปกติทั่วไปเลย
function setStockTokenFlexMessageJson(stock) {
//color code
//stock data
//condition for text color in Flex Message
if (stockChange > 0) {
stockTextTitleColor = greenTextTitle;
} else {
stockTextTitleColor = redTextTitle;
}
if (stockChange > 0) {
stockTextBodyColor = greenTextBody;
} else {
stockTextBodyColor = redTextBody;
}
}
จากนั้นทำการ return Flex Message ออกมาเป็น json ซึ่งโค้ดมันยาวตรงนี้แหละ ค่อยๆส่องกันแล้วกันเนอะ
.
สร้าง function ใหม่ที่ชื่อว่า setFlexMessageForStockToken
เพื่อทำการนำมาเข้า format ของ Flex Message ในการส่งออกให้ถูกต้องนั่นเอง
โดยเราจะใช้ flexMessageTemplate
จากใน line_template.js
มาช่วยประกอบร่าง ซึ่ง parameter ตัวแรกก็คือ altText
และตัวต่อมาก็คือ json ของ Flex Message ที่เราโยน data ของหุ้นแต่ละตัว ที่ได้จาก Google Sheet จาก function setStockTokenFlexMessageJson
function setFlexMessageForStockToken(stock) {
return lineTemplate.flexMessageTemplate(
`Stock Token : ${stock[0].split(":")[1]}`,
setStockTokenFlexMessageJson(stock)
);
}
สุดท้าย อย่าลืม module.exports
ออกไปด้วยนะ เพื่อนำไปใช้ใน module อื่นๆต่อไป
module.exports = {
setStockTokenFlexMessageJson,
setFlexMessageForStockToken
};
ทำการประกอบร่างกับ Flex Message
เมื่อเราทำการผลิต Flex Message มาแล้ว เราจะต้องนำมาเชื่อมกับข้อมูลที่ได้จาก Google Sheet เพื่อนำไปแสดงผลในบอทของเรานั่นเอง
กลับมาที่ google_sheet.js
ทำการ import module กันก่อน
// Firebase Cloud Function
const functions = require("firebase-functions");
// import module
const utils = require("./utils");
const lineTemplate = require("../templates/line_template");
const stockToken = require("./stock_token");
ต่อมา เปลี่ยนชื่อ function ที่สร้างตอนแรกไว้นามว่า stockToken
ให้เป็น stockTokenFlexMessage
โดยรับ replyToken
เพื่อส่งข้อความออกไป และ name
ชื่อหุ้น เข้ามาค้นหาใน Google Sheet นั่นเอง
จากนั้นนำเอา data มาวน loop เพื่อหาว่าชื่อหุ้นนี้ตรงกับแถวนี้ไหม ถ้าตรงให้ปั้น Flex Message แล้วทำการส่งข้อความออกไปนะ
function stockTokenFlexMessage(replyToken, name) {
return sheets.spreadsheets.values.get({
auth: jwtClient,
spreadsheetId: googleSheetId,
range: "stock token!A2:H6"
}).then((response) => {
const data = response.data.values;
return data.forEach(stock => {
const stockIdName = stock[0].split(":")[1].toLowerCase();
if (stockIdName === name) {
utils.reply(
replyToken,
stockToken.setFlexMessageForStockToken(stock)
)
}
});
});
}
และสร้าง function ใหม่ที่ชื่อว่า stockTokenCarousel
เพื่อแสดงข้อมูลหุ้นทั้งหมดออกมา โดยเอาข้อมูลในแต่ละแถวที่ได้มาวนลูป เพื่อสร้าง Flex Message ที่เป็น json ออกมา แล้วนำมาใส่ใน array ตัวนึง เมื่อวนลูปครบแล้วให้ทำการส่งข้อความออกไป เป็นแบบ carousel นั่นเอง
function stockTokenCarousel(replyToken) {
return sheets.spreadsheets.values.get({
auth: jwtClient,
spreadsheetId: googleSheetId,
range: "stock token!A2:H6"
}).then((response) => {
var data = response.data.values;
var allStockTokenFlexMessage = [];
data.forEach(stock => {
const flexMessageResult = stockToken.setStockTokenFlexMessageJson(stock);
allStockTokenFlexMessage.push(flexMessageResult);
}
);
return utils.reply(
replyToken,
lineTemplate.carouselTemplate("Stock Token price", allStockTokenFlexMessage)
);
});
}
และสุดท้าย อย่าลืม export ออกมาด้วย เราจะใช้ใน index.js
ในตอนสุดท้าย
module.exports = { stockTokenCarousel, stockTokenFlexMessage };
การนำไปใช้จริงในบอทของเรา
กลับมาที่ index.js
ทำการ import module กันก่อน
// import module
const googleSheet = require("./services/google_sheet");
const utils = require("./services/utils");
อันนี้อาจจะไม่ใช่วิธีที่ดีที่สุดเนอะ แต่คิดว่าพอดัก condition ได้อยู่ ที่แปลว่าได้นะ 555
มาดูโค้ดทั้งหมด เดี๋ยวจะค่อยๆอธิบายให้ฟัง
.
ก็คือก่อนหน้านี้เราดัก message type เป็น text ไป แล้วเราดัก text ที่ได้ว่า user เขาพิมพ์ว่าอะไร ถ้าเป็น #stock_token
ให้แสดงหุ้นทุกตัวออกมาเนอะ โดยให้เข้าไปทำ googleSheet.stockTokenCarousel(request.body.events[0].replyToken);
แต่ถ้าพิมพ์ $ แล้วตามด้วยชื่อหุ้น เราก็จะให้พิมพ์ $ แล้วตามด้วยชื่อเหรียญด้วยเช่นกัน (อันนี้เราอิงตามใน Twitter แหละ)
ดังนั้นเราจะต้องทำการแยกว่ามันคือหุ้นหรือเหรียญกันแน่นะ ถ้าเป็นหุ้น ให้เอาชื่อหุ้นไปหาแล้วแสดง Flex Message ออกมา ถ้าเป็นชื่อเหรียญบอกว่าไม่มีข้อมูลไปก่อน เพราะยังไม่ได้ทำ แฮร่~~
แล้วเราจะแยกชื่อหุ้นออกยังไง? อันนี้อาจจะมีวิธีที่ดีกว่านี้แหละเนอะ คือสร้าง array ชื่อหุ้นขึ้นมา
const stockTokenList = ['tsla', 'coin', 'mstr', 'aapl', 'msft'];
แล้วมา check ก่อนว่ามีตรงตามนี้ไหม?
const foundStockToken = stockTokenList.find(stockToken => stockToken === name);
ถ้าตรงกัน มันจะได้เป็น type String ออกมา โดย typeof foundStockToken === "string"
จะเป็น true
จากนั้นไปทำ Flex Message ต่อได้เลย
googleSheet.stockTokenFlexMessage(request.body.events[0].replyToken, name);
ถ้าไม่มีจะเป็น type ที่เป็น undefined เนอะ ดังนั้นในตอนนี้ให้ส่ง text message ว่ายังไม่มีข้อมูลไปก่อน เพราะในส่วนนี้เราจะมาทำการแสดงราคาเหรียญคริปโตต่างๆใน content ถัดไปนั่นเอง
utils.reply(
request.body.events[0].replyToken,
{ type: "text", text: `not have data for ${textMessage}` }
)
ตอน deploy จริง ให้เลือกที่ใกล้ที่สุดตามใน tier1 นี้นะ เนื่องจากลอง tier 2 แล้วไม่ได้แหะ อันนี้ยังไม่ได้ตามต่อว่าทำไม
ก็เลยเลือก asia-east2
เพราะฮ่องกงน่าจะใกล้ไทยสุดหล่ะ
เสร็จแล้วอย่าลืมใช้ Firebase Environment
ทำไมต้องทำ? เพราะเราต้องการ secure key ต่างๆที่ใช้ในโปรเจกเรา ดังนั้นเราจะต้อง set key ต่างๆเป็น environment variable นั่นเอง
วิธีการทำก็ตามนี้เลย แต่ไม่มีแบบให้แก้เป็น UI อ่ะ สมมุติว่าใส่ผิดงี้ เราต้องพิมพ์ key นั้นใหม่เลย
โค้ดเต็มสามารถเข้าไปดูใน branch นี้ได้เลยจ้า
demo ให้ดูนิดนึงว่าการใช้งานเป็นยังไง ถ้าดึงข้อมูลทุกตัวมันก็จะช้าๆหน่อยหน่ะ และในตอนนี้ยังไม่มี Rich Menu ดังนั้นขอทำ feature อื่นๆก่อน แล้วจะค่อยปล่อยมาให้เล่นกันน้า
Reference
ในส่วนการดึง Google Sheet API มาใช้พร้อมเชื่อมต่อ
การทดสอบใน localhost
อันนี้อ่านขั้นตอนแรกพอ
โค้ดพี่ตี๋ช่วยหนูได้เยอะเลย
carousel ของ Flex message ที่ถูกต้อง งมหานานมาก กว่าจะเจอ format ที่ถูกต้อง
https://www.ninenik.com/forum_view_3105_1.html
เป็นบล็อกที่ทำยาวนานมากเป็นเดือนๆ และตอนนี้บล็อกจบแล้ว เย้ๆ
download แอพอ่านบล็อกใหม่ของเราได้ที่นี่
ติดตามข่าวสารและบทความใหม่ๆได้ที่
ช่องทางใหม่ใน Twiter จ้า
และ YouTube ช่องใหม่จ้า