อย่างแรกเลย เตรียมอุปกรณ์ต่างๆ ให้เรียบร้อย Raspberry Pi + ลำโพง + ไมโครโฟน
ก่อนลงมือทำอย่างอื่นให้ทำการอัพเดทระบบก่อนครับ
sudo apt-get update
sudo apt-get upgrade
จากนั้นทำการติดตั้ง Node.js และติดตั้ง developer tools ต่างๆ ให้พร้อมใช้งาน
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install nodejs
sudo apt-get install sox libmagic-dev libatlas-base-dev
sudo apt-get install build-essential
กำหนด NODE_PATH เพื่อให้เรียกใช้งานโมดูลของ Node.js ที่ติดตั้งแบบ global ได้ เพราะเดียวเราจะติดตั้งโมดูทั้งหมดเป็นแบบ global
export NODE_PATH=/usr/lib/node_modules
เมื่อติดตั้งเสร็จแล้ว ลองเช็คดูก่อนว่าสามารถเรียกใช้คำสั่ง node และ npm ได้ปกติแล้ว ง่ายๆ ก็ลองสั่งให้แสดง version ขึ้นมาดูก่อนเลย
node -v
npm -v
ขั้นตอนถัดไปให้ทำการคอนฟิกและทดสอบลำโพงกับไมโครโฟน แต่ก่อนอื่นเราต้องทราบก่อนว่าทั้งลำโพงและไมโครโฟนมันต่ออยู่ที่ card id และ device id อะไร เพราะเดียวเราต้องใช้ทั้ง card id และ device id ตัวนี้ในการคอนฟิกในขั้นตอนถัดไป
ตรวจสอบหมายเลข card id และ device id ของลำโพง
aplay -l
จากรูปจะเห็นว่ามี card อยู่หลายใบ ให้สั่งเกตุหมายเลข card id และ device id ที่ผมไฮไลท์เอาไว้ด้วยนะครับ ให้เลือกใช้ card id และ device id อันที่ลำโพงเราต่ออยู่ (ข้างหลังมันมีชื่อรุ่นบอก น่าจะพอเดาได้อยู่)
ตรวจสอบหมายเลข card id และ device id ของไมโครโฟน
arecord -l
ทำการสร้างไฟล์ ~/.asoundrc เพื่อกำหนดค่า default ของลำโพงและไมโครโฟนให้ระบบ
nano ~/.asoundrc
โดยให้พิมพ์คำสั่งตามนี้ลงไป จะเห็นว่าในช่องของ playback.pcm ซึ่งก็คือลำโพงของเรา ให้เราใส่ hw:1,0 ซึ่งเป็นหมายเลข card id , device id ในที่นี้ก็คือ card 1, device 0 และสำหรับ capture.pcm ซึ่งเป็นไมโครโฟน ให้เราใส่เป็น hw:1,0 ซึ่งก็คือไมโครโฟนจาก card 1, device 0 (ถ้าหาก card id และ device id ของท่านแตกต่างจากนี้ก็ให้ใส่ให้ตรงกับของตัวเองด้วยนะครับ)
pcm.!default {
type asym
playback.pcm {
type plug
slave.pcm "hw:1,0"
}
capture.pcm {
type plug
slave.pcm "hw:1,0"
}
}
เราสามารถปรับความดังของลำโพงและไมโครโฟนได้โดยใช้คำสั่ง alsamixer (ถ้าท่านใช้ตัวแปลง USB To Sound Adapter เพื่อทำการแปลงสาย USB เป็น 3.5mm เพื่อใช้เสียบลำโพงกับไมโครโฟนแบบผม ก็ให้กด F6 เพื่อเลือก device ก่อนนะครับ)
alsamixer
ทำการทดสอบการบันทึกเสียงจากไมโครโฟน ให้สั่ง rec test.wav และพูดใส่ไมโครโฟนและถ้าต้องการหยุดให้กด CTRL+C
rec test.wav
ลองสั่ง play เสียงที่เราบันทึกไว้เมื่อสักครู่นี้
aplay test.wav
ขั้นตอนถัดไปให้ทำการติดตั้ง snowboy และโมดูลต่างๆ ที่ต้องใช้งาน โดยเราจะติดตั้งทั้งหมดเป็นแบบ global ไปเลยนะครับ
sudo npm install -S -g snowboy
sudo npm install -S -g node-record-lpcm16
sudo npm install -S -g play-sound
ต่อไปเป็นการสร้างโมเดลเสียงของคำที่ต้องการ โดยให้เข้าไปที่ https://snowboy.kitt.ai/dashboard จะเห็นปุ่ม Create Hotword คลิกเลยครับ
ทำการตั้งชื่อและเลือกภาษาให้เรียบร้อย แต่ระบบยังไม่มีภาษาไทยให้เลือกนะ ให้เราเลือกเป็น Other ไปก่อนนะ ผมลองแล้วก็ได้เหมือนกัน
ขั้นตอนถัดไปเป็นการบันทึกเสียง ให้เราบันทึกเสียงของคำที่เราต้องการลงไป 3 ครั้ง
ขั้นตอนสุดท้ายเป็นการทดสอบและดาวน์โหลดโมเดลเสียงของเรา โดยเราจะได้มาเป็นไฟล์ .pmdl ดาวน์โหลดมาเก็บไว้ให้เรียบร้อยครับ
หลังจากติดตั้งโปรแกรมและสร้างไฟล์โมเดลของเสียงเรียบร้อยแล้วให้ทำการดาวน์โหลดโค้ดที่ผมเตรียมไว้ไปทดสอบรันได้เลยครับ Download Showboy Example โดยในโค้ดตัวอย่างจะมีไฟล์ snowboy.js ให้ทำการเปิดโค้ดขึ้นมาดูก่อนเลยครับ จะเห็นว่าในตัวอย่างผมมีโมเดลของคำสั่งเสียงอยู่ 2 ตัวคือ thai-hello.pmdl และ thai-what-is-your-name.pmdl ให้เอาโมเดลเสียงของตัวเองมาแทน 2 ไฟล์นี้นะครับ
snowboy.js
const record = require('node-record-lpcm16');
const Detector = require('snowboy').Detector;
const Models = require('snowboy').Models;
const player = require('play-sound')(opts = {})
const models = new Models();
models.add({
file: 'thai-hello.pmdl',
sensitivity: '0.5',
hotwords: 'Hello'
});
models.add({
file: 'thai-what-is-your-name.pmdl',
sensitivity: '0.5',
hotwords: 'What\'s your name'
});
const detector = new Detector({
resource: "common.res",
models: models,
audioGain: 2.0
});
detector.on('silence', function() {
//console.log('silence');
});
detector.on('sound', function() {
//console.log('sound');
});
detector.on('error', function() {
//console.log('error');
});
detector.on('hotword', function(index, hotword) {
console.log('Index='+index+', Hotword='+hotword);
if(index == 1){
player.play('sound-hello.wav', function(err){
//console.log('play sound');
});
}else if(index == 2){
player.play('sound-my-name.wav', function(err){
//console.log('play sound');
});
}
});
const mic = record.start({
threshold: 0,
verbose: false
});
mic.pipe(detector);
เรียบร้อยแล้วครับ ให้สั่งรัน node snowboy.js และพูดคำสั่งที่เราตั้งไว้ได้เลยครับ
node snowboy.js
หากติดขัดปัญหาใดค้นหาข้อมูลเพิ่มเติมจาก Google และอ่านรายละเอียดได้จากแหล่งอ้างอิงครับ
หมายเหตุ : ในไฟล์ตัวอย่างระบบจะบอกว่าตัวเองชื่ออาร์เรย์ พอดีเพิ่งมาคิดชื่อบทความได้ทีหลังว่าจะใช้จาร์วิส แต่ไม่อยากกลับไปแก้เลยทิ้งไว้อย่างนั้น
อ้างอิง :
https://snowboy.kitt.ai/
http://docs.kitt.ai/snowboy/
https://github.com/kitt-ai/snowboy
https://www.npmjs.com/package/snowboy
1. การสตรีมวิดีโอไปยัง Facebook Live (Profile Account)
อันนี้เป็นการใช้แอคเค้าเฟสบุคธรรมดาของเรานี้หละครับ ซึ่งปกติเราก็กดถ่ายถอดสดจากมือถือหรือจากคอมพิวเตอร์ได้อยู่แล้ว แต่เดียวเราจะลองถ่ายถอดสดจากไฟล์หนังกันดูครับ เริ่มแรกให้เข้าไปที่ https://www.facebook.com/live/create/ และทำการคลิก Create Live Stream
เลือก Share on your own Timeline และคลิก Next
จากนั้นเราจะได้หน้าที่แสดง Server URL และ Stream Key ให้ copy ค่านี้เอาไว้ เดียวเราต้องใช้ในการสตรีม
เมื่อได้ Stream Key มาแล้ว เราก็มาสั่งสตรีมจาก ffmpeg ได้เลยครับ โดยให้สั่ง
ffmpeg -re -i test.mp4 -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://rtmp-api.facebook.com:80/rtmp/XXXXXXXXXXXXX?ds=1&s_l=1&a=ZZZZZZZZZZZZZZ"
เรียบร้อยครับ กด Go Live ได้เลย
2. การสตรีมวิดีโอไปยัง Facebook Live (Page Account)
อันนี้เป็นการใช้แฟนเพจแอคเค้าในการสตรีมนะครับ เพสบุคเขาเตรียมเครื่องมือเอาไว้ให้พร้อมแล้วเช่นกัน โดยเริ่มจากการเข้าไปในหน้าเพจของเราแล้วคลิกที่ Publishing Tools และเลือก Video Library ทางเมนูซ้ายมือ จากนั้นคลิกที่ปุ่ม + Live
ได้ Stream Key มาแล้ว กด Next
สั่งสตรีมด้วยคำสั่งต่อไปนี้ อย่าลืมแก้ Stream Key เป็นของตัวเองให้เรียบร้อยนะครับ
ffmpeg -re -i test.mp4 -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://rtmp-api.facebook.com:80/rtmp/XXXXXXXXXX?ds=1&s_l=1&a=ZZZZZZZZZZ"
กด Go Live เป็นอันเรียบร้อย
3. การสตรีมวิดีโอไปยัง Youtube Live
อันสุดท้ายเป็นการสตรีมไปยัง Youtube Live ให้เข้าไปที่ https://www.youtube.com/live_dashboard ให้เลื่อนลงมาล้างสุดจะเห็นหัวข้อ ENCODER SETUP ให้ทำการกด Reveal ระบบจะแสดง Stream name/key โดยในส่วนของ Share คือ Link ที่ใช้สำหรับดูไลฟ์จริง ส่งตัวนี้ให้เพื่อนได้เลยครับ ส่วนพารามิเตอร์ตัวอื่นๆ อย่างเช่นการใส่ภาพ thumbnail ก็ลองไปซนดูกันต่อเองครับ
จากนั้นนำ Stream name/key ที่ได้มาสั่งให้ FFmpeg สตรีมไปยัง Youtube Live โดยใช้คำสั่งต่อไปนี้
ffmpeg -re -i test.mp4 -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://a.rtmp.youtube.com/live2/XXXX-XXXXX-XXXXX-XXXXX"
เรียบร้อยไลฟ์ได้แล้วครับ สำหรับข้อมูลเพิ่มเติมดูได้จากอ้างอิงด้านล่างนะครับ
เพิ่มเติม
หากต้องการสตรีมจากกล้อง webcam ที่ต่ออยู่กับ Raspberry Pi สามารถใช้คำสั่งได้ดังนี้
ffmpeg -f video4linux2 -s 426x240 -r 30 -b 2500k -i /dev/video0 -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://rtmp-api.facebook.com:80/rtmp/XXXXXXXXXXXXX?ds=1&s_l=1&a=ZZZZZZZZZZZZZZ"
หรือสามามารถใช้คำสั่ง avconv ดังต่อไปนี้
avconv -f video4linux2 -s 426x240 -r 30 -b 2500k -i /dev/video0 -f flv "rtmp://rtmp-api.facebook.com:80/rtmp/XXXXXXXXXXXXX?ds=1&s_l=1&a=ZZZZZZZZZZZZZZ"
หรือหากต้องการสตรีมจาก RTSP อื่นๆ ไปยัง Facebook Live หรือ Youtube Live สามารถใช้คำสั่งได้ดังนี้
ตัวอย่างนี้จะสตรีมจาก RTSP อื่นไปยัง Facebook Live
ffmpeg -re -i "rtsp://192.168.1.108/rtsp/live" -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://rtmp-api.facebook.com:80/rtmp/XXXXXXXXXXXXX?ds=1&s_l=1&a=ZZZZZZZZZZZZZZ"
อันนี้ใช้สำหรับสตรีมจากกล้อง CCTV ที่ติดในบ้านไปยัง Facebook สังเกตว่าต้องเราต้องเพิ่ม -i input-sound.mp3 เข้าไปด้วยเพื่อเพิ่มเสียงเข้าไป เพราะถ้าไม่มีเสียงส่งไปด้วย Facebook จะไม่ยอมไลฟ์ให้
ffmpeg -re -i "rtsp://user:[email protected]:554/cam/realmonitor?channel=1&subtype=1" -i input-sound.mp3 -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://rtmp-api.facebook.com:80/rtmp/XXXXXXXXXXXXX?ds=1&s_l=1&a=ZZZZZZZZZZZZZZ"
อ้างอิง:
https://www.facebook.com/live/create/?step=landing
https://www.youtube.com/live_dashboard
https://ffmpeg.org/ffmpeg.html
https://www.facebook.com/facebookmedia/get-started/live
ในการเรียกใช้งาน Service ของ Google API เราต้องทำการร้องขอ Access Token ไปยัง Server ของทาง Google เพื่ออนุญาตให้แอพที่เราสร้างสามารถเข้าถึง Service ที่เราระบุเอาไว้ได้ ซึ่งเมื่อเราได้ Access Token มาแล้วเราสามารถที่จะใช้ Access Token ตัวนี้ในการเรียกใช้ API ต่างๆ ได้ ซึ่งในบทความนี้เราจะทำการเรียกใช้ Google Drive API
มาลองทดลองทำจริงเลยดีกว่าครับ เริ่มแรกเลยให้ทำการดาวน์โหลดโค้ดทั้งหมดจาก Github ลงมาก่อน https://github.com/LookHin/google-drive-api จากนั้นทำการเปิดใช้งาน Google Drive API โดยคลิกเข้าไปที่ Enable Google Drive API จากนั้นเลือกสร้างโปรเจคใหม่ หรือเลือกโปรเจคเก่าที่เรามีอยู่แล้วก็ได้
คลิก Create credentials และเลือก OAuth client ID
ในช่อง Application type ให้เลือกเป็น Other และช่อง Name ให้ใส่เป็นชื่อที่เราต้องการ และคลิก Create
หลังจากคลิก Create แล้วระบบจะแสดง Client Id และ Client secret ขึ้นมาให้ ให้เรา copy รหัสทั้ง 2 ตัวนี้ไปใส่ในไฟล์ authorize.php และ example.php
$strClientId = "YOUR_CLIENT_ID";
$strClientSecret = "YOUR_CLIENT_SECRET";
ทำการ Authorize โดยเรียก authorize.php จากบราวเซอร์ เช่น http://YOUR_SERVER/google-drive/authorize.php และทำการคลิก Allow เพื่อทำการอนุญาติให้แอพที่เราสร้างสามารถเข้าถึงข้อมูลใน Google Drive ได้
หลังจากคลิก Allow แล้วระบบจะแสดง Refresh Token ขึ้นมาให้ ให้ทำการ copy รหัสตัวนี้ไปใส่ในไฟล์ example.php
$strRefreshToken = "YOUR_REFRESH_TOKEN";
เพียงเท่านี้โปรแกรมของเรา ที่เราเขียนไว้ในไฟล์ example.php ก็พร้อมที่จะทำงานได้แล้วครับ แต่ก่อนอื่นมารู้จักกับ File Id และ Folder Id ที่ใช้ภายใน Google Drive กันก่อน ในระบบของ Google Drive จะอ้างอิงถึงไฟล์และโฟลเดอร์ต่างๆ ผ่านทาง Id ฉะนั้นเวลาเราจะสร้างโฟลเดอร์ใหม่ หรือทำการอัพโหลดเข้าไปในโฟลเดอร์ต่างๆ เราต้องรู้ก่อนว่าโฟลเดอร์นั้นมี Id เป็นอะไร โดยวิธีที่ง่ายที่สุดก็คือเปิดเข้าไปที่ Google Drive และคลิกเลือกไปที่โฟลเดอร์ที่ต้องการ เราจะเห็น Id ของโฟลเดอร์นั้นๆ แสดงเป็น URL ดังรูป
ตัวอย่าง: จากตัวอย่างของโค้ด ผมทำตัวอย่างการแสดงไฟล์ สร้างโฟลเดอร์ ลบไฟล์และโฟลเดอร์ และอัพโหลดไฟล์ไว้ให้แล้ว ลองเล่นกันดูครับ
setAccessTokenFromRefreshToken($strRefreshToken);
// List File From Root Folder
$arrFile = $obj->ListFileAndFolder("root");
print_r($arrFile);
// # List File From Folder Id
//$arrFile = $obj->ListFileAndFolder("_PARENT_FOLDER_ID_");
//print_r($arrFile);
// # Create Folder In Root Folder
//$obj->CreateFolder("root", "_NEW_FOLDER_NAME_");
// # Create Folder In Parent Folder
//$obj->CreateFolder("_PARENT_FOLDER_ID_", "_NEW_FOLDER_NAME_");
// # Delete File & Folder
//$obj->Delete("_FILE_OR_FOLDER_ID_");
// # Upload File To Root Folder
// $arrResult = $obj->Upload("root", "no-face.png");
// print_r($arrResult);
// # Upload File To Parent Folder
// $arrResult = $obj->Upload("_PARENT_FOLDER_ID_", "no-face.png");
// print_r($arrResult);
?>
อ้างอิง :
https://github.com/LookHin/google-drive-api
https://developers.google.com/identity/protocols/OAuth2WebServer
https://developers.google.com/drive/v3/reference/files
https://developers.google.com/drive/v3/web/resumable-upload
โดยระบบที่เราจะทดสอบทำกันวันนี้ จะเป็นการรอรับข้อความจากผู้ใช้และตอบกลับข้อความนั้นๆ ด้วยข้อความที่เราเตรียมไว้ และทำการส่งข้อความหาผู้ใช้ที่แอ็ดเป็นเพือนกับบอทของเราเพื่อใช้สำหรับสร้างระบบแจ้งเตือนต่างๆ เช่นแจ้งผู้บุกรุก แจ้งราคาน้ำมัน แจ้งราคาทองอะไรประมาณนั้น
มาเริ่มกันเลย ในการสร้าง LINE Bot ให้เราล๊อกอินเข้าไปที่ LINE Business Center และทำการกรอกข้อมูลและลงทะเบียนให้เรียบร้อย อันนี้ทำเองนะครับ พอดีผมไม่ได้ print screen หน้าจอเอาไว้ เข้าไปทำอีกรอบไม่ได้ ฮาาา
เมื่อลงทะเบียนเสร็จแล้วให้เข้าไปที่เมนู Service -› Messaging API และคลิกที่ปุ่ม Start using Developer Trial
อัพเดท: เนื่องจากทาง LINE มีการแก้ไขในส่วนของการลงทะเบียน Messenger API รูปในบทความนี้อาจจะไม่ตรงกับหน้าลงทะเบียนใหม่ ให้ท่านใช้บทความนี้เป็นแนวทางในการศึกษาและอ่านเอกสารและวิธีลงทะเบียนได้จากลิงค์นี้นะครับ https://developers.line.me/en/services/messaging-api/ ส่วนขั้นตอนการเขียนโปรแกรมยังสามารถใช้งานได้เหมือนเดิม
ทำการตั้งชื่อบอท เลือกรูปภาพ และกรอกข้อมูลอื่นๆ ให้เรียบร้อย จากนั้นกดปุ่ม OK ด้านล่าง
ตรวจสอบข้อมูลต่างๆ ให้เรียบร้อยแล้วกด Apply
เมื่อสร้างเรียบร้อยแล้วให้คลิกที่ LINE@ Manager
จากนั้นกดที่ปุ่ม “ใช้ API” และกด “ยืนยัน” (อ้าว ภาษาไทยได้ไงหว่า)
จะเห็นว่าตอนนี้เราสามารถใช้งาน API ได้ 2 ฟังชั่นคือ REPLY_MESSAGE และ PUSH_MESSAGE โดยสามารถดูรายละเอียดการใช้งานทั้ง 2 ฟังชั่นนี้ได้จาก REPLY_MESSAGE และ PUSH_MESSAGE คลิกเข้าไปดูจะเห็นว่าเขียนไม่ยากครับ แค่รอรับและส่งข้อมูลกลับไปกลับมาเท่านั้น
ในหน้านี้จะเห็นว่าด้านขวามือมีชื่อของบอทของเราอยู่ พร้อมกับ LINE@ ID ของบอท เราสามารถแอ็ดเฟรนจาก ID นี้เลยก็ได้ หรือจะใช้ QR Code ในขั้นตอนถัดไปก็ได้ครับ และในส่วนของการตั้งค่าให้เลือก webhook เป็น “อนุญาต” และเลือก Bot เข้าร่วมกลุ่มแชท, ข้อความตอบรับอัตโนมัติ, คำทักทายเริ่มต้นสำหรับการเพิ่มเพื่อนใหม่ เป็น “ไม่อนุญาต” ทั้งหมด แต่ถ้าหากใครจะลองเปิดไว้ก็ได้นะครับ ทาง LINE เขามีระบบตอบรับข้อความอัตโนมัตไว้ให้อยู่แล้ว แทบไม่ต้องทำอะไรเพิ่มเลย เมื่อเลือกเสร็จแล้วกด “บันทึก” เมื่อกดบันทึกเรียบร้อยแล้วให้กดที่ LINE Developers ต่อได้เลยครับ เดียวเราต้องไปใส่ URL ของ webhook ในหน้านั้นอีกที
ในหน้านี้จะเห็นว่ามี QR Code เราสามารถใช้ QR Code ตัวนี้เพื่อทำการแอ็ดเฟรนกับบอทได้เลยครับ หรือจะแอ็ดโดยใช้ LINE@ ID จากหน้าที่แล้วก็ได้ แต่ ID มันสุ่มมาให้อาจจะพิมพ์ตามยากหน่อย และในหน้าเดียวกันจะเห็นว่าในช่อง Webhook URL ยังไม่มีค่าอะไร ให้กด Edit
ทำการใส่ Webhook URL ของเราลงไปครับ URL ตรงนี้จะเป็น URL ที่ใช้รับข้อความจาก LINE โดยจะต้องเป็น HTTPS เท่านั้นนะครับ
หลังจากที่เราใส่ Webhook URL เข้าไปแล้ว ขั้นตอนถัดไปเป็นขั้นตอนการหา Access Token เพื่อเอาไปใช้กับโปรแรกมของเรา ให้คลิกเข้าไปที่ ISSUE ระบบก็จะแสดง Access Token ขึ้นมาให้
เอาหละ เกือบเสร็จแล้ว ขั้นตอนถัดไปคือการเขียนโปรแกรมครับ copy โค้ดตามนี้และทำความเข้าใจกันเอาเองอธิบายไม่ถูกหละ โดยโค้ดชุดนี้จะเป็นการรอรับข้อความที่ถูกส่งเข้ามา และเราจะตอบกลับข้อความนั้นกลับไปว่า ID ของเขาชื่ออะไร หรือหากว่าใครจะเพิ่มคำสั่งอื่นลงไปก็เพิ่มเข้าไปเองเลยครับ และเราจะต้องใช้ ID ตัวนี้ในการส่งข้อความแจ้งเตือนโดยไม่ต้องรอให้ผู้ใช้ทักเข้ามาด้วย (ดูโค้ดแล้วทำการแก้ไข ACCESS_TOKEN เป็น Token ของตัวเองให้เรียบร้อยนะครับ)
หลังจากเขียนโค้ดและอัพโหลดขึ้นเซิฟเวอร์เรียบร้อยก็ลองทักบอทของเราได้เลยครับ มันตอบคำถามได้บ้างหละ
ขึ้นตอนถัดไปเราจะทำระบบ Push message ฟังชั่นนี้เอาไว้ทำระบบแจ้งเตือนต่างๆ เช่นการแจ้งเตื่อนผู้บุกรุกจากอุปกรณ์ IoT หรือแจ้งเตือนราคาน้ำมัน ราคาทองอะไรก็แล้วแต่ โดยเราต้องใช้ ID ของผู้รับจากขั้นตอนที่แล้วในการส่ง เราอาจจะเก็บ User ID ลง Databsae เพื่อเอามาไว้ใช้ทีหลังอะไรก็แล้วแต่นะครับ แต่สำหรับโค้ดตัวอย่างนี้ผมจะใส่ User Id ลงไปตรงๆ (แก้ ACCESS_TOKEN และ USER_ID ให้เรียบร้อยและลองรันได้เลยครับ)
หลังจากตรงนี้ไป ก็ไปต่อยอดกันเอาเองครับ แล้วแต่จินตนาการกันเช่นเคย
อ้างอิง :
https://developers.line.me/messaging-api/getting-started
https://developers.line.me/en/services/messaging-api/
https://developers.line.me/console/register/messaging-api/provider/
https://devdocs.line.me/en/
ในการทดลองการดักจับข้อมูลครั้งนี้ เราจะให้ทั้งคอมฯ และมือถือต่ออยู่ใน Wi-Fi เน็ทเวิร์คเดียวกัน โดยเราจะใช้ Burp Suite Free Edition ซึ่งสามารถหาดาวน์โหลดได้จาก Burp Suite Free Edition เป็นโปรแกรมที่ทำหน้าที่เป็น proxy แต่ผมไม่ลงวิธีการติดตั้งนะครับตัวใครตัวมัน
หลังจากติดตั้งเรียบร้อยแล้ว ให้เปิดโปรแกรม Burp Suite Free Edition และเข้าไปที่แท็บ Proxy -› Options และเลือก Add เพื่อตั้ง proxy ใหม่
ทำการกำหนด Bind to port เป็น 8089 (ปกติก็คงเป็น 8080 แต่พอดีผมใช้มันไปทำอย่างอื่นแล้ว) และเลือก Bind to address เป็น All interfaces เมื่อใส่ค่าทุกอย่างเรียบร้อยก็คลิก OK
Windows Firewall จะขึ้นมาถามยืนยันการใช้งานพอร์ทให้กด Allow access
ถ้าในช่อง Running ในส่วนของ proxy ที่เราสร้างไว้ยังไม่ถูกติ๊กเป็นเครื่องหมายถูก ก็ติ๊กให้มันทำงานด้วยครับ
และในแท็บ Intercept ให้เลือก Intercept เป็น Off
จากนั้นมาที่มือถือ Android โดยให้เข้าไปที่ Setting -› Wi-Fi กดค้างที่ Wi-Fi ที่เราต่อเอาไว้แล้วเลือก Modify network
เลือก Show Advanceed options ติ๊กเลือก Show advance options และเลือก Proxy เป็น Manual และใส่ค่าต่างๆ ดังนี้
Proxy hostname = ให้ใส่ IP ของเครื่องคอมฯ ที่เราติดตั้ง Burp Suite ไว้
Proxy port = ใส่หมายเลข port ที่เรากำหนดไว้ใน Burp Suite
จากนั้นกด Connect
ขั้นตอนถัดไปคือการติดตั้ง CA Certificate ของ Burp Suite ลงในเครื่อง Android ให้เราพิมพ์ URL http://burp บนบราวเซอร์ของ Android และคลิกที่ปุ่ม CA Certificate เพื่อทำการดาวน์โหลด เมื่อทำการดาวน์โหลดมาแล้วจะได้ไฟล์ชื่อ cacert.der ให้ทำการเปลี่ยนนามสกุลของไฟล์เป็น cacert.cer
ทำการติดตั้ง CA Certificate โดยเข้าไปที่ Setting -› Advanced settings -› Security และเลือก Install from SD card
เลืกไฟล์ cacert.cer และทำการตั้งชื่อ Cartificate name
ที่หน้า Setting -› Advanced settings -› Security คลิกที่แท็บ Trusted credentials และเลือกแท็บ User จะเห็นว่ามี CA Certificate ใหม่ของเราติดตั้งไว้แล้ว เป็นอันเสร็จเรียบร้อย
ต่อไปมาเริ่มทำการทดสอบกันเลยครับ ว่ามันสามารถดักข้อมูลที่วิ่งผ่าน HTTP/HTTPS ได้จริงไหม โดยให้เปิดบราวเซอร์และพิมพ์ url ที่เป็น HTTPS ลงไป ในตัวอย่างก็เทสจากเว็บผมเองนี้หละ จะเห็นว่า HTTPS ก็ยังเป็นสีเขียวอยู่
กลับมาดูที่หน้า Burp Suite ในแท็บ HTTP history จะเห็นว่ามีข้อมูลที่วิ่งไปยังเว็บของเราแล้ว
ทีนี้ลองเปิดแอพบน Android ขึ้นมาครับ ตัวอย่างนี้ผมเลือกใช้แอพของไปรษณีย์เพราะอยากรู้ว่าเขาส่งข้อมูลไปตรวจสอบสถานะของพัสดุที่ไหน โดยลองกรอกรหัสที่ใช้ตรวจสอบพัสดุ EMS ลงไปดูนะครับ หรือหากใครจะลองแอพตัวอื่นก็ได้เช่นกัน เอาจากของไทยๆก่อนนี้หละครับ ง่ายดี
กลับมาดูที่หน้า HTTP history จะเห็นว่ามีข้อมูลวิ่งที่ยังเซิฟเวอร์ของไปรษณีย์ไทยแล้วครับ (อ้าว มี username กับ password ติดมาด้วย อันนี้ไม่ได้ตั้งใจ อยู่นอกเหนือจากที่ผมคิดไว้ ฮาาา)
]]>
ในขั้นตอนการติดตั้งจะแนะนำเฉพาะบน Windows เท่านั้นนะครับ สำหรับผู้ที่ใช้ Linux น่าจะมีพื้นฐานมากกว่าอยู่แล้ว และขั้นตอนการติดตั้งก็ไม่ยากนักคิดว่าคงทำกันได้หมด
ติดตั้ง youtube-dl โดยให้เข้าไปดาวน์โหลดที่ https://rg3.github.io/youtube-dl/ ให้คลิกไปที่เมนู Download และเลือก youtube-dl.exe หลังจากดาวน์โหลด ให้นำไปไว้ที่ c:\youtube-dl\
ติดตั้ง FFmpeg โดยเข้าไปที่ https://ffmpeg.org/download.html และเลือก Windows Packages จะมีลิงค์ไปหน้าดาวน์โหลดสำหรับ Windows ที่ https://ffmpeg.zeranoe.com/builds/ เมื่อดาวน์โหลดมาแล้วให้ unzip และนำไปไว้ที่ c:\ffmpeg\
จากนั้นทำการคอนฟิก Enviroment Variable Path ของ windows โดยให้เข้าไปที่ Control Panel -› System and Security -› System -› Advanced system Setting และเลือกที่ Enviroment Variables
ในส่วนของ System variables ให้เลือกไปที่ Path และเลือก Edit
ทำการเพิ่ม path ของ youtube-dl และ ffmpeg เข้าไปดังรูป
เมื่อเรียบร้อยแล้วให้ลองเปิด command และพิมพ์คำสั่งดังต่อไปนี้ เพื่อตรวจสอบ version กันก่อน ถ้าทุกอย่างเรียบร้อย น่าจะขึ้นประมาณนี้
youtube-dl --version
ffmpeg -version
และก่อนใช้งานทุกครั้งเราควรสั่ง youtube-dl -U เพื่อทำการ update โปรแกรมให้เป็น version ใหม่สุดอยู่เสมอ
สำหรับการดาวน์โหลดวิดีโอจาก youtube เราสามารถโหลดได้ทั้งแบบเป็น playlist และที่เป็นวิดีโอเดี่ยวๆ โดยสามารถใช้คำสั่งได้ดังต่อไปนี้
แบบเป็น playlist
youtube-dl --no-check-certificate --ignore-errors "https://www.youtube.com/playlist?list=PL6B3937A5D230E335"
แบบแยกเป็นรายวิดีโอ
youtube-dl --no-check-certificate "https://www.youtube.com/watch?v=YE7VzlLtp-4"
สำหรับ facebook ก็สามารถโหลดได้เช่นกันโดยใช้คำสั่งดังต่อไปนี้
youtube-dl --no-check-certificate "https://www.facebook.com/DevExp/videos/1378097708883662/"
และสำหรับวิดีโอที่เราซื้อคอร์สออนไลน์ไว้บน udemy เราสามารถโหลดทั้งคอร์สมาได้ โดยใช้คำสั่งดังต่อไปนี้
youtube-dl -u username -p password -o "%(chapter_number)s-%(chapter)s/%(autonumber)s-%(title)s.%(ext)s" "https://www.udemy.com/java-tutorial/"
ในกรณีที่ดาวน์โหลดวิดีโอลงมาแล้ว ไฟล์ที่ได้อาจจะเป็นไฟล์ .mkv หรือนามสกุลอื่นๆ เราสามารถทำการแปลงฟอร์แมตของไฟล์ได้โดยใช้ ffmpeg โดยให้สร้างโฟลเดอร์ใหม่ขึ้นมาก่อน ในที่นี้ผมจะตั้งชื่อโฟลเดอร์ว่า new-mp4 เอาไว้เก็บไฟล์ที่ได้จากการแปลง และใช้คำสั่งสำหรับการแปลงเป็น mp4 ดังนี้
ffmpeg -i old-video-file.mkv -vcodec libx264 -profile:v high -acodec aac ./new-mp4/new-video-file.mp4
หรือหากว่าต้องการแปลงทั้งโฟลเดอร์ให้ใช้คำสังดังต่อไปนี้
FOR /F "tokens=*" %G IN ('dir /b *') DO ffmpeg -i "%G" -vcodec libx264 -profile:v high -acodec aac "./new-mp4/%~nG.mp4"
อ้างอิง: https://github.com/rg3/youtube-dl/blob/master/README.md
]]>
ในการใช้งานแบบฟรีเราสามารถอัพโหลดได้ 4MB ต่อภาพ และใช้งานได้ฟรี 1,000 หน่วยต่อเดือน (หน่วยในทีนี้ผมเข้าใจว่าหมายถึงจำนวนการร้องขอการตรวจสอบ เช่นถ้า 1 ภาพเราต้องการให้ตรวจสอบทั้ง Text และ Landmark ก็จะนับเป็น 2 หน่วย) ถ้ามากกว่านั้นก็ต้องเสียตังค์ (ก็สมเหตุสมผล ใช้มากก็ต้องใช้เงินแก้ปัญหาไป)
ขั้นตอนการสมัครเข้าใช้งาน Google Cloud Vision API ให้เข้าไปที่ Cloud Platform Console และคลิกที่ปุ่ม CREATE PROJECT
ตั้งชื่อโปรเจคและใส่ข้อมูลต่างๆ ให้เรียบร้อย
จากนั้นทำการเปิดใช้งาน Cloud Vision API โดยคลิกที่ลิงค์นี้และเลือกโปรเจคที่เราสร้างไว้เมื่อสักครู่ Enable Cloud Vision API
ขั้นตอนถัดไปให้สร้าง API Key โดยให้คลิกเข้าไปที่เมนูรูปแฮมเบอร์เกอร์ด้านซ้ายมือและเลือกไปที่ API Manager และคลิกไปที่เมนู Credentials จากนั้นให้ทำการคลิกที่ Create Credentials และเลือกเป็น API Key
หลังจากนั้นเราจะได้ API Key มาชุดหนึ่ง ให้กด RESTRICT KEY และก็กด Save ในหน้าถัดไปเลยครับ
หลังจากได้ API Key มาแล้ว เราก็มาถึงขั้นตอนการเขียนโปรแกรมหละ ให้ดาวน์โหลดตัวอย่างรูปภาพและโค้ดที่ผมเตรียมไว้ลงไปก่อนครับ google-cloud-vision-api.zip (รูปตัวอย่างผมขโมยมาจากเน็ท ฮาา) เมื่อโหลดมาแล้วจะเห็นไฟล์ google-cloud-vision.php อันนี้เป็นตัวอย่างโค้ดที่ผมเตรียมไว้ให้ ให้ทำการเปลี่ยน API_KEY เป็นของตัวเองนะครับ
จากนั้นสั่งรันโค้ด เราจะได้ค่าผลลัพธ์กลับมาเป็น JSON เป็นอันเรียบร้อย
อ้างอิง : https://cloud.google.com/vision/docs/
]]>
แต่สำหรับกรณีของ instagram นี้ยากหน่อย เพราะเขาทำการ encrypt ข้อมูลด้วย secret key ที่อยู่ภายในแอพก่อนแล้วค่อยทำการส่งข้อมูลนั้นออกมา การหา secret key และวิธีเข้ารหัสอะไรนี้ผมเองก็ทำไม่เป็นหรอกนะ แต่พอดีว่าผมไปเห็นโค้ดของคนอื่นใน Github ที่เขาแกะข้อมูลทุกอย่างไว้หมดแล้ว แต่โค้ดเขาเยอะมาก มากเกินความต้องการของเรา ผมเลยเอาโค้ดของเขามารีไรท์ใหม่ และตัดให้เหลือแค่ส่วนที่ตัวเองต้องการใช้งาน นั้นคืออัพโหลดรูปปละวิดีโอ การแกะโค้ดคนอื่นก็ดีครับได้ทบทวนความรู้ตัวเองไปด้วย ถ้าใครสนใจอยากดูโค้ดของเขาก็เข้าไปดูได้ครับ โค้ดเขาอยู่ที่นี้ Instagram’s private API
บทความนี้สั้นๆ นะครับ แค่จะโชว์โค้ด และเดโมการอัพโหลดรูปและวิดีโอขึ้น instagram ให้ดู ส่วนการทำงานของโค้ดว่ามันทำงานยังไงก็ไปอ่านเอาเองครับ ไม่น่ายากเกินความพยายาม โดยคลาสที่ผมเขียนขึ้นมาใหม่จะไม่มีส่วนของการ crop รูปภาพ และแปลง format ของวิดีโอนะครับ ให้ไปทำกันเอาเอง โดยวิดีโอที่ผมทดสอบจะเป็น MP4 (H264)
อ่านตรงนี้ก่อนสำคัญมาก! การจะใช้งานสคริปนี้ได้เราต้องทำการปิดการใช้งาน Two-Factor Authentication ของ Instagram ก่อน โดยให้เข้าไปที่ https://www.instagram.com/accounts/two_factor_authentication/ จากนั้นเอาเครื่องหมายถูกหน้าคำว่า Two-Factor Authentication ออกดังรูป
มาเริ่มเลย อย่างแรกเข้าไปเอาซอสโค้ดและตัวอย่างทั้งหมดมาจาก Github ที่ผมแก้ไขโค้ดและเอาขึ้นไว้ที่ https://github.com/LookHin/instagram-photo-video-upload-api
เมื่อโหลดมาหมดแล้วจะเห็นว่ามีไฟล์ทั้งหมดอยู่ 5 ไฟล์ดังนี้
example.php //ตัวอย่างโปรแกรม
instagram-photo-video-upload-api.class.php //คลาสที่เรียกใช้งาน
square-image.jpg //ตัวอย่างรูปภาพ ขอให้เป็นภาพสี่เหลี่ยมจัตุรัสนะครับ
square-thumb.jpg //ตัวอย่างรูปภาพ thumbnail ที่จะใช้กับวิดีโอ ขอให้เป็นภาพสี่เหลี่ยมจัตุรัสเช่นกัน
test-video.mp4 //ตัวอย่างวิดีโอ เป็นไฟล์ MP4 (H264)
เปิดไฟล์ example.php ขึ้นมา จะเห็นมีอยู่แค่ไม่กี่บรรทัด คือใช้เท่านี้จริงๆ ส่วนการทำงานเบื่องหลังจะอยู่ในไฟล์ instagram-photo-video-upload-api.class.php ทั้งหมด อย่างแรกเลยให้ทำการแก้ไข YOUR_IG_USERNAME และ YOUR_IG_PASSWORD เป็น username และ password ที่เราใช้ในการ login เข้า instagram ถ้าได้แก้ไขเรียบร้อยแล้วก็สั่งรันได้เลยครับ (ผมทดสอบบน PHP 5.6 และ PHP 7)
include_once("instagram-photo-video-upload-api.class.php");
// Upload Photo
$obj = new InstagramUpload();
$obj->Login("YOUR_IG_USERNAME", "YOUR_IG_PASSWORD");
$obj->UploadPhoto("square-image.jpg", "Test Upload Photo From PHP");
// Upload Video
$obj = new InstagramUpload();
$obj->Login("YOUR_IG_USERNAME", "YOUR_IG_PASSWORD");
$obj->UploadVideo("test-video.mp4", "square-thumb.jpg", "Test Upload Video From PHP");
เมื่อสั่งรันแล้ว เราจะได้รูปภาพและวิดีโอตัวอย่างไปขึ้นที่ Instagram ของเราแล้วครับ
]]>
หลังจากไปหาซื้อมาแล้วก็แกะกล่อง ใช้ไขขวงดันๆ เดียวมันก็หลุดออกมาครับ (หลุดพร้อมประกัน)
ตรงกลางๆ ของแผ่นวงจรจะเห็นมีรูให้บัดกรีขาอยู่ 5 ขา ให้เอาก้างปลามาบัดกรีให้เรียบร้อย (ถ้าเป็นรุ่นก่อนหน้านี้จะมีอยู่ 4 ขา ซึ่งจริงๆ เราก็ใช้แค่ 4 ขานั้นหละ ส่วนขาที่ 5 เป็น GPIO14 เผื่อว่าเราอยากต่อเซ็นเซอร์อะไรเพิ่มเติม) โดยถ้ามองจากด้านบนจะมีตำแหน่งของขาต่างๆ ดังนี้
GPIO14
GND
TX
RX
VCC 3.3V
เมื่อบัดกรีขาต่างๆ เรียบร้อยแล้ว ให้ทำการต่อ Sonoff กับ USB To UART เพื่อทำการเขียนโปรแรกมลงไป โดยให้ต่อขาต่างๆ ดังนี้
[Sonoff] --> [USB To UART]
VCC --> VCC (3.3V)
RX --> TX
TX --> RX
GND -->GND
หลังจากต่อวงจรเสร็จเรียบร้อยให้ทำการกดสวิตซ์สีดำค้างเอาไว้ และเสียบสาย USB เข้ากับคอมพิวเตอร์เพื่อทำการโปรแกรม (ต้องกดค้างก่อนเสียบสายด้วยนะครับ สำคัญมากๆ) โดยให้เขียนโค้ดต่างๆ ดังนี้
โดยให้ใส่ SSID และ Password ของ WI-FI ของเราลงไป และเราจะเขียนโปรแรกมให้ฟิกค่า IP ของอุปกรณ์เอาไว้เพื่อความสะดวกในการเรียกใช้งาน (คงไม่สะดวกแน่ๆ ถ้าจะให้มันรับ DHCP เข้ามา) ดาวน์โหลดโค้ดตัวอย่าง
const char* ssid = "WIFI_SSID";
const char* password = "WIFI_PASSWORD";
const IPAddress ip(192, 168, 1, 100); // IP ของอุปกรณ์ตัวนี้ 192.168.1.100
const IPAddress subnet(255, 255, 255, 0);
const IPAddress gt(192, 168, 1, 1);
#include
#include
const char* ssid = "WIFI_SSID";
const char* password = "WIFI_PASSWORD";
const IPAddress ip(192, 168, 1, 100);
const IPAddress subnet(255, 255, 255, 0);
const IPAddress gt(192, 168, 1, 1);
const int SwitchPin = 12; // GPIO12
int SwitchValue = HIGH;
ESP8266WebServer server(80);
void handleNotFound(){
//server.send(404, "text/plain", "404 Not Found");
if(SwitchValue == HIGH) {
server.send(200, "text/plain", "ON");
}else{
server.send(200, "text/plain", "OFF");
}
delay(1000);
}
void setup(void){
// Set Output PIN
pinMode(SwitchPin, OUTPUT);
digitalWrite(SwitchPin, SwitchValue);
// Connect WiFi
WiFi.mode(WIFI_STA);
WiFi.config(ip, gt, subnet);
WiFi.begin(ssid, password);
// Wait for connection
while(WiFi.status() != WL_CONNECTED){
delay(1000);
}
server.on("/", [](){
if(SwitchValue == HIGH) {
server.send(200, "text/plain", "ON");
}else{
server.send(200, "text/plain", "OFF");
}
delay(1000);
});
server.on("/ON", [](){
SwitchValue = HIGH;
server.send(200, "text/plain", "ON");
digitalWrite(SwitchPin, SwitchValue);
delay(1000);
});
server.on("/OFF", [](){
SwitchValue = LOW;
server.send(200, "text/plain", "OFF");
digitalWrite(SwitchPin, SwitchValue);
delay(1000);
});
server.onNotFound(handleNotFound);
server.begin();
}
void loop(void){
server.handleClient();
}
เพื่อความสะดวกในการนำไปติดตั้งใช้งานจริง เราจะหาแม่เหล็กกระดุมมาติดกับฐานของบอร์ทเอาไว้ เพื่อจะได้เอาไปติดกับโคมไฟเพดานง่ายๆ หน่อย แม่เหล็กขนาดนี้หาซื้อได้จากคลองถมนะครับ ตัวละ 15 บาท แต่ถ้าใครไม่มีก็หาวิธีติดเอาเอง เอากาวสองหน้าก็ได้
หลังจากอัพโหลดโปรแกรมเรียบร้อยแล้ว ให้ทำการประกอบทุกอย่างลงกล่องให้เหมือนเดิมและนำไปใช้งานได้ (ที่สำคัญให้ต่อสาย L กับ N ให้ถูกทั้งขาเข้าและขาออกด้วยนะครับ)
ทดสอบสั่งเปิดปิดไฟ โดยเปิดบราวเซอร์และพิมพ์ IP ของ Sonoff WiFi Smart Switch ที่เราคอนฟิกไว้ตอนเขียนโปรแกรม ดังนี้
http://192.168.1.100/ON
http://192.168.1.100/OFF
ก่อนจบ: ข้อเสียอย่างหนึ่งของ Sonoff Smart Switch คือว่ามันใช้ Relay ธรรมดา ทำให้เวลาเปิดปิดวงจรจะมีเสียงนิดหน่อย ถ้าเป็นไปได้ผมว่าจะหา Solid State Relay มาเปลี่ยนอยู่ //แต่ก็แพง
]]>
ขั้นตอนการทำก็แบ่งออกเป็น 2 ขั้นตอนใหญ่ๆ คือ
1. สร้าง Telegram Bot
2. เขียนโปรแกรมบน ESP8266 เพื่อส่งข้อความมายัง Telegram ของเรา (ในบทความนี้จะใช้ ESP-01 และใช้สวิตซ์เป็นอินพุต ในการใช้งานจริงให้เปลี่ยนจากสวิตซ์ไปเป็น PIR Sensor หรือหากว่าต้องการรับอินพุตที่เป็น Analog ให้เปลี่ยนไปใช้ ESP-07 หรือ ESP-12 ที่มีขา ADC มาให้นะครับ)
สำหรับการสร้าง Telegram Bot ให้เราทำการเพิ่ม @BotFather เป็นเพื่อนกับเราก่อน ซึ่งเราจะต้องสั่งให้ @BotFather สร้างบอทให้เรา (ไม่เข้าใจเหมือนกันว่าทำไมเขาไม่ให้ทำผ่านหน้าเว็บ แต่เขาให้ทำในนี้ก็ทำไปครับ)
เมื่อเพิ่ม @BotFather เป็นเพื่อนแล้ว เราจะเห็นคำสั่งต่างๆ ขึ้นมาให้เราใช้งาน ลองพิมพ์ /help ระบบจะแสดงคำสั่งต่างๆ ขึ้นมาให้
ทีนี้ให้เราสร้าง Bot โดยใช้คำสั่ง /newbot ซึ่งระบบจะให้เราใส่ชื่อที่จะใช้เรียกบอทของเรา และให้ใส่ username ของบอท ซึ่งตรง username นี้จะต้องไม่ซ้ำกับคนอื่นและจะต้องลงท้ายด้วย bot เท่านั้น (ตัวอย่างผมจะใช้ชื่อบอทว่า SmartHomeABC123 และใช้ username ว่า SmartHomeABC123Bot) เมื่อสร้างเสร็จแล้วระบบจะแสดง Access Token ขึ้นมาให้เรา Token ตัวนี้จะใช้สำหรับการส่งข้อความนะครับ จดไว้ๆ
จากนั้นให้เราทำการเพิ่มบอท @SmartHomeABC123Bot เป็นเพื่อนของเราก่อน และลองทักมันไปสัก 1 ครั้ง จะเห็นว่าไม่มีอะไรขึ้นมา ไม่ต้องตกใจ อ่านข้อต่อไปครับ สิ่งที่เราต้องการไม่ได้ให้มันตอบกลับ แต่เราต้องการ ID ของเราเอง เพื่อใช้ในการส่งข้อความกลับ
จากนั้นให้พิมพ์คำสั่งนี้ที่ browser หรือหากใครใช้ CURL เป็นก็ตามสะดวก ออ อย่าลืมเปลี่ยนตรงคำว่า <ACCESS_TOKEN> เป็น Access Token ของบอทตัวเองด้วยนะครับ
https://api.telegram.org/bot<ACCESS_TOKEN>/getUpdates
สำหรับฟอร์แมตของคำสั่งจะเป็น https://api.telegram.org/bot<ACCESS_TOKEN>/API_COMMAND นะครับ สามารถอ่านข้อมูลเพิ่มเติมได้ว่าเราสามารถสั่งอะไรได้บ้างจาก Link นี้ครับ https://core.telegram.org/bots/api
หลังจากสั่ง /getUpdates เราจะได้ข้อมูลของข้อความและ id ของผู้ส่ง ซึ่งเดียวเราจะใช้ id ตรงนี้ในการนำไปใช้ในการส่งข้อความจาก ESP8266 ต่อไป (ถ้าสั่ง /getUpdates แล้วไม่มีข้อมูลอะไรขึ้น ให้ลองพิมพ์ข้อความทักบอทของเราไปอีกรอบ บาททีเราอาจจะเว้นช่วงนานไปจนข้อความนั้นหมดอายุไปก่อน)
หลังจากนั้นลองทำการส่งข้อความจากบอทของเรากลับมาหาเราหน่อยโดยใช้คำสั่ง CURL ถ้าใครใช้ CURL ไม่เป็นหรือไม่ได้ลงไว้ก็ข้ามไปเลยครับ อันนี้ผมทำให้ดูเฉยๆ โดยเราจะส่งเป็นพารามิเตอร์ text และ chat_id เป็น method post เข้าไป
curl -X POST https://api.telegram.org/bot/sendMessage -d text="test test" -d chat_id="" -k
เย้ๆ ส่งข้อความได้แล้ว
ขั้นตอนถัดไป เรามาเขียนโปรแกรมเพื่อส่งข้อความบน ESP8266 กันต่อ โดยผมจะใช้ ESP-01 เป็นตัวทดสอบ โดยจะให้กดสวิตซ์บนบอร์ตแล้วให้ส่งข้อความออกไป อันนี้ไม่ยากลอกโค้ดแล้วไปทำความเข้าใจกันเอา
อย่ากแรกต่อวงจรตามนี้ก่อน โดยให้ต่อ ESP-01 เข้ากับ USB To UART เพื่อทำการเขียนโปรแกรมลงไป และต่อสวิตซ์แบบ pull-up เข้ากับขา GPIO-2 ส่วนรายละเอียดอื่นๆ ตามนี้ครับ
[ESP-01] --> [USB To UART]
RX --> TX
TX --> RX
VCC --> VCC (3.3v)
CH_PD --> VCC (3.3v)
GNC --> GND
GPIO-0 --> GND
GPIO-2 --> ต่อ pull-up กับสวิตซ์
เขียนโค้ดบน Arduino และทำการ upload sketch เข้าไปที่ ESP-01 ที่เราต่อวงจรเตรียมเอาไว้ เมื่อเรียบร้อยแล้วก็ทดสอบกดสวิตซ์ ระบบจะทำการส่งข้อความมาหาเราที่ Telegram ของเราแล้วครับ (Download Source Code)
โดยจากโค้ดให้แก้บรรทัดดังต่อไปนี้ โดยให้ใส่ค่าต่างๆ ตามที่เราได้มาจากขั้นตอนก่อนหน้านี้นะครับ
const char* ssid = "WIFI_SSID";
const char* password = "PASSWORD123";
const String AccessToken = "";
String PostData = "text=แจ้งเตือน: สวิตซ์บน ESP8266 ถูกกด&chat_id=";
#include
#include
// WIFI SSID & Password
const char* ssid = "WIFI_SSID";
const char* password = "PASSWORD123";
// Telegram Server API
const int httpsPort = 443;
const char* host = "api.telegram.org";
const String AccessToken = "";
const int SwitchPin = 2; // GPIO2
int SwitchOldStatus = HIGH;
int SwitchNewStatus = HIGH;
void setup(void){
Serial.begin(9600);
pinMode(SwitchPin, INPUT);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Wait for connection
while(WiFi.status() != WL_CONNECTED){
delay(500);
}
}
void loop(void){
// Read Data From Switch
SwitchNewStatus = digitalRead(SwitchPin);
if(SwitchNewStatus == LOW && SwitchNewStatus != SwitchOldStatus){
String PostData = "text=แจ้งเตือน: สวิตซ์บน ESP8266 ถูกกด&chat_id=";
WiFiClientSecure client;
Serial.print("connecting to ");
Serial.println(host);
if (!client.connect(host, httpsPort)) {
Serial.println("connection failed");
return;
}
// POST
client.print(String("POST ") + "/bot" + AccessToken + "/sendMessage HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"User-Agent: ESP8266-Notification\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"Cache-Control: no-cache\r\n" +
"Content-Length: " + String(PostData.length()) + "\r\n" +
"\r\n" +
PostData);
// Header
Serial.println("-------Response Header-------");
while (client.connected()) {
String line = client.readStringUntil('\n');
if (line == "\r") {
break;
}
Serial.println(line);
}
// Body
Serial.println("-------Response Body-------");
String body = client.readStringUntil('\n');
Serial.println(body);
}
SwitchOldStatus = SwitchNewStatus;
delay(500);
}
หลังจากทำการ upload sketch ให้ลองเปิด Serial Monitor ขึ้นมาดู Log และทดสอบกดสวิตซ์ดูได้เลยครับ จะเห็นว่ามีข้อมูลถูกส่งออกไปยัง API ของ Telegram แล้ว
ขั้นต่อไปก็เอาไปใช้งานจริง ให้ถอดตัว USB To UART ที่เราใช้ upload sketch ออกและต่อวงจรดังรูป
[ESP-01] --> [Battery]
VCC --> VCC (3.3v)
CH_PD --> VCC (3.3v)
GNC --> GND
GPIO-2 --> ต่อ pull-up กับสวิตซ์
หมายเหตุ: ปกติผมจะส่งข้อมูลจากเซ็นเซอร์ไปยัง Raspberry Pi ที่ทำหน้าที่ควบคุมทั้งระบบก่อน แล้วค่อยส่งจาก Raspberry Pi ออกไปยัง service อื่นๆ ข้างนอกอีกทีนะครับ เพราะถ้าต้องมาแก้ไขข้อความหรือเปลียน Access Token ผมคงแก้ไขจากฝั่งของ Raspberry Pi น่าจะง่ายกว่ามานั้ง upload sketch ใหม่
]]>