Connect to the Twitter API in an Angular 6 App

change the app Access permissions level to Read and write

In this tutorial, you’ll learn how to authenticate and connect to the Twitter API using Node.js and Angular 6. By the end of this tutorial, you’ll have done the following:

  • authenticate with the Twitter API
  • post tweets with the Twitter API
  • read the Twitter timeline with the Twitter API
  • and more!

Create a Node Server

We will start by building a Node server which will handle interaction with the Twitter API. The first step will be to register a new app so as to obtain the credentials to start using the Twitter API.

Simply go to https://apps.twitter.com/, create a new app, and fill out all the necessary details—i.e. the app name, description, and URL. After creating your application, you will be required to create unique keys for your application. To do that, simply go to the Keys and Access Token tab and click on the Create my access token button located at the bottom of the page.

The application will generate four keys as follows:

  • Consumer Key (the API key)
  • Consumer Secret (the API secret)
  • Access Token
  • Access Token Secret

Please make note of the above keys as they will come in handy later on.

Create a directory for the server code, create a .json file by running npm init, and create a server.js file.

mkdir server
cd server
npm init
touch server.js

We will then install the twit package and the rest of the dependencies necessary to bootstrap an Express application.

npm install twit body-parser cors express

The twit package will help us in interacting with the Twitter API. Next, in server.js, initialize the modules, create an Express app, and launch the server.

const express = require('express');
const Twitter = require('twit');
const app = express();

app.listen(3000, () => console.log('Server running'))

Authentication

We will then supply the API keys to the twit package as shown below.

const api-client = new Twitter({
  consumer_key: 'CONSUMER_KEY',
  consumer_secret: 'CONSUMER_SECRET',
  access_token: 'ACCESS_TOKEN',
  access_token_secret: 'ACCESS_TOKEN_SECRET'
});

The keys are unique to your application and are linked to your Twitter account. So when you make a request with the Twitter API, you will be the authorized user.

We will then create the endpoints for posting and retrieving tweets on our Node server.

Twitter provides the following endpoints that will enable us to interact with our Twitter timeline when retrieving and posting tweets.

  • GET statuses/home_timeline—returns the most recent tweets posted by the user and the users they follow
  • GET statuses/home_timeline—returns the most recent mentions for the authenticating user
  • POST statuses/update—used for posting tweets

Retrieving Tweets

This first endpoint will be used to retrieve the latest tweets on your timeline. We’ll also specify the number of tweets we want to retrieve.

app.get('/home_timeline', (req, res) => {
    const params = { tweet_mode: 'extended', count: 10 };
  
    client
      .get(`statuses/home_timeline`, params)
      .then(timeline => {
        
        res.send(timeline);
      })
      .catch(error => {
      res.send(error);
    });
     
});

Next is the API for retrieving all the tweets where the authenticating user has been mentioned.

app.get('/mentions_timeline', (req, res) => {
    const params = { tweet_mode: 'extended', count: 10 };
  
    client
      .get(`statuses/mentions_timeline`, params)
      .then(timeline => {
      
        res.send(timeline);
      })
      .catch(error => {
      res.send(error);
    });
     
});

In order to be able to write to the Twitter timeline, we need to change the app Access permissions level to Read and write as shown below.

Posting Tweets

Next, update the server.js file to call the API for posting tweets.

app.post('/post_tweet', (req, res) => {

  tweet = req.body;
  
    client
      .post(`statuses/update`, tweet)
      .then(tweeting => {
        console.log(tweeting);
        
        res.send(tweeting);
      })

     .catch(error => {
      res.send(error);
    });
      
   
});

We are now done with the node server, and you can now test your REST API with Postman to ensure it is working right.

Testing the Back-End

If you query the home_timeline endpoint in your API, you should see something like the following.

home_timeline endpoint in Postman

And here is a GET request to the mentions_timeline endpoint:

metions_timeline endpoint in Postman

The server code we have created above can also be used to create a Twitter bot. Below is an example of a basic Twitter bot that updates a user’s status.

const express = require('express');
const Twitter = require('twit');

const app = express();
const client = new Twitter({
  consumer_key: 'Consumer Key Here',
  consumer_secret: 'Consumer  Secret  Here',
  access_token: 'Access Token Here',
  access_token_secret: 'Token  Secret Here'
});


app.use(require('cors')());
app.use(require('body-parser').json());

app.post('/post_tweet', (req, res) => {

  tweet = {status:"Hello world"};
    
    client
      .post(`statuses/update`, tweet)
      .then(timeline => {
        console.log(timeline);
        
        res.send(timeline);
      })

     .catch(error => {
      res.send(error);
    });
      
   
});

app.listen(3000, () => console.log('Server running'));

Build an Angular App to Consume the REST APIs

We will now start building our Angular application which will consume the APIs from our Node server.

First, create an Angular application.

ng new client

Twitter Service

We will start by creating a Twitter service that will make requests to the Node server. Issue the following command in the Angular application.

ng generate service twitterservice

This will create two files, twitter.service.ts and twitter.service.spec.ts. Open twitter.service.ts, add the required imports, declare the API endpoint, and inject the HttpClient module in the constructor.

api_url = 'http://localhost:3000';
 
  constructor(private http: HttpClient) { }

We will then define the functions for consuming the REST API.

export class TwitterService {

 api_url = 'http://localhost:3000';
 
  constructor(private http: HttpClient) { }

  getTimeline() {
    return this.http
      .get<any[]>(this.api_url+'/home_timeline')
      .pipe(map(data => data));

  }

  getMentions() {
    return this.http
      .get<any[]>(this.api_url+'/mentions_timeline')
      .pipe(map(data => data));

  }

}

Access the Twitter Service from Component.

In order to access the Twitter service from our component, we will need to generate the following components.

ng generate component twitter_timeline
ng generate component twitter_mentions
ng generate component tweet

Next, declare the routes for the generated components in app.module.ts.

import { RouterModule, Routes } from '@angular/router';

const appRoutes: Routes = [
  {
    path: 'twitter_timeline',
    component: TwitterTimelineComponent
  },
  {
    path: 'twitter_mentions',
    component: TwitterMentionsComponent
  },

  {
    path: 'tweets',
    component: TweetComponent
  },

  { path: '',
    redirectTo: '',
    pathMatch: 'full'
  }
];

Now open app.component.html and render the components as shown below.

<mat-toolbar color="primary">
   <mat-toolbar-row>
     <!--  <span>HOME</span> -->
      <span><a href="/">HOME</a></span>
      <span class="spacer"></span>
      <span mat-button  routerLink="/twitter_timeline">Timeline</span>
      <br>
      <a  mat-button  routerLink="/twitter_mentions">Mentions</a>
      <br>
      <a  mat-button  routerLink="/tweets">Tweets</a>
   </mat-toolbar-row>
</mat-toolbar>
<router-outlet></router-outlet>

Retrieving Tweets

We’ll create two components for displaying our tweets. The TwitterTimelineComponent will display the most recent tweets from the timeline of the authenticated user, while the TwitterMentionsComponent will display all the tweets in which the authenticated user has been mentioned.

We will start with the TwitterTimelineComponent. Update twitter-timeline.component.ts as follows:

export class TwitterTimelineComponent implements OnInit {
  
  myTimeline: any;

  constructor(private api: TwitterService) { }

  ngOnInit() {
   this.getTwitterTimeline();
  }
  
  getTwitterTimeline(): void {
    this.api.getTimeline()
      .subscribe(
        myTimeline => {
          this.myTimeline = myTimeline;
          console.log(this.myTimeline);
        }
      )
   }
  
}

The getTwitterTimeline method uses the TwitterService to pull data from the authenticated users timeline. We then update twitter-timeline.component.html as shown below.

<h1>Tweeter Timeline</h1>
<div *ngIf="undefined === myData">Loading...</div>
<div *ngIf="undefined !== myData">
  <div class ="card">
    <ng-container *ngFor="let tweets of myData.data">
      <h3>{{tweets.full_text
        }}
      </h3>
      <p>{{tweets.created_at}}</p>
      <p>{{tweets.user.name}}</p>
      <p>{{tweets.user.screen_name}}</p>
      <p>{{tweets.user.location}}</p>
      <p>{{tweets.user.description}}</p>
    </ng-container>
  </div>
</div>

Here, we iterate through the array returned by the getTwitterTimeline method and display the following attributes for each tweet:

  • location
  • description
  • username
  • created_at
  • screen_name

We then move on to the TwitterMentionsComponent and update it as follows.

export class TwitterMentionsComponent implements OnInit {
  
  myMentions: any;

  constructor(private api: TwitterService) { }

  ngOnInit() {
   this.getTwitterMentions();
  }
  
  getTwitterMentions(): void {
    this.api.getTimeline()
      .subscribe(
        myMentions => {
          this.myMentions = myMentions;
          console.log(this.myMentions);
        }
      )
   }
  
}

Lastly, we need to display the data from the API in the template. Update twitter-mentions.component.html as follows:

<h1>Tweeter Mentions</h1>
<div *ngIf="undefined === myData">Loading...</div>
<div *ngIf="undefined !== myData">
  <div class ="card">
    <ng-container *ngFor="let tweets of myData.data">
      <h3>{{tweets.full_text
        }}
      </h3>
      <p>{{tweets.created_at}}</p>
      <p>{{tweets.user.name}}</p>
      <p>{{tweets.user.screen_name}}</p>
      <p>{{tweets.user.location}}</p>
      <p>{{tweets.user.description}}</p>
    </ng-container>
  </div>
</div>

Now, when you run the app, you should see all the attributes of your tweets displayed.

Posting Tweets

We will start with the form for posting data to the /post_tweet endpoint, where we define an input field and a submit button for posting tweets. We will use the FormBuilder module to build our status update form. Add the following code to tweet.component.ts.

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

export class TweetComponent implements OnInit {
tweetForm: FormGroup;
   
  constructor(private api: TwitterService private formBuilder: FormBuilder) { }

  ngOnInit() {

   this.tweetForm = this.formBuilder.group({
            tweetdata: ['', Validators.required]
        });
  }

}

Now update the template so that Angular knows which form to use.

<mat-card class="contact-card">
  <mat-card-content>
    <form [formGroup]="tweetForm" (ngSubmit)="onSubmit()">
    <mat-form-field>
      <input matInput placeholder="Status"  formControlName="tweetdata" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.tweetdata.errors }" >
    </mat-form-field>
    <br>
    <div class="form-group">
      <button [disabled]="loading" class="btn btn-primary">TWEET</button>
      <img *ngIf="loading" src="https://media.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif" />
    </div>
    </form>
  </mat-card-content>
</mat-card>

As you can see above, we have added validators so that the form cannot be submitted if it is blank.

We then go on to the Twitter service and update it to include the code for posting data to the API.

  tweet(tweetdata: string) {
        return this.http.post<any>(`${this.api_url}/post_tweet/`, { status: tweetdata})
            .pipe(map(tweet => {
            
                alert("tweet posted")

                return tweet;
            }));
    }

}

We will then update the TweetComponent to feature the code for calling the method for posting to the Twitter API. Add the following to tweet.component.ts.

export class TweetComponent implements OnInit {
tweetForm: FormGroup;
    loading = false;
    submitted = false;
    returnUrl: string;
    error = '';

  constructor(private api: TwitterService private formBuilder: FormBuilder) { }

  ngOnInit() {

   this.tweetForm = this.formBuilder.group({
            tweetdata: ['', Validators.required]
        });
  }

  get f() { return this.tweetForm.controls; }

    onSubmit() {
        this.submitted = true;

        // stop here if form is invalid
        if (this.tweetForm.invalid) {
            return;
        }

        this.loading = true;
        this.api.tweet(this.f.tweetdata.value)
            .pipe(first())
            .subscribe(
                data => {
                    console.log("yes")
                },
                error => {
                    this.error = error;
                    this.loading = false;
                });
    }

}

You should now be able to retrieve the latest tweets by hitting the /home_timeline endpoint, retrieve your mentions via the /mentions_timeline endpoint, and post tweets via the /post_tweet endpoint.

Source:: Net Tuts