mineur/twitter-stream-api
Laravel package for consuming the Twitter/X streaming API with PHP. Connect to filtered streams, handle tweets as they arrive, and process them through Laravel-friendly events and callbacks.
composer require mineur/twitter-stream-api
Because the repo isn't linked in the package metadata, treat the vendor source as the documentation:
vendor/mineur/twitter-stream-api/src/ and identify the main client/stream class and any Example/ or examples/ directory.listen(callable) method). That contract is your integration point.Minimal Laravel setup:
// config/services.php
'twitter' => [
'consumer_key' => env('TWITTER_CONSUMER_KEY'),
'consumer_secret' => env('TWITTER_CONSUMER_SECRET'),
'token' => env('TWITTER_ACCESS_TOKEN'),
'secret' => env('TWITTER_ACCESS_TOKEN_SECRET'),
],
First use case: a tracking stream listening for a small set of keywords, echoing each tweet to storage/logs/twitter.log, so you confirm authentication and payload shape before wiring persistence. Run it once by hand (php artisan twitter:listen or a throwaway script) before introducing a supervisor.
Long-running Artisan command. Streaming is a persistent HTTP connection, not a request/response call — never inside a controller. Wrap it in a command and keep the handler thin:
class StreamTweets extends Command
{
protected $signature = 'twitter:stream';
public function handle(TwitterStream $stream): int
{
$stream->track(config('twitter.track_terms'))
->onTweet(function (array $tweet) {
BroadcastTweet::dispatch($tweet);
})
->listen();
return self::SUCCESS;
}
}
Handler-per-event. If the package exposes a handler interface, implement one class per event type (TweetHandler, LimitHandler, DeleteHandler) rather than a single fat closure. Streaming endpoints push limit, delete, and disconnect messages alongside tweets; ignoring them silently loses data.
Persist-then-fan-out. Normalise the tweet into an Eloquent model keyed on the tweet ID (updateOrCreate or insertOrIgnore) before dispatching jobs. Streaming connections have no backpressure, so you want durability before queueing.
Config-driven filters. Keep track, follow, and locations in a config file so you can tune them without redeploying the stream process — but remember a filter change requires a reconnect.
Process management. Supervise with Supervisor or Horizon-style workers; a command that dies silently at 3 a.m. is the default failure mode. Log PID + last-received timestamp as a heartbeat.
Testing. Never hit the live endpoint in tests. Extract a StreamClient interface, bind a fake in the container, and feed recorded payload lines through your handler.
~11) with no linked repository — verify it targets the endpoint you actually have access to. Twitter's v1.1 filtered stream API has been deprecated in favour of API v2, and v1.1 access is gated behind paid tiers or academic access. Test credentials against the endpoint manually before building around it.config(), not env() — env() returns null once config is cached.listen() in a while (true) with exponential backoff, and distinguish fatal auth errors (401) from transient ones (420, timeouts) so you don't hot-loop against a ban.CURLOPT_TIMEOUT/CURLOPT_READ_TIMEOUT; if not, patch via subclass.max_tweets/max_runtime guard) rather than relying on PHP to clean up.How can I help you explore Laravel packages today?