カテゴリー別アーカイブ: HTML

Facebook Messenger Platform でメッセージbot作成(v2.7)

【Facebook Messenger Platform beta + Facebook SDK v2.7】

前回のブログにFacebook SDKでメッセージ送信する記事を書きましたが、モバイルで使える方法はないのかなと調べていたら、Facebook Messenger Platformなるものを発見。

これでモバイルでもメッセージ送信できるんじゃないのかと調べてみたら、基本的にアプリやFacebookページ内でのメッセージ送信(チャット)に関するAPIのようです。

FacebookアプリやFacebookページを作って、そこにメッセージが送信されたときにコールバックを受け取る処理を組み込んでおいて反応させるもののようです。

JSで使用するにはNode.jsが必要


他のAPIと同じように、JavaScriptでもPHPでも書けるようですが、JavaScriptの場合はNode.jsが必要になるようです。Node.jsをインストール済の外部サーバがないので、今回はPHPでテストしてみました。

PHPはSSL配下で動作させる必要がある


今回はレンタルサーバ(さくらのレンタルサーバ)についている共有SSL機能を使いました。

大まかな手順は、上のGetting Started – Messenger Platformに書いてありますが、実際にテストしてみた手順をメモしておきます。

1. Create a Facebook App and Page(FacebookアプリとFacebookページを作成)


Quick Starts – 開発者向けFacebookを開いて、Facebookアプリを作成します。ここでは「testMessenger2」という名前で作成しました。アプリ名を入力して、「新しいFacebookアプリIDを作成」ボタンを押します。
bot01

開かれたポップアップで、メールアドレスを入力してカテゴリを選択します。ここでは「コミュニケーション」を選択しました。
bot02

アプリの設定画面に切り替わります。ページの内容は無視して、右上の「Skip Quick Start」ボタンを押します。
bot03

作成したFacebookアプリの管理画面が表示されます。
bot04

次にFacebookページを作成ページを開いて、Facebookページを作成します。ここでは会社・団体カテゴリからこのサイト名と同じ「As blind side」の名前で作成しました。
bot05

Facebookページの設定画面が表示されます。今回は全てスキップを選択します。
bot06

Facebookページが表示されます。
bot07

2. Setup Webhook(Webhookを設定)


Webhookを設定します。Webhookとはざっくりいうと、イベントに対するコールバックのことです。詳しくは下記を。

【参考】
Webhookとは? | ブログ | SendGrid
アプリのおしらせ作業を楽にするプッシュ通知の3つのポイント | BACKEND AS A SERVICE mbaas BLOG

ここでは「FacebookのMessengerにメッセージが送信されたときのコールバック」を指す、と考えていいと思います。

Facebookアプリのコールバック用PHPを作成します(ここではcallback2.phpという名前で作成)。「$access_token」には任意のトークンを設定します(ここでは”testmesenger”)。このPHPとトークンは、Facebookにコールバックphpを認証させるためのものです。

<?php
$hub_verify_token = "testmesenger"; // 任意のトークンを自分で作成
if($_GET['hub_verify_token'] == $hub_verify_token) {
    echo $_GET["hub_challenge"];
} else {
    echo 'error';
}

次にコールバック用PHPを外部サーバにアップします。アップするサーバはSSLでなければなりません。

まずFacebookアプリの管理画面から、プロダクト>製品を追加を選び、表示された中から「Messenger」のところにある「スタート」ボタンを押します。
bot08

Messengerの設定画面で「Set Webhooks」ボタンを押すと、下記のポップアップが表示されます。フォロー入力欄の全ての項目にチェックを入れ、「コールバックURL」に先程サーバに上げたPHPのURL、「トークンを確認」にPHPで設定したトークン(ここでは”testmesenger”)を入力して「確認して保存」ボタンを押します。
bot11

コールバック用PHPが正しく確認されると、Facebookアプリ管理画面のWebhooks欄に完了のマークが表示されます。
bot12

3. Get a Page Access Token(ページアクセストークンの取得)


Facebookアプリ(callback2.php)がFacebookページ(As blind side)にアクセスするためのトークンを取得します。

Messengerの設定画面で「トークン生成」の「Facebookページ」から先程作成したFacebookページ(As blind side)を選択して、ページアクセストークンを生成します。
bot10

ページアクセストークン欄に表示された文字列をコピーします。

4. Subscribe the App to the Page(Facebookページにアプリを登録する)


ターミナルから以下のコマンドを入力してBOTを起動します。Facebookページとアプリは、ページアクセストークンで紐付けされます。

curl -X POST “https://graph.facebook.com/v2.7/me/subscribed_apps?access_token=**********”

※**********には、ページアクセストークンを設定する。

正しく起動されると {“success”: true} と表示されます。
bot13

Botを使ってみる


これでBotの準備が出来ました。

Facebookアプリのコールバック用PHP(callback2.php)を書き換えて、受け取ったメッセージに対して返信するようにします。「$access_token」には上でコピーしたページアクセストークンを設定します。

<?php
$access_token = "*******************";
$json_string = file_get_contents('php://input');
$json_object = json_decode($json_string);
$messaging = $json_object->entry{0}->messaging{0};

if(isset($messaging->message)) {
    $id = $messaging->sender->id;
    $rcv_msg = $messaging->message->text;

    $message = '「';
    $message .=$rcv_msg;
    $message .= '」ってなんですか?';

    $post = <<< EOM
    {
        "recipient":{
            "id":"{$id}"
        },
        "message":{
            "text":"{$message}"
        }
    }
EOM;

    api_send_request($access_token, $post);
}

function api_send_request($access_token, $post) {
    error_log("api_get_message_content_request start");
    $url = "https://graph.facebook.com/v2.6/me/messages?access_token={$access_token}";
    $headers = array(
            "Content-Type: application/json"
    );

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    $output = curl_exec($curl);
}
?>

コード内容については、この辺を見るといいかも。
Webhook Reference – Messenger Platform

書き換えたコールバック用PHPをアップロードして上書きします。

Botのテストをしてみます。Fcebookページ(As Blind side)からメッセージ送信すると、こんなかんじになります。
bot14

モバイルのMessengerアプリからメッセージ送信すると、こんな感じ。
bot15

これで完成です。いろいろ処理を書き込めば、ある程度メッセージは自動応答化できるのかなと思います。

【補足】
これはあくまでテスト用に作ったページとアプリなので、開発モードになっているため開発者権限でしか動作しません(作った本人しか使えない)。実際に稼働させるには、Facebookアプリ管理画面のアプリレビューで、「アイテムを審査に送信」を行って、公開設定する必要があります。
bot16

【参考】
Facebook Messenger Platform + さくらのレンタルサーバ + RapidSSL + PHP で BOT作成 – Qiita
Facebook、Messengerをプラットフォーム化、APIを公開 – iPhone Mania
Heroku+Railsで動かすFacebook Messengerのオウム返しBot – Qiita
Messengerで簡単なBotつくる(Facebook Messenger Platform from F8) – Qiita
FacebookGraphAPIを使った投稿パターンと見え方まとめ

Facebook SDKでメッセージ送信(v2.6)

【Facebook グラフAPI Version v2.6】

Facebook SDKでのメッセージ送信について調べてみました。やりたいことは下記の2つ。

  • 自分の友達を調べる。
  • その友達にメッセージを送る。

久しぶりに調べてみたら、2014.4に出たv2.0以降でかなり仕様が変わったようです。割と自由に引き出せた情報が、v2.0以降はかなり制限されたり、個別に権限が必要になったようです。

※前提としてFacebookでページをアプリ登録します。登録方法についてはこちら

Facebookアプリに権限を付与


Facebook for Developerのアクセス許可のリファレンスを見ると、かなり細かく権限が分かれていて、多くの権限はFacebookのレビューを受けないと使用できないようです。

Facebookのレビューなしに使用できる権限は、以下の3つです。

但しデフォルトで使用できるのは「public_profile」のみで、他の2つはログイン時に使用を宣言する必要があります。

1.Facebookのログインボタンを使用する場合

<fb:login-button scope="public_profile,email,user_friends" onlogin="checkLoginState();">
</fb:login-button>

2.JavaScriptでログインする場合

  function login(){
    FB.login(function(response) {
      if (response.authResponse) {
        alert('ログインも連携認証もされた');
      } else {
        alert('ログインもしくは連携認証がキャンセルされた');
      }
    },{scope:'public_profile,email,user_friends'});
  }

どちらの場合も、「scope」で使用する権限を付与します。

FB SDKを非同期にロード


	//FB SDKを非同期にロード
	(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/ja_JP/sdk.js";
		fjs.parentNode.insertBefore(js, fjs);
	}(document, 'script', 'facebook-jssdk'));

FB SDKのロード後に実行される処理を書く


「window.fbAsyncInit」で指定した内容が、SDKロード後に実行されます。ここでは2つの処理を行います。

	  //FB SDKのロード後に実行される
	  window.fbAsyncInit = function() {
		  FB.init({
		    appId      : '***************',
		    cookie     : true,  //セッション用にクッキーを有効化
		    xfbml      : true,  // このページのパース許可
		    version    : 'v2.6' // use version 2.6
		  });

		//FBのログインチェック
		FB.getLoginStatus(function(response) {
			statusChangeCallback(response);
		});
	
	};

※appIdの ‘***************’ には、Facebookアプリ登録時に発行されたidを指定する。

FB ログインチェック後の処理


「FB.getLoginStatus()」でログインチェックが行われると、戻り値(response)を受け取り、「statusChangeCallback()」が処理を振り分けます。

	  //FB.getLoginStatus()のコールバック
	  function statusChangeCallback(response) {
	    if (response.status === 'connected') {
			// Facebookにログイン済で、このアプリを認証済み
			testAPI();
			
			userID = response.authResponse.userID;
			console.log("userID >> "+userID);
	    } else if (response.status === 'not_authorized') {
			//Facebookにログイン済で、このアプリを認証していない
			document.getElementById('status').innerHTML = '右上のボタンでこのアプリを認証してください。';
	    } else {
			//Facebookにログインしていない
			document.getElementById('status').innerHTML = '右上のボタンでFacebookにログインしてください。';
	    }
	  }

ログイン状態に応じて、次のように処理を振り分けます。

not_authorizedFacebookにログイン済、かつこのFacebookアプリを認証していないFacebookアプリの認証を促すメッセージを表示する。

ログイン状態(response.status) 意味 実行する処理
connected Facebookにログイン済、かつこのFacebookアプリを認証済み 次の処理へ(testAPI())
その他(unknown) Facebookにログインしていない(未ログインのため、Facebookアプリの認証は不明) Facebookのログインを促すメッセージを表示する。

・Facebookアプリを認証していない場合のページ表示例
page02_ninsho

・Facebookにログインしていない場合のページ表示例
page03_fb

ユーザー情報を表示する


Facebookにログイン済、かつこのFacebookアプリを認証済みの場合は、ユーザー情報を表示します。

	// FBにログイン済且つアプリを認証済みの場合、ユーザー情報を表示する
	function testAPI() {
		FB.api('/me', function(response) {
		  document.getElementById('status').innerHTML =
		    'ようこそ ' + response.name + ' さん!';
		});
	}

・ユーザー情報のページ表示例
page04_logined

自分の友達を調べる


FBにログイン済且つアプリを認証済みの場合は、「友達を探す」ボタンをクリックしたタイミングで「getFriendlist()」を呼び出し、友人リストを取得します。

・友人リストを取得

	//---友人リスト取得
	function getFriendlist() {
		console.log('Welcome!  Fetching your information.... ');
		FB.api(
		'/me/friends',
		'GET',
		{},
		    function (response) {
		      if (response && !response.error) {
			        //友人リスト表示
			        editPostData(response.data);
			        
		      } else {
			        for (var item in response.error){
				        console.log(item+":"+response.error[item]);
			        }
		      }
		    }
		);    
	}

但し、ここで取得できる友達リストは、以下の条件に合致するもののみになります。

  • ログインしたユーザーの友達であること。
  • このFacebookアプリを認証している友人であること。

つまりユーザーの友人全てのリストを取得することはできません。この辺はAPIのver.2以降で制限がかかったようです。

【参考】Facebook API v2.0で、フレンド数やフレンド一覧を取得する方法 | Sunday In The Park

そして取得したリストから、友人一覧をページに表示します。

	//----投稿データ編集
	function editPostData(data){
		
		//件数関連パラメタ:保存
		var resultCount = data["length"];
		var resultArray = data;
		
		var resultTitle = "";
		var html = "";
		$("#mainContent .resultSec").empty();
		
		var matchCount = 0;
		
		if (resultCount == 0){
				resultTitle = ("検索結果:該当する友達がいません。");
		} else {
			resultTitle = ("検索結果:"+resultCount+"件");
			for (var i=0;i<resultArray.length;i++){
			
					//友達を表示
					html += '<li class="resultArea">';	
					html += '<div class="result">';	
					html += '<span class="resultInfo">';	
					html += '<span class="songName">'+resultArray[i]["name"]+'</span>';	
					html += '<span class="artistName">'+resultArray[i]["id"]+'</span>';						
					html += '</div>';	
					
					html += '<ul class="resultBtn">';
					html += '<li>';
					html += '<div class="btn" id='+resultArray[i]["id"]+'>';
					html += '<span>メッセージ送信</span>';
					html += '</div>';
					html += '</li>';
					html += '</ul>';
					
					html += '</li>';			
					
					matchCount++;		
			}
			
			if (html != ""){
				$("#mainContent .resultSec").append(html);
				resultTitle = ("検索結果:"+matchCount+"件");
			} else {
				resultTitle = ("検索結果:このアプリを使っている友人がいません。");
			}
		}
	
		var html_title = "";
		html_title += '<li class="titleArea">'
		html_title += '<div class="icon">'
		html_title += '<img src="img/search/ico_search.png" width="40" height="40" />'
		html_title += '</div>'
		html_title += '<div class="txt">'+resultTitle+'</div>'
		html_title += '</li>'
		$("#mainContent .resultSec").prepend(html_title);
		
	
		$('#mainContent .resultSec .resultBtn .btn').each(function() {
			$(this).unbind('click');
			$(this).bind('click',clickSendMessageFunc);
		});
		
		//---メッセージ送信ボタン:クリック処理
		function clickSendMessageFunc(event){
			var targetID = event.currentTarget.id;
			sendMessage(targetID);
		}	
		
	}

・友人リストのページ表示例

この例では2人の友人が表示されています。
この例では2人の友人が表示されています。

友人にメッセージを送る


友人一覧に設定したボタンをクリックすると、「sendMessage()」が呼び出され、メッセージが送信されます。

・送信ボタンクリック

		//---メッセージ送信ボタン:クリック処理
		function clickSendMessageFunc(event){
			var targetID = event.currentTarget.id;
			sendMessage(targetID);
		}	

・メッセージ送信

	  //FBメッセージ送信(モバイルは不可)
	  function sendMessage(sendId){
	      FB.ui(
	      { 
	          method: 'send', 
	          to: sendId,
	          link: "http://www.c-geru.com"
	      }, 
	      function(param){
	        //callback
	      }
	      );
	}

FB.ui送信ダイアログを使って、メッセージ送信するのですが、モバイル機器には対応していません

モバイルのブラウザでメッセージ送信ボタンを押すと、モバイルに対応していない旨のメッセージが表示される。
モバイルのブラウザでメッセージ送信ボタンを押すと、モバイルに対応していない旨のメッセージが表示される。

ホントはPC、モバイルの両方で使えるようにしたかったんですが・・・。残念。

最後にjsを含むHTMLのサンプルコードを書いておきます。Facebookアプリ登録が正しく行われていれば、説明通りに動くはずです。参考までに。

<!DOCTYPE html>
<html>
<head>
<title>Facebookログインテスト</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" type="text/css" href="css/main.css">
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
</head>
<body>
<script>
	//FacebookのuserID保存用
	var userID;
	
	  //FB.getLoginStatus()のコールバック
	  function statusChangeCallback(response) {
	    console.log('statusChangeCallback');
	    console.log(response);
	    if (response.status === 'connected') {
			// Facebookにログイン済で、このアプリを認証済み
			testAPI();
			
			userID = response.authResponse.userID;
			console.log("userID >> "+userID);
	      
	      
	    } else if (response.status === 'not_authorized') {
			//Facebookにログイン済で、このアプリを認証していない
			document.getElementById('status').innerHTML = '右上のボタンでこのアプリを認証してください。';
	    } else {
			//Facebookにログインしていない
			document.getElementById('status').innerHTML = '右上のボタンでFacebookにログインしてください。';
	    }
	  }
	
	  // This function is called when someone finishes with the Login
	  // Button.  See the onlogin handler attached to it in the sample
	  // code below.
	  function checkLoginState() {
	    FB.getLoginStatus(function(response) {
	      statusChangeCallback(response);
	    });
	  }
	  
	  //FB SDKのロード後に実行される
	  window.fbAsyncInit = function() {
		  FB.init({
		    appId      : '*****************',
		    cookie     : true,  //セッション用にクッキーを有効化
		    xfbml      : true,  // このページのパース許可
		    version    : 'v2.6' // use version 2.6
		  });

		//FBのログインチェック
		FB.getLoginStatus(function(response) {
			statusChangeCallback(response);
		});
	
	};
	
	//FB SDKを非同期にロード
	(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/ja_JP/sdk.js";
		fjs.parentNode.insertBefore(js, fjs);
	}(document, 'script', 'facebook-jssdk'));
	
	// FBにログイン済且つアプリを認証済みの場合、ユーザー情報を表示する
	function testAPI() {
		console.log('Welcome!  Fetching your information.... ');
		FB.api('/me', function(response) {
		  console.log('Successful login for: ' + response.name);
		  document.getElementById('status').innerHTML =
		    'ようこそ ' + response.name + ' さん!';
		    
		 	//---友人を探すボタン:表示処理
		// 		showSerachBtnFunc();
		});
	}
	  
	//---友人リスト取得
	function getFriendlist() {
		console.log('Welcome!  Fetching your information.... ');
		FB.api(
		'/me/friends',
		'GET',
		{},
		    function (response) {
		      if (response && !response.error) {
			        //友人リスト表示
			        editPostData(response.data);
			        
		      } else {
			      console.log("---error:"+response.error);
			        for (var item in response.error){
				        console.log(item+":"+response.error[item]);
			        }
		      }
		    }
		);    
	}
  
	  //FBメッセージ送信(モバイルは不可)
	  function sendMessage(sendId){
	      FB.ui(
	      { 
	          method: 'send', 
	          to: sendId,
	          link: "http://www.c-geru.com"
	      }, 
	      function(param){
	        //callback
	      }
	      );
	}
	//----友人リスト表示
	function editPostData(data){
		
		//件数関連パラメタ:保存
		var resultCount = data["length"];
		var resultArray = data;
		
		var resultTitle = "";
		var html = "";
		$("#mainContent .resultSec").empty();
		
		var matchCount = 0;
		
		if (resultCount == 0){
				resultTitle = ("検索結果:該当する友達がいません。");
		} else {
			resultTitle = ("検索結果:"+resultCount+"件");
			for (var i=0;i<resultArray.length;i++){
			
					//友達を表示
					html += '<li class="resultArea">';	
					html += '<div class="result">';	
					html += '<span class="resultInfo">';	
					html += '<span class="songName">'+resultArray[i]["name"]+'</span>';	
					html += '<span class="artistName">'+resultArray[i]["id"]+'</span>';						
					html += '</div>';	
					
					html += '<ul class="resultBtn">';
					html += '<li>';
					html += '<div class="btn" id='+resultArray[i]["id"]+'>';
					html += '<span>メッセージ送信</span>';
					html += '</div>';
					html += '</li>';
					html += '</ul>';
					
					html += '</li>';			
					
					matchCount++;		
			}
			
			if (html != ""){
				$("#mainContent .resultSec").append(html);
				resultTitle = ("検索結果:"+matchCount+"件");
			} else {
				resultTitle = ("検索結果:このアプリを使っている友人がいません。");
			}
		}
	
		var html_title = "";
		html_title += '<li class="titleArea">'
		html_title += '<div class="icon">'
		html_title += '<img src="img/search/ico_search.png" width="40" height="40" />'
		html_title += '</div>'
		html_title += '<div class="txt">'+resultTitle+'</div>'
		html_title += '</li>'
		$("#mainContent .resultSec").prepend(html_title);
		
	
		$('#mainContent .resultSec .resultBtn .btn').each(function() {
			$(this).unbind('click');
			$(this).bind('click',clickSendMessageFunc);
		});
		
		//---メッセージ送信ボタン:クリック処理
		function clickSendMessageFunc(event){
			var targetID = event.currentTarget.id;
			sendMessage(targetID);
		}	
		
		//---友人を探すボタン:表示処理
		function showSerachBtnFunc(){
		    $("#mainContent .check .btnCheck").css({
			    "display":block
		    });
		}	
		
	}


	jQuery.event.add(window, "load", function(){
	
		/* 友達を検索;クリック処理  */
		$("#mainContent .check .btnCheck").bind('click',getFriendlist);
		
		//---aタグにロールオーバー/ロールアウトを設定
		$('.btnCheck').mouseover(function() {
		    $(this).css({
			    "opacity":0.8
		    });
		});
		    
		$('.btnCheck').mouseout(function() {
		    $(this).css({
			    "opacity":1
		    });
		});
	
	});

</script>

	<header>
		<div class="headerin">
				<div class="bar clearfix">
					<div class="barL">Facebookログインテスト</div>
					<div class="barR">
						<fb:login-button scope="public_profile,email,user_friends" onlogin="checkLoginState();">
						</fb:login-button>
					</div>
				</div>
				<div class="title">
					<div id="status" class="copy">右上のボタンでログインしてください。</div>
				</div>
		</div>
	</header>

	<div id="mainContent">
		<div class="check">
			<div class="btnCheck">
				<span>友達を探す</span>
			</div>
		</div>
		
		<ul class="resultSec" id="result"></ul>
	</div>
</body>
</html>

【その他参考】
リファレンス – Facebookログイン
Facebookアプリで重要な連携と権限(FacebookAPI その5) | CODE COPILOT
FacebookSDKを使ってMessageを送信する方法 – Qiita
facebook認証状態を調べるFB.getLoginStatusでできるグロースハック3つ – Qiita

Twitterで特定期間のツイートを検索する

先日、Twitterについて調べていたときに、こんな記事を見つけました。

・Twitterで期間を限定して検索する方法&ヘルプに載ってない裏技テク – 聴く耳を持たない(片方しか)
・Twitterの新機能! 過去のツイートを検索する方法 | iPhoneひとすじ! かみあぷ速報

試してみると、コレ、公式サイトの検索窓を使わずにブラウザで直接URL叩いても動くんですね。Twitterにログインしてなくても表示されます。例えば、こんな感じ

で、フォローしている鍵アカも検索できるように、twitterアカウントでOAuth認証を通すようにして、ひとネタページを作ってみました(下の画像からリンクしてます)。

thum_fb_2tones
【twitter】○○年の今頃何してた? | 2tones-dev.net

やってることは基本的に、入力したアカウントと選択した年と現在の日付から前後一日を取得して、JavascriptでURL生成してwindow.open()してるだけです(笑)。あとアカウントのデフォルトは、OAuth認証で返ってくる情報から自分のアカウントを自動入力しています。

まあ検索するなら公式サイトの検索窓使うかURL直打ちすればいいんですが、いちいちキーワード入力するのも面倒だし(ライトユーザーはそんなことしなさそうだし)、ふと「去年の今頃何してたっけ?」みたいなことを思ったりすることもたまにあるので、ネタとしてはいいかなと思いまして(笑)。

ちなみに検索に前後一日ずつの幅を持たせているのは、なるべく検索にヒットするようにです。みんながみんな、毎日ツイートしてるわけじゃないと思うので。

APIでも過去検索できればアプリに組み込んだりできるんですが、そこはまあ負荷の問題なんですかね。制限があるのは。

ちなみにOAuth認証はこの辺を参考にPHPで書いています。

・【PHP】2015春版!TwitterOAuthでログイン機能を実装する – Qiita
・PHP と Twitter API V1.1 で OAuth 認証を行う 「タイムライン取得」「呟き(つぶやき)投稿」「ログイン」(API V 1.1)

twitterでリンクにサムネイル設定するには「Twitter Cards」というのを使うんですね。この辺も普段あまり自分で書かないのでしりませんでした。

・すぐにできるTwitter Cards設定 – E-riverstyle Vanguard

FacebookのOPG用画像をチェックするのに、こんなサイトがありました。フルサイズでも小さい表示でもうまく表示されるよう確認するのに便利です。

・OGP画像シミュレータ | og:image Simulator

Twitterに限らずAPI周りの情報はたくさんありますが、古いAPIの情報だったり、Developersページのデザインが変わってたりするので、その辺が注意点かと。

【補足】
・当初iPhoneのSafariでURLを叩いてみたら、Safariで未ログインだと検索結果が表示されませんでした。iPhoneだとモバイル用のページが開くので、その辺の仕様に違いがあるのかなと。また最初は別ウィンドウで表示するようにしていたのですが、iPhoneだと別タブで公式サイトを開いていると、そちらに結果が表示されてしまいました。

・上記の現象があったのでtwitterのOAuth認証を組み込んだのですが、このブログ書くために再度テストしたら未ログインでも結果表示されていました。キャッシュの問題なのか、再現しないのでちょっとわからないですが。。。

【HTML/CSS】諸々リンクなど

たまにやろうとすると色々引っかかるのでメモ。順次追加予定。

【HTML】
HTML:HTML5でIE8以下のバージョンに対応させる | raining
HTML5で追加されたinput要素のタイプはiPhone、Androidでどのくらい使えるのか | Developers.IO
ほんっとにはじめてのHTML5:[51] セレクトメニューを作ろう <select><option><optgroup>
videoタグでサイト内に動画を埋め込む(IE8対応)
【Web制作】HTML5のvideoタグにはMP4形式動画だけ指定すればよい(IE8対応)@2014年末
IE8でHTML5のvideoタグを使う方法

【CSS】
IE8とIE9できれいに透過を適応させるCSS
【シンプルなソース】CSSだけでアニメーション・ドロップダウンメニュー
横並びリストを中央寄せにする – CSSテクニック – acky info

【JS/JQuery】
jQueryでスマートフォンとタブレットでviewportを切り替える実験(iPhone6 Plus対応) | BlackFlag
実は簡単にできる!PCサイトとスマホサイトを選んで振り分ける方法 | smart4meブログ
[JS][jQuery] 要素の存在を確認する6通りのコードと実行速度 | きほんのき
jQueryでセレクトボックスのoption要素を追加/削除する方法
jQueryプラグイン「ColorBox」でオリジナルの閉じるボタン(Closeボタン)を設置する | blog|blow→in
JavaScript – リンクタグを使用した閉じるボタン記述方法「colorbox.js」 – Qiita

【スマホ関連】
jQuery×HTML5×CSS3を真面目に勉強(4):WebページをRetina対応させるテクニック~基礎知識編 (2/2) – @IT
いまさら聞けないRetina対応のための「ピクセル」の話 – Rriver