Laravelを使用してリアルタイムでツイートを処理する方法
序章
このチュートリアルでは、 Twitter Streaming API を使用して、Laravelアプリケーションからのツイートをリアルタイムで処理する方法を示します。 これにはさまざまな使用例があります。たとえば、会社の言及に自動応答したり、Twitterでコンテストを実行したり、ユーザーが製品について不満を言ったときにサポートチケットを作成したりする場合があります。 このチュートリアルでは、承認されたツイートをアプリのホームページに表示するための「注目のツイート」ウィジェットを作成します。
多くの開発者が精通しているTwitterRESTAPIを最初に見るかもしれません。 これらのAPIを使用すると、アプリユーザーに代わってツイートを読み書きしたり、フォロワーやリストを管理したりするなど、多くの優れた機能を実行できます。 ただし、送信されたツイートを処理する場合、RESTAPIの管理は非常に困難です。 ページネーションとレート制限は、すぐにロジスティックの悪夢になります。
REST APIはリクエスト情報を強制しますが、ストリーミングAPIはフィード情報を提供します。 ドキュメントでどのように機能するかについて詳しく読むことができますが、基本的にはTwitterからアプリケーションへのパイプであり、ツイートの継続的なフローを提供します。
チュートリアルが終了するまでに、アプリ内のツイートのコレクションが常に更新され、ホームページに表示するために承認または不承認にすることができます。 これが最終的な結果のプレビューです。
概要
道具
- パブリックストリーミングAPI: 3つのストリーミングAPIがありますが、私たちが気にするのはパブリックAPI、より具体的には「フィルター」エンドポイントです。 このエンドポイントは、定義したキーワードでフィルタリングされた、すべての公開ツイートのストリームを配信します。
- Phirehose: Phirehose ライブラリは、ストリーミングAPIの認証およびその他の実装の詳細を処理します。
- ホームステッド:選択した環境でアプリを作成できますが、このチュートリアルでは、ホームステッドを使用していることを前提としています。
ノート
- ストリーミングAPIは、Twitterによって特別に扱われます。 1つのTwitterアプリから開くことができる接続は1つだけです。
- Streaming APIへの接続には特別な性質があるため、アプリのWebに面する部分から分離することが重要です。 このチュートリアルでは、Artisanコンソールコマンドを使用して接続を作成します。
- ストリーミングAPIは非常に扱いにくいため、ツイートを収集しているのと同じプロセスで、ツイートを集中的に実行しないことが重要です。 このチュートリアルでは、ツイートをキューに入れるだけです。
- 追跡している用語に注意してください。 人気のある有名人のすべての言及を追跡しようとすると、アプリはおそらく溶けてしまいます。
アプリの構造
作成するアプリの主な部分は次のとおりです。
- と呼ばれるクラス
TwitterStream
これにより、Phirehoseが拡張され、ツイートが到着するとキューに配置されます。 - 職人の命令、
ConnectToStreamingAPI
、のインスタンスでストリーミングAPIへの接続を開きますTwitterStream
- ジョブクラス、
ProcessTweet
、キューからプルされたときにツイートを処理するためのハンドラーが含まれます - A
Tweet
Eloquentモデル - ツイートウィジェットを表示するためのいくつかのブレードテンプレート
チュートリアルを読みながら、このGitHubリポジトリをフォローすることができます。 ステップごとに個別のコミットがあります。
https://github.com/dabernathy89/Laravel-Twitter-Streaming-API-Demo
ステップ1—新しいLaravelアプリを作成する
Laravel インストーラーを使用して、新しいLaravelインスタンスを作成します。
- laravel new twitter-stream-test
それが完了したら、アプリをHomestead構成ファイルに追加します。 あなたの編集を忘れないでください hosts
構成に追加したカスタムドメインを含むファイル。 ホームステッドを起動します。
- homestead up --provision
ホームステッドへのSSH:
- homestead ssh
ついに、 cd
アプリのフォルダに入れます。
ステップ2—Phirehoseをインストールします
次に、Phirehoseライブラリをプルする必要があります。 走る composer require fennb/phirehose
最新バージョンを入手します。 PhirehoseはPSR-0またはPSR-4の自動読み込みをサポートしていないため、Composerを使用する必要があります。 classmap
自動読み込みオプション。 の直後に行を追加します database
エントリ:
"classmap": [
"database",
"vendor/fennb/phirehose/lib"
],
ステップ3—作成する ProcessTweet
仕事
概要で、StreamingAPIからのすべてのツイートをキューに入れることを説明しました。 Laravel 5.2には、キュー内のアイテムを処理するための特別なジョブクラスがあります。 アプリには次のようなジョブがあります ProcessTweet
これは、ツイートをキューから引き出し、それらを使って何かを行う責任があります。 簡単なArtisanコマンドでジョブを作成できます。
- php artisan make:job ProcessTweet
これにより、にJobクラスが生成されます app/Jobs
フォルダ。 今のところ、調整する必要があるのは2つだけです。
- このクラスがツイートを処理することはご存知でしょう(まだ設定していませんが)。 $ tweet変数をコンストラクターに渡し、それをプロパティとして設定します。
- のツイートで何かをする
handle()
方法。 今のところあなたはただすることができますvar_dump()
ツイートからのいくつかの基本的な情報。
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class ProcessTweet extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $tweet;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($tweet)
{
$this->tweet = $tweet;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$tweet = json_decode($this->tweet,true);
var_dump($tweet['text']) . PHP_EOL;
var_dump($tweet['id_str']) . PHP_EOL;
}
}
ステップ4—作成する TwitterStream
クラス
Phirehoseを使用するには、基本のPhirehoseクラスを拡張する単純なクラスを作成する必要があります。 これはどこにでも行くことができますが、私はそれを直接に配置しました app
フォルダ。 フルクラスは次のとおりです。
<?php
namespace App;
use OauthPhirehose;
use App\Jobs\ProcessTweet;
use Illuminate\Foundation\Bus\DispatchesJobs;
class TwitterStream extends OauthPhirehose
{
use DispatchesJobs;
/**
* Enqueue each status
*
* @param string $status
*/
public function enqueueStatus($status)
{
$this->dispatch(new ProcessTweet($status));
}
}
注意すべき点がいくつかあります。
- クラスは
DispatchesJobs
ツイートをキューに簡単にプッシュできるようにする特性。 - 方法は1つだけです。
enqueueStatus
、ツイートごとにPhirehoseから呼び出されます。
ステップ5—登録する TwitterStream
クラス
登録する必要があります TwitterStream
Laravelコンテナでクラス化して、依存関係を適切に取り込むことができるようにします。 の中に register
あなたの方法 AppServiceProvider
クラスには、以下を追加します。
$this->app->bind('App\TwitterStream', function ($app) {
$twitter_access_token = env('TWITTER_ACCESS_TOKEN', null);
$twitter_access_token_secret = env('TWITTER_ACCESS_TOKEN_SECRET', null);
return new TwitterStream($twitter_access_token, $twitter_access_token_secret, Phirehose::METHOD_FILTER);
});
また、追加する必要があります use Phirehose;
と use App\TwitterStream;
サービスプロバイダーのトップにあります。 今のところ、環境変数について心配する必要はありません。まもなく作成します。
ステップ6—職人コマンドを作成する
Artisanコマンドを生成して、コマンドラインからストリーミングAPI接続を開始できるようにします。
php artisan make:console ConnectToStreamingAPI
これにより、定型コンソールコマンドクラスが生成されます。 次に、次のことを行う必要があります。
- コマンドの署名と説明を更新します
- のインスタンスをプルします
TwitterStream
コンストラクターを介したクラス - コマンドの
handle()
メソッド、検索語を含むPhirehoseオブジェクトの構成を完了し、接続を開きます
完成したコマンドは次のようになります。 キーワードを含むツイートを取り込みます scotch_io
:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\TwitterStream;
class ConnectToStreamingAPI extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'connect_to_streaming_api';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Connect to the Twitter Streaming API';
protected $twitterStream;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(TwitterStream $twitterStream)
{
$this->twitterStream = $twitterStream;
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$twitter_consumer_key = env('TWITTER_CONSUMER_KEY', '');
$twitter_consumer_secret = env('TWITTER_CONSUMER_SECRET', '');
$this->twitterStream->consumerKey = $twitter_consumer_key;
$this->twitterStream->consumerSecret = $twitter_consumer_secret;
$this->twitterStream->setTrack(array('scotch_io'));
$this->twitterStream->consume();
}
}
また、コマンドを登録する必要があります。 更新するだけです $commands
のプロパティ App\Console\Kernel
クラス:
protected $commands = [
Commands\ConnectToStreamingAPI::class
];
ステップ7—Twitterアプリを作成する
Twitterでアプリを生成し、キーとアクセストークンを取得します。 それらをあなたに追加します .env
ファイル:
TWITTER_CONSUMER_KEY=KEY
TWITTER_CONSUMER_SECRET=SECRET
TWITTER_ACCESS_TOKEN=TOKEN
TWITTER_ACCESS_TOKEN_SECRET=SECRET
ステップ8—キュードライバーを構成する
キューは好きなように設定できますが、デモンストレーションの目的で、データベースドライバーは正常に機能します。 それを設定するには、 .env
ファイル:
QUEUE_DRIVER=database
デフォルトでは、アプリは次の名前のデータベースを検索します homestead
. あなたの中でこれを更新することを忘れないでください .env
アプリ用に別のデータベースが必要な場合は、ファイル:
DB_DATABASE=twitterstreamtest
また、データベースキューを準備するには、次のコマンドを実行する必要があります。
- php artisan queue:table
- php artisan migrate
ステップ9—いくつかのツイートを読んでください!
これで、いくつかのツイートの処理を開始する準備が整いました。 Artisanコマンドを実行します。
php artisan connect_to_streaming_api
Phirehoseからのコンソールの接続に関するいくつかの情報が表示されます。 ツイートが処理されるたびに通知されるわけではありませんが、接続のステータスが時々更新されます。
やがて、Scottch.ioがキューに並んでいることについてのツイートがいくつかあるはずです。 ツイートが届いているかどうかを確認するには、データベースにアクセスして、 jobs
テーブル:
それでは、キューの処理を試してみましょう。 新しいシェルウィンドウを開き、Homesteadでアプリに移動して、最初のアイテムをキューから取り出します。
php artisan queue:work
すべてがうまくいけば、コンソールにツイートのテキストとIDが表示されます。 handle()
のメソッド ProcessTweet
仕事。
ステップ10—ツイートモデルを設定する
Streaming APIに正常に接続できたので、注目のツイートウィジェットの作成を開始します。 を生成することから始めます Tweet
モデルと対応するデータベースの移行:
- php artisan make:model Tweet --migration
モデルにいくつかのプロパティを追加するので、先に進んでそれらを設定します。 完成したモデルと移行は次のようになります。TwitterIDは大量であるため、モデルIDに文字列を使用していることに注意してください。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tweet extends Model
{
protected $fillable = ['id','json','tweet_text','user_id','user_screen_name','user_avatar_url','public','approved'];
}
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTweetsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tweets', function (Blueprint $table) {
$table->string('id');
$table->text('json');
$table->string('tweet_text')->nullable();
$table->string('user_id')->nullable();
$table->string('user_screen_name')->nullable();
$table->string('user_avatar_url')->nullable();
$table->boolean('approved');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tweets');
}
}
最後に、データベースを移行します。
- php artisan migrate
ステップ11—ProcessTweetジョブを便利にする
今、 ProcessTweet
ジョブは、ツイートに関する情報をコンソールに表示しているだけです。 を更新します handle
ツイートをデータベースに保存する方法:
public function handle()
{
$tweet = json_decode($this->tweet,true);
$tweet_text = isset($tweet['text']) ? $tweet['text'] : null;
$user_id = isset($tweet['user']['id_str']) ? $tweet['user']['id_str'] : null;
$user_screen_name = isset($tweet['user']['screen_name']) ? $tweet['user']['screen_name'] : null;
$user_avatar_url = isset($tweet['user']['profile_image_url_https']) ? $tweet['user']['profile_image_url_https'] : null;
if (isset($tweet['id'])) {
Tweet::create([
'id' => $tweet['id_str'],
'json' => $this->tweet,
'tweet_text' => $tweet_text,
'user_id' => $user_id,
'user_screen_name' => $user_screen_name,
'user_avatar_url' => $user_avatar_url,
'approved' => 0
]);
}
}
それが完了したら、キューリスナーを実行してキューを空にし、ツイートをデータベースにインポートできます。
php artisan queue:listen
これで、データベースにいくつかのツイートが表示されるはずです。
ステップ12—認証を設定する
Laravelの認証スキャフォールディングのおかげで、これはおそらく最も簡単なステップです。 とにかく走れ:
php artisan make:auth
ステップ13—ツイートをウェルカムビューに渡す
今のところ、アプリはメインのランディングページに注目のツイートウィジェットのみを表示します。 認証されたユーザーは、ツイートを承認または却下できるようになるため、すべてのツイートを受信します(ページ分割)。 訪問者は、最近承認された5つのツイートのみを表示できます。
ツイートを既存のものに渡します welcome
のメインルートを更新して表示 routes.php
ファイル:
Route::get('/', function () {
if (Auth::check()) {
$tweets = App\Tweet::orderBy('created_at','desc')->paginate(5);
} else {
$tweets = App\Tweet::where('approved',1)->orderBy('created_at','desc')->take(5)->get();
}
return view('welcome', ['tweets' => $tweets]);
});
ステップ14—ブレードテンプレートを作成する
注目のツイートウィジェット用に3つのブレードテンプレートを作成する必要があります。これらはすべて、 resources/views/tweets
ディレクトリ:
list.blade.php
最近のツイートの公開リストになりますlist-admin.blade.php
すべてのツイートの管理者向けリストになりますtweet.blade.php
両方のツイートリストに共通する小さな部分になります
The list-admin
ビューは最も複雑です。 リストはフォームにラップされており、登録ユーザーがツイートを簡単に承認できるように、いくつかの無線入力が含まれています。
3つのテンプレートを順番に示します。
// list.blade.php
@foreach($tweets as $tweet)
<div class="tweet">
@include('tweets.tweet')
</div>
@endforeach
// list-admin.blade.php
<form action="/approve-tweets" method="post">
{{ csrf_field() }}
@foreach($tweets as $tweet)
<div class="tweet row">
<div class="col-xs-8">
@include('tweets.tweet')
</div>
<div class="col-xs-4 approval">
<label class="radio-inline">
<input
type="radio"
name="approval-status-{{ $tweet->id }}"
value="1"
@if($tweet->approved)
checked="checked"
@endif
>
Approved
</label>
<label class="radio-inline">
<input
type="radio"
name="approval-status-{{ $tweet->id }}"
value="0"
@unless($tweet->approved)
checked="checked"
@endif
>
Unapproved
</label>
</div>
</div>
@endforeach
<div class="row">
<div class="col-sm-12">
<input type="submit" class="btn btn-primary" value="Approve Tweets">
</div>
</div>
</form>
{!! $tweets->links() !!}
// tweet.blade.php
<div class="media">
<div class="media-left">
<img class="img-thumbnail media-object" src="{{ $tweet->user_avatar_url }}" alt="Avatar">
</div>
<div class="media-body">
<h4 class="media-heading">{{ '@' . $tweet->user_screen_name }}</h4>
<p>{{ $tweet->tweet_text }}</p>
<p><a target="_blank" href="https://twitter.com/{{ $tweet->user_screen_name }}/status/{{ $tweet->id }}">
View on Twitter
</a></p>
</div>
</div>
ステップ15-ウェルカムビューにウィジェットを表示する
ブレードテンプレートの準備ができたら、それらを自分のブレードテンプレートに取り込むことができます。 welcome
見る:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="tweet-list">
@if(Auth::check())
@include('tweets.list-admin')
@else
@include('tweets.list')
@endif
</div>
</div>
</div>
</div>
@endsection
リストに非常に基本的なスタイルを設定するには、次のCSSをリストに追加します。 app.blade.php
ファイル:
.tweet {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
margin-bottom: 20px;
}
これで、ウィジェットを表示できるようになりました。 ブラウザに移動して、アプリのホームページにアクセスします。 ツイートが表示されない場合は、必ずキューリスナーを実行してください(php artisan queue:listen
)まだそこにある可能性のあるものを処理します。 許可されたユーザーには、次のようなものが表示されます(さらにいくつかのツイートがあり、ぼやけが少なくなっています)。
ステップ16—ツイートを承認するためのルートを追加する
最後のステップは、ステップ14の管理者リストを機能させることです。 のフォーム list-admin
テンプレートは現在、存在しないルートを指しています。 あなたはそれをあなたのに追加する必要があります routes.php
ファイル。 そのルート内で、ツイートを承認または却下するための基本的なロジックを実行します。 外観は次のとおりです。
Route::post('approve-tweets', ['middleware' => 'auth', function (Illuminate\Http\Request $request) {
foreach ($request->all() as $input_key => $input_val) {
if ( strpos($input_key, 'approval-status-') === 0 ) {
$tweet_id = substr_replace($input_key, '', 0, strlen('approval-status-'));
$tweet = App\Tweet::where('id',$tweet_id)->first();
if ($tweet) {
$tweet->approved = (int)$input_val;
$tweet->save();
}
}
}
return redirect()->back();
}]);
このルートを設定すると、ツイートを承認済みまたは不承認としてマークできるようになります。 一部を承認してから、認証されていないユーザーとしてページにアクセスしてください。 次のようになります。
結論
それでおしまい! LaravelアプリをTwitterStreamingAPIに接続しました。 ただし、完全に本番環境に対応しているわけではありません。 考慮すべき他のいくつかのことがあります:
- Laravelがキューリスナーを監視するために使用するスーパーバイザーを構成して、Artisanコマンドを監視し、失敗した場合は再起動することをお勧めします。
- デプロイメントプロセスへのスーパーバイザーへの呼び出しを処理する必要があります。
- 検索用語は変更される可能性があり、Phirehoseはスクリプトを中断せずにそれらを更新するためのメソッドを提供します。