AUTOMATING TWITTER POSTS WITH LARAVEL AND VUE

In this tutorial, we are going to show you how to integrate Twitter Api to Autopost a Post on twitter using Laravel Framework and Vue js

TWITTER MARKETING IS HUGE

Well for my platform it is anyway, whenever I create a new app or website Twitter is the first social network that I turn to. It’s fast, the analytics are on point, and it’s easy to use, my only issue is that I am busy coding and whatnot to Tweet as much as I would like or need to in order to optimize my reach. This leaves me with two options:

  1. Pay someone to manage my account for me
  2. Learn the Twitter API and write my own automation program to manage it myself

The idea of paying another person to manage my social media just made my stomach and my wallet hurt so the OBVIOUS choice is to use the API. Now let me tell you this  API is DENSE there is a lot you can do with it (click here for the docs) so I will only focus on one aspect in this tutorial, sending posts. The first basic application that I wrote was a simple post scheduler, it allows me to create as many posts as I want, set a date-time to post at, then a Laravel job executes at the desired time, then deletes the entry from the database. This basic application has saved me tremendous time because now I can just schedule all my important tweets weeks or months early!

 

REGISTERING YOUR TWITTER APP

Before you can do any actual coding you need to register your app on Twitter, head over to the developer portal and create your app. The home page will show a list of your Twitter apps, if this is your first time then you won’t have any apps, click on create a new app.

Fill out all the mandatory fields then proceed you should see a screen that shows you your Consumer Key and Consumer Secret. Copy those down and also create some access tokens. These access tokens are for writing Twitter apps that only interact with your OWN account. Copy down the access token and the access token secret and that’s all you have to do. Now let’s code!

 

APP COMPONENTS

 

The main page will be a Vue.js app that allows you to add new tweets, and an area below to edit and delete them. In a traditional SPA manner, the app will interact with an API for all its calls. The backend will consist of one model (Tweet), one controller (TweetController), and one Job ProcessTweet, pretty simple stuff let’s begin.  Start by creating your Laravel application.

laravel new tweeter && cd tweeter && php artisan make:auth

This app only has one composer dependency add it

composer require thujohn/twitter

In the config/app.php make sure to add the following provider and alias

'providers' => [
    ThujohnTwitterTwitterServiceProvider::class,
]
'aliases' => [
    'Twitter' => ThujohnTwitterFacadesTwitter::class,
]

Lastly, run the following command to import the twitter config/ttwitter.php file and modify inserting your Twitter app credentials

php artisan vendor:publish --provider="ThujohnTwitterTwitterServiceProvider"

TWEET MODEL

Now create the Tweet model along with its migration

php artisan make:model -m Tweet

The Tweet model only has two attributes a string that holds the content that is limited to 140 characters and a timestamp for when you want the tweet to be published.

<?php
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateTweetsTable extends Migration
{
 /**
 * Run the migrations.
 *
 * @return void
 */
 public function up()
 {
 Schema::create('tweets', function (Blueprint $table) {
 $table->increments('id');
 $table->string('content',140);
 $table->timestamp('publish_timestamp');
 $table->timestamps();
 });
 }/**
 * Reverse the migrations.
 *
 * @return void
 */
 public function down()
 {
 Schema::dropIfExists('tweets');
 }
}

The Tweet model is pretty bare bones

<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Tweet extends Model
{
 //
 public $fillable = [
 'content',
 'publish_timestamp'
 ];
}

Go ahead and run your migrations we are done with models, now to make our RESTful controller.

RESTFUL CONTROLLER AND ROUTES

Create a resource controller for our Tweet model

php artisan make:controller --resource TweetController

The controller is basic I purposely left out validation and such as a homework exercise for you, but the gist is basic CRUD operations that return JSON

<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppTweet;
use AppJobsProcessTweet;
class TweetController extends Controller
{
 /**
 * Display a listing of the resource.
 *
 * @return IlluminateHttpResponse
 */
 public function index()
 {
 //
 return response()->json(Tweet::all());
 }
/**
 * Show the form for creating a new resource.
 *
 * @return IlluminateHttpResponse
 */
 public function create()
 {
 //
 }
/**
 * Store a newly created resource in storage.
 *
 * @param IlluminateHttpRequest $request
 * @return IlluminateHttpResponse
 */
 public function store(Request $request)
 {
 //create the tweet
 $tweet = Tweet::Create([
 'content' => $request->content,
 'publish_timestamp' => CarbonCarbon::parse($request->publish_timestamp)
 ]);
 
 //Add tweet to the queue
 ProcessTweet::dispatch($tweet)->delay(CarbonCarbon::parse($request->publish_timestamp));
//return json
 return response()->json($tweet);
 }/**
 * Display the specified resource.
 *
 * @param int $id
 * @return IlluminateHttpResponse
 */
 public function show($id)
 {
 //
 return response()->json(Tweet::findOrFail($id));
 }/**
 * Show the form for editing the specified resource.
 *
 * @param int $id
 * @return IlluminateHttpResponse
 */
 public function edit($id)
 {
 //
 }/**
 * Update the specified resource in storage.
 *
 * @param IlluminateHttpRequest $request
 * @param int $id
 * @return IlluminateHttpResponse
 */
 public function update(Request $request, $id)
 {
 //
 $tweet = Tweet::findOrFail($id);
 $tweet->fill([
 'content' => $request->content,
 'publish_timestamp' => CarbonCarbon::parse($request->publish_timestamp)
 ]);
 //return json
 return response()->json($tweet);
 }
/**
 * Remove the specified resource from storage.
 *
 * @param int $id
 * @return IlluminateHttpResponse
 */
 public function destroy($id)
 {
 //
 Tweet::destroy($id);
 }
}

Notice the ProcessTweet job? We will implement that next but for now, open up the routes/api.php file and add the following resource route

<?php
use IlluminateHttpRequest;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
 return $request->user();
});
Route::resource('/tweet','TweetController');

Now our Vue application (patience it’s coming) can interact with our backend. Now let’s add our ProcessTweet job and we will be finished on the backend.

PROCESSTWEET JOB

In order to schedule the tweets to post at any given time, you must utilize Laravel Jobs this will allow you to schedule your events to fire at a certain point in time. If you aren’t familiar with jobs and queues please look at my previous post because I will not be covering setting up queues in this tutorial, otherwise create a new job

php artisan make:job ProcessTweet

In the handle method, we simply call the Twitter API and send the tweet then delete it from the database

<?php
namespace AppJobs;
use IlluminateBusQueueable;
use IlluminateQueueSerializesModels;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchable;
use Twitter;
class ProcessTweet implements ShouldQueue
{
 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 public $tweet;
 /** * Create a new job instance.
 *
 * @return void
 */
 public function __construct(AppTweet $tweet)
 {
 //
 $this->tweet = $tweet;
 }
/**
 * Execute the job.
 *
 * @return void
 */
 public function handle()
 {
 //post the tweet
 Twitter::postTweet(['status' => $this->tweet->content, 'format' => 'json']);
 //delete the tweet from database
 AppTweet::destroy($this->tweet->id);
 }
}

Your backend is now functioning run your queue worker and test around with it or continue to creating the Vue application.

GETTING THE FRONT END TOGETHER

We need to add vue-resource to call our api so let’s add that first

npm install --save vue-resource

Also, update the resources/js/app.js file

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */
require('./bootstrap');
window.Vue = require('vue');
const resource = require('vue-resource');
Vue.use(resource);
/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */
Vue.component('tweet-component', require('./components/TweetComponent.vue'));
const app = new Vue({
 el: '#app'
});

As you can see the example-component has been replaced with the tweet-component rename your ExampleComponent.vue to TweetComponent.vue and update it with the following contents

<template>
 <div class="container">
 <div class="row">
 <div class="col-md-8 col-md-offset-2">
 <div class="panel panel-default">
 <div class="panel-heading">Tweet Scheduler</div>
<div class="panel-body">
 <div class="form-group">
 <input class="form-control" placeholder="Content" v-model="newTweet.content">
 </div>
 <div class="form-group">
 <input class="form-control" type="datetime-local" placeholder="Description" v-model="newTweet.publish_timestamp">
 </div>
<div class="form-group">
 <button class="btn btn-success" v-on:click="addTweet(newTweet)">Add Tweet</button>
 </div>
 <ul v-if="ready" class="list-group">
 <li v-for="post in tweets" class="list-group-item clearfix">
 {{post.content}}
 <span class="pull-right button-group">
 <button class=" btn btn-default" v-on:click="openEditTweet(post)">Edit</button>
 <button class=" btn btn-danger" v-on:click="deleteTweet(post)">Delete</button>
 </span>
 </li>
 </ul>
</div>
 </div>
 </div>
 </div>
 <!-- Modal -->
<div id="editModal" class="modal fade" role="dialog">
 <div class="modal-dialog">
<!-- Modal content-->
 <div class="modal-content">
 <div class="modal-header">
 <button type="button" class="close" data-dismiss="modal">&times;</button>
 <h4 class="modal-title">{{selectedTweet.content}}</h4>
 </div>
 <div class="modal-body">
 <div class="form-group">
 <input class="form-control" placeholder="Content" v-model="selectedTweet.content">
 </div>
 <div class="form-group">
 <input class="form-control" type="datetime-local" placeholder="Publish At" v-model="selectedTweet.publish_timestamp">
 </div>
 <div class="form-group">
 <button class="btn btn-info" v-on:click="editTweet(selectedTweet)">Edit Tweet</button>
 </div>
 </div>
 <div class="modal-footer">
 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
 </div>
 </div>
</div>
 </div>
 </div>
</template>
<script>
export default {
 mounted() {
 console.log('Component mounted.')
 },
 data(){
 return {
 tweets: {},
 newTweet:{
 'content': '',
 'publish_timestamp': ''
 },
 selectedTweet:{
 'content': '',
 'publish_timestamp': ''
 },
 ready: false
 }
 },
 created(){
 this.$http.get('/api/tweet').then(function(data){
 this.tweets = data.data;
 this.ready = true;
 });
 },
 methods: {
 addTweet: function(tweet){
 this.$http.post('/api/tweet',tweet).then(function(data){
 this.tweets.unshift({content:tweet.content,publish_timestamp:tweet.publish_timestamp});
 });
 },
 editTweet: function(tweet){
 this.$http.put('/api/tweet/'+tweet.id,this.selectedTweet).then(function(data){
 let index = this.tweets.indexOf(tweet);
 this.tweets[index] = tweet;
 alert('Updated!');
 $("#editModal").modal('hide');
 });
 },
 openEditTweet: function(tweet){
 console.log(tweet);
 this.selectedTweet = tweet;
 $("#editModal").modal({show: true});
},
 deleteTweet: function(tweet){
 this.$http.delete('/api/tweet/'+tweet.id).then(function(data){
 let index = this.tweets.indexOf(tweet)
 this.tweets.splice(index, 1);
 });
}
}
}
</script>

Open up your resources/assets/sass/app.scss file and add the following fade transition

.fade-enter-active, .fade-leave-active {
 transition: opacity .5s
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
 opacity: 0
}

Run your npm build script as well as your queue worker and start tweeting! You can get the full source code here, and as always please subscribe to my blog via email or push notifications, share, and leave your comment below!

 

Article Source : https://jyroneparker.com/2017/10/23/ho/

One thought to “AUTOMATING TWITTER POSTS WITH LARAVEL AND VUE”

  1. I absolutely love your blog and find most of your post’s to be exactly I’m looking for.
    Does one offer guest writers to write content available for you?
    I wouldn’t mind producing a post or elaborating on most of the subjects you write in relation to here.
    Again, awesome web site!

Leave a Reply

Your email address will not be published. Required fields are marked *