まめわざでは、TwitterとFacebookのアカウントでのログインと、両SNSにまめわざで作ったページの紹介を同時投稿する機能を提供しています。
Facebookの仕様変更により、Facebookのログイン方法と同時投稿の方法が変わりましたので、ここでご説明いたします。
末尾にはFacebook Javascript SDKの使い方も解説します。
まめわざのログイン画面で、「Facebookでログイン」を押すだけです。
ただし、Facebookアカウントを予め関連付けする必要があります。
関連付け(ログイン設定)の方法を、ホームページが作成済みの場合、これから新規作成する場合の両方について以下で説明します。
まめわざでページを新設・更新する際に、その内容の要約をFacebookの個人のウォールや管理しているFacebookページのウォールに投稿できます。
ブログ機能との相性が良く、ブログ記事の投稿とFacebookでの紹介が同時にできるので便利です。
以前との違い)以前はFacebookに投稿するために「その他の設定」で関連付けをする必要がありましたが、現在はその作業は不要になりました。
Facebookでログインをしていると、各ページの保存時に下部に「同時投稿する」のチェックが表示されます。
これまで使っていたFacebook PHP SDKからJavascript SDKに変更をしました。
Javascript SDKを使って、Facebookログインや個人のウォール・Facebookページのウォールに投稿するまでの技術的な手順を説明します。
尚、ここではjQueryの利用を前提としていますのでご了承願います。
事前にFacebookのアプリケーションIDを取得する必要があります。大まかには
という流れです。時間も面倒も掛かる最難関のステップですが、その説明は過去のこちらの記事に譲ります。
尚、publish_actionsなど投稿関連の審査は、2015年の上記記事の投稿時に比べ、更に厳しくなっています。Facebookへ投稿する際の、投稿内容(本文・リンク・画像など)を投稿者が自ら設定できなければいけないようなのでご注意下さい。
コードは非常にシンプルです。
Javascript SDKによるログインの肝は「Facebookの非ログインユーザーにログインを促す時のポップアップブロックの回避」にあると言っても過言ではありません。
以下のコードでは、下記で解説するようにポップアップブロックが動作しないようにSDKの本体ファイルを$(document).readyで非同期に前読みしており、またFacebookの公式説明にあるFB.getLoginStatusは利用していません。
<button onclick="fb_login()">Facebookログイン</button>
<script type="text/javascript">
function fb_login() {
FB.login(function(res) {
if(typeof(res) == "object" && typeof(res.authResponse) == "object") {
//ログインしている場合の処理
alert("ログイン中。IDは" + res.authResponse.userID + "です。");
} else {
//ログインしていない場合の処理
alert("ログインしていません。再度ログインしてください。");
}
} );
};
$(document).ready(function() {
$.ajax( {
"dataType": "script",
"cache": true,
"url": "//connect.facebook.net/ja_JP/sdk.js",
"success": function() {
FB.init( {
appId: "アプリケーションID",
version: "v2.3",
} );
},
} );
} );
</script>
下記の4つのケースについて、Facebookの非ログインユーザーがボタンを押した際のポップアップの動作状況を確認しました。
ポップアップの動作は、iOSのSafari、AndroidのChrome、IE11、Edge、Chromeなど主要ブラウザで同様の結果となります(ただし、ポップアップブロックが動作した際に、それを知らせるブラウザと、無視するブラウザがあります)。
成功例です。
sdk.jsを前読みしておき、ボタン押下→FB.loginと間を挟まずにすぐ実行するとポップアップブロックが動作しません。
コードは上記と同一。
失敗例です。
FBがundefinedの場合にsdk.jsを読み込みます。Facebookの公式説明にもある「アクション時にsdk.jsを読み込む」方法ですが、多くのブラウザでポップアップブロックが動作します。
<button onclick="fb_login()">Facebookログイン</button>
<script type="text/javascript">
function fb_login() {
if(typeof(FB) == "undefined") {
$.ajax( {
"dataType": "script",
"cache": true,
"url": "//connect.facebook.net/ja_JP/sdk.js",
"success": function() {
FB.init( {
appId: "アプリケーションID",
version: "v2.3"
} );
fb_login();
},
} );
return "";
}
FB.login(function(res) {
if(typeof(res) == "object" && typeof(res.authResponse) == "object") {
alert("ログイン中。IDは" + res.authResponse.userID + "です。");
} else {
alert("ログインしていません。再度ログインしてください。");
}
} );
};
</script>
失敗例です。
こちらは(a)のFB.loginを、公式説明にあるFB.getLoginStatusに変え、ログインしていない場合に新たにFB.loginを実行するケースです。すぐにFB.loginを実行した(a)と異なり、ポップアップブロックが動作します。
<button onclick="fb_login()">Facebookログイン</button>
<script type="text/javascript">
function fb_login() {
FB.getLoginStatus(function(res) {
if(typeof(res) == "object" && typeof(res.authResponse) == "object") {
alert("ログイン中。IDは" + res.authResponse.userID + "です。");
} else {
FB.login();
}
} );
};
$(document).ready(function() {
$.ajax( {
"dataType": "script",
"cache": true,
"url": "//connect.facebook.net/ja_JP/sdk.js",
"success": function() {
FB.init( {
appId: "アプリケーションID",
version: "v2.3"
} );
},
} );
} );
</script>
もう1つの成功例です。
window.location.hrefによりFacebookページにリダイレクトすることで、当然ながらポップアップブロックは回避できますが、FB.getLoginStatusの使い所の例として挙げました。
リダイレクト処理が挟まるためページは再読込されます。Facebookログイン設定以外に入力欄がある場合など、ページが再読込されては困る場合は、この方法は利用できません。
<button onclick="fb_login()">Facebookログイン</button>
<script type="text/javascript">
function fb_login() {
if(typeof(FB) == "undefined") {
$.ajax( {
"dataType": "script",
"cache": true,
"url": "//connect.facebook.net/ja_JP/sdk.js",
"success": function() {
FB.init( {
appId: "アプリケーションID",
version: "v2.3"
} );
fb_login();
},
} );
return "";
}
FB.getLoginStatus(function(res) {
if(typeof(res) == "object" && typeof(res.authResponse) == "object") {
alert("ログイン中。IDは" + res.authResponse.userID + "です。");
} else {
window.location.href = "https://www.facebook.com/dialog/oauth?client_id=アプリケーションID&redirect_uri=" + encodeURIComponent(document.URL);
}
} );
};
</script>
FB.loginの第2引数で、scopeを指定し、return_scopes: trueとします。scopeは
の3つです。自分のウォールへの投稿に限った場合はpublish_actionsだけでOKです。
FB.login(mycallback, {
"scope": "publish_pages,publish_actions,manage_pages",
"return_scopes": true
} );
FB.loginのコールバック(第1引数)として以下を実行します(関数名は任意で変更して下さい)。
まず、コールバック関数の引数に含まれるres.authResponse.grantedScopesで、権限が与えられたことを確認する必要があります。こちらも、自分のウォールへの投稿に限った場合はpublish_actionsだけでOKです。
権限が得られた場合は、FB.api("/me/accounts")で管理するFacebookページのリストを取得します。ここでは、selectタグでウォールの選択欄を設けるためにoptionタグを生成しています。
var mycallback = function(res) {
if(typeof(res) != "object" || typeof(res.authResponse) != "object") {
//ログインしていない場合の処理
alert("ログインしていません。");
return "";
}
var scopes = res.authResponse.grantedScopes;
if(!scopes || scopes.indexOf("publish_pages") == -1 || scopes.indexOf("publish_actions") == -1 || scopes.indexOf("manage_pages") == -1) {
//許可が得られなかった場合の処理
alert("一部が許可されていません。もう1度ログインしてください。");
return "";
}
//許可が得られた場合の処理(ここではselectにoptionタグを設置)
var options = "<option value=\"\">個人のウォール</option>";
FB.api("/me/accounts", {}, function(res) {
if(typeof(res) != "object" || typeof(res.data) != "object" || !res.data[0]) {
return "";
}
for(var i = 0; i < res.data.length; i++) {
options += "<option value=\"" + res.data[i].id + "\" data-token=\"" + res.data[i].access_token + "\">『" + res.data[i].name + "』のウォール</option>";
}
} );
//selectタグにoptionを設置
$("select[name=\"fb_wall\"]").html(options);
};
「投稿する」ボタン押下時に、選んだウォールのIDとaccess_tokenを取得し、textareaに入力したメッセージを投稿するサンプルです。
投稿は
FB.api("/me/feed", "post", {"message": "メッセージ"});
で行います。
Facebookウォールに投稿する際は、下記のようにFacebookページのIDとaccess_tokenをセットする必要があります。
<select name="fb_wall">
<option value="" data-token="">自分のウォール</option>
<option value="(FacebookページaのID)" data-token="(Facebookページaのaccess_token)">『〇〇』のウォール</option>
<option value="(FacebookページbのID)" data-token="(Facebookページbのaccess_token)">『〇〇』のウォール</option>
</select>
<textarea name="fb_msg" colspan="20" rowspan="5"></textarea>
<button onclick="fb_post()">投稿する</button>
var fb_post = function() {
var id = $("select[name=\"fb_wall\"]").val();
var token = $("select[name=\"fb_wall\"]" option:selected").data("token");
var msg = $("textarea[name=\"fb_msg\"]").val();
var dat = {
"message": msg,
};
if(token) {
dat.access_token = token;
}
FB.api("/" + (id ? id : "me") + "/feed", "post", dat, function(res) {
if(typeof(res) == "object" && res.id) {
alert("投稿に成功しました。投稿した文章のIDは" + res.id + "です。");
} else {
alert("投稿に失敗しました。");
}
} );
};
2017年3月末にあったFacebookの仕様変更により、一時的にFacebookログインが出来ない状況が続き、ご不便をおかけしまして申し訳ございませんでした。
この仕様変更によってFacebook側でOAuthの取扱方法が変更になり、その結果Facebook PHP SDK v3が利用できなくなって、最新版であるv5へのバージョンアップを余儀なくされました。
しかしv5はPHPのバージョーンが5.4以上の環境でなければ利用できないという更なる制約があります。
まめわざのサーバー事情を鑑みて検討した結果、代替案として挙がったのがFacebook Javascript SDKの導入でした。
処理をサーバーサイドからクライアントサイドに変更するという根本的な変更を伴いますが、Facebook APIのドキュメントを見る限りでは可能なようなのでトライしました。
今後も仕様変更を繰り返す可能性があるPHP SDKに比べると、Javascript SDKは仕様変更に振り回されるずに長く使える可能性が期待できます。