- Published on
โปรเจค Facebook Auto Like ทำงานอย่างไร
- Authors
- Name
- Samiti
เกริ่น
ช่วงปี 2560 ได้สร้าง script การทำงานบนเว็บไซต์ที่เขียนด้วยภาษา PHP ในบทความนี้จะมาให้ความรู้ว่าระบบกดไลค์อัติโนมัติทำงานอย่าง เพื่อเป็นวิทยาทานสำหรับคนที่สนใจ code จะย่อโครงสร้างให้สั้นกระชับ แต่จริงๆ มีอีกเยอะมาก ดังนั้นบทความนี้จะเป็นเพียงไกค์ไลน์เท่านั้น โดยภาพรวมคือการเขียน PHP ยิงผ่าน facebook api Facebook API เพื่อที่เราจะสามารถใช้ API กดไลค์ได้ หรือนำไปเพิ่มไลค์ให้แก่คนอื่น
หากใครยังไม่ได้เป็น facebook developer รบกวนสมัครก่อนใช้งาน
ภาพรวมระบบกดไลค์
การกดไลค์อัติโนมัติคือ การเอา Token ของผู้ใช้งาน โดยจะมีลักษณะเป็นตัวอักขระผสมกันยาว ๆ นำมาป้อนตอนยิงฟังชั่นกดไลค์ผ่าน API ของเฟสบุ๊ค ดังนั้น พูดง่ายๆ ว่า เป็นเพียงแค่ การยิง request ผ่าน post บน Facebook API เท่านั้น เพื่อให้บัญชีผู้ใช้ที่เราได้ Token มากดไลค์ใส่คนอื่นๆ
โดยนักพัฒนาสามารถเข้าชม API ที่เฟสุบ๊คให้บริการได้ที่ Facebook API
แต่มีข้อเสียคือ การจะได้ตัว Token นั้นต้องได้รับการยินยอมจากบัญชีผู้ใช้งานคนๆ นั้น ในแง่มุมตรงนี้ผู้พัฒนาแอปจำเป็นต้องให้ทางผู้ใช้งาน copy token ดังกล่าวแล้ว ป้องเข้ามาใน Input ฟอร์มที่เตรียมไว้ให้
สำหรับการเขียน เราจะทำกันเพียงแค่ 2 ไฟล์ แต่ในโปรเจคทำงานจริงๆ เราทำงานในหลายองค์กรประกอบ ดังนั้นจะดึงเฉพาะส่วนที่เกี่ยวข้อง ดังต่อไปนี้
- facebook.php
- likes.php
โดยเราจะเขียน PHP Object บน facebook.php เพื่อใช้เป็นก้อน Object ตั้งค่าข้อมูลที่ต้องใช้และให้ likes.php เพื่อทำเป็นฟังชั่นบริการกดไลค์บน web application ของเรา
สร้างระบบกดไลค์
- สร้างคลาส abstract class Facebook โดยอย่างลืมลากก้อน Exception มาด้วยเพื่อได้ใช้งาน
abstract class BaseFacebook
{
....
}
- property สร้างตามรูปด้านล่าง
protected $appId;
protected $apiSecret;
protected $accessToken = null;
- อย่าลืมเพิ่ม construct
public function __construct($config) {
$this->setAppId($config['appId']);
$this->setApiSecret($config['secret']);
}
- get set แต่ละตัวให้ครบตามตัวอย่าง
public function setAppId($appId) {
$this->appId = $appId;
return $this;
}
public function getAppId() {
return $this->appId;
}
public function setApiSecret($apiSecret) {
$this->apiSecret = $apiSecret;
return $this;
}
public function getApiSecret() {
return $this->apiSecret;
}
public function setAccessToken($access_token) {
$this->accessToken = $access_token;
return $this;
}
public function getAccessToken() {
if ($this->accessToken !== null) {
return $this->accessToken;
}
$this->setAccessToken($this->getApplicationAccessToken());
if ($user_access_token = $this->getUserAccessToken()) {
$this->setAccessToken($user_access_token);
}
return $this->accessToken;
}
- สร้าง service บริการผ่าน api
โดยเริ่มจากฟังชั่นสำหรับยิง Request API ชื่อ _restserver ด้านล่างนี้เป็น service สำหรบเรียกการยิง API
public function api(/* polymorphic */) {
$args = func_get_args();
if (is_array($args[0])) {
return $this->_restserver($args[0]);
} else {
return call_user_func_array(array($this, '_graph'), $args);
}
}
func_get_args() จะรวบอาร์กิวเมนต์ที่ตรงเข้ามาในฟังชั่นทั้งหมดมา อ้างอิง
protected function _restserver($params) {
$params['api_key'] = $this->getAppId();
$params['format'] = 'json-strings';
$result = json_decode($this->_oauthRequest(
$this->getApiUrl($params['method']),
$params
), true);
if (is_array($result) && isset($result['error_code'])) {
throw new FacebookApiException($result);
}
return $result;
}
สำหรับ Object FacebookApiException สามารถเขียนได้ตามด้านล่าง หากพอใจตรงไหนก็ปรับเปลี่ยนได้ตามต้องการ เพียงหลักการง่าย ๆ คือ ตอน throw Error ให้ส่ง error_code เข้ามา
class FacebookApiException extends Exception
{
protected $result;
public function __construct($result) {
$this->result = $result;
$code = isset($result['error_code']) ? $result['error_code'] : 0;
if (isset($result['error_description'])) {
$msg = $result['error_description'];
} else if (isset($result['error']) && is_array($result['error'])) {
$msg = $result['error']['message'];
} else if (isset($result['error_msg'])) {
$msg = $result['error_msg'];
} else {
$msg = 'Unknown Error. Check getResult()';
}
parent::__construct($msg, $code);
}
อธิบายการทำงานคือ _oauthRequest รับช่องพารามิเตอร์ api url กับ คิวรี่พารามิเตอร์ เพื่อจุดประสงค์คือ ตรวจหาว่า access_token อยู่หรือไม่ ถ้าไม่ก็ตั้งค่าใหม่
และที่สำคัญคือ encode ทุกตัวเป็น json string
protected function _oauthRequest($url, $params) {
if (!isset($params['access_token'])) {
$params['access_token'] = $this->getAccessToken();
}
foreach ($params as $key => $value) {
if (!is_string($value)) {
$params[$key] = json_encode($value);
}
}
return $this->makeRequest($url, $params);
}
จะสังเกตว่าในคลาสก้อนนี้มี makeRequest() ที่รับเอา params ตรงนี้เป็นการ Request ธรรมดาขึ้นอยู่แต่ละคน แน่นอนตัวเลือกของ PHP คือเรียกใช้ curl สามารถดูเพิ่มเติมได้ ที่นี่
ตัวอย่าง makeRequest
protected function makeRequest($url, $params, $ch=null) {
if (!$ch) {
$ch = curl_init();
}
$opts = self::$CURL_OPTS;
$opts[CURLOPT_URL] = $url;
if (isset($opts[CURLOPT_HTTPHEADER])) {
$existing_headers = $opts[CURLOPT_HTTPHEADER];
$existing_headers[] = 'Expect:';
$opts[CURLOPT_HTTPHEADER] = $existing_headers;
} else {
$opts[CURLOPT_HTTPHEADER] = array('Expect:');
}
curl_setopt_array($ch, $opts);
$result = curl_exec($ch);
if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT
self::errorLog('Invalid or no certificate authority found, '.
'using bundled information');
curl_setopt($ch, CURLOPT_CAINFO,
dirname(__FILE__) . '/fb_ca_chain_bundle.crt');
$result = curl_exec($ch);
}
if ($result === false) {
$e = new FacebookApiException(array(
'error_code' => curl_errno($ch),
'error' => array(
'message' => curl_error($ch),
'type' => 'CurlException',
),
));
curl_close($ch);
throw $e;
}
curl_close($ch);
return $result;
}
- ขั้นตอนสุดท้ายนั้นก็คือ การเรียกใช้ Service จนกระทั่งผมได้ค้นพบวิธีใหม่และดีกว่าเดิมคือ โดยในไฟล์นี้ให้ตั้งชื่อ likes.php
ขั้นแรก เรียกไฟล์ facebook.php แล้วต่อดาต้าเบส
require 'include/facebook.php';
$token = $_GET["accesstoken"];
$host = "localhost";
$username = "xxxxxxxxxxx";
$password = "xxxxxxxxxxx";
$dbname = "xxxxxxxxxxx";
mysql_connect($host,$username,$password) or die(mysql_error());
mysql_select_db($dbname) or die(mysql_error());
mysql_query("SET NAMES utf8");
$result = mysql_query("SELECT * FROM Likers ORDER BY RAND() LIMIT ".$likelimit);
แล้วเรียกก้อนที่เราสร้างมาเมื่อขั้นตอนก่อนหน้า และอย่าลืมสร้างตัวแปรต่างๆ ที่เราอาจจะใช้งาน
.....
$output = '';
$total = 0;
$facebook = new Facebook(array(
'appId' => $fb_app_id,
'secret' => $fb_secret
));
ต่อดาต้าเบส แล้วสร้างตัวแปรพวกนี้ result และ Access Token ของผู้ใช้งานคนนั้นออกมากเพิ่ม ในก้อน $facebook->setApiSecret();
จากนั้นก็ยิงก้อน $facebook->api() ตามปกติ
if($result){
while($row = mysql_fetch_array($result, MYSQL_ASSOC)){
$m = $row['access_token'];
$facebook->setAccessToken ($m);
$id = trim($_POST ['postid']);
try {
$facebook->api("/".$id."/likes", 'POST');
$total++;
}
catch (FacebookApiException $e) {
$output .= "<p>'". $row['name'] . "' failed to like.</p>";
}
}
flush();
}
mysql_close();
mysql_connect($host,$username,$password) or die(mysql_error());
mysql_select_db($dbname) or die(mysql_error());
mysql_query("INSERT INTO `like_queue` SET `post_id` = '".trim(mysql_real_escape_string($_POST['postid']))."',`like_limit` = '".$likelimit."',`done` = '".$total."',`ip` = '".$_SERVER['REMOTE_ADDR']."',`time` = '".time()."';");
echo "<script>alert('คุณสุ่มไลท์ได้ทั้งหมด ".$total." ไลค์');</script>";
mysql_close();
ในท้ายๆ บรรทัดอย่าลืมปิดฐานข้อมูลด้วย หากไม่ใช้งานแล้ว และบันทึกข้อมูลการใช้งานแต่ละบัญชีว่ากดไลค์ไปเท่านั้น เพื่อที่เราจะได้นำมาคำนวณในภายหลัง