ขั้นตอนการทำระบบ PageFeed

ขั้นตอนการทำระบบ PageFeed

จุดเริ่มต้นของระบบนี้ก็คือ ผมเป็นคนที่อ่าน Post ของ Facebook Page ต่างๆผ่านทาง RSS Feed มานาน โดยเมื่อก่อน จะใช้วิธีการในการแปลง URL ของ Page ต่างๆ แล้วเอาไปเรียกผ่าน www.facebook.com/pages/feed.php ก็ไม่มีปัญหาอะไร จนกระทั่งเมื่อวันที่ 23/07/2558 ที่ผ่านมา ก็ไม่สามารถอ่านข้อความไม่ได้อีก ตรวจสอบพบว่า Facebook ปิด Feature นี้ไปแล้ว เพราะว่าต้องการให้ใช้งานผ่าน Graph API/{page-id}/feed ของ facebook เท่านั้น ทีนี้ปัญหาเกิดทันที เพราะว่าการใช้งานผ่าน Graph API นั้น ต้องมีกระบวนการให้ได้มาซึ่ง Access Token ของ Facebook ก่อน ไม่อย่างนั้นจะเรียกใช้งาน Feature นี้ไม่ได้ (บางตัวของ Graph API ของ Facebook ก็ไม่จำเป็นต้องใช้ แต่ว่าตัวนี้จำเป็นครับ)

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

หาโดเมนก่อน

แน่นอนว่าเราต้องมี Domain สักอันเพื่อให้เข้าใช้งานระบบนี้ได้ แต่ว่าไม่อยากจดใหม่ เพราะโดเมนในมือมีอยู่เยอะแล้ว ก็เลยเอาโดเมนมาสร้าง sub domain แล้วเอามาใช้ก็แล้วกัน นั่นคือโดเมน pagefeed.siam.cc ก็เข้าไปชี้ A Record เข้าไปที่ VPS ส่วนตัวเลย

เมื่อได้โดเมนแล้ว ก็ต้องหา Server

พอดีมี VPS เปิดทิ้งไว้เยอะแยะ หยิบเอามาใช้งานสักตัว VPS ตัวนี้อยู่ที่ LA, USA ที่ใช้ของต่างประเทศ เหตุผลคือ มันถูก แค่นั้นแหล่ะครับ (ปีละ $19 ได้ Ram 2GB ,CPU 1 Core , HDD 50GB) จริงๆแล้ว อีกส่วนหนึ่งเป็นเพราะว่า ระบบนี้ไม่ได้ใช้คนเดียวด้วย ตั้งเป้าเอาไว้ว่าให้ใช้กันทั่วโลกไปเลย ดังนั้น เว็บไหนที่ตั้งเป้าให้เข้าใช้งานได้เร็วจากทั่วทั้งโลก ไม่ควร Host ในไทยครับตัดทิ้งไปได้เลย แล้วการ Host ต่างประเทศโดยเฉพาะ USA นั้น ผมค้นมาแล้วว่า มี LA นี่แหล่ะ ที่ค่อนข้างจะเร็วแล้วเพราะอยู่ใกล้ ASIA เรามากแล้ว (ประมาณว่าเป็น ศูนย์กลางแห่งหนึ่งของ Internet ที่อยู่ใกล้ ASIA) แล้ว เวลาอ่าน Graph API facebook การใช้ Server ต่างประเทศจะทำให้เข้าถึงได้เร็วกว่า และทำงานบางอย่างที่ต้องติดต่อกับ Server ต่างประเทศได้เร็วกว่ามากทีเดียว อย่างเวลาผม Deploy งาน Server ในไทยใช้เวลา 15 - 120 วินาที แต่ว่า Server ต่างประเทศ 5-30 วินาที ต่างกันเยอะ สรุปต่างประเทศ Work ที่สุดแล้ว สำหรับงานนี้

แน่นอนว่าเป็น Linux ครับ CentOS 6.x เนื่องจาก VPS ตัวนี้ไม่ได้ใช้งานมาระยะหนึ่งแล้ว ดังนั้น สิ่งแรกที่ต้องทำก็คือ Update software ต่างๆให้ทันสมัยก่อนเลย ด้วยคำสั่ง

yum update

เพื่อให้มั่นใจว่า server ใช้ software ที่ใหม่สดจริงๆ แน่นอนว่า หนึ่งในนั้นมี openssl ที่เป็นข่าวดังเหลือเกิน แต่ก็มีตัวอื่นๆอีกหลายตัวที่ update ไปพร้อมกันนี้ด้วย

ติดตั้ง PHP , MariaDB

Project นี้ตั้งใจว่าจะใช้เวลาพัฒนาสั้นๆ เพื่อให้เสร็จเร็วๆ ดังนั้น ก็ติดตั้ง PHP ก่อนเลย โดยเลือกเป็น PHP 5.4 ซึ่งต้องใช้ Package พิเศษ เพราะว่า Package PHP เดิมๆ ของ Centos 6 ยังเป็น PHP 5.3 อยู่ ซึ่งมันเก่ามากกกกก จริงๆคือ PHP 5.3 หมดอายุการ Support ไปแล้ว ดังนั้น ใครที่ยังใช้อยู่ให้เลิกใช้ได้แล้วครับ ส่วน Database แน่นอนว่า ต้อง MariaDB ถูกเอามาใช้งานแทน MySQL ที่ผมเลิกใช้มาระยะหนึ่งแล้ว ซึ่งมันก็ทำงานทดแทน MySQL ได้เลยเป็นอย่างดีอีกต่างหาก (Feature ต่างๆเพิ่มมาเยอะเลย) ใครที่ยังใช้ MySQL 5.5 หรือเก่ากว่าก็เลิกใช้ได้แล้วนะครับ

จากนั้น สั่งติดตั้ง PHP ด้วยคำสั่ง

yum install php54w php54w-common php54w-devel php54w-pdo php54w-mysqlnd php54w-xml

อ้อ ลืมบอก ผมใช้ Package จาก webtatic.com นะครับ จะได้ง่ายและเร็วครับ และถ้าสงสัยว่าทำไมไม่ใช้ PHP 5.5 ไปเลย … จริงๆเป็นเพราะผมยังไม่เคยเทส 5.5 ของเค้าเลยว่า work หรือเปล่า เลยใช้ 5.4 ไปก่อน แต่เดี๋ยวงานหน้าขึ้น PHP 5.5 ไปเลยครับ

จากนั้นติดตั้ง MariaDB ด้วยการสร้าง ไฟล์ Repo มาก่อน ดังนี้

vi /etc/yum.repos.d/MariaDB.repo

แล้วใส่เนื้อหาดังนี้

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.0/centos6-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

จากนั้น ก็สั่งติดตั้งเลย รอไม่นาน เพราะว่า VPS อยู่ต่างประเทศ เร็วกว่าการสั่งติดตั้ง Server ที่ตั้งในไทยอย่างเห็นได้ชัดเลย

yum install MariaDB-server MariaDB-client

สำหรับ คนที่มี Error ให้ดูว่ามันบอกว่า Error อะไร อย่างของผม Error เพราะว่า Package ชนกับ MySQL เดิม (ของเดิมมีติดตั้ง MySQL อยู่ก่อนแล้ว) ก็ทำการลบออกให้หมดแล้วค่อยสั่งติดตั้งครับ จนกว่าจะจบแบบไม่มี Error
เมื่อเรียบร้อย ก็ทำการ Start MySQL

/etc/init.d/mysql start

เมื่อ Start แล้ว ก็เข้า MySQL ผ่าน Command line ได้ทันที

mysql -uroot 

ก็จะเข้ามาเลย สังเกตุได้ว่า เราไม่ต้องใส่รหัสผ่านดังนั้น สิ่งแรกที่ต้องทำ ก็คือการตั้งรหัสผ่านให้ Root ก่อนเลย

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('cleartext password');

จากนั้น ก็สร้าง Database , สร้าง User ใหม่ , Grant สิทธ์ให้ เพราะเราจะไม่ใช้ Root Account ในการทำงานครับ

CREATE DATABASE newdatabase;
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON * . newdatabase TO 'newdatabase'@'localhost';

แล้วทดสอบด้วยการ Login ดู

mysql -unewuser -p

แล้วใส่รหัสผ่าน ถ้าผ่าน เป็นอันจบครับ ทั้งนี้ อาจจะสงสัยว่าใช้ MariaDB แต่ทำไมคำสั่งเป็นของ MySQL ทั้งหมดเลย อย่างที่บอกนะครับว่า MariaDB ทดแทน MySQL ได้เกือบทั้ง 100% ดังนั้นเรื่องพื้นฐานอะไรต่างๆก็ทำงานได้เหมือนกันทั้งหมดครับ คำสั่งเลยเป็นเหมือนกันหมดเลย

ชี้โดเมนเข้า server

หลังจากที่เราได้ point dns A record ของโดเมน เข้าไปที่ IP ของ VPS ตั้งแต่ตอนแรกแล้วนั้น เราต้องไปตั้ง VHOST ใน /etc/httpd/conf/httpd.conf ให้รับโดเมนด้วย เวลาเรียกหน้าเว็บระบบจะได้รู้ได้ว่า ต้องเรียกไฟล์จากไหนขึ้นมาแสดง

NameVirtualHost *:80
<virtualHost *:80>
    ServerAdmin b@entercm.com
    DocumentRoot "/path/your/file/in/server"
    ServerName pagefeed.siam.cc
    ErrorLog "/var/log/httpd/pagefeed.siam.cc.com-error_log"
    CustomLog "/var/log/httpd/pagefeed.siam.cc.com-access_log" common
</VirtualHost>

แล้วก็ Restart httpd สักที ตอนนี้ server พร้อม โดเมน พร้อม หมดเวลาไป 36 นาทีแล้ว

เขียนโค้ด
เนื่องจาก ผมจะมี CMS ส่วนตัว ที่พัฒนามาจาก CodeIgniter Version 3.0 (พึ่งยกเครื่องใหม่มาสดๆร้อนๆ) เปิด Sublime สร้าง Project ใหม่ เปิด database localhost เครื่องตัวเอง สร้าง database ใหม่ ตั้ง httpd ในเครื่องตัวเอง แล้วชี้ URL l.pagefeed.com เข้าเครื่องตัวเอง ปกติ ผมจะใช้ URL local หน้าตาแบบนี้ในขั้นตอนการพัฒนาเว็บ เพราะมันจะลดปัญหาเรื่องการอ้างอิง Path file ไปได้มากครับ เวลาใช้ http://localhost/website แบบนี้ยุ่งยากมีปัญหาบ่อยๆ เสียเวลาครับ

สำหรับวิธีการ ง่ายมาก ผมใช้ XAMPP แบบ Portable นะครับ เริ่มต้นให้เปิด

/xampp/apache/conf/extra/httpd-xampp.conf

แล้วเพิ่มชุดนี้ไปด้านล่าง

<VirtualHost *:80>
    ServerAdmin webmaster@l.pagefeed.com
    DocumentRoot "fullpath\to\your\website\in\your\computer"
    ServerName l.pagefeed.com
    ErrorLog "path/to/your/website/in/your/computer/log/l.pagefeed.com-error.log"
    CustomLog "path/to/your/website/in/your/computer/log/l.pagefeed.com-access.log" common
</VirtualHost>

มี \ เพราะผมเขียนโค้ดบน Windows นะครับ อ้างอิงด้วย \ ได้ครับ อื่นๆ ก็จะเห็นได้ว่าเหมือนกับที่เรา Set บน httpd.conf ใน linux นั่นแหล่ะ

จากนั้น สร้าง repo ที่ git server (ผมใช้ของ bitbucket.org ฟรีครับ) แล้วสร้าง repo เครื่องตัวเอง จากนั้นทดสอบ Code CMS ที่ copy มาว่าทำงานได้ แล้วจึง initial commit แล้ว push ขึ้น git server เป็นอันว่า เราได้เว็บในเครื่องเรา และสำเนาเข้าไปเก็บที่ git server เรียบร้อยแล้ว

setup website

หลังจากที่เรียบร้อยก็ทำการ deploy โค้ดลง server พร้อมเอา database ขึ้น เพื่อดูว่าทุกอย่างทำงานได้ตามปกติหรือเปล่า ประมาณว่าทำเทสระบบว่าทุกอย่างทำงานสอดประสานกันได้ปกติดี เพราะหากมีปัญหาก็จะได้แก้ตั้งแต่ตอนนี้เลย ซึ่งเจอปัญหาหลายจุดพอสมควรครับ เรื่องนึง มาจาก Facebook ทำการเพิ่ม Version Graph API ผมก็เลยย้ายไปใช้ Version ใหม่ล่าสุดเลย ส่งผลให้การทำงานหลายอย่าง โดยเฉพาะส่วนของ Authen เปลี่ยนไปจากเดิมพอสมควร ก็ต้องค่อยๆซ่อมกันไป

แล้วยังตรวจสอบพบว่า Mod rewrite ไม่ทำงาน วิธีแก้ไขคือ ตั้ง AllowOverride all ใน /etc/httpd/conf/httpd.conf (ของเดิมเป็น none) แล้วสั่ง restart httpd เป็นอันใช้ได้

tail -f ของไฟล์ Apache log แล้วลองใช้งานถ้าไม่พบ error อื่นใดเพิ่มเติม และหน้าเว็บทำงานได้ครบทุกส่วนใน Function เริ่มต้นที่ได้เขียนเอาไว้เป็นอันผ่าน

ถึงตรงนี้ เสร็จเฉพาะส่วนพื้นฐานทั้งหมดใช้เวลา 1 ชั่วโมง 24 นาที (งานหน้าจะทำให้เร็วกว่านี้ครับ ช้าเพราะว่าติดขัดหลายอย่าง) ขั้นต่อไป เราก็จะเริ่มเขียนระบบจริงกันแล้ว

สร้าง facebook App ID

สร้างได้จาก https://developers.facebook.com/ เพราะว่าการที่เราจะต้องเรียก Facebook Access Token ออกมาได้นั้น เราจะต้องมี App ID, App Secret ด้วย

สร้าง Google Analytics

แน่นอน เป็นเครื่องมือการวัดผลการแสดงหน้าเว็บ ที่ฟรี และดี www.google.com/analytics สร้างเป็น Property ใหม่ใน Account เดิมที่เคยมีอยู่ (ไม่จำเป็นต้องสร้าง Account ใหม่ทุกครั้ง)

ทดสอบ authen app ด้วย facebook login

เปิดมาก็ไม่ผ่านซะแล้ว เพราะว่า facebook return มาแค่ name, id เท่านั้น ไม่พอใช้ในระบบ (เมื่องานก่อน ยังใช้งานได้ปกติดี) ตรวจสอบรายละเอียดจึงพบว่า facebook เพิ่ม API version ใหม่ 2.4 ทำให้เราต้อง query field ที่ต้องการด้วยตัวเองเท่านั้น จากเดิมที่จะส่งมาให้เกือบหมดเลย ก็ต้องซ่อมจนทำให้ระบบ Authen facebook login ได้ และเก็บข้อมูลได้ถูกต้อง

POC การอ่าน page post
เราต้อง fetch page post มาให้ได้ เลยเขียนเข้าไปอ่าน feed ออกมาจาก Graph API /{page-id}/post เพื่อดูว่าระบบทำงานเป็นอย่างไรบ้าง และทำให้พบปัญหาว่า ระบบยังไม่ได้เขียนตัวเก็บ Access token ซึ่งมีความจำเป็นในการเข้าไปดึง page/feed ออกมา ทำให้ก่อนการเรียก /page/feed ระบบต้องเสียเวลาไปทำ oauth เพื่อขอรับ Access Token ใหม่ทุกครั้ง ดังนั้น ก็เขียนตัวเก็บ Access Token เอาไว้ใช้ชั่วคราว สำหรับการ Login ครั้งนั้นๆ หรือจนกว่า Token จะหมดอายุ ก็จะให้ระบบไปขอมาเก็บใหม่

ท้ายที่สุด ก็สำเร็จระบบอ่าน page post ออกมาได้แล้ว แล้วก็เลยเขียนต่อยอดเพื่อให้มันเก็บเข้า database ไปด้วยเลยทีเดียว เวลาจะเอามาใช้ก็จะได้อ่านออกมาจาก database ตรงๆเลย

มี bot วิ่งเข้าเครื่อง

นั่งดู Access log อยู่ก็เห็นว่ามี Bot วิ่งเข้ามาในเครื่อง ทั้งๆที่ยังไม่ได้ Promote หรืออะไรเลย ตรวจสอบ ต้นทางมาจาก เยอรมันนี เลยต้องรีบไปเพิ่ม vhost ให้ http://IP ชี้เข้า default page ไปก่อนเลย ไม่งั้นเดี๋ยวจะยุ่งยากทีหลัง

POC อ่าน Feed แล้วเก็บลง database

หลังจากที่ทุกอย่างเรียบร้อยแล้ว ก็ทำการเขียนโค้ดต่อ เพื่อให้เอา Page post เก็บลง database ได้ถูกต้อง โดยแยกแยะได้ว่า Post ไหนเป็นของ Page ไหน และเช็คด้วยว่า ถ้าข้อความที่ได้รับมานั้นซ้ำแล้ว ก็จะไม่เก็บลง database อีกต่อไป เพื่อไม่ให้เสียเวลา ก็ผ่านไปได้ด้วยดี

ถึงตรงนี้ผ่านไปแล้ว ห้าชั่วโมงเศษๆ เริ่มหมดแรง 555 ก็เลยพักไปกินข้าว กลายเป็นพักยาวเลย

ทำหน้าจอจัดการ page ของตัวเอง

เนื่องจากไม่ได้ขอ permission page_likes ทำให้ต้องทำตัวจัดการ Page แบบ Manual เอง ก็คือ ผู้ใช้งานต้องป้อน Page URL เข้ามาเอง แล้วให้ระบบทำการตรวจสอบ ว่าถูกต้องหรือเปล่า โดยรูปแบบที่จะเรียก Page ได้ถูกต้อง ก็มีหลายรูปแบบพอสมควร ก็ต้องตรวจสอบให้ครบถ้วน ถ้าเกินกว่านั้นก็ Reject ออกไป ตรงนี้ทำเสียเวลาพอสมควร เพราะว่าต้องค้นหา pattern ก่อน แล้วก็เอามาตัด string เพื่อให้เหลือส่วนที่ต้องการเพื่อเอาไปใช้งานต่อ แต่สมองก็เริ่มตื้อๆละ ทำงานไป แว้บดู Youtube ไป 555

ส่วนนี้ เป็นส่วนที่ค่อนข้างเสียเวลา เพราะว่าทำให้มันทำงานเป็นแบบ AJAX เพราะจะได้ไม่ต้อง Redirect ไปมาเยอะแยะ จบในหน้าเดียวเลย ก็เลยต้องเขียนๆเทสๆ เยอะหน่อย อีกอย่างที่ทำให้ยุ่งยากก็คือ มันต้องไปอ่าน Graph API ตลอด ทำให้ทดสอบในเครื่องตัวเองไม่ได้ ต้องเขียนข้างล่าง Push งานขึ้นข้างบนแล้วค่อยเทส

ตรงนี้ ก็ใช้ไปอีก ครึ่งชั่วโมงกว่า ไม่นานอย่างที่คิด แต่เสียเวลาทดสอบ นี่แหล่ะ (อันนี้ คนละวันกันแล้ว เพราะเมื่อวานหมดแรงก่อน)

ทำหน้า RSS Feed

อ่าน Page ได้แล้ว ทำระบบจัดการ Page เสร็จแล้วก็ทำการเพิ่มหน้าแสดงผล data RSS Feed ของแต่ละ Facebook page ซึ่งตรงนี้ ก็จะถูกนำไปใช้งานต่อใน RSS reader software ตัวอื่นๆต่อไป โดยมาตรฐานที่ใช้ก็คือ RSS 2.0 ขั้นตอนนี้ไม่ยากเท่าไร เพราะว่าก็แค่ดึงข้อมูลขึ้นมาจาก database แล้วจัด Format ให้เป็นมาตรฐานเท่านั้นเอง และ set header ให้เป็น RSS เท่านั้น จบเลย

ใช้ไปอีกหนึ่งชั่วโมง รวมทั้ง Project นี้ 6 ชั่วโมงครึ่งเข้าไปแล้ว

เขียนระบบ fetch ข้อมูลจาก page ต่างๆ และทำให้เป็นระบบอัตโนมัติ

ขั้นตอนนี้ก็ต่อยอดจากของเดิม ที่ได้เขียน function เพื่อไปอ่าน page post มาเก็บแล้ว ก็ปรับปรุงนิดหน่อย ด้วยทำการทำให้อ่าน Access token ขึ้นมา แล้วไล่ อ่านแต่ละ page เพื่อเอาเข้ามาเก็บทีเดียว จากนั้น ตั้ง crontab เพื่อให้ทำงานอัตโนมัติทุกๆ สองชั่วโมง โดยสั่ง

crontab -e

แล้วใส่ crontab command เข้าไป

* */2 * * * curl 'http://pagefeed.siam.cc/url_run_auto' > /var/www/pagefeed/cron.log

(url นี้ไม่ใช่ของจริงนะครับ แต่เป็น URL หนึ่งในเว็บ เพื่อให้ทำการอ่าน page post ทั้งหมดครับ) โดยไป curl URL ดังกล่าว เพื่อเป็นการกระตุ้นการทำงานโดยอัตโนมัติทุก 2 ชั่วโมง จากนั้นเขียน Log เข้าไปที่ /var/www/pagefeed/cron.log เพื่อดูว่า response เป็นอย่างไรครับ

ทำ icon ของเว็บ และตกแต่งหน้าเว็บ ขั้นตอนสุดท้าย

ก็จนออกมาเป็นอย่างที่เห็นนั่นล่ะครับ ขั้นตอนนี้ ใช้ไปอีก ชั่วโมงนึงได้ เก็บรายละเอียดของเว็บหลายจุด และทดสอบแบบเต็มๆด้วย ว่าทำงานได้ถูกต้องหรือเปล่า ก็เป็นอันเสร็จสิ้นทั้งหมด

รวมทั้ง Project นี้ 7 ชั่วโมง แบบไม่รวดเดียวจบนะครับ เวลาในโลกจริงก็ประมาณ 2 วันได้ครับ ทำบ่ายๆวันศุกร์เสร็จวันอาทิตย์บ่ายๆครับ ปิด Job

ใครที่อ่าน Page post ผ่านพวก RSS Feed แบบผม ก็ลองใช้บริการได้นะครับ ฟรีครับ ฟรี ผมตั้งใจเปิดให้เป็น Public เพื่อให้ทุกคนได้ใช้กันฟรีๆครับ ทั้งนี้ถ้ามีปัญหาอะไรตรงไหน แจ้งในหน้า Contact ได้เลยนะครับ

ได้ขึ้นงานแบบใช้เทคนิคอะไรใหม่ๆบ้าง ทุกๆครั้งที่ขึ้นงานใหม่ ก็จะได้เรียนรู้อะไรใหม่ๆเสมอๆครับ ต่อจากจุดนี้ก็คงเก็บส่วนที่ดีๆเอาไปใช้ใน CMS ส่วนตัว เพื่อไว้ต่อยอดในงานอื่นๆต่อไปครับ (ยิงปืนนัดเดียวได้นกหลายตัวเลย ขอตัวไปตามเก็บนกก่อนนะ)

Create: Modify : 2015-08-02 10:33:32 Read : 8240 URL :