Blog Aggregator Dengan Blogger API (1)

Bismillah

Ini adalah bagian kedua dari tulisan sebelumnya : Blog Aggregator dengan Blogger API (0). Sebelum melanjutkan, ada baiknya kita pastikan kita berada pada halaman yang sama. Kita sudah bisa :

0. Menginstall CodeIgniter, sekaligus integrasi dengan Zend Gdata library
1. Punya akses ke Blogger API, ditunjukkan dengan halaman API Console. Jika belum, maka kemungkinan ada masalah saat pengajuan permohonan ke Brett Morgan. Anda bisa kontak ulang dia, dan yakinkan dia bahwa Anda tidak membuat sesuatu yang melanggar TOS Google.


Tujuan akhir dari seri tulisan belajar menggunakan Blogger API ini adalah Blog Aggregator, yang saat ini Anda bisa lihat hasilnya di situs blog aggregator Ilmu Komputer Universitas Gadjah Mada '04 (CapCuan). Cara kerja CapCuan secara sederhana kira-kira seperti berikut :

RSS -----> CapCuan (CI + SimplePie + Cron running) -----> Blogger API (*.blogspot.com)

Pertama, multi feeds dari berbagai blog dibaca. Cron berjalan misalnya setiap 1 hari sekali, jam 19:00. Ada 2 table utama dalam database CapCuan. Pertama blogs, kedua options. Fields dalam table blogs yang penting : blog_rss, blog_owner, dan last_update. Sedangkan di table options, kita akan simpan access_token, consumer_key, consumer_secret, dan blog_id (masing-masingnya akan dijelaskan kemudian).

Kedua, semua feed diurutkan berdasarkan publication_datenya, mulai dari yang paling lama. Masing-masing feed memiliki title, content, url ke original post, publication_date, dan owner.

Ketiga (terakhir), kita akan kirim masing-masing post ke blogspot dengan blogger API. Masing-masing post ini contentnya akan ditambah dengan string : "Original post : {url}", dan diberi label (di Wordpress = category/tag) sesuai owner dari contentnya. Bila posting berhasil, maka value field 'last_update' di table blogs untuk blog bersangkutan akan diubah sesuai publication date dari post. It's that simple.

Tulisan kali ini fokus pada 3 hal saja : penggunaan OAuth, integrasi SimplePie ke CI, dan terakhir penggunaan Blogger API.

Penggunaan OAuth
OAuth adalah salah satu Open Web Specifications, yang dengannya kita bisa mengakses data user tanpa user tersebut harus membagi username dan passwordnya. OAuth adalah solusi dari web APIs yang aman, karena third-party diberi akses hanya pada bagian yang perlu diakses sahaja. Sebagai contoh, katakan sebuah web service ingin mengakses address book dari akun GMail. Apakah kita memberikan username dan password? Jika ya, maka web service tersebut dapat pula melihat foto-foto kita di Picasa, melihat akun Blogger yang kita set private, dsb. Ini tidak kita inginkan.

Analogi OAuth kira-kira sama seperti valet key dari sebuah mobil mewah. Alih-alih memberi kunci mobil yang asli, kita memberikan valet key. Kunci ini memungkinkan mobil hidup hingga tempat parkir saja, dan akses ke fitur mobil yang lain seperti telepon, radio, tv, music player, dll, tidak bisa digunakan. Detil tentang OAuth bisa dibaca di situs http://hueniverse.com/oauth/guide/intro/.

Untuk penggunaan metode authentication yang lain, bisa kunjungi referensi berikut 
http://code.google.com/apis/blogger/docs/1.0/developers_guide_php.html#Authenticating

Sedangkan untuk OAuth beserta sample codenya, bisa dibaca di https://developers.google.com/gdata/docs/auth/oauth. Bila ada yang kurang jelas, kolom komentar selalu terbuka. Setelah user granted access pada aplikasi CapCuan, maka kita akan simpan access_token di table options. Value access_token inilah yang menunjukkan specific user, scope (jenis service yang dipakai, dalam hal ini Blogger API), url aplikasi, yang sifatnya long-lived.

$accessToken = unserialize($this->option_model->get_token());

$httpClient = $accessToken->getHttpClient($oauthOptions);
$gdClient = new Zend_Gdata($httpClient, 'muhajirin-Capcuan-v1');

$blogID = $this->option_model->get_blog_id();

$uri = 'http://www.blogger.com/feeds/' . $blogID . '/posts/default';


Integrasi SimplePie di CodeIgniter
SimplePie adalah library untuk parsing feed. Salah satu kekurangannya adalah tidak bisa menyimpan cache di dalam database. Tapi untuk kebutuhan kita, library ini lebih dari cukup. Download versi terbarunya dari www.simplepie.org/downloads/, dan salin ke dalam folder libraries. Untuk pengguna PHP 5.3 mungkin akan sedikit ada error karena beberapa function yang sudah deprecated. Salah satu solusinya adalah dengan tidak menghiraukan error message deprecated, ubah file index.php (di kita berarti capcuan.php) menjadi seperti berikut

case 'development':
     error_reporting(E_ALL & ~E_DEPRECATED); 

Untuk menggunakannya di controller

$this->load->library('SimplePie');

...dan kita akan ambil semua post dari feeds yang sudah ditambahkan


//get all RSS inside the blogs table
$blogs = $this->blog_model->get_blogs();

$posts = array();
//loop through all blogs
foreach ($blogs as $blog)
{
      //using simplepie to get the feed
      $this->simplepie->set_feed_url($blog->blog_rss);
      $this->simplepie->set_cache_location('/path/to/cache/folder/');
      $this->simplepie->init();
      $this->simplepie->handle_content_type();

      $items = array();
      $items = $this->simplepie->get_items();

      //loop through items/feed
      foreach ($items as $item)
      {
            //is item old?
            $publication_date = $item->get_date('c');
            if (strtotime($publication_date) <= strtotime($blog->last_update))
            {
                  //break the loop
                  break;
            }

            $title = $item->get_title();
            $description = $item->get_content();

            $description.= '


Original post : ' . anchor($item->get_permalink(), $title);

            $author = $blog->blog_owner;

            //saved for later, because we want to order the posts by publication date
            $posts[] = array($blog->id, $publication_date, $title, $description, $author);

      }
}

Di sini variable posts sudah berisi semua post yang siap dipublish dengan Blogger API. Namun untuk lebih meyakinkan, kita ingin mengurutkan semua posting berdasarkan publication_date-nya. Untuk itu, kita butuh sorting multi-dimensi. Kira-kira sebagai berikut :


//sort posts based on publication_date
foreach ($posts as $key => $row)
{
      $pub_date[$key] = $row[1];//$row[1] is publication_date
}

array_multisort($pub_date, SORT_ASC, $posts);

Done. Saat ini kita sudah punya semua posting yang siap dipublish dengan Blogger API, dan terurut berdasarkan publication_date.

Penggunaan Blogger API

Masing-masing post sudah punya title, content (full, bukan summary), publication date, dan label (yang berisi author). 

$entry = $gdClient->newEntry();

Kita bersihkan title dan content dari tag script dengan function xss_clean();
//making an entry
$entry->title = $gdClient->newTitle(xss_clean($title));
$entry->content = $gdClient->newContent(xss_clean($description));
$entry->content->setType('text');

Karena Blogger API hanya menerima date dengan format ISO 8601
$publication_date = $publication_date ? $publication_date : date('c');
$entry->published = $gdClient->newPublished($publication_date);

Untuk memilih posting berdasarkan pemilik blog, kita tambahkan label sesuai dengan author name
//set the label = $author
$labels[] = $gdClient->newCategory($author, 'http://www.blogger.com/atom/ns#');
$entry->setCategory($labels);

Terakhir, posting ke blogspot.com
//create an entry
$createdPost = $gdClient->insertEntry($entry, $uri);


Karena di Blogger ada keterbatasan hanya boleh posting 50 tulisan per hari, ada kemungkinan ukuran $posts terlalu besar. Ini bukan masalah karena kita menyimpan value 'last_update' di table blogs setiap kali 1 buah post berhasil dikirim ke blogspot. Posting yang tidak terkirim akan disimpan dan dikirim pada hari berikutnya, demikian seterusnya.

Langkah terakhir adalah menjalankan cron per hari (bisa diatur di hosting masing-masing). Di CodeIgniter, menjalankan controller tertentu dari CLI kira-kira sebagai berikut 

php5 capcuan.php controller function

Hal ini sama halnya bila kita memanggil URL example.com/capcuan.php/controller/function/
Dan untuk lebih amannya, kita bisa set agar cron hanya bisa dipanggil lewat CLI request dengan menambahkan baris berikut di __construct();

if (! $this->input->is_cli_request())
{
      log_message('debug', 'Someone with IP : '. $this->input->ip_address() . ' tried to access your cron');
      die("How about 5,000 words on why you should stay the fuck out of my house!");
}


Kesimpulan dan Saran
*kayak skripsi aje Bang...*
0. Aplikasi CapCuan, walau sederhana, sudah bisa menerapkan ilmu Blogger API, pemakaian Gdata library, dan model otentikasi OAuth (yang lebih direkomendasikan daripada model otentikasi lain seperti AuthSub milik Google yang proprietary).
1. CapCuan memiliki banyak kekurangan, salah satunya adalah tidak bisa mendeteksi apakah sebuah feed memang karena content baru atau modifikasi content/post lama.
2. Mungkin di masa depan, semua content benar-benar dipindahkan, misalnya images. Blog aggregator populer seperti planetplanet juga tetap mengarahkan images ke original URL. Bila CapCuan ditambah feature ke API Picasa (seperti yang kita tahu, semua images yang diupload ke Blogger, akan muncul di Picasa), maka kita bisa "colong" semua images di dalam post ke blogspot/Blogger. Keren kayaknya.
3. Code di atas mungkin bukan best practice. Penulis terbuka untuk koreksi.

Update 2012-11-01:
Saat ini CapCuan sudah dapat terkoneksi dengan API Picasa, sehingga semua image yang tersedot dari konten dalam RSS akan otomatis tersimpan di Album khusus. Ini membuat CapCuan menjadi aggregator nomor 1 di dunia [citation needed]

Demikian, semoga bermanfaat. Bila ada saran dan kritik, bisa disampaikan melalui komentar atau email saya di prabowo.murti at gmail.

"No thinking, that comes later. You must write your first draft with your heart. You rewrite with your head. The first key to writing is.. to write, not to think!" -- William Forrester

12 komentar:

  1. kalau sempat, buat gambar atau diagram yang menggambarkan komponennya, posisi ada di mana, interaksinya bagaimana, dst.

    jadi pemula seperti saya dapat langsung memahami kalau si A ditempatkan di si B, interaksinya pakai inu, ..

    BalasHapus
    Balasan
    1. Hehehe.. Soalnya bingung Mas, pengennya nulis dulu, dikomentari, baru dimodifikasi dikit2 tulisannya. Postingan ini sudah jadi draft sejak sebulan yang lalu. Nanti insya Allah akan saya perbaiki. Terima kasih sarannya.

      Hapus
  2. Putri said at 30 May 2012 07:13

    Sebenarnya kekurangan dari capcuan bisa diselesaikan dengan sederhana. Dalam blogger API anda akan menemukan getPublished() dan getUpdated(). Bila anda melakukan update, maka getUpdated() akan merekamnya. Jadi gunakan hal itu. Saya juga telah melihat detail tulisan anda. cukup menarik. untuk memindahkan image ke posting blog anda bisa menerapkan setContent(). Lalu mengolahnya dengan javascript posisi image url. Bila saya tidak salah ialah, anda mencoba melakukan update tanpa harus membuka akun blogger. Tetapi melalui akun wordpress. Kemudian di transmisi ke akun blogger. Blogger tidak menjadi masalah seberapa banyak posting dibuat dalam sehari. Tetapi, bila melebihi 50 posting maka posting berikutnya akan diterbitkan esok harinya. Mungkin anda bisa bertukar pikiran di http://www.threelas.com/search/label/Blogger%20Api kami menjelaskan tutorial blogger API secara detail dan setahap demi setahap. Sementara ini hanya untuk public. tetapi saya yakin anda mengerti alur programmnya bila menggunakan autentic.

    BalasHapus
    Balasan
    1. Terima kasih Mbak Putri atas komentarnya (saya comot dari CapCuan)

      Sebelumnya saya juga sudah baca dokumentasi Blogger API untuk PHP, dan soal update post itu saya pikir terlalu kompleks. Pertama, karena penghuni CapCuan juga tidak banyak. Tercatat hanya 20-an authors. Yang posting saja sedikit, apalagi yang mengupdate post (sehingga tetap tercatat di RSS/feed). Dengan kadar kesederhanaan seperti ini, agak2 buang resource mencari content mana yang harus diubah di dalam CapCuan.

      Alasan selanjutnya, untuk 50 posts a day limitation, saya sudah kirim email dan lempar topik ke forum bloggerdev (dijawab oleh Brett Morgan). Ia tanya, apa added value dengan adanya planetplanet wannabe ini? Kalau memang banyak yang pakai service serupa, ia bakal naikin limitationnya. Tapi kalau nggak ada nilai tambahnya, dia pun mikir2 mengapa harus peduli dengan apps yang tidak populer. Mungkin seperti itu yang saya tangkap.

      Saya sudah lihat situs Anda, isinya sungguh informatif. Terima kasih. :)

      Hapus
    2. Saya juga sudah lihat isi email anda ke Brett. Tapi aplikasi anda suatu ide bagus.

      Hapus
  3. kok bahasa Indonesia-ne wagu tho?

    BalasHapus
  4. ada kode yang udah jadi mas? kode php yang siap di pake buat posting ke blogger?

    Di tunggu ya mas... :)

    BalasHapus
    Balasan
    1. Source code sedang saya jual. Kalau berminat, bisa ajukan penawaran ke prabowo.murti at gmail dot com. Saya buka di US$800 :)

      Hapus
  5. Mas ni gmna mas klo blh tau bloger saya baru n dh saya klola nmun tetap blom exis aja,mohon blsannya.

    tank's

    BalasHapus
    Balasan
    1. Maaf saya tidak paham. Belum eksisnya seperti apa, Pak? Saya lihat google plusnya belum ada link menuju blognya.

      Hapus

speak now or forever hold your peace

About Me