Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Async Tweets Bundle Laravel Package

alexislefebvre/async-tweets-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup for Laravel Integration
Since this is a Symfony bundle, Laravel integration requires **Symfony Bridge** or a **standalone approach** (recommended for Laravel). Here’s how to start:

1. **Install Dependencies**
   ```bash
   composer require abraham/twitteroauth doctrine/dbal doctrine/orm

(Note: Laravel uses illuminate/database instead of Doctrine by default—see "Implementation Patterns" for alternatives.)

  1. Configure Twitter API Keys Store keys in .env (Laravel convention):

    TWITTER_CONSUMER_KEY=your_key
    TWITTER_CONSUMER_SECRET=your_secret
    TWITTER_TOKEN=your_token
    TWITTER_TOKEN_SECRET=your_token_secret
    
  2. First Use Case: Fetch Tweets Create a Laravel command to mimic the Symfony CLI:

    php artisan make:command FetchTweets
    

    Command Logic (in app/Console/Commands/FetchTweets.php):

    use Abraham\TwitterOAuth\TwitterOAuth;
    use Illuminate\Support\Facades\Log;
    
    public function handle() {
        $connection = new TwitterOAuth(
            config('twitter.consumer_key'),
            config('twitter.consumer_secret'),
            config('twitter.token'),
            config('twitter.token_secret')
        );
    
        $tweets = $connection->get('statuses/home_timeline', ['count' => 200]);
        $this->storeTweets($tweets); // Implement storage logic (see below)
        $this->info('Fetched ' . count($tweets) . ' tweets.');
    }
    

    Run it:

    php artisan fetch:tweets
    
  3. Database Setup Create a tweets table manually or use a migration:

    php artisan make:migration create_tweets_table
    

    Migration Example (adapted from Symfony’s schema):

    Schema::create('tweets', function (Blueprint $table) {
        $table->id();
        $table->string('user_id');
        $table->text('text');
        $table->string('profile_image_url_https')->nullable();
        $table->integer('retweet_count')->default(0);
        $table->integer('favorite_count')->default(0);
        $table->boolean('is_retweet')->default(false);
        $table->timestamps();
    });
    

Implementation Patterns

1. Asynchronous Fetching Workflow

  • Cron Job: Schedule php artisan fetch:tweets hourly via Laravel’s scheduler (app/Console/Kernel.php):
    protected function schedule(Schedule $schedule) {
        $schedule->command('fetch:tweets')->hourly();
    }
    
  • Queue Jobs: For scalability, wrap the fetch logic in a job:
    php artisan make:job FetchTweetsJob
    
    public function handle() {
        $this->fetchAndStoreTweets();
    }
    
    Dispatch it in the command:
    FetchTweetsJob::dispatch();
    

2. Displaying Tweets

  • Controller:
    public function index() {
        $tweets = Tweet::latest()->paginate(5); // Match Symfony’s 5/tweet limit
        return view('tweets.index', compact('tweets'));
    }
    
  • View (resources/views/tweets/index.blade.php):
    @foreach($tweets as $tweet)
        <div class="tweet">
            <img src="{{ $tweet->profile_image_url_https }}" alt="Profile">
            <p>{{ $tweet->text }}</p>
            <span>❤️ {{ $tweet->favorite_count }}</span>
            <span>🔄 {{ $tweet->retweet_count }}</span>
        </div>
    @endforeach
    
  • Pagination: Use Laravel’s built-in pagination (matches Symfony’s --table output).

3. Handling Retweets and Media

  • Retweets: Check is_retweet flag and style accordingly (e.g., italics or a "RT" prefix).
  • Media: Store URLs in a media table (one-to-many with tweets) and display with:
    @if($tweet->media)
        <img src="{{ $tweet->media->url }}" class="img-fluid">
    @endif
    

4. Marking Tweets as Read

  • Add a read_at column to the tweets table and update via:
    $tweet->read_at = now();
    $tweet->save();
    
  • Filter unread tweets in queries:
    Tweet::whereNull('read_at')->latest()->get();
    

5. Deleting Old Tweets

  • Create a command:
    php artisan make:command PruneOldTweets
    
    public function handle() {
        Tweet::where('created_at', '<', now()->subDays(30))->delete();
        $this->info('Pruned old tweets.');
    }
    
  • Schedule it weekly:
    $schedule->command('prune:old-tweets')->weekly();
    

Gotchas and Tips

1. Doctrine vs. Eloquent

  • Pitfall: The bundle uses Doctrine ORM. In Laravel, replace Doctrine calls with Eloquent:
    • Symfony: $tweetRepo->findBy(...)Laravel: Tweet::where(...)->get().
    • Symfony: EntityManager::persist()Laravel: $tweet->save().
  • Tip: Use a repository pattern to abstract differences:
    class TweetRepository {
        public function findUnread() {
            return Tweet::whereNull('read_at')->latest()->get();
        }
    }
    

2. Twitter API Rate Limits

  • Gotcha: The bundle fetches 200 tweets at once (Twitter’s max). If you hit limits:
    • Solution: Implement exponential backoff in your job:
      try {
          $tweets = $connection->get('statuses/home_timeline', ['count' => 200]);
      } catch (\Exception $e) {
          if ($e->getCode() === 88) { // Rate limit exceeded
              sleep(60); // Wait 1 minute
              retry();
          }
      }
      

3. Image Handling

  • Gotcha: The bundle uses Assetic (Symfony) for image optimization. In Laravel:
    • Tip: Use Laravel Mix or Vite to process images. Store raw URLs in the DB and let the frontend handle resizing:
      <img src="{{ $tweet->media->url }}" loading="lazy" class="max-w-full h-auto">
      

4. Cron Job Debugging

  • Gotcha: Laravel’s scheduler runs in the background. Log output to storage/logs/laravel.log:
    $this->info('Fetching tweets...'); // Logs to console
    Log::info('Tweets fetched', ['count' => count($tweets)]); // Logs to file
    
  • Tip: Test manually with:
    php artisan schedule:run
    

5. Retweet Parsing

  • Gotcha: Retweets in the API include the original tweet’s text under retweeted_status. Parse it:
    $text = $tweetData['retweeted_status']['text'] ?? $tweetData['text'];
    $isRetweet = isset($tweetData['retweeted_status']);
    

6. Database Indexes

  • Tip: Add indexes for performance:
    Schema::table('tweets', function (Blueprint $table) {
        $table->index('created_at');
        $table->index('user_id');
    });
    

7. Testing

  • Tip: Mock the Twitter API in tests:
    $mock = Mockery::mock('overload:Abraham\TwitterOAuth\TwitterOAuth');
    $mock->shouldReceive('get')->andReturn([/* mock data */]);
    
  • Use Laravel’s HTTP tests to verify routes:
    $response = $this->get('/tweets');
    $response->assertSee('Twitter timeline');
    

8. Security

  • Gotcha: Never expose Twitter keys in client-side code. Use Laravel’s .env and validate input:
    $this->validate(request(), ['tweet_id' => 'required|integer']);
    

9. Extending Functionality

  • Tip: Add columns for:
    • in_reply_to_status_id (for threading).
    • lang (to filter by language).
    • entities (for hashtags/mentions).
  • Example
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware