跳到主要內容

Facebook - Establish a app in 5 minutes - Find the Single

要做一個Facebook的應用程式,一點也不難!今天要帶給大家的是:5分鐘做一個facebook AP。第一步是加入開發人員這個應用程式。

加入開發人員應用程式

在上方的搜尋輸入開發人員就能找到應用程式,點擊後會導入如下圖的授權頁面。

在點擊前往應用程式後,你可以看到類似下圖的畫面,差別在於你不會像我這裡有三個應用程式。這個畫面我把它叫做應用程式主控板,你可以看到你建立的應用程式資訊。

新增應用程式

在應用程式主控板上點擊建立新的應用程式,會出現如下圖的Dialog。App Name即應用程式名稱,應用程式名稱空間即應用程式的URL名稱,而Web Hosting則是使用Herocu提供的服務,讓你可以不需要把應用程式放在自己的主機上,它還有許多強大的功能,有興趣可以參考它的介紹。當初我在寫國軍登出倒數計時器時,還沒有這麼好用的東西,只能把寫好的應用程式放在自己家中而已。言歸正傳,今天我們要做的應用程式叫「Find The Single」 - 尋找單身。

在按繼續並輸入驗證碼後,會出現如下圖應用程式主控板。

在點擊編輯應用程式後會進入下面這個頁面。我預計要把應用程式放在Apache Server上,並透過Canvas的方式讓User存取。我需要輸入以下資料:

  • 基本資料: 如果有App Domain就填入Domain,類別選擇你應用程式的類別。Find The Fuck Buddy Single我想是策略性遊戲吧…
  • Website with Facebook Login: 輸入網站的URL即可。
  • Facebook上的App: 輸入網站的URL即可。如果支援Https就輸入Https的URL。

部屬與撰寫程式

Apache Config

設定Artifact的目錄。

<Directory "/var/www/FindTheSingle">
        Order Deny,Allow
        Allow from all
</Directory>

Alias /FindTheSingle /var/www/FindTheSingle
Alias /findTheSingle /var/www/FindTheSingle
Alias /findthesingle /var/www/FindTheSingle

HTML and Javascript

需求

Find The Single顧名思義為尋找單身。我希望能夠找到單身的異性朋友,包含難以言喻(Complicated)與單身(Single),而不詳(Unknown)僅做為參考用。你也許會問: 為什麼難以言喻也要放進來? 我說: 因為機會比單身還大啊! 因此我預計將UI設計為三個區塊,而顯示內容主要以朋友的大頭照為主。這個範例直接透過Facebook Javascript的API即可完成。讓我們先看看預期出現的結果:

骨架

以下程式碼是這個範例的骨架。在<body>內為整個頁面的layout,分成Complicated、Single與Unknown三個區塊,而fb-root區塊為load Facebook Javascript SDK所需要。在Javascript區塊的部分,引用了jquery與我自己整理的fb-util.js。實作內容則直接由SDK範例中複製修改,主要有三個動作:

  1. Load SDK: 將最新的FB Javascript API source file讀取進來。
  2. Init SDK: 必須給定應用程式的App ID,可於應用程式主控板看到。其它參數則是決定是否啟用功能,其中xfbml設定為true代表要去parse頁面中有使用FB的特有語法(XFBML)。
  3. Login: 讓應用程式透過OAuth方式取得Access_token(門牌),以存取在臉書上的資料。這應用程式需要存取的權限包含朋友清單、我的關係與朋友的關係(read_friendlists, user_relationships, and friends_relationships)。在完成授權與登入後,會透過callback的方式呼叫function(response)的內容,一切的實作都是從這開始!

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Find The Single</title>
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="js/fb-util.js"></script>
<script type="text/javascript">
	window.fbAsyncInit = function() {
		FB.init( {
			appId : 'App ID', 
			status : true, // check login status
			cookie : true, // enable cookies to allow the server to access the session
			xfbml : true // parse XFBML
		});
 
		FB.login(function(response) {
			if (response.authResponse) {
				// implement here!
			}
		}, {
			scope : 'read_friendlists,user_relationships,friends_relationships'
		});
	};
 
	(function(d) {
		var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
		if (d.getElementById(id)) {
			return;
		}
		js = d.createElement('script');
		js.id = id;
		js.async = true;
		js.src = "//connect.facebook.net/en_US/all.js";
		ref.parentNode.insertBefore(js, ref);
	}(document));
</script>
</head>
<body>
<div id="fb-root"></div>
<h2><img src="images/unstarred.gif" /> Complicated:</h2>
<hr />
<div id='complicated-friend-list'></div>
<h2><img src="images/unstarred.gif" /> Single:</h2>
<hr />
<div id='single-friend-list'></div>
<h2><img src="images/unstarred.gif" /> Unknown:</h2>
<hr />
<div id='unkown-friend-list'></div>
</body>
</html>
要求使用者授權的畫面:

主要實作

程式流程非常簡單。登入後讀取我的性別與朋友列表,接著根據朋友的感情狀態進行分類,最後產生朋友的大頭照塞入對應的layout中。

登入後的動作

再登入後呼叫initFriendsRelationShip() function。
	FB.login(function(response) {
		if (response.authResponse) {
			initFriendsRelationShip();
		}}, {
			scope : 'read_friendlists,user_relationships,friends_relationships'
	});
透過Graph API去查詢我的性別,用以判斷異性朋友。(要找同性的請自行改寫…)
	function initFriendsRelationShip(){
		FB.api('/me', function(response) {
			handelFriendList(response.gender);
		});		
	};
讀取朋友清單,並一個個丟到handleRelationship中處理。FB.Canvas.setAutoResize()是為了在產生整個頁面資料後,用來調整layout長寬的。
	function handelFriendList(myGender) {
		FB.api('/me/friends', function(response) {
			var data = response.data;
			for ( var i = 0 ; i < data.length; i++) {
				handleRelationship(data[i].id, myGender);
			}
			FB.Canvas.setAutoResize();
		});
	};
透過Graph API取得的內容為Json format:

處理朋友清單

根據朋友的id透過Graph API找她的感情狀態來做比對,並skip掉同性朋友。接著根據狀態去呼叫各別的function做處理。
	function handleRelationship(uid, myGender){
		FB.api('/'+uid, function(response) {
			var data = response.relationship_status;
			var friendGender = response.gender;
			if( myGender == friendGender ){
				return;
			}
 
			if(data){
				if( data == 'Single' ||
						data == 'Separated'){
					insertToSingleFriendList(uid);
				} else if( data == 'It\'s complicated' ){
					insertToComplicated(uid);
				}
			} else {
				insertToUnkownFriendList(uid);
			}
		});
	}

產生大頭照

在根據感情狀態呼叫各自的function後,接著會產生根據朋友的uid產生fxbml語法(FacebookUtillity.getUserSqurePicWithLogo)去加入到對應的div中。最後透過API去parse這個語法以顯示出fxbml的內容。大頭照的fxbml語法為fb:profile-pic標籤,在這裡我有做特殊處理,讓它點擊後會開新視窗。

	function insertThePicToDiv(uid, div){
		var fbHtml = FacebookUtillity.getUserSqurePicWithLogo(uid,true);
		$('#'+div).append(fbHtml);
		FacebookUtillity.parseXFBML(div);
	};
 
	function insertToSingleFriendList(uid){
		insertThePicToDiv(uid, 'single-friend-list');
	};
 
	function insertToUnkownFriendList(uid){
		insertThePicToDiv(uid, 'unkown-friend-list');
	};
 
	function insertToComplicated(uid){
		insertThePicToDiv(uid, 'complicated-friend-list');
	};

Summary

做一個Facebook應用程式不難吧?完全不需要Server Side Programming,就能夠完成一個有趣的程式。言歸正傳,看完這篇你可能會存在這些疑問:
  1. OAuth是什麼?
  2. Graph API是什麼?
  3. 難道授權畫面只能透過pop-up的方式嗎?
  4. fxbml語法還有哪些?
  5. 我想透過其它語言實作行嗎?
也許還有許多疑問,在之後的文章會再一一替大家解答。(或許前兩個問題Google比較快啦!)

留言

這個網誌中的熱門文章

解決RobotFramework從3.1.2升級到3.2.2之後,Choose File突然會整個Hand住的問題

考慮到自動測試環境的維護,我們很久以前就使用java去執行robot framework。前陣子開始處理從3.1.2升級到3.2.2的事情,主要先把明確的runtime語法錯誤與deprecate item處理好,這部分內容可以參考: link 。 直到最近才發現,透過SeleniumLibrary執行Choose File去上傳檔案的動作,會導致測試案例timeout。本篇文章主要分享心路歷程與解決方法,我也送了一條issue給robot framework: link 。 我的環境如下: RobotFramework: 3.2.2 Selenium: 3.141.0 SeleniumLibrary: 3.3.1 Remote Selenium Version: selenium-server-standalone-3.141.59 首先並非所有Choose File的動作都會hang住,有些測試案例是可以執行的,但是上傳一個作業系統ISO檔案一定會發生問題。後來我透過wireshark去比對新舊版本的上傳動作,因為我使用 Remote Selenium ,所以Selenium會先把檔案透過REST API發送到Remote Selenium Server上。從下圖我們可以發現,在3.2.2的最後一個TCP封包,比3.1.2大概少了500個bytes。 於是就開始了我trace code之路。包含SeleniumLibrary產生要送給Remote Selenium Server的request內容,還有HTTP Content-Length的計算,我都確認過沒有問題。 最後發現問題是出在socket API的使用上,就是下圖的這支code: 最後發現可能因為開始使用nio的方式送資料,但沒處理到尚未送完的資料內容,而導致發生問題。加一個loop去做計算就可以解決了。 最後我有把解法提供給robot framework官方,在他們出新的版本之前,我是將改完的_socket.py放在我們自己的Lib底下,好讓我們測試可以正常進行。(shutil.py應該也是為了解某個bug而產生的樣子..)

Show NIC selection when setting the network command with the device option

 Problem  在answer file中設定網卡名稱後,安裝時會停在以下畫面: 所使用的command參數如下: network --onboot = yes --bootproto =dhcp --ipv6 =auto --device =eth1 Diagnostic Result 這樣的參數,以前試驗過是可以安裝完成的。因此在發生這個問題後,我檢查了它的debug console: 從console得知,eth1可能是沒有連接網路線或者是網路太慢而導致的問題。後來和Ivy再三確認,有問題的是有接網路線的網卡,且問題是發生在activate階段: Solution 我想既然有retry應該就有次數或者timeout限制,因此發現在Anaconda的說明文件中( link ),有提到dhcptimeout這個boot參數。看了一些人的使用範例,應該是可以直接串在isolinux.cfg中,如下: default linux ksdevice = link ip =dhcp ks =cdrom: / ks.cfg dhcptimeout = 90 然而我在RHEL/CentOS 6.7與6.8試驗後都無效。 因此我就拿了顯示的錯誤字串,問問Google大師,想找一下Anaconda source code來看一下。最後找到別人根據Anaconda code修改的版本: link ,關鍵在於setupIfaceStruct函式中的setupIfaceStruct與readNetConfig: setupIfaceStruct: 會在dhcp時設定dhcptimeout。 readNetConfig: 在writeEnabledNetInfo將timeout寫入dhclient config中;在wait_for_iface_activation內會根據timeout做retry。 再來從log與code可以得知,它讀取的檔案是answer file而不是boot command line。因此我接下來的測試,就是在answer file的network command上加入dhcptimeout: network --onboot = yes --bootproto =dhcp --ipv6 =auto --device =eth1 --...

第一次寫MIB就上手

SNMP(Simple Network Management Protocol)是用來管理網路設備的一種Protocol,我對它的認識也是從工作接觸開始。雖說是管理網路設備,但是主機、電源供應器、RAID等也都可以透過它來做管理。如果你做了一個應用程式,當然所有的操作也都可以透過SNMP來完成,不過可能會很痛苦。前陣子遇到一個學弟,它告訴我說:「我可能不會想寫程式。」為什麼? 因為這是他痛苦的根源。 在這篇文章中,不是要告訴你SNMP是什麼,會看這篇文章的大哥們,應該已經對SNMP有些認識了。 是的!主題是MIB(Management information base)! 對於一個3th-party的SNMP oid,有MIB可以幫助你去了解它所提供的資訊是什麼,且可以對它做什麼操作。最近我運氣很好剛好做到關於修改MIB的工作,也讓我順便了解一下它的語法,接下來我要交給大家MIB的基礎認識。 smidump 我並非使用什麼高強的Editor去編寫MIB,我僅透過Nodepad++編輯和smidump編譯而已。smidump是Kay教我使用的一個將MIB module轉成樹狀結構或oid列表的工具,唯一的缺點是不會告訴你哪一行打錯。當然有錢直接買編輯樹狀結構的工具就可以不需要了解語法了! 安裝 在Ubuntu上可先輸入smidump確認是否安裝,如果沒安裝可透過apt-get install libsmi2ldbl安裝。(CentOS可以透過yum install libsmi) root@tonylin:~/multi-boot-server# smidump The program 'smidump' is currently not installed. You can install it by typing: apt-get install libsmi2ldbl 使用 透過下面兩行指令,就可以將mib file產生出對應的tree與oid列表的檔案。也可以透過這個結果確認MIB是不是你想要的。 smidump -f tree example1.mib > xtree.txt smidump -f identifiers example1.mib > xiden.txt 如果有參考其它檔案要加上p的參數: smidum...