11

Connect to the Twitter API in an Angular 6 App

 5 years ago
source link: https://www.tuicool.com/articles/hit/UZB7veZ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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 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—ie. 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 Keys and Access Token tab and click on Create my access token  button located at the bottom of the page.

The application will generate 4 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 . j son 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 in our Node server.

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

statuses/home_timeline
statuses/home_timeline
statuses/update

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.

ZvmQFrb.png!web

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.

EvAj6bI.png!web

And here is a GET request to the mentions_timeline endpoint:

jYzyQvy.png!web

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 API's 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 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  file 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, your mentions via the  /mentions_timeline endpoint and post tweets via the  /post_tweet endpoint. 

Conclusion

In this tutorial, you learned how to get started with the Twitter API and how to build a simple Twitter Bot with just a few lines of code. You also learned how to connect with a REST API from Angular, including creating an API Service and components to interact with that service.

To learn more about the Twitter API, head over to https://developer.twitter.com/en/apps and explore some of the endless possibilities.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK