ColdFusionカフェテリア
SAMURAIZ

 

ColdFusionで開発するはじめてのfacebookアプリケーション【アプリ開発編】

作成日: 2011年5月23日
作成者:(有)デジタルムーン 橋本 晴子
最終更新日: 2011年5月23日
 

今回はサンプルアプリを例に、ColdFusionとjavascript SDKでfacebookアプリを開発する方法をご紹介します。
 

サンプルアプリの内容
まずはアプリからfacebookへログインし、パーミッションを許可します。すると、facebookプロフィール画像をメッセージフレームと合成して、 アルバムに投稿する事ができます。自分のプロフィール画像はもちろん、友達のプロフィール画像も加工することができます。
加工した画像を友達のアルバムに投稿してサプライズは如何ですか?

 

サンプル

http://www.cf-girl.net/facebook/
http://apps.facebook.com/coldfusionapp/
上記どちらからでも同じアプリが見えます。

 

ファイル構成

 

制作の手順

手順

 

 

1.ログイン

■ログインボタン
ログインボタンをクリックすると、login関数が動くようにします。
 
HTML

<button id="login”>ログイン</button>

javascript SDKを利用する場合は、このコードを忘れずに書いておいて下さい。

<div id="fb-root”></div>


jQuery

//ログインボタンをクリックしたらlogin関数を実行する
$(’#login’).bind(’click’, function() {
login();
});

 
■ログイン処理

ログインボタンを押した時の処理は、javascript SDKを利用します。
ここでのポイントはパーミッションを設定する事です。
自動的に、パーミッションを許可するか否かのポップアップウインドウが表示されます。
パーミッションの種類はこちらを参照してください。
サンプルアプリでは、投稿を許可する、publish_stream,user_photos, friends_photos を設定しています。
ただし、パブリックな情報については許可の必要はありません。
 

javascript SDK

//ログイン処理
function login(){
//ログインにパーミッションの設定をします。
FB.login(handleSessionResponse, {perms:’publish_stream, user_photos, friends_photos’});
}

 

2.プロフィール画像の取得と表示

プロフィール画像の取得には、SQLの構文で書ける、FQL(Facebook Query Language)を利用します。

 

2−1.自分のプロフィール画像の取得と表示

■自分のプロフィール画像を表示する。
HTML 

<div id="myimage” ></div>

 

■index.cfm getProfile関数 −自分のプロフィール画像を取得−
javascript SDKで、FQLを利用してプロフィール画像を取得します。
ユーザーIDをキーに、profile テーブルから自分のプロフィール画像を取得します。
ユーザーIDは、ユーザーがアプリにログインしていると、me() とう書き方で取得できます。
ちなみに、FB.getSession().uid でもユーザーIDが取得できます。
FQLを利用するには、FB.api を使います。
プロフィール画像を表示する部分は、dspProfile関数で行います。
 

FB.api 構文
FB.api( FQL , コールバック関数 ) 
FQL部分の詳細  
{
method: ‘fql.query’,
query: ‘SELECT id,name, pic,pic_square FROM profile WHERE id= me()’
}
 
javascript SDK 

//プロフィール画像を取得
function getProfile(){
FB.api(
{
method: ‘fql.query’,
query: ‘SELECT id,name, pic,pic_square FROM profile WHERE id= me()’
},
//コールバック関数
function(response) {
if (!response || response.error) {
//エラーの場合
alert(’クエリーエラー ’+ response.error.message);
} else {
//成功の場合
//プロフィール画像を表示する関数
dspProfile(response);

}//end if
}//end callback
);//end FB.api
}//end getProfile


■index.cfm dspProfile関数 −取得した自分のプロフィール画像を表示−

プロフィール画像を表示する部分です。jQueryを利用してHTMLを作成しています。
IMGタグのID名はユニークになるように、ユーザーIDを利用しています。
SRCには正方形のプロフィール画像のパスを設定しています。
合成画像には大きなプロフィール画像を使いたいので、NAME属性に大きい画像のパスを設定しています。
jQuery

//プロフィール画像を表示
function dspProfile(response){
//FQLで取得した1行目をuser変数にセット
var user = response[0];

//プロフィール画像を表示
$(’#myimage’).html(’<img id="f’+ user.id + ‘” src=”‘ + user.pic_square + ‘” name=”‘ + user.pic + ‘” onclick="profileImageClick(this.id)”>’).show(’fast’);

//ユーザー名を配列に保存(アルバム投稿時に使います。)
pName[user.id] = user.name ;

}

 

 

2−2.友達のプロフィール画像の取得と表示

■友達のプロフィール画像を表示する。
HTML 

<div id="friend-image” ></div>


■index.cfm getFriend関数 
 −友達のプロフィール画像を取得−
友達のプロフィール画像は、FQLのサブクエリーを使って抽出します。
サブクエリーの中で、friendテーブルから、自分のユーザーIDをキーに、友達のユーザーIDを取得します。
サブクエリーで取得した友達のユーザーIDをキーに、profileテーブルから友達のプロフィール画像を取得します。
javascript SDK

//友達のプロフィール画像を取得
function getFriend(){
FB.api(
{

//友達のプロフィール画像は、サブクエリーを使います。
method: ‘fql.query’,
query: ‘SELECT id,name, pic_big , pic_square FROM profile WHERE id IN (SELECT uid2 FROM friend WHERE uid1 = me())’
},
//クエリー取得したら実行
function(response) {
if (!response || response.error) {
alert(’クエリーエラー ’+ response.error.message);
} else {

//プロフィール画像を表示
dspFriendProfile(response);

}//end if
}//end callback
);//end FB.api
}//end getFriend関数

 

■index.cfm dspFriendProfile関数 −取得した友達のプロフィール画像を表示−
友達のプロフィール画像を表示する部分です。jQueryを利用してHTMLを作成しています。
今回は複数のレコードがある想定なので、ループしながら表示します。
IMGタグのID名はユニークになるように、ユーザーIDを利用しています。
SRCには正方形のプロフィール画像のパスを設定しています。
合成画像には大きなプロフィール画像を使いたいので、NAME属性に大きい画像のパスを設定しています。
 
jQuery

//友達プロフィール画像を表示
function dspFriendProfile(response){
//複数のレコードをループしながら画像を表示します。
for (var i=0, l=response.length; i<l; i++) {
//処理行をuser変数に保持
var user = response[i];
//画像を表示します
$("#friend-image").append(’<img id="f’+ user.id + ‘” src=”‘ + user.pic_square + ‘” name=”‘ + user.pic_big + ‘” onclick="profileImageClick(this.id)”>’);
//友達の情報を配列に保存
pName[user.id] = user.name ;
}//end ループ
}//end dspFriendProfile関数

 

 

3.フレーム画像とプロフィール画像を選択

画像クリックした場合の処理
・1つ前に選択していた画像のボーダーを消す
・クリックした画像のIDを変数に保持
・クリックした画像にボーダーを表示
・ポップアップウインドウを開く処理

 

ポップアップウインドウ
フレーム画像とプロフィール画像をクリックしたら、
確認用のポップアップウインドウを開きます。
合成画像のイメージは予めIMGタグのname属性に設定しておいた、大きなプロフィール画像を使っています。
ここではCSSでフレーム画像と重ねて表示しています。
この段階では合成画像はまだ作成していません。
ポップアップウインドウは、ColdFusionのajax機能であるcfwindowを利用しています。
コードの詳細は末尾のまとめのコードをご覧下さい。

 

4.シェアボタンを押すと、合成画像作成CFCをコール

ポップアップウインドウ内のシェアボタンを押すと、ColdFusion コンポーネント(CFC)にフレーム画像のパスと、プロフィール画像のパスを渡し、
画像を合成します。
javascriptとCFCを連携させるためには、ColdFusionのajax機能を利用すると簡単です。
ヘッダー内に次のコードを書きます。
cfajaximport:利用するColdFusion AJAX タグを指定します。
cfajaxproxy:javascriptとCFCを紐付けします。サンプルでは、ドメイン直下のfacebookフォルダー内のfacebook.cfcをfacebookという名前で利用できるようにしています。
javascriptからCFCをコールする部分は次ぎの3点セットで記述します。
1.コール
2.コールバック関数(成功時)
3.エラー処理関数(失敗時)
 

cfajaxのしくみ
cfajax

HEADタグ −javascriptプロキシの設定− 

<head>

<!— cfajax を使うときに必要です。必ずheadタグの中に書きます。—>
<!— CFAJAX用のタグを書きます。(今回はcfwindowのみ利用。)—>
<cfajaximport tags="cfform,cfwindow”>
<!— jacasvriptとCFCを紐付けます。
ドメイン直下のfacebookフォルダー内のfacebook.cfcを利用します。 —>
<cfajaxproxy cfc="facebook.facebook” jsclassname="facebook”>
<link rel="stylesheet” href="base.css”>
</head>

 
■index.cfm makeImageCFC関数 
−画像合成CFCをコール−

javascript側からCFCをコールする部分です。
 
順番
1.プロキシのインスタンス作成
2.成功時に実行する関数(コールバック関数)
3.エラー時に実行する関数
4.CFCの関数をコール
 
画像合成を作成するCFCに渡す引数

・フレーム画像のパス
・プロフィール画像のパス
javascript

//画像合成CFCをコール
//CFCにフレーム画像とプロフィール画像のパスを渡します。
var makeImageCFC = function(frameImagePath,profileImagePath){

//1.プロキシのインスタンスを作成します。
var f = new facebook();
//2.成功した場合のコールバック関数の指定
f.setCallbackHandler(makeImage_success);
//3.失敗の場合のエラー処理関数の指定
f.setErrorHandler(makeImage_error);
//4.CFCのmakeImag関数を呼び出します
f.makeImage(frameImagePath,profileImagePath);

}

 
■index.cfm makeImage_success関数 
−画像合成CFCコール 成功した場合のコールバック関数

javascript側の成功時に実行する関数(コールバック関数)です。
CFCで合成した画像ファイル名を受け取り、アルバムに投稿する準備をします。
 
アルバムに投稿する準備
・合成画像のファイル名
・ログイン者のアクセストークン(facebookに投稿する為に必要です)
・プロフィール画像の名前(アルバムにタグ付用)
・プロフィール画像のユーザーID(アルバムにタグ付用)
facebookに投稿するには、ユーザーのアクセストークンが必要になります。アクセストークンは、FB.getSession().access_tokenで取得できます。アルバムを投稿する際にはタグ付けも行うので、プロフィール画像の名前とユーザーIDも渡します。タグ付けする事で、友達のアルバムに画像を投稿する事ができます。
・アルバムにタグ付けして投稿するCFCを呼び出すpostImageCFC関数を実行します。
javascript

//画像合成CFC 成功した場合のコールバック関数
//CFCで合成した新しい画像ファイル名を受け取り、アルバムに投稿する関数を呼び出します。
var makeImage_success = function(newImageName)
{

//クリックしたプロフィール画像のuidを取得
var userId = pId.slice(1, pId.length);

//画像をfacebookのアルバムにタグ付けして投稿する準備をします
//合成画像のファイル名
var imageName = newImageName;
//アクセストークン(postする際に必要です)
var access_token = FB.getSession().access_token;
//クリックしたプロフィールの名前(タグ付けで使います)
var prof_name = pName[userId];
//クリックしたプロフィール画像のユーザーID(タグ付けで使います)
var tag_uid = userId;

//アルバムにタグ付けして投稿する関数を呼び出します。
postImageCFC(imageName,access_token,prof_name,tag_uid);

}

 
■index.cfm makeImage_error関数
−画像合成CFCコール 失敗した場合のエラー処理関数−

javascript側の失敗時に実行するエラー処理関数です。非同期で処理しています。
javascript

//画像合成CFCコール 失敗した場合のエラー処理関数(非同期)
var makeImage_error = function(statusCode, statusMsg)
{
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
//エラーメッセージ表示
$(’#winDspEnd’).html(’エラーが発生しました。画像が作成できませんでした。’ ).show(’fast’);
}


■facebook.cfc makeImage関数    −CFC側 合成画像を作成−

ColdFusionコンポーネント側の処理です。
ここではcfimageタグを使って実際にプロフィール画像とフレーム画像を合成しています。
合成した画像のパスをjavascript側に返します。
合成画像を作成する為にjavascript側から受け取る引数
・フレーム画像のパス
・プロフィール画像のパス
ColdFusion コンポーネント(CFC)

<!—合成画像のパス —>
<cfset thisPath=ExpandPath("photo/*.*")>
<cfset thisDirectory=GetDirectoryFromPath(thisPath)>

<!— 合成画像URL —>
<cfset imageUrl="http://www.cf-girl.net/facebook/photo/”>

 

<!—CFC側 合成画像を作成する関数 —>
<cffunction name="makeImage” access="remote” output="false”>
<!—javascript側から受け取る引数 —>
<cfargument name="frameImagePath” type="string” required="yes” hint="背景画像パス” >
<cfargument name="profileImagePath” type="string” required="yes” hint="プロフィール画像パス” >

<!— ▼ここから画像加工 —>
<!— プロフィールオブジェクト作成 —>
<cfimage source="#profileImagePath#” name="myImage1″>
<!— ベース画像オブジェクト作成 —>
<cfimage source="img/base.png” name="myImage2″>
<!— フレーム画像オブジェクト作成 —>
<cfimage source="#frameImagePath#” name="myImage3″>
<!— ベース画像にアンチエイリアスをつける —>
<cfset ImageSetAntialiasing(myImage2)>
<!— フレーム画像にアンチエイリアスをつける —>
<cfset ImageSetAntialiasing(myImage3)>
<!— フレーム画像のサイズを変更する —>
<cfset ImageResize(myImage3,"80″,””,"lanczos")>
<!— プロフィール画像のサイズを変更する —>
<cfset ImageResize(myImage1,"80″,””,"lanczos")>
<!— ベース画像の上にプロフィール画像を貼る —>
<cfset ImagePaste(myImage2,myImage1,0,0)>
<!— ベース+プロフィール画像の上にフレーム画像を貼る —>
<cfset ImagePaste(myImage2,myImage3,0,0)>

<!— ▼画像を書き出す (年月日時分秒ミリ秒)—>
<!— ファイル名 —>
<cfset imgName = “#dateformat(now(),"YYMMDD")##timeformat(now(),"HHMMSSl")#.png”>

<cftry>
<!— 合成画像を物理的に書き出す —>
<cfimage source="#myImage2#” action="write” destination="#thisDirectory##imgName#” overwrite="no”>
<cfcatch type="any”>
<!— 既に同じファイル名の画像が存在していたらエラー —>
<cfset newImagepath="error”>
</cfcatch>
</cftry>

<!— 新しく合成した画像のパスを返す —>
<cfreturn imgName>

</cffunction>

 

 

5.facebookのアルバムに画像を投稿

index.cfm postImageCFC関数
 −アルバムに合成画像を投稿するCFCをコール−

アルバムに画像を投稿するCFCを呼び出す部分です。
先ほど、合成画像を作成したCFCから返された合成画像ファイル名、合成画像CFCコールのコールバック関数で準備したアクセストークン、プロフィール画像の名前、ユーザーIDを利用します。
 
順番

1.プロキシのインスタンス作成
2.成功時に実行する関数(コールバック関数)
3.エラー時に実行する関数
4.CFCの関数をコール
 
アルバムに投稿するCFCに渡す引数

・合成画像のファイル名
・ログイン者のアクセストークン(facebookに投稿する為に必要です)
・プロフィール画像の名前(アルバムにタグ付用)
・プロフィール画像のユーザーID(アルバムにタグ付用)
javascript

//アルバムに合成画像を投稿するCFCをコール
var postImageCFC = function(imageName,access_token,prof_name,tag_uid){

//1.プロキシのインスタンス作成
var f2 = new facebook();
//2.成功時に実行する関数(コールバック関数)
f2.setCallbackHandler(postImage_success);
//3.エラー時に実行する関数
f2.setErrorHandler(postImage_error);
//4.CFCの関数をコール
f2.postAlbum(imageName,access_token,prof_name,tag_uid);

}

  
index.cfm postImage_success関数
−アルバムに合成画像を投稿するCFCコール 成功した場合のコールバック関数−

javascript側の成功時に実行する関数(コールバック関数)です。
CFC側で、アルバム投稿が成功していたら、ニュースフィードにも投稿します。アルバム成功が失敗していたら、アラートを表示します。アルバム投稿はCFHTTPで行っているので、その処理結果により判断しています。javascriptからCFCをコールした処理は成功していても、CFC内部のcfhttpが失敗している場合があるので、条件分岐を入れています。
次に、ニュースフィードへ投稿する準備をします。
ニュースフィードに投稿する準備
・ログイン者のアクセストークン(facebookに投稿する為に必要です)
・メッセージ(ポップアップウインドウで入力したテキストです)
・合成画像のファイル名
・ニュースフィードに投稿するCFCを呼び出すpostFeedCFC関数を実行します。
javascript

//アルバムに合成画像を投稿するCFCコール 成功した場合のコールバック関数
var postImage_success = function(newImageName){

// cfhttpの処理結果がOKかNGか判定します。
if(newImageName.indexOf("NG")==-1){

// cfhttpがokの場合
var imageName = newImageName;
var message = $(’#message’).val();//入力したメッセージ
var access_token = FB.getSession().access_token;

// Feedに投稿する。
postFeedCFC(access_token,message,imageName);

}

else{

// cfhttpがngの場合
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
$(’#winDspEnd’).html(’エラーが発生しました。アルバムに投稿できませんでした。’ ).show(’fast’);

}

}

 
index.cfm postImage_error関数
−アルバムに合成画像を投稿するCFCコール 失敗した場合のエラー処理関数−

javascript側の失敗時に実行するエラー処理関数です。非同期で処理しています。
javascript

//アルバムに合成画像を投稿するCFCコール 失敗した場合のエラー処理関数(非同期)
var postImage_error = function(statusCode, statusMsg)
{
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
$(’#winDspEnd’).html(’エラーが発生しました。<br>アルバムに投稿できませんでした。<br><br>statusCode:’+statusCode + ‘<br>statusMsg:’+statusMsg ).show(’fast’);
}

 
■facebook.cfc postAlbum関数    −CFC側 アルバムに投稿−

ColdFusionコンポーネント側の処理です。
ここではcfhttpタグを使ってfacebookのアルバムに合成画像を投稿します。
 
アルバムに投稿する為にjavascript側から受け取る引数
・合成画像のファイル名
・ログイン者のアクセストークン(facebookに投稿する為に必要です)
・プロフィール画像の名前(アルバムにタグ付用)
・プロフィール画像のユーザーID(アルバムにタグ付用)。
 
facebook APIに渡す引数

・アクセストークン
・画像パス
・アルバムに投稿する際の投稿文(ここは固定にしています)
・タグ付用テキスト(名前とユーザーID)
 
ColdFusion コンポーネント(CFC)

<!— facebookアルバムに投稿する —>
<cffunction name="postAlbum” access="remote” output="false” hint="アルバムにタグ付けして写真を投稿する”>

<!— javascript側から受け取る引数 —>
<cfargument name="imageName” type="string” required="yes” hint="画像ファイル名” >
<cfargument name="access_token” type="string” required="yes” hint="アクセストークン” >
<cfargument name="prof_name” type="string” required="yes” hint="プロフィール画像の人の名前” >
<cfargument name="tag_uid” type="string” required="yes” hint="プロフィール画像の人のuserid” >

<!— 画像が存在していたら処理する —>
<cfif fileexists("#thisDirectory##imageName#")>

<!— ▼cfhttpでfacebookのアルバムに投稿 —>
<cfhttp method="post” url="https://graph.facebook.com/me/photos” multipart="yes” result="res”>

<!— facebook API に渡す引数 —>
<!— アクセストークン —>
<cfhttpparam type="formfield” name="access_token” value="#access_token#”>
<!— 画像パス —>
<cfhttpparam type="file” name="source” file="#thisDirectory##imageName#”>
<!— アルバムに投稿する際の投稿文(ここは固定にしています) —>
<cfhttpparam type="formfield” name="message” value="message photo frame made by using ColdFusionアプリが画像を作成しました!”>
<!— タグ付用テキスト(名前とユーザーID) —>
<cfhttpparam type="formfield” name="tags” value=’[{"tag_text”:"#prof_name#”,"tag_uid”:"#tag_uid#”,"x”:"20″,"y”:"20″}]’>

</cfhttp>
<!— ▲cfhttpでfacebookのアルバムに投稿 —>

<!—cfhttpの戻り値により、成功か失敗か条件分岐 —>
<cfif res.Statuscode contains “200″>
<!—成功なら合成画像パスをjavascriptに返す —>
<cfreturn imageName>
<cfelse>
<!—失敗ならエラーメッセージを返す —>
<cfset error_message = “NG ” & res.Statuscod>
<cfreturn error_message>
</cfif>

<cfelse>
<!— 画像が存在していなかったら処理する —>
<cfreturn “NG 画像がありません”>
</cfif>

</cffunction>

 

 

6.facebookのニュースフィードに投稿

index.cfm postFeedCFC関数  −ニュースフィードに投稿するCFCをコール−
いよいよ最後です。ニュースフィードへ投稿するCFCの呼び出し部分です。
 
順番
1.プロキシのインスタンス作成
2.成功時に実行する関数(コールバック関数)
3.エラー時に実行する関数
4.CFCの関数をコール
 
ニュースフィードに投稿するCFCに渡す引数

・ログイン者のアクセストークン(facebookに投稿する為に必要です)
・投稿文(ポップアップウインドウで入力したテキストです)
・合成画像のファイル名
javascript 

//ニュースフィードに投稿するCFCコール
var postFeedCFC = function(access_token,message,imageName){

//1.プロキシのインスタンス作成
var f = new facebook();
//2.成功時に実行する関数(コールバック関数)
f.setCallbackHandler(postFeed_success);
//3.エラー時に実行する関数
f.setErrorHandler(postFeed_error);
f.postFeed(access_token,message,imageName);
}

 

index.cfm postFeed_success関数
−ニュースフィードに投稿するCFCコール 
成功した場合のコールバック関数−
javascript側の成功時に実行する関数(コールバック関数)です。
CFC側で、ニュースフィードへの投稿が失敗していたら、アラートを表示します。
成功していたら、ポップアップウインドウ内に完了メッセージを表示します。
javascript

//ニュースフィードに投稿するCFCコール 成功した場合のコールバック関数
var postFeed_success = function(res)
{

if(res.indexOf("200″)==-1){
//CFHTTPタグを利用したニュースフィードへの投稿が失敗した場合、エラーメッセージを表示
$(’#winDspForm’).hide(’fast’);
$(’#winDspEnd’).html(’エラーが発生しました。Feedに投稿できませんでした。’ ).show(’fast’);
}
else{
//CFHTTPタグを利用したニュースフィードへの投稿が成功した場合、完了処理を実行
//ウインドウを完了表示に切り替える
dspWinEnd();
}

}

 
index.cfm postFeed_error関数
−ニュースフィードに投稿するCFCコール 失敗した場合のエラー処理関数−

javascript側の失敗時に実行するエラー処理関数です。非同期で処理しています。
javascript

//ニュースフィードに投稿するCFCコール 失敗した場合のエラー処理関数
var postFeed_error = function(statusCode, statusMsg)
{
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
$(’#winDspEnd’).html(’エラーが発生しました。<br>ニュースフィードに投稿できませんでした。<br><br>statusCode:’+statusCode + ‘<br>statusMsg:’+statusMsg ).show(’fast’);
}

 
■facebook.cfc postFeed関数    −CFC側 ニュースフィードに投稿−

ColdFusionコンポーネント側の処理です。
ここではcfhttpタグを使ってfacebookのニュースフィードに投稿します。
ニュースフィードに投稿する為にjavascript側から受け取る引数
・ログイン者のアクセストークン(facebookに投稿する為に必要です)
・投稿文(ポップアップウインドウで入力したテキストです)
・合成画像のファイル名
 
facebook APIに渡す引数

・アクセストークン
・アプリ名
・リンク
・画像パス
・アプリのURL
・投稿文(ポップアップウインドウで入力したテキスト)
・説明文
 
注意
何度も投稿すると、スパムと認識され投稿できなくなります。開発時にはテストユーザーを作成する事をお勧めします。
 

ColdFusion コンポーネント(CFC)

<!— faebookニュースフィードに投稿する —>
<cffunction name="postFeed” access="remote” output="false” hint="feedへ投稿”>
<!— 投稿のlimitあり。 —>
<!— javascript側から受け取る引数 —>
<cfargument name="access_token” type="string” required="yes” hint="アクセストークン” >
<cfargument name="message” type="string” required="yes” hint="入力したメッセージ” >
<cfargument name="imageName” type="string” required="yes” hint="合成した画像ファイル名” >

<!— ▼CFHTTPを利用してニュースフィードに投稿 —>
<cfhttp method="post” url="https://graph.facebook.com/feed” result="res” >
<!— facebook API に渡す引数 —>
<!— アクセストークン —>
<cfhttpparam type="formfield” name="access_token” value="#access_token#”>
<!— アプリ名 —>
<cfhttpparam type="formfield” name="name” value="coldfusionapp”>
<!— リンク —>
<cfhttpparam type="formfield” name="link” value="http://apps.facebook.com/coldfusionapp/”>
<!— 画像パス —>
<cfhttpparam type="formfield” name="picture” value="#imageUrl##imageName#”>
<!— アプリのURL —>
<cfhttpparam type="formfield” name="caption” value="http://apps.facebook.com/coldfusionapp/”>
<!— 投稿文(ポップアップ画面で入力したもの) —>
<cfhttpparam type="formfield” name="message” value="#message#”>
<!— 説明文 —>
<cfhttpparam type="formfield” name="description” value="message photo frame made by using ColdFusionでプロフィール画像を飾ろう。”>
</cfhttp>
<!— ▲CFHTTPを利用してニュースフィードに投稿 —>

<!— javascript側にCFHTTPの処理結果を返します —>
<cfreturn res.Statuscode>

</cffunction>

 

 

7.すべてのコード

CSS base.css

@charset “utf-8″;
/* CSS Document */

#wrapper{width: 640px; margin: 0 auto;}
#caption{
margin-top:0;
font-size:12px;
}

/****************************************
ログインボタン
*****************************************/
#button{
margin-top:20px;
}

/****************************************
フレーム画像
*****************************************/
#frame-title{background:#3B5998;
color:#FFFFFF;
font-weight:bold;
padding:3px 10px;
width:619px;
height:20px;
}

#frame-image {
border:1px solid #808080;
height: 200px;
}
#frame-image img {
margin:25px 5px 10px 5px;
}

/****************************************
プロフィール画像
*****************************************/
#user-info{
margin-top:10px;
border:1px solid #808080;
}
#profile-title{
background:#3B5998;
color:#FFFFFF;
font-weight:bold;
padding:3px 10px;
width:619px;
height:20px;
}

#user-info img{
margin:15px 10px;
}

.friendborder {
border-bottom:1px dotted #CCCCCC;
color:#3B5998;padding-left:10px;
margin-top:5px;
}

/****************************************
ポップアップウインドウ
*****************************************/
#logo {
position: relative;
}
#logo .w-profile-image {
width: 80;
}
#logo .w-frame-image {
position: absolute;
top: 0px;
left: 0px;
}

/* テキストエリアに文字をプレ表示 */
.focus{color: #969696}

 

 

HTML・javascrript側
index.cfm

FB.init({ apiKey: ‘<ここにアプリのAPI keyをセットして下さい>’ });の部分はご自分のアプリを登録し、そのAPIkeyをセットしてください。アプリの登録、javascriptSDKの基本的な説明については、前回の記事ColdFusionで開発するはじめてのfacebookアプリケーション【準備編】をご参照ください。

<!doctype html>
<html>
<!–
Copyright Facebook Inc.

Licensed under the Apache License, Version 2.0 (the “License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
–>
<head>
<meta http-equiv="content-type” content="text/html; charset=utf-8″>
<title>ColdFusionフォトフレーム</title>
<!— cfajax を使うときに必要です。必ずheadタグの中に書きます。—>
<!— CFAJAX用のタグを書きます。(今回はcfwindowのみ利用。)—>
<cfajaximport tags="cfform,cfwindow”>
<!— jacasvriptとCFCを紐付けます。
ドメイン直下のfacebookフォルダー内のfacebook.cfcを利用します。 —>
<cfajaxproxy cfc="facebook.facebook” jsclassname="facebook”>
<link rel="stylesheet” href="base.css”>
</head>
<body>

<div id="wrapper”>

<img src="img/head.png” alt="coldfusion photo frame” width="640″ height="132″>
<div id="button”>
<button id="login”>facebookと連携する</button>
<button id="logout”>facebookとの連携を解除する</button>
</div>
<div class="caption” style="margin:-18px 0 0 200px;”>フレーム画像とプロフィール画像をクリックしてください。</div>
<div id="content” style="margin-top:20px;”>
<!–フレーム画像エリア –>
<div id="frame-image”>
<div id="frame-title”>frame image</div>
<!— 枠画像 —>
<div align="center”>
<img id="waku6″ src="img/waku6.png” onclick="backImageClick(this.id)” width="80″ />
<img id="waku1″ src="img/waku1.png” onclick="backImageClick(this.id)” width="80″ />
<img id="waku2″ src="img/waku2.png” onclick="backImageClick(this.id)” width="80″ />
<img id="waku3″ src="img/waku3.png” onclick="backImageClick(this.id)” width="80″ />
<img id="waku4″ src="img/waku4.png” onclick="backImageClick(this.id)” width="80″ />
<img id="waku5″ src="img/waku5.png” onclick="backImageClick(this.id)” width="80″ />
</div>
</div>
<!–プロフィール画像エリア –>
<div id="user-info” >
<div id="profile-title”>profile image</div>
<!–自分のプロフィール画像 –>
<div id="myimage” ></div>
<div class="friendborder”>friend’s</div>
<!–友達のプロフィール画像 –>
<div id="friend-image” ></div>
</div>
<div id="fb-root”></div>
</div>

</div><!–end wrapper –>

<!— jQuery —>
<script type="text/javascript” src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js”></script>

<!— facebook SDK —>
<script type="text/javascript” src="http://connect.facebook.net/ja_JP/all.js”></script>

<script>

//▼▼▼ ログイン関連ファンクション

// 初期化 自分のアプリのAPI keyをセット
FB.init({ apiKey: ‘<ここにアプリのAPI keyをセットして下さい>’ });

// ログイン状態を取得
FB.getLoginStatus(handleSessionResponse);

 //ログインボタンをクリックしたらlogin関数を実行する
$(’#login’).bind(’click’, function() {
login();
});

 //ログアウトボタンクリック
$(’#logout’).bind(’click’, function() {
FB.logout(handleSessionResponse);
});

//アプリの許可取り消しボタンクリック
$(’#disconnect’).bind(’click’, function() {
FB.api({ method: ‘Auth.revokeAuthorization’ }, function(response) {
clearDisplay();
});
});

//ログイン中 (ログインボタンを非表示 ログアウトボタンを表示)
function hideLoginBtn(){
$(’#login’).hide(’fast’);
$(’#logout’).show(’fast’);
}
//ログアウト中 (ログアウトボタンを非表示 ログインボタンを表示)
function hideLogoutBtn(){
$(’#logout’).hide(’fast’);
$(’#login’).show(’fast’);
}

// 画面表示をクリア
function clearDisplay() {
$(’#user-info’).hide(’fast’);
}

//ログイン処理
function login(){
//パーミッションの設定を追加した場合、次回のログイン時に、新たに承認画面が表示される。
FB.login(handleSessionResponse, {perms:’publish_stream’});//,read_stream,publish_stream,offline_access
}

// セッション状態を判定し処理
function handleSessionResponse(response) {
if (response.session) {
if (response.perms) {
//alert(’ ログインしています。アプリの承認済みです。’);
// perms is a comma separated list of granted permissions
//ログアウトボタン表示・ログインボタンを非表示
hideLoginBtn();
//アプリ初期画面表示
appIni();

} else {
// user is logged in, but did not grant any permissions
//alert(’ ログインしています。アプリは承認していません。’);
//login();
//ログインボタン表示・ログアウトボタンを非表示
hideLogoutBtn();
}
} else {
//alert(’ ログアウトしています。’);
clearDisplay();
//ログインボタン表示・ログアウトボタンを非表示
hideLogoutBtn();
}
}

//▼▼▼ 画面表示ファンクション

var pName = new Array(1);//クリックしたプロフィール画像の人の名前

//アプリ初期画面表示
function appIni(){
//表示エリアを表示
$(’#user-info’).show(’fast’);
//友達プロフィール画像エリアをクリア
$("#friend-image").empty();
//自分のプロフィール画像を取得して表示する。
getProfile();
//友達のプロフィール画像を表示する。
getFriend();
}

var myProfileResponse ;
//プロフィール画像を取得
function getProfile(){
FB.api(
{
method: ‘fql.query’,
query: ‘SELECT name, pic,pic_square FROM profile WHERE id= me()’
},
//クエリー取得したら実行
function(response) {
if (!response || response.error) {
alert(’クエリーエラー ’+ response.error.message);
} else {

//プロフィール画像を表示
dspProfile(response);

}
}
);
}

//プロフィール画像を表示
function dspProfile(response){
//FQLで取得した1行目をuser変数にセット
var user = response[0];

//プロフィール画像を表示
$(’#myimage’).html(’<img id="f’+ user.id + ‘” src=”‘ + user.pic_square + ‘” name=”‘ + user.pic + ‘” onclick="profileImageClick(this.id)”>’).show(’fast’);

//ユーザー名を配列に保存(アルバム投稿時に使います。)
pName[user.id] = user.name ;

}

//友達のプロフィール画像を取得
function getFriend(){
FB.api(
{
method: ‘fql.query’,
query: ‘SELECT id,name, pic_big , pic_square FROM profile WHERE id IN (SELECT uid2 FROM friend WHERE uid1 = me())’
},
//クエリー取得したら実行
function(response) {
if (!response || response.error) {
alert(’クエリーエラー ’+ response.error.message);
} else {

//プロフィール画像を表示
dspFriendProfile(response);

}//end if
}//end callback
);//end FB.api
 
}//end getFriend関数

//友達プロフィール画像を表示
function dspFriendProfile(response){

for (var i=0, l=response.length; i<l; i++) {
var user = response[i];
$("#friend-image").append(’<img id="f’+ user.id + ‘” src=”‘ + user.pic_square + ‘” name=”‘ + user.pic_big + ‘” onclick="profileImageClick(this.id)”>’);
//友達の情報を配列に保存
pName[user.id] = user.name ;
}
}

 

//▼▼▼ プログラム本体(画像クリックしてウインドウ表示)

var bId = “”; //一つ前に選択した背景画像のid
var pId = “”; //一つ前に選択したプロフィール画像のid
var prevWinName = “winPost”; //プレビューウインドウ名

//背景画像がクリックされた場合の処理
function backImageClick(id){
//一つ前に選択していた画像のボーダーを消す
delBorder(bId);
//現在のIDを保存
saveId("bId”,id);
//現在選択している画像にボーダーを表示
setBorder(id,"solid”,"10px”,"red");
//プレビュー画面表示
openPreview();
}

//プロフィール画像がクリックされた場合の処理
function profileImageClick(id){
//一つ前に選択していた画像のボーダーを消す
delBorder(pId);
//現在のIDを保存
saveId("pId”,id);
//現在選択している画像にボーダーを表示
setBorder(id,"solid”,"10px”,"red");
//プレビュー画面表示
openPreview();

}

//画像にボーダーをつける
function setBorder(id,stle,size,color){
if(id != “"){
var img = document.getElementById(id);
img.style.borderStyle=stle;
img.style.borderWidth=size;
img.style.borderColor=color;
}
}

//画像からボーダーを消す
function delBorder(id){
if(id != “"){
var img = document.getElementById(id);
img.style.borderStyle=’none’;
}
}

//現在のIDを保存
function saveId(idName,id){
this[idName]=id;
}

//プレビュー画面表示
function openPreview(){
if(bId != “” && pId != “"){

//ウインドウ内を表示する
dspWinShow();

//cssで疑似的に表示する
var img = document.getElementById(’wPimage’);
img.src = document.getElementById(pId).name; //大きいプロフィール画像を表示
var img = document.getElementById(’wFimage’);
img.src = document.getElementById(bId).src;

//モーダルウインドウを開く(背景画像+プロフィール画像)
winOpen(prevWinName);

}
}

//モーダルウインドウを開く
function winOpen(winName){
//背景画像にプロフィール画像を重ねるCFCをコール
javascript:ColdFusion.Window.show(winName);
}
//モーダルウインドウを閉じる
function winClose(winName){
javascript:ColdFusion.Window.hide(winName);
}

//ウインドウのシェアボタン
function doPost(){
//ポップアップウインドウ内をローディング中の表示にする。
$(’#winDspForm’).hide(’fast’);
$(’#winDspLoading’).html(’<img src="img/loading.gif”>’ ).show(’fast’);
//フレーム画像とプロフィール画像をCFCで合成して画像を作成する。
//大きい画像を使う
//makeImageCFC( document.getElementById(bId).src , document.getElementById(pId).name );

}
//ウインドウのキャンセルボタン
function doCancel(){
winClose(prevWinName);

}

//画像合成CFCをコール
//CFCにフレーム画像とプロフィール画像のパスを渡します。
var makeImageCFC = function(frameImagePath,profileImagePath){
//1.プロキシのインスタンスを作成します。
var f = new facebook();
//2.成功した場合のコールバック関数の指定
f.setCallbackHandler(makeImage_success);
//3.失敗の場合のエラー処理関数の指定
f.setErrorHandler(makeImage_error);
//4.CFCのmakeImag関数を呼び出します
f.makeImage(frameImagePath,profileImagePath);
}

//画像合成CFC 成功した場合のコールバック関数
//CFCで合成した新しい画像ファイル名を受け取り、アルバムに投稿する関数を呼び出します。
var makeImage_success = function(newImageName)
{
//クリックしたプロフィール画像のuidを取得
var userId = pId.slice(1, pId.length);

//画像をfacebookのアルバムにタグ付けして投稿する準備をします
//合成画像のファイル名
var imageName = newImageName;
//アクセストークン(postする際に必要です)
var access_token = FB.getSession().access_token;
//クリックしたプロフィールの名前(タグ付けで使います)
var prof_name = pName[userId];
//クリックしたプロフィール画像のユーザーID(タグ付けで使います)
var tag_uid = userId;

//アルバムにタグ付けして投稿する関数を呼び出します。
postImageCFC(imageName,access_token,prof_name,tag_uid);

}

//画像合成CFCコール 失敗した場合のエラー処理関数(非同期)
var makeImage_error = function(statusCode, statusMsg)
{
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
//エラーメッセージ表示
$(’#winDspEnd’).html(’エラーが発生しました。画像が作成できませんでした。’ ).show(’fast’);
}

//アルバムに合成画像を投稿するCFCをコール
var postImageCFC = function(imageName,access_token,prof_name,tag_uid){
//1.プロキシのインスタンス作成
var f2 = new facebook();
//2.成功時に実行する関数(コールバック関数)
f2.setCallbackHandler(postImage_success);
//3.エラー時に実行する関数
f2.setErrorHandler(postImage_error);
//4.CFCの関数をコール
f2.postAlbum(imageName,access_token,prof_name,tag_uid);
}

//アルバムに合成画像を投稿するCFCコール 成功した場合のコールバック関数
var postImage_success = function(newImageName) {

// cfhttpの処理結果がOKかNGか判定します。
if(newImageName.indexOf("NG")==-1){
// cfhttpがokの場合
var imageName = newImageName;
var message = $(’#message’).val();//入力したメッセージ
var access_token = FB.getSession().access_token;

//Feedに投稿する。
postFeedCFC(access_token,message,imageName);

}
else{
// cfhttpがngの場合
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
$(’#winDspEnd’).html(’エラーが発生しました。アルバムに投稿できませんでした。’ ).show(’fast’);
}

}

//アルバムに合成画像を投稿するCFCコール 失敗した場合のエラー処理関数(非同期)
var postImage_error = function(statusCode, statusMsg)
{
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
$(’#winDspEnd’).html(’エラーが発生しました。<br>アルバムに投稿できませんでした。<br><br>statusCode:’+statusCode + ‘<br>statusMsg:’+statusMsg ).show(’fast’);
}

//ニュースフィードに投稿するCFCコール
var postFeedCFC = function(access_token,message,imageName){

//1.プロキシのインスタンス作成
var f = new facebook();
//2.成功時に実行する関数(コールバック関数)
f.setCallbackHandler(postFeed_success);
//3.エラー時に実行する関数
f.setErrorHandler(postFeed_error);
f.postFeed(access_token,message,imageName);
}

//ニュースフィードに投稿するCFCコール 成功した場合のコールバック関数
var postFeed_success = function(res)
{

if(res.indexOf("200″)==-1){
//CFHTTPタグを利用したニュースフィードへの投稿が失敗した場合、エラーメッセージを表示
$(’#winDspForm’).hide(’fast’);
$(’#winDspEnd’).html(’エラーが発生しました。Feedに投稿できませんでした。’ ).show(’fast’);
}
else{
//CFHTTPタグを利用したニュースフィードへの投稿が成功した場合、完了処理を実行
//ウインドウを完了表示に切り替える
dspWinEnd();
}

}

//ニュースフィードに投稿するCFCコール 失敗した場合のエラー処理関数
var postFeed_error = function(statusCode, statusMsg)
{
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
$(’#winDspEnd’).html(’エラーが発生しました。<br>ニュースフィードに投稿できませんでした。<br><br>statusCode:’+statusCode + ‘<br>statusMsg:’+statusMsg ).show(’fast’);
}

//入力エリアにテキストプレ表示。クリックしたら消す。
$(function(){
$(”.focus").focus(function(){
if(this.value == “この写真について何か書く"){
$(this).val("").css("color”,"#333333″);

}
});
$(”.focus").blur(function(){
if(this.value == “"){
$(this).val("この写真について何か書く").css("color”,"#969696″);
}
});
});

function dspWinEnd(){
//ローディング中を消す
$(’#winDspLoading’).hide(’fast’);
//ウインドウ内を完了画面にする
$(’#winDspEnd’).html(’投稿しました。’ ).show(’fast’);
}
function dspWinShow(){
//入力エリアを初期化
$(’#message’).val("この写真について何か書く").css("color”,"#969696″);
//ウインドウ内を表示する
$(’#winDspForm’).show(’fast’);
$(’#winDspEnd’).hide(’fast’);
}

</script>

<!— ▼ポップアップウインドウ height="230″—>
<cfwindow x="100″ y="250″ width="400″ height="280″ name="winPost” title="Post your album” initshow="false” draggable="true” resizable="true” >

<div style="margin-left:auto;margin-right:auto;width:370px;”>

<div id="winDspForm”>

<div class="caption” style="margin-left:10px;”>アルバムにタグ付けして投稿します。</div>

<!— 合成画像(cssで表示) —>
<div id="logo” align="left” style="float:left;margin:20px 10px 0 10px;”>
<div class="w-frame-image”><img src=”” id="wFimage” width="80″></div>
<div class="w-profile-image”><img src=”” id="wPimage” width="80″></div>
</div>

<form name="f1″ method="post” action=””>
<textarea class="focus” id="message” cols="30″ rows="5″ style="margin-top:20px;”>この写真について何か書く</textarea>

<div style="margin:18px 0 0 110px;”>
<a href="#” onClick="doPost();” ><img src="img/btn_Shere.png” align="シェアボタン” border="0″></a>
<a href="#” onClick="doCancel();” ><img src="img/btn_cancel.png” align="キャンセルボタン” border="0″></a>
</div>

</form>

</div>

<!— ローディング中の表示 —>
<div id="winDspLoading” align="center” style="margin-top:60px;”></div>
<!— 送信後のメッセージ表示 —>
<div id="winDspEnd” align="center”></div>

</div>

</cfwindow>
<!— ▲ポップアップウインドウ —>

</body>
</html>

 
ColdFusionコンポーネント(CFC)側
facebook.cfc

<cfcomponent>

<!—合成画像のパス —>
<cfset thisPath=ExpandPath("photo/*.*")>
<cfset thisDirectory=GetDirectoryFromPath(thisPath)>

<!— 合成画像URL —>
<cfset imageUrl="http://www.cf-girl.net/facebook/photo/”>

<!—CFC側 合成画像を作成する関数 —>
<cffunction name="makeImage” access="remote” output="false”>

<!—javascript側から受け取る引数 —>
<cfargument name="frameImagePath” type="string” required="yes” hint="背景画像パス” >
<cfargument name="profileImagePath” type="string” required="yes” hint="プロフィール画像パス” >

ColdFusionの各種情報の配信


最新情報
■2017/6/26
『ColdFusion 実験室』
実験6

■2017/3/27
ColdFusion 2016 対応
インストール セットアップ情報
CFサーバーのインストール
CFビルダーのインストール

■2016/9/20
『ColdFusion 2016 リリース
Enterprise Edition 活用資料』
記事一覧

■2016/3/30
『ColdFusion 実験室』
実験4、実験5

■2015/8/10 〜
『ColdFusion クリニック』
記事一覧(随時更新中)

■2015/4/8
『JasperReportsによる帳票出力』
2. JasperReportsによる帳票出力【後編】

■2015/3/12
アップクロス株式会社
西元 貞昭様
『JasperReportsによる帳票出力』
1. JasperReportsによる帳票出力【前編】


■2015/2/25
『ColdFusionでエクセルを使いこなそう!』
4. 【上級】ColdFusionのエクセル機能を利用したPDF帳票の紹介

ColdFusionトレーニング


ColdFusionユーザーグループ
ColdFusionユーザーグループ
Copyright 2012 Samuraiz Corporation. All Rights Reserved.