skip to Main Content

I’m in the middle of a proof-of-concept work, related to Twitter/X API integration and automation. This step is for basic exploration, so the code is not production ready.

Context:

  • Laraval 10 (no flexibility to change – unless versions like 9 or 8)
  • "php": "^8.1",
  • Local dev environment (http://127.0.0.1)
  • I created my Twitter/X FREE developer account 2 days ago

Twitter/X Developer account – User Authentication Settings:

My code is almost working perfectly. This is what I have set up in Laravel.

composer.json

"atymic/twitter": "^3.0",

.env

# Consumer keys:
TWITTER_CONSUMER_KEY=123
TWITTER_CONSUMER_SECRET=321

# Authentication Token (not OAuth 2.0)
TWITTER_ACCESS_TOKEN=456
TWITTER_ACCESS_TOKEN_SECRET=654
TWITTER_API_VERSION=1.1

configtwitter.php

return [
    'debug' => env('APP_DEBUG', false),

    'api_url' => 'api.twitter.com',
    'upload_url' => 'upload.twitter.com',
    'api_version' => env('TWITTER_API_VERSION', '1.1'),

    'consumer_key' => env('TWITTER_CONSUMER_KEY'),
    'consumer_secret' => env('TWITTER_CONSUMER_SECRET'),
    'access_token' => env('TWITTER_ACCESS_TOKEN'),
    'access_token_secret' => env('TWITTER_ACCESS_TOKEN_SECRET'),
    'bearer_token' => env('TWITTER_BEARER_TOKEN'),

    'authenticate_url' => 'https://api.twitter.com/oauth/authenticate',
    'access_token_url' => 'https://api.twitter.com/oauth/access_token',
    'request_token_url' => 'https://api.twitter.com/oauth/request_token',
];

appHttpControllersTwitterController.php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use AtymicTwitterFacadeTwitter;
use AtymicTwitterTwitter as TwitterContract;
use IlluminateSupportFacadesHttp;

class TwitterController extends Controller
{
    private $twitter;

    public function __construct(TwitterContract $twitter)
    {
        $this->twitter = $twitter;
    }

    public function redirectToTwitter()
    {
        $authCallback = 'http://127.0.0.1:8000/auth/twitter/callback';

        $response = $this->twitter->usingCredentials(
            config('twitter.access_token'),
            config('twitter.access_token_secret'),
            config('twitter.consumer_key'),
            config('twitter.consumer_secret')
        )
        ->getRequestToken($authCallback);

        $url = 'https://api.twitter.com/oauth/authenticate?oauth_token=' . $response['oauth_token'];


        session(['oauth_token' => $response['oauth_token']]);
        session(['oauth_token_secret' => $response['oauth_token_secret']]);


        return redirect($url);
    }


    public function handleProviderCallback(Request $request)
    {
        $oauthToken = $request->query('oauth_token');
        $oauthVerifier = $request->query('oauth_verifier');

        if (!$oauthToken || !$oauthVerifier) {
            return redirect()->route('twitter.error')->withErrors('Invalid OAuth response from Twitter');
        }

        // Ensure the oauth_token matches the one stored in the session.
        if ($oauthToken !== session('oauth_token')) {
            // TODO: Log the error or handle it as per your application's needs
        }

        try {

            $tokenCredentials = $this->twitter->usingCredentials(session('oauth_token'), session('oauth_token_secret'))
            ->getAccessToken($oauthVerifier);

            session([
                'twitter_access_token' => $tokenCredentials['oauth_token'],
                'twitter_token_secret' => $tokenCredentials['oauth_token_secret'],
            ]);

            // Post a tweet or perform other actions with the authenticated user's token credentials.
            if ($this->postTweet($request)) {
                // The tweet was successfully posted
                return response()->json(['status' => 'OAuth Success'], 200);
            } else {
                // The tweet was not posted
                return response()->json(['status' => 'OAuth Success, but error posting message'], 200);
            }


        } catch (Exception $e) {
            // Handle errors, such as logging or displaying a message
            return redirect()->route('twitter.error')->withErrors('Failed to obtain access tokens from Twitter');

        }
    }

    public function postTweet(Request $request)
    {
        $status = $request->input('status', 'This is a tweet posted from my Laravel application using API v2.');

        try {
            $twitter = $this->twitter->usingCredentials(
                config('twitter.access_token'),
                config('twitter.access_token_secret'),
                config('twitter.consumer_key'),
                config('twitter.consumer_secret')
            );

            // Post the tweet
            $response = $twitter->postTweet(['status' => $status]);

            if (isset($response['data']) && isset($response['data']['id'])) {
                // return response()->json(['status' => 'Message posted', 'tweet_id' => $response['data']['id']], 200);
                return true;
            } else {
                // return response()->json(['status' => 'Error posting message', 'error' => $response], 500);
                return false;
            }
        } catch (Exception $e) {
            // return response()->json(['status' => 'Exception caught', 'error' => $e->getMessage()], 500);
            return false;
        }
    }
}

routesweb.php

use AppHttpControllersTwitterController;

Route::get('auth/twitter', [TwitterController::class, 'redirectToTwitter'])->name('twitter.login');
Route::get('auth/twitter/callback', [TwitterController::class, 'handleProviderCallback'])->name('twitter.callback');
Route::get('auth/twitter/post', [TwitterController::class, 'postTweet'])->name('twitter.post');

The methods redirectToTwitter and handleProviderCallback are working fine. I can authenticate and the callback works perfectly.

Problem

The problem is with postTweet, more specifically, this line:

$response = $twitter->postTweet(['status' => $status]);

When this line executes, it returns me this error message:

[453] You currently have access to a subset of Twitter API v2 endpoints and limited v1.1 endpoints (e.g. media post, oauth) only. If you need access to this endpoint, you may need a different access level. You can learn more here: https://developer.twitter.com/en/portal/product

Initially, I suspected it were the API version I was using TWITTER_API_VERSION=1.1 as I read somewhere that the API version 1 was being deprecated. However, I switched that to TWITTER_API_VERSION=2 and did an isolated test with the auth/twitter/post route, but the problem persisted.

Other Hypophysis:

  • Requires HTTPS access?
  • Free account and doesn’t allow me to post?
    Note: In the dashboard, it does say that I would have up to 1500 posts per month
  • Not being done through the subdomain set up in the website field?
  • Something missing in my app settings?
  • I’m not using the API version 2 correctly?

Also, if anyone has a better working suggestion? Either with Guzzle, Laravel Http, Laravel Socialite, or any other dependencies, I would appreciate. Thanks!

2

Answers


  1. I was just implementing Atymic Twitter with Laravel 10 today.

    Here’s what I did that got it to work:

    • Use Twitter API v2
    • Go to Developer Portal -> Your App -> Settings -> Authentication Settings -> App Permissions -> select Read and Write
    • Go to Developer Portal -> Your App -> Keys and tokens -> Regenerate your Access Token and Secret so it comes with Read and Write Permissions

    Additionally, according to the issues post, postTweet is only available for Twitter API v1 however the code provided by Github user @reliq is working for me:
    https://github.com/atymic/twitter/issues/399#issuecomment-1254272114

    use AtymicTwitterContractHttpClient;
    use AtymicTwitterFacadeTwitter;
    
    ...
    
    $querier = Twitter::forApiV2()->getQuerier();
    $result = $querier->post(
        'tweets', 
        [
            Client::KEY_REQUEST_FORMAT => Client::REQUEST_FORMAT_JSON,
            'text' => 'my tweet'
        ]
    );
    
    Login or Signup to reply.
  2. I was able to get auto-posting to the X-API (formerly Twitter) from PHP without any third-party libraries to work just now, December of 2024, following these instructions to the letter:

    https://presuppositions.org/software/php-post-tweet-x-api

    I hope this helps someone!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search