GORAGOD.com

การโพสต์รูปภาพที่สร้างจาก canvas ด้วย Javascript ไปยัง Facebook

การโพสต์รูปภาพที่สร้างจาก canvas ด้วย Javascript ไปยัง Facebook ออกจะซับซ้อนนิดหนึ่ง เพราะต้องทำถึงสามขั้นตอนด้วยกัน คือ
  1. โพสต์รูปภาพที่สร้างจาก Canvas ไปยัง Facebook ด้วย Ajax เลียนแบบการทำงานของฟอร์ม (จำลองการอัพโหลดรูปภาพด้วย Ajax) ไปยัง URL https://graph.facebook.com/me/photos ซึ่งจะเป็นการสร้างอัลบัมของ Facebook และอัปโหลดรูปภาพไปไว้ในนั้น ส่งค่ากลับเป็น ID ของโพสต์
  2. อ่านรูปภาพที่อัพโหลดไปจาก ID ของโพสต์ที่ส่งกลับมาตามข้อ 1
  3. โพสต์รูปภาพที่ได้ไปยังหน้า Wall ของ Facebook
อันดับแรกเลยที่ต้องทำก่อนคือการเชื่อมต่อกับ API ของ Facebook 
window.fbAsyncInit = function () {
  FB.init({
    appId: 'FACEBOOK_APP_ID',
    cookie: true,
    status: true,
    xfbml: true,
    version: 'v2.8'
  });
};
(function (d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) {
    return;
  }
  js = d.createElement(s);
  js.id = id;
  js.src = "//connect.facebook.net/th_TH/sdk.js";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
  • FACEBOOK_APP_ID คือ App ID ที่ได้จาก Facebook สำหรับใช้ในการเชื่อมต่อกับ Facebook
ถัดมาโค้ด HTML ซึ่งเป็นปุ่มสำหรับโพสต์ไปยัง Facebook ซึ่งก็ไม่มีอะไรซับซ้อนครับ โดยที่เมื่อมีการกดปุ่มจะเรียกไปยังฟังก์ชั่น doPostToFacebook
<button type="button" onclick="doPostToFacebook()">โพสต์ไปยัง Facebook</button>

ฟังก์ชั่น doPostToFacebook จะทำคำสั่งวาดรูปบน Canvas (ฟังก์ชั่น draw()) เสร็จแล้วแปลงเป็นข้อมูลประเภท Blob (ข้อมูลแบบเดียวกับการอ่านรูปภาพไปเก็บยัง MySQL นั่นแหละ ด้วยฟังก์ชั่น dataURItoBlob()) จากนั้นก็จะตรวจสอบการเข้าระบบด้วย Facebook เมื่อสำเร็จแล้วก็จะเป็นการโพสต์ข้อมูล Blob ที่ได้ไปยัง Facebook ด้วยฟังก์ชั่น postImageToFacebook()
var doPostToFacebook = function () {
  // วาดรุปภาพแล้วส่งกลับเป็นข้อมูล DOMString
  var image = draw().toDataURL("image/png");
  try {
    // แปลงเป็นข้อมูลสำหรับโพสต์
    blob = dataURItoBlob(image);
  } catch (e) {
  }
  // เข้าระบบด้วย Facebook
  FB.getLoginStatus(function (response) {
    if (response.status === "connected") {
      postImageToFacebook(response.authResponse.accessToken, blob);
    } else if (response.status === "not_authorized") {
      FB.login(function (response) {
        postImageToFacebook(response.authResponse.accessToken, blob);
      }, {scope: "publish_actions"});
    } else {
      FB.login(function (response) {
        postImageToFacebook(response.authResponse.accessToken, blob);
      }, {scope: "publish_actions"});
    }
  });
}

ฟังก์ชั่น postImageToFacebook ในขั้นตอนแรกจะเป็นการอัพโหลดรูปภาพไปยัง Facebook ด้วย Ajax (ตัวอย่างนี้ใช้ GAjax ในการอัพโหลด ใครใช้ตัวอื่นก็ดัดแปลงกันตามอัธยาศัย) ซึ่งจะได้ผลลัพท์เป็น ID ของโพสต์
function postImageToFacebook(token, image) {
  var fd = new FormData();
  fd.append("access_token", token);
  fd.append("source", image);
  fd.append("no_story", true);
  var req = new GAjax({
    contentType: null
  });
  // โพสต์ไปยังอัลบัมของ Facebbok
  req.send("https://graph.facebook.com/me/photos?access_token=" + token, fd, function (xhr) {
      // ข้อมูลส่งครับ
    var data = xhr.responseText.toJSON();
    // คืนค่า ID ของโพสต์
    console.log(data.id);
  });
}

เราจะนำ ID ของโพสต์ส่งกลับไปสอบถาม URL ของรูปภาพที่เพิ่งโพสต์ไปจาก Facebook อีกครั้งโดยใช้ data.id ที่ได้ ซึ่งค่าที่ตอบกลับจะเป็นรายชื่อรูปภาพทั้งหมดในอัลบัม และ รูปภาพที่เพิ่งโพสต์ไปจะอยู่ที่ response.images[0].source
FB.api(
  "/" + data.id + "?fields=images",
  function (response) {
    if (response && !response.error) {
      // URL ของรูปภาพที่โพสต์
      console.log(response.images[0].source);
    }
  }
);

สุดท้ายเราจะนำรูปภาพที่ได้โพสต์กลับไปยังหน้า Wall ของ Facebook อีกที
FB.ui({
  method: 'share_open_graph',
  action_type: 'og.shares',
  action_properties: JSON.stringify({
  object: {
    'og:title': document.title,
    'og:image:width': 476,
    'og:image:height': 476,
    'og:image': response.images[0].source,
    'og:url': response.images[0].source
  }
});
  • og:title ใช้ระบุข้อความ Title ของโพสต์
  • og:image:width และ og:image:height ให้ระบุความกว้างและความสูงของรูปภาพ
สำหรับโค้ดสำเร็จเลยก็ตามนี้เลยครับ ซึ่งโค้ดนี้มีการเรียกใช้ GAjax ด้วย (https://github.com/goragod/kotchasan/blob/master/js/gajax.js) อย่าลืม include ไฟล์นี้เข้าไปด้วยนะครับ
/**
 * ฟังก์ชั่นโพสต์ไปยัง Facebook
 *
 * @param {string} token
 * @param {string} image
 */

function postImageToFacebook(token, image) {
  var fd = new FormData();
  fd.append("access_token", token);
  fd.append("source", image);
  fd.append("no_story", true);
  var req = new GAjax({
    contentType: null
  });
  // โพสต์ไปยังอัลบัมของ Facebbok
  req.send("https://graph.facebook.com/me/photos?access_token=" + token, fd, function (xhr) {
    var data = xhr.responseText.toJSON();
    // โพสต์ไปยัง Facebook สำเร็จคืนค่า id ของโพสต์กลับมา
    // อ่านรูปภาพจาก id ของโพสต์
    FB.api(
      "/" + data.id + "?fields=images",
      function (response) {
        if (response && !response.error) {
          // โพสต์รูปภาพที่อ่านได้ไปยังหน้า wall ของ Facebook
          FB.ui({
            method: 'share_open_graph',
            action_type: 'og.shares',
            action_properties: JSON.stringify({
              object: {
                'og:title': document.title,
                'og:image:width': 476,
                'og:image:height': 476,
                'og:image': response.images[0].source,
                'og:url': response.images[0].source
              }
            })
          });
        }
      }
    );
  });
}
/**
 * แปลงรูปภาพเป็นข้อมูลสำหรับโพสต์
 *
 * @param {string} dataURI
 * @returns {Blob}
 */

function dataURItoBlob(dataURI) {
  var byteString = atob(dataURI.split(',')[1]);
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }
  return new Blob([ab], {
    type: 'image/png'
  });
}
/**
 * ฟังก์ขั่นสร้างรูปภาพด้วย canvas
 *
 * @returns {Element|draw.canvas}
 */

function  draw() {
  var canvas = document.createElement('canvas'),
    ctx = canvas.getContext("2d");
  canvas.width = 800;
  canvas.height = 800;
  ctx.fillStyle = '#FF0000';
  ctx.fillRect(0, 0, 800, 800);
  return canvas;
}
/**
 * ฟังก์ชั่น เรียกเมื่อต้องการโพสต์ไปยัง Facebook
 */

var doPostToFacebook = function () {
  // วาดรุปภาพแล้วส่งกลับเป็นข้อมูล DOMString
  var image = draw().toDataURL("image/png");
  try {
    // แปลงเป็นข้อมูลสำหรับโพสต์
    blob = dataURItoBlob(image);
  } catch (e) {
  }
  // เข้าระบบด้วย Facebook
  FB.getLoginStatus(function (response) {
    if (response.status === "connected") {
      postImageToFacebook(response.authResponse.accessToken, blob);
    } else if (response.status === "not_authorized") {
      FB.login(function (response) {
        postImageToFacebook(response.authResponse.accessToken, blob);
      }, {scope: "publish_actions"});
    } else {
      FB.login(function (response) {
        postImageToFacebook(response.authResponse.accessToken, blob);
      }, {scope: "publish_actions"});
    }
  });
};
window.fbAsyncInit = function () {
  FB.init({
    appId: 'FACEBOOK_APP_ID',
    cookie: true,
    status: true,
    xfbml: true,
    version: 'v2.8'
  });
};
(function (d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) {
    return;
  }
  js = d.createElement(s);
  js.id = id;
  js.src = "//connect.facebook.net/th_TH/sdk.js";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));