In this tutorial, I’ll show you how to integrate and use Pinterest API in your Laravel Application. At first, I wanted to use dirkgroenen/pinterest-api-php which would work flawlessly for any PHP project but I faced an issue when trying to integrate it into Laravel. I added this package, wrote a service provider and a facade to statically call methods on the Pinterest class. This package would have worked fine if I would have used the dependency injection technique where you would type-hint a class on constructor to resolve and inject it into your controller. Here’s an example Service Provider and Controller.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php class PinterestServiceProvider extends ServiceProvider { public function boot(){...} public function register() { $this->app->bind('Pinterest', function(){ return new Pinterest( config('pinterest.config.client_id'), config('pinterest.config.client_secret') ); }); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class HomeController extends Controller { private $pinterest; public function __construct(Pinterest $pinterest) { $this->pinterest = $pinterest; } public function callAPI(){ $this->pinterest->auth->setOAuthToken(Auth::user()->access_token); } } |
But instead, I wanted to use Facade. Here is an example of Facade and Controller.
1 2 3 4 5 6 7 8 9 |
<?php namespace WaleedAhmad\Pinterest\Facade; use Illuminate\Support\Facades\Facade; class Pinterest extends Facade { protected static function getFacadeAccessor() { return 'Pinterest'; } } |
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class HomeController extends Controller { public function callAPI(){ Pinterest::auth->setOAuthToken(Auth::user()->access_token); } } |
When I called my controller method, it rendered an error saying that auth cannot be called statically. It was then that I realized that Facade classes can only redirect method calls to the underlying class. So I checked and there were no getter setters available to access $auth or $request data members on the Pinterest class. This is where this package failed for my specific use case. So I forked this package, made all the necessary changes required to make it work with Laravel Facades, updated docs and published it as waleedahmad/pinterest-laravel.
Getting Started
After creating a new Laravel Project, run php artisan make:auth to generate authentication scaffold. Now install these dependencies.
1 2 3 |
composer require laravel/socialite composer require socialiteproviders/pinterest composer require waleedahmad/pinterest-laravel |
If your Laravel project doesn’t support Package auto-discovery, add these service providers to $providers[] array in config/app.php
1 2 3 4 |
'providers' => [ \SocialiteProviders\Manager\ServiceProvider::class, \WaleedAhmad\Pinterest\ServiceProviders\PinterestServiceProvider::class, ]; |
Now run
1 |
php artisan vendor:publish --provider="WaleedAhmad\Pinterest\ServiceProviders\PinterestServiceProvider" |
to publish Pinterest configuration to your Laravel config folder. Also, add SocialiateWasCalled event to $listen[] array in EventServiceProvider.
1 2 3 4 5 6 7 8 |
protected $listen = [ 'App\Events\Event' => [ 'App\Listeners\EventListener', ], \SocialiteProviders\Manager\SocialiteWasCalled::class => [ 'SocialiteProviders\\Pinterest\\PinterestExtendSocialite@handle', ], ]; |
Register a Pinterest Application
Create a new Application in by visiting developers.pinterest.com. Fill in App name and description.
Create and copy app id and secret and update env variables in .env file.
1 2 3 |
PINTEREST_KEY=YOUR_KEY PINTEREST_SECRET=YOUR_SECRET PINTEREST_REDIRECT_URI=https://127.0.0.1/login/pinterest/callback |
Make sure you update app settings and enter same redirect URI in web section.
Authentication
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php Auth::routes(); Route::group(['middleware' => ['auth']], function(){ /** * Authorization Routes */ Route::get('/login/pinterest', 'Auth\PinterestController@redirectToPinterestProvider'); Route::get('/login/pinterest/callback', 'Auth\PinterestController@handlePinterestProviderCallback'); }); |
Since Pinterest API doesn’t return email address of the authorized user, we’ll register the user with conventional form based authentication and then later ask them to authorize with Pinterest OAuth service. Create PinterestController under Auth Controller directory by running.
1 |
php artisan make:controller Auth/PinterestController |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Auth; use Laravel\Socialite\Facades\Socialite; class PinterestController extends Controller { public function redirectToPinterestProvider(){ return Socialite::with('pinterest')->scopes([ 'read_public', 'write_public', 'read_relationships', 'write_relationships' ])->redirect(); } public function handlePinterestProviderCallback(){ $user = Socialite::driver('pinterest')->user(); $details = [ "token" => $user->token ]; if(Auth::user()->pinterest){ Auth::user()->pinterest()->update($details); }else{ Auth::user()->pinterest()->create($details); } return redirect('/'); } } |
You can remove or add your own scopes to Socialite scopes method. Read more about here. On callback, we’ll create a new record on pinterest table and create or update token. Create a migration for pinterest table.
1 |
php artisan make:migration create_pinterest_table --create=pinterest |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?php class CreatePinterestTable extends Migration { public function up() { Schema::create('pinterest', function (Blueprint $table) { $table->increments('id'); $table->string('token'); $table->integer('user_id')->unsigned(); $table->foreign('user_id')->references('id')->on('users'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('pinterest'); } } |
Edit User model and add this method to it to create a one to one relation between users and pinterest table.
1 2 3 |
public function pinterest(){ return $this->hasOne('App\Pinterest', 'user_id', 'id'); } |
Also update $fillable[] array on your Pinterest model.
1 2 3 4 5 6 7 8 |
<?php class Pinterest extends Model { protected $table = 'pinterest'; protected $fillable = ['user_id', 'token']; } |
Update your routes and add index route.
1 2 3 |
Route::group(['middleware' => ['auth']], function(){ Route::get('/', 'HomeController@index'); }); |
1 2 3 4 5 6 7 8 9 10 11 |
<?php namespace App\Http\Controllers; class HomeController extends Controller { public function index() { return view('index'); } } |
Render index view for it and add this code to your index view.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> @if(Auth::user()->pinterest) <div class="user-details">...</div> @else <a href="/login/pinterest"> <button class="btn btn-primary">Authorize Pinterest</button> </a> @endif </div> </div> @endsection |
We’ll render a login link if a user doesn’t have a record on pinterest table. Otherwise, we’ll render user details.
Middleware
You need to set user token before using API via Pinterest Facade. Write a middleware.
php artisan make:middleware PinterestMiddleware
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php class PinterestMiddleware { public function handle($request, Closure $next) { if(Auth::user()->pinterest){ Pinterest::auth()->setOAuthToken(Auth::user()->pinterest->token); } return $next($request); } } |
We’re setting user access token by calling setOAuthToken() if a user has a Pinterest record. Register this middleware by adding it to app\Http\Kernel.php $routeMiddleware[] array.
1 2 3 4 |
protected $routeMiddleware = [ [...] // a bunch of other middlewares 'pinterest' => \App\Http\Middleware\PinterestMiddleware::class, ]; |
Now add pinterest middleware to your authenticated route group in the routes file.
1 2 3 |
Route::group(['middleware' => ['auth', 'pinterest']], function(){ // app routes }); |
API Usage
Update your routes file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php Auth::routes(); Route::group(['middleware' => ['auth']], function(){ /** * API Routes */ Route::get('/', 'HomeController@index'); Route::get('/user', 'HomeController@getAuthUser'); Route::get('/pins', 'HomeController@getPins'); Route::get('/boards', 'HomeController@getBoards'); Route::post('/pin', 'HomeController@createPin'); Route::post('/pin/edit', 'HomeController@editPin'); Route::get('/following/users', 'HomeController@getFollowingUsers'); Route::get('/following/boards', 'HomeController@getFollowingBoards'); Route::get('/following/interest', 'HomeController@getFollowingInterests'); Route::post('/follow/user', 'HomeControlloer@followUser'); Route::post('/follow/board', 'HomeControlloer@followBoard'); Route::post('/follow/interest', 'HomeControlloer@followInterest'); Route::post('/unfollow/user', 'HomeControlloer@unfollowUser'); Route::post('/unfollow/board', 'HomeControlloer@unfollowBoard'); Route::post('/unfollow/interest', 'HomeControlloer@unfollowInterest'); /** * Authorization Routes */ Route::get('/login/pinterest', 'Auth\PinterestController@redirectToPinterestProvider'); Route::get('/login/pinterest/callback', 'Auth\PinterestController@handlePinterestProviderCallback'); }); |
Get User
1 2 3 4 |
public function getAuthUser(){ $user = Pinterest::user()->me(); dd($user); } |
By default, API will only return a few user attributes. You can ask it for more by passing an array to me() method with.
1 2 3 |
Pinterest::user()->me(array( 'fields' => 'username,first_name,last_name,image[small,large]' )); |
Get Pins
1 2 3 4 5 6 7 8 9 10 11 |
public function getPins() { $pins = Pinterest::user()->getMePins(); dump($pins); if($pins->hasNextPage()){ $more_pins = Pinterest::user()->getMePins([ 'cursor' => $pins->pagination['cursor'] ]); dd($more_pins); } } |
You can get user pins by calling getMePins() method. By default, API returns only 25 pins and paginate results for you. You can check if it has a next page by calling $pins->hasNextPage(). To get next page results, you can pass cursor to get getMePins() method returned from the last collection.
Get Boards
1 2 3 4 5 |
public function getBoards() { $boards = Pinterest::user()->getMeBoards(); dd($boards); } |
getMeBoards() will return user boards. If you’ve more than 25 boards, API will automatically paginate results for you and you can fetch next page like we did with getMePins() method.
Create Pin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public function createPin() { // Create a pin from external source Pinterest::pins()->create(array( "note" => "Pin Caption", "image_url" => "https://imgur.com/oSDNUSD", "board" => "waleedahmad/pinterest-laravel" )); // Create a pin from storage path Pinterest::pins()->create(array( "note" => "Pin Caption", "image" => Storage::path('/path/to/your/image.jpg'), "board" => "waleedahmad/laravel-pinterest" )); // Create ping with base64 encoded image Pinterest::pins()->create(array( "note" => "Pin Caption", "image_base64" => "[base64 encoded image]", "board" => "waleedahmad/laravel-pinterest" )); } |
You can create a pin from an external source, storage path, and base64 encoded string.
Edit Pin
1 2 3 4 5 6 |
public function editPin() { Pinterest::pins()->edit("181692166190244554", array( "note" => "Update Caption" )); } |
You can update pin caption by passing a note to edit() method.
Get Following Users
1 2 3 4 5 |
public function getFollowingUsers() { $users = Pinterest::following()->users(); dd($users); } |
You can retrieve following users by calling users() chained method via following() object. Just like pins and routes, results will be paginated with a cursor to next page.
Get Following Boards
1 2 3 4 5 |
public function getFollowingBoards() { $boards = Pinterest::following()->boards(); dd($boards); } |
You can retrieve user following boards by calling following()->boards().
Get Following Interests
1 2 3 4 5 |
public function getFollowingInterests() { $interests = Pinterest::following()->interests(); dd($interests); } |
You can retrieve user interests by calling following()->interests() .
Follow/Unfollow User, Boards and Interests
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public function followUser(){ Pinterest::following()->followUser("username"); // username as param } public function followBoard(){ Pinterest::following()->followBoard("id"); //board id as param } public function followInterest(){ Pinterest::following()->followInterest("architecten-911112299766"); // interesst id as param } public function unfollowUser(){ Pinterest::following()->unfollowUser("waleedahmad"); // username as param } public function unfollowBoard(){ Pinterest::following()->unfollowBoard("503066289565421201"); // board id as param } public function unfollowInterest(){ Pinterest::following()->unfollowInterest("architecten-911112299766"); // interesst id as param } |
You can follow or unfollow User, boards, and interests by following methods. You can wrap them in an if condition to check if your action was successful.
1 2 3 4 5 |
if(Pinterest::following()->followUser("username")){ // followed, do something }else{ // failed, do something } |
There are so many more methods available to perform action on user behalf. Read package docs for more info. If API starts to throw 429 error, it means that you ran out of requests.
Effective April 16 2018, all unapproved apps are allowed 10 calls per hour for each unique user token.
After you successfully submit an app for approval, each app (with a unique app ID) is allowed 1000 calls per hour for each unique user token.
In both cases, the 60-minute window is a sliding window based on when you make your first request. If you hit your rate limit, you’ll have to wait a minimum of 1 hour to get a few more requests.
Read more about rate limiting here. I’ve also set up a demo repository. If you ran into an issue or my package threw an error, you can comment here or send me a message on Facebook page. I’ll try to help you with it.
Create pin is not working.
how can be schedule post on pinterest using api in php?
i am not looking up third party tools.
kindly support me for schedule post on pinterest go live on later date using pinterest api in php(laravel).
You can write a simple scheduler in Laravel for queuing your Pinterest posts.
thanks for your reply.
i have created queue job for schedule post on LinkedIn and pinterest , the job stored into job table while i run php artisan queue:work command the job delivered from job table but post doesn’t posting on linkedin
do you have any idea kindly help me to short out issue.