[PHP][JavaScript]Twitter APIとFacebook APIのそれぞれ違う注意事項・制約事項

##**概要**
先日のプロジェクトでのウェブアプリに記事を投稿すると、
TwitterとFacebookの方にも記事が投稿される追加機能を着手しました。
**🌟二種類全部 有効期間更新無し(無期限)、SNSログイン無し(非認証)で 記事投稿できる**

着手しながらTwitter APIとFacebook APIのそれぞれに制約があって、
その内容を振り替えてみます。

Twitter APIとFacebook APIのそれぞれの投稿方法は以下のリンクをご覧ください。
[🔗[PHP]PHPのアプリにTwitterの投稿機能を導入](http://qiita.com/leedohyung-dba/items/f5254b79add95a13c2ac)
🔗[PHP]PHPのアプリにFacebookの投稿機能を導入(投稿準備中)

##**Twitter APIとFacebook APIのそれぞれ違う注意事項・制約事項**
それぞれのAPIを実際のプロジェクトに扱ってみて、それぞれ違う**注意事項**・**制約事項**がありました。
それは大きく**9つ**です。

##**① Facebook API側は公認IPのドメインが必須**
**Facebook API側はドメインが無かったらFacebook_API_Appを生成することができません。**
しかも、Facebook_API_Appを生成してAccessTokenを取得しても、
**そのドメインサーバ以外の他のローカル開発環境には動きません。**
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/a1c78cfd-9c31-88b3-9ae3-a1f07ff953b7.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/c5f9771d-6701-51ef-4618-f42016f08271.png)
そのため、ローカル開発環境では結果を確認できなかったので、すごく不便でした。

一方、Twitter API側は環境に関わらず可能です。

##**② Facebook API側はAccessTokenの有効期間が短いし種類が多すぎ**
Facebook API側は有効期間が時間単位です。
Facebook_API_Appの認証申請を成功すると2ヶ月は取れます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/7734a3fb-bdb1-35d7-4ee8-72cec6ff55d5.png)
✪AccessTokenをDebugした結果が満期日無、つまり無期限のAccessTokenを取得するのは可能でが、
方法が辛いし、ドキュメントに案内されてませんので、信用性として情報アップは無理でございます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/48b725ca-4d35-fdfc-7374-d0af022a6ba1.png)

**一方で、Twitter API側は特に有効期間がありません。**
Access Tokenは一度発給すると他の情報(ログイン情報、Request Tokenなど)がまったく必要なしに
すぐAPI呼び出しが可能になり、使用者がアカウント情報を変更(パスワード変更など)したとしても、
このAccess Tokenは有効です。
Access Tokenの有効期間はサービスプロバイダの政策によって異なる部分があるが、
[🔗ツイッターOAuth faq](https://dev.twitter.com/oauth/overview/faq)を確認すれば、現在Access Tokenの有効期間はない(!)と明示しています。 
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/7ff70064-ec10-e5d5-4ee7-bef5a83708a2.png)

したがって、トークンの保管に注意をする必要があるはずです。 
Access Tokenの有効期間がないけどしかし、
使用者が自分のアカウント設定でアプリケーションを明示的に拒否したり、
管理者が制限した場合にAccess Tokenが満了されることがあります。

##**③ PHPバージョン5.3以下のFacebook APライブラリーは存在しない**
先日、機能を追加するウェブアプリのPHPバージョンは5.3でした。
Twitter API の方はPHP Vr.5.3から支援するライブラリー([🔗themattharris/tmhOAuthby](https://github.com/themattharris/tmhOAuth/blob/master/tmhOAuth.php))がやっとありましたが、
Facebook API の方はありませんでした。
PHP Vr.5.3も支援するライブラリー[🔗facebookarchive/facebook-php-sdk](https://github.com/facebookarchive/facebook-php-sdk)はありましたが、使用が中止されました。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/16c0c5e8-2fef-d739-3c12-0a0a6db1b78e.png)

PHP Vr.5.6から支援するAPIライブラリー🔗facebook/php-graph-sdkを
頑張って5.3バージョンにも動けるように調整をChallengeしてみましたが、おすすめはしません。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/bcd86694-a195-92e5-9a27-b04754bfd7ab.png)

残念ですが、自分はjavascriptを利用しました。(//connect.facebook.net/en_US/sdk.js)

##**④ Facebookの方はウェブSDK言語が少ない**
Facebookの方はウェブSDK言語がPHPとJavascriptの2つしかありません。
[🔗Facebook API Doc](https://developers.facebook.com/docs/web)

もう一方で、Twitterの方はASP, .NET, Go, Javascript / node.js, PHP, Rubyなどがあります。
[🔗Twitter API Doc](https://dev.twitter.com/overview/api/twitter-libraries)

##**⑤ Twitter APIの方はテキストと画像のそれぞれにサイズ制限がある**
Twitter APIの方にはテキストサイズの制限があります。(ドキュメントの内容は[🔗こちら](https://dev.twitter.com/ja/overview/terms/policy))
それは1つの投稿につき**140文字**までしか送信できない制限です。
`{"code":186,"message":"Status is over 140 characters."}`

また、Twitter は文字を数えるとき、バイト数ではなく、最終的な文字数を数えます。
つまり、使用している言語、API によっては、正確な文字数をそのまま取得することはできない場合があります。
しかし、いろいろな罠が潜んでいますので、以下の記事をご参考してください。
[🔗Twitterは140文字ではない。と気づいた時の処方箋](http://tech.aainc.co.jp/archives/6472)
[🔗ツイートの文字数](http://blog.aki-null.net/blog/2012/05/11/tweet-length-count/)

また、Twitter APIの方には画像と動画のサイズ制限があります。(ドキュメントの内容はこちら)
それは1つの投稿につき画像サイズ**5MB**でまでしか送信できない制限です。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/bd708d05-c9d1-309b-b346-82f800f80460.png)

最近、Twitterにより大きなGIFファイル(15MBまで)を投稿できるようになったという記事を見つけましたが、
実際はまだ5MBで制限されているのを確認しました。まだ5MBの制限があるらしいです。
[🔗Twitter、GIFファイルの最大サイズを15Mバイトに](http://japan.cnet.com/news/service/35085776/)

**もう一方で、Facebookの方は制限が全然ありません。( w o w ~ ! )**
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/0de3f664-58e1-a85f-9550-6f4e0dafff9f.png)
しかし、Facebookの方は設定した画嬢のソースが存在しなくてもエラーを出力しませんし、
そのまま投稿成功します。(ㅇㅁ ㅇ... )
しかも、Facebookの方は画像の大きさが少ない過ぎたら端末機によって画嬢が表示されたりされなかったりします。
例えば、PC側は画像が表示されるけど、スマホ側には表示されない現状です。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/74304183-1ce7-333c-bc28-d91ab32d508b.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/556d63fe-9149-790b-38b8-d412b18c14da.png)

正確にエラーでレスポンスされるTwitterの方よりFacebookの方が製品を
リリースした後に問題が起きる可能性が高いです。
自分の以下の記事で十分だとはいえませんが、できるだけ、注意事項を熟知してしっかり色んなケースをテストしましょう。
[🔗[PHP]PHPのアプリにTwitterの投稿機能を導入](http://qiita.com/leedohyung-dba/items/f5254b79add95a13c2ac)
🔗[PHP]PHPのアプリにFacebookの投稿機能を導入(投稿準備中)

##**⑥ Twitter APIとFacebook APIのそれぞれに画嬢の経路に制約がある**
まず、Twitter API の方はサーバに存在する画像しか使えません。

```php:Twitter.php
$up_twitter_image = WWW_ROOT . IMAGES_URL . $Model->alias . '/' . $registerdData[$Model->alias]['id'] . '/img1/' . $registerdData[$Model->alias]['img1']['file_name'];
$up_twitter_image_name  = basename($up_twitter_image);
$params = array(
    'media[]'  => "@{$up_twitter_image};type=image/jpeg;filename={$up_twitter_image_name}",
    'status'   => "{$up_twitter_content}"
);
```

そのため、URLの画像ソースは使えません。
自分はウェブアプリにコンテンツデザインの投稿形式のケースもありましたので、
その本文の画像は絶対経路で接続できませんでした。
そのため、streamをかコピーしたメタstreamデータを利用する必要がありました。

```php:Twitter.php
// twitterの場合はFacebookと違って、絶対経路（その以外は、エラーが発生されます）を求めています。
// しかし、詳細画像の場合、コンテンツデザインなので、実際の画像が存在しません。（urlで接続するべき）
// そのため、ストリームをコピーして使っています。
$tmp = tmpfile();
stream_copy_to_stream(fopen($up_twitter_image, 'rb'), $tmp);
$streamGetMetaData = stream_get_meta_data($tmp);
$params = array(
    'media[]'  => '@' . $streamGetMetaData['uri'],
    'status'   => "{$up_twitter_content}"
);
$endpoint = $tmhOAuth->url('1.1/statuses/update_with_media');
```
詳しい内容は以下の記事の中に仮想イメージを画像ソースに使う部分をご参考してください。
[🔗[PHP]PHPのアプリにTwitterの投稿機能を導入](http://qiita.com/leedohyung-dba/items/f5254b79add95a13c2ac)

逆に、Facebook API の方は画像のソースがURLでございます。
つまり、URLで接続出来る画像ソースしか使えません。

```js:Facebook.js
picture: PHPVALUE.upImage // = http://~
```
そのため、URLで接続できない画像がある場合、画像ソースに使えません。
自分はウェブアプリにコンテンツデザインの投稿形式のケースもありましたので、
その本文の画像にはURLで接続出来る自体ができませんでした。
なので、URLで実際の画像に接続できるように🔗ContentsDesignerのライブラリーを拡張する必要がありました。
詳しく内容は以下の記事の中にContentsDesignerライブラリー拡張部分をご覧ください。
🔗[PHP]PHPのアプリにFacebookの投稿機能を導入(投稿準備中)

##**⑦ facebook側は画像のサイズによって投稿フォーマットが違う**
Facebook側はAPIの設定値を入れて以下のように記事の内容フォーマットを設定するのができます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/45d4f843-41f1-8f33-b3a4-67da931fe497.png)
①：message
②：name
③：description
④：caption

しかし、設定値に関わらず画像の大きさによって、以下のようにフォーマットが変わってしまいます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/203f1dda-6bfe-c222-e543-b2a4ed09234c.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/386dde8c-106b-ff04-1cc4-1d07b60dbcb5.png)
ということで、利用者が混乱する可能性があり、しっかり対応する必要があります。

Twitterの側はHTTP Metaデータを設定して以下のように記事の内容フォーマットを設定するのができます。
これは[🔗TwitterCard](https://dev.twitter.com/ja/cards/overview)でございます。
ドキュメントには申請が必要だと説明されているんですが、実際はいらなかったですし、ものすごく簡単です。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/f7d0ae00-fe14-e9d9-1c4b-a76a53fe7ced.png)
しかし、html側の設定値なので、APIの以外、処理作業が必要になります。

##**⑧ Twitter APIの方はtimeoutが10秒**
Facebook APIの方は特にありませんが、
Twitter APIの方は処理時間が**timeout**の時間、**10秒**を過ぎたらレシーブされません。
`'error' => 'Operation timed out after 10000 milliseconds with 0 bytes received', 'errno' => 28,`
ちなみに、このエラーはAPI側のエラーではなく、ライブラリー側のエラーなので、
APIドキュメントには定義されてません。
[🔗Twitter APIドキュメント response-codes](https://dev.twitter.com/overview/api/response-codes)
[🔗Twitter APIエラーコード一覧](http://pentan.info/web_service/twitter/api_error_code_list.html)
Twitter APIのライブラリー🔗themattharris/tmhOAuthの内部的にはcurlが利用されてますし、
curlのタイムアウトも明確に設定されていました。
🔗[tmhOAuth.php](https://github.com/themattharris/tmhOAuth/blob/master/tmhOAuth.php)

```php:tmhOAuth.php
...
'curl_timeout' => 10,
...
```

一応、ライブラリーのtimeout時間設定を切り替えるのは、
当たり前に可能ですが、向こうからも設定されているらしいでした。
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/b95e5928-ad14-1250-a027-fbcc9949d7c1.png)

詳しい内容は以下の記事をご覧ください。
🔗[PHP]Twitter APIライブラリー 「tmhOAuthby」の timeoutエラー(投稿準備中)

##**⑨ TwitterAPIの方は同じ記事を再び投稿できない**
TwitterAPIの方は内容(文字列及びメディアなど)が
前回の記事と完全統一したらアップできません。
また、こちらは、エラーのresponseが無いので、特にご注意してください。

一方、FacebookAPIの方は同じ記事を再びアップできます。

##**まとめ**
結構2つ全部結局SNSなのに、こんなにAPI政策がちがいますね。
自分のローカルにノートした内容を見るともっとありますが、
その部分は、それぞれの投稿手順の内容を投稿すると確認できます。
  
特にFacebook API側はプラットフォーム政策が変わる頻度が多いので、
実際のフロジェクトに導入したらもっとちゃんと確認するべきです。

とにかく、ご注意くださいー！

######また、Facebookが嫌ではないんですが、自分はFacebook APIよりTwitter APIの方がもっとしやすかったですw。