Coditty
8 years ago

How to get email from Twitter API by using Angular and Laravel


How to get email from Twitter user using twitter oauth?
Early this year (2016) twitter announced that it is finally possible to get user email from Twitter API on very easy way.

So, to make it working right let's start...

Laravel

On Laravel side we will use Twitterouath plugin. Install it using your composer:
composer require abraham/twitteroauth

Create controller which will take care of Twitter logins, in your terminal type this:
php artisan make:controller TwitterAuth 

Then in you TwitterAuth controller create method and connect it to the route which can be called from angular side:

public function anyLoginTwitter(Request $request)
    {
    }
and in Route.php create route to this function:
Route::controller( 'auth', 'Auth\TwitterAuth');

Then, again in TwitterAuth controller include twitteroauth library and other needed dependencies so the final controller looks like this:

namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use App\Http\Requests;
use Abraham\Twitteroauth\TwitterOAuth;
use Log;
use App\Models\TwitterTokens;

class SocialAuth extends Controller
{   

    private $twitter_consumer_key;
    private $twitter_secret;
    private $callback_url;  

    public function __construct()
    {
        
        $this->callback_url = env('CALLBACK_URL'); 
        $this->twitter_consumer_key=env('TWITTER_CONSUMER_KEY');
        $this->twitter_secret=env('TWITTER_SECRET');
   
    }


    public function anyLoginTwitter(Request $request)
    {
        // if this is firste request to twitter - users need to confirm usage
        if (!$request->input('oauth_token') || !$request->input('oauth_verifier'))
        {      

            //create twitter instance
            $twitterOAuth = new \Abraham\TwitterOAuth\TwitterOAuth($this->twitter_consumer_key, 
                            $this->twitter_secret);

            // get auth token
            $request_token = $twitterOAuth->oauth('oauth/request_token', array('oauth_callback' => $this->callback_url));
  

            // save token auth and token secret to DB so it can be used later in next step
            $tokens = TwitterTokens::create($request_token);

            return response()->json(['oauth_token'=>$request_token['oauth_token']]);
            

        }else{
            
            // get token secret from db 
            $token = TwitterTokens::where('oauth_token', $request->input('oauth_token'))->first(); 


            // open twitter connection
            $connection = new \Abraham\TwitterOAuth\TwitterOAuth(
                            $this->twitter_consumer_key, 
                            $this->twitter_secret, 
                            $request->input('oauth_token'), 
                            $token->oauth_token_secret// twitter secret from DB
                            );
        
            // get acces token
            $access_token = $connection->oauth("oauth/access_token", ["oauth_verifier" => $request->input('oauth_verifier')]); 
           
             // new TwitterOAuth instance to get email
            $twitterOAuth = new \Abraham\TwitterOAuth\TwitterOAuth( $this->twitter_consumer_key, $this->twitter_secret, $access_token['oauth_token'], $access_token['oauth_token_secret'] );

            // Let's get the user's info with email
            $twitterUser = $twitterOAuth->get('account/verify_credentials', ['include_entities' => 'false','include_email'=>'true','skip_status'=>'true',]);


            // output user object from twitter in your Log file
            Log::info(['user'=>$twitterUser]);
          
            
 
        }
    }
As you can see we are using some parameters that needs to be added in .env file which i will explain later,  and was you can see inside of our method we have if statement which is making difference between two states: first one is when app asks user for first time to use Twitter API and in this case user needs to confirm, and second state is when user is using already approved app which is happening in this line:
if (!$request->input('oauth_token') || !$request->input('oauth_verifier'))

In first state, if user confirm permission to the app then two we are getting oauth_token and oauth_token_secret, oauth_token is sent back to Angular and oauth_token is saved in DB for use in next step:
 $tokens = TwitterTokens::create($request_token);
As you can see we need to create TwitterTokens DB in order to save this data, so in your terminal type this:
php artisan make:model Models/TwitterTokens --migration
and then open newly created migration file and add something like this:
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTwitterTokensTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('twitter_tokens', function (Blueprint $table) {
            $table->increments('id');
            $table->string('oauth_token');
            $table->string('oauth_token_secret');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('twitter_tokens');
    }
}
 and then execute migration command in your terminal:
php artisan migrate --step

next, open your TwitterTokens model and make sure that it looks like this:
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class TwitterTokens extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'twitter_tokens';


    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['oauth_token','oauth_token_secret'];
}

      


There is one more thing that needs to be done in Laravel side and this is creating env variables for Twitter, so open .env file and add these lines:
TWITTER_CONSUMER_KEY=...
TWITTER_SECRET=...
we will populate this data later, when we create Twitter app.


Twitter APP

To be able to use twitter login we need to create twitter app and ask for email permission. So go to apps.twitter.com create new app and fill in data:






example of filled in data



Once your application is created, click the "tab  permissions  ." It is recommended to think about the level of access to your application before it is set up, do not be too greedy, and use a justified level of access ( users do not necessarily agree to link their account to an application that can read their private messages ).
So we will use basic read permission with request for user email:

select "Request email address from user"



Now when we have our app created go to "Keys And Access Tokens" tab and copy consumer key and consumer secret and paste in in .env file


Application accès data Key And Secret




Now it is time to ask twitter for email permission. 
To request additional leave, go on  support.twitter.com/forms/platform  and check "  I need to access special permissions ." You will need to complete the form with the right information, be as specific as possible.



how to fill in Twitter request for email permission



Then click " Send " to complete the request. The waiting period is usually 24 hours but for the time I made the request, it has took an hour. Be patient.

Once the requested additional permission is active, go into the "Tab  Settings  " to complete the missing fields in the form ( they are required to use the new permission ):

  1. Privacy Policy URL : URL to access the policy privacy of your site / application
  2. Terms of Service URL : URL Access Terms and Conditions ( Terms ) of your site / application

That is all from twitter side, now lets see what is needed on angula side:


Angular

Go to Satelizer and download the JS files, and them include it your app:
var app = angular.module('MyApp', ['ui.router','ngMaterial','ngAnimate', 'ngMdIcons', 'satellizer'])

And then in your app.config use authprovider to make a call to larval backend:

app.config(['$authProvider', function($authProvider) {

    $authProvider.twitter({
    url: 'path/to/your/LaravelApp/twitter_login', // defined earlier in our Route.php file
   }
  });
}]);

And Finally in our HTML file create a button which can trigger Twitter Login:
<button ng-if="logged_in == false" ng-click="authenticate('twitter')" class="twitter-button login-btn">
       <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 417 346"><defs><style>.cls-1{fill:#1da1f2;}.cls-2{fill:#fff;}.cls-3{fill:none;}</style></defs><title>Log in wit twitter</title><g id="Dark_Blue" data-name="Dark Blue"><rect class="cls-1" width="51" height="51"/></g><g id="Logo_FIXED" data-name="Logo — FIXED"><path class="cls-2" d="M153.62,301.59c94.34,0,145.94-78.16,145.94-145.94,0-2.22,0-4.43-.15-6.63A104.36,104.36,0,0,0,325,122.47a102.38,102.38,0,0,1-29.46,8.07,51.47,51.47,0,0,0,22.55-28.37,102.79,102.79,0,0,1-32.57,12.45,51.34,51.34,0,0,0-87.41,46.78A145.62,145.62,0,0,1,92.4,107.81a51.33,51.33,0,0,0,15.88,68.47A50.91,50.91,0,0,1,85,169.86c0,.21,0,.43,0,.65a51.31,51.31,0,0,0,41.15,50.28,51.21,51.21,0,0,1-23.16.88,51.35,51.35,0,0,0,47.92,35.62,102.92,102.92,0,0,1-63.7,22A104.41,104.41,0,0,1,75,278.55a145.21,145.21,0,0,0,78.62,23"/><rect class="cls-3" width="31" height="31"/></g></svg>
                <span>Log in</span>
            </button>


That's all Folks :)