Monika Vaghasiya

Monika Vaghasiya's Posts

Sr. Laravel Developer

Send real time notification with Pusher using Laravel and Javascript

Here we will learn how to send real-time notifications using Pusher + Laravel.

First of all, you need to create an account in the Pusher and get API keys from there.

Setting up your Laravel application

Now we need to install Pusher SDK, you can install it by the composer using the below command,

composer require pusher/pusher-php-server

After the composer is done, we will need to configure Laravel to use Pusher as its broadcast driver, update the below variables in the .env file,

PUSHER_APP_ID=123456
BROADCAST_DRIVER=pusher

// Get the API Keys from your pusher dashboard

PUSHER_APP_ID=XXXXX
PUSHER_APP_KEY=XXXXXXX
PUSHER_APP_SECRET=XXXXXXX

Open config/app.phpand uncomment the "App\Providers\BroadcastServiceProvider::class".

Now we need an event that will be broadcast to the pusher driver. Let's create a NotificationEvent.

php artisan make:event NotificationEvent

This command will create a below file

namespace App\Events;
use Illuminate\Queue\SerializesModels;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class NotificationEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $username;
    public $message;
    public function __construct($username)
    {
        $this->username = $username;
        $this->message  = "{$username} send you a notification";
    }
    public function broadcastOn()
    {
        //it is a broadcasting channel you need to add this route in channels.php file
        return ['notification-send'];
    }
}

Add broadcasting route in channels.php file

Broadcast::channel('notification-send', function ($user) {
    return true;
}); 

Cache Event at Javascript Side

// Initiate the Pusher JS library

var pusher = new Pusher('YOUR_API_KEY', {
    encrypted: true
});

// Subscribe to the channel we used in our Laravel Event

var channel = pusher.subscribe('notification-send');
channel.bind('App\\Events\\NotificationEvent', function(data) {
    // this is called when the event notification is received...
});

Testing and Setup

Using the below route we can send a notification.

Route::get('test', function () {
    event(new App\Events\NotificationEvent('Monika'));
    return "Event has been sent!";
});
January 16, 20211 minuteMonika VaghasiyaMonika Vaghasiya
Show saved annotations from database in document using PDFTron

Here we will learn how to import annotations saved in the database using PDFTron.

In my last blog, we have learned how to save annotations in the database.

Events for import annotation

At the time of document load, we will get all annotations saved in the database using AJAX call and then we'll import that annotation. Now the question is if we import annotation then that will be drawn and again annotation changed event will fire and again annotation will be saved (as I say in my last blog), so this will become an infinite flow, but we can overcome this problem by checking if an annotation is imported or not. If an annotation is not imported then only we'll save annotation in the database process otherwise we'll ignore it.

When we draw any annotation, the "annotationChanged" event will be fired, and check if it is an imported annotation, then we can ignore it(eg, save annotation process).

Here is an example of how to import annotations from the database.

Example

WebViewer({
    path: 'path_to_the_PDFTron_'lib'_folder_on_your_server',
    css: 'webviewer_css',
    licenseKey: 'YOUR_PDF_TRON_LICENSE_KEY',
    initialDoc: 'YOUR_FILE URL' //url of a file to load
}, document.getElementById('viewer'))
    .then(function (instance) {
        let docViewer = instance.docViewer;
        let annotManager = instance.annotManager;

        annotManager.on('annotationChanged', (annots, action, e) => {
            //if annotation is imported we'll return
            if (e.imported) return;
            //when document will loaded we'll get annotations fro db
            docViewer.on('documentLoaded', function () {
                $.ajax({
                    url: `URL_TO_SAVE_ANNOTATION`,
                    type: 'GET',
                    success: function (result) {
                        if (result.success) {
                            result.data.forEach(annotationObj => {

      annotManager.importAnnotations(annotationObj.annotation);
                            });
                        }
                    },
                    error: function (result) {
                        console.log(result);
                    }
                });
            });
        });
    });
December 28, 20201 minuteMonika VaghasiyaMonika Vaghasiya
Export annotations of PDFTron using jquery

Here we will learn how to export annotations drawn using PDFTron.

Events for export annotation

When we draw any annotation "annotationChanged" event will be fired, then we cache that event and we can export that annotation using "exportAnnotations".

When we draw annotations we'll save them in the database and when we reload the same document we can retrieve saved annotations from the database and can again show them, we will learn that in my next blog post.

Here is an example of how to save an annotation in a database.

Example

WebViewer
   (
     { path: 'path_to_the_PDFTron_'lib'_folder_on_your_server',     
      css: 'webviewer_css',     
      licenseKey: 'YOUR_PDF_TRON_LICENSE_KEY',     
      initialDoc: 'YOUR_FILE URL' //url of a file to load 
     }, 
    document.getElementById('viewer')
   )     
  .then(function (instance) {        
       let docViewer = instance.docViewer;        
       let annotManager = instance.annotManager;                 
       annotManager.on('annotationChanged', 
       (annots, action, e) => {             
            if (e.imported) return;
            annotManager.exportAnnotations({
                links: false,
                widgets: false,
                annotList: annots
            }).then(function (xfdfStrings) {

                annots.forEach(function (annot) {
                    if (action === "delete") {
                        deleteAnnotation(annot.mu);
                    } else {
                        saveAnnotation(annot.mu, xfdfStrings);
                    }
                });

                if (action === "add") {
                    annotManager.selectAnnotation(annots[0]);

                    if (annots[0] !== 'Comment') {
                        // to open comment box

document.getElementById('viewer').childNodes[0].contentWindow.document.querySelector
('div[data element="annotationCommentButton"]').click();
                    }
                }
            });
        });
    });

let saveAnnotation = function (annotationId, annotationXfdf) {
    let saveAnnotationUrl = '';
    if (fromExtension) {
        saveAnnotationUrl = YOUR_PROJECT_URL/annotations/${annotationId};
    } else {
        saveAnnotationUrl = YOUR_PROJECT_URL/annotations/${annotationId};
    }

    $.ajax({
        url: saveAnnotationUrl,
        type: 'POST',
        data: {annotation: annotationXfdf},
        success: function (result) {
            console.log(result);
        },
        error: function (result) {
            console.log(result);
        }
    });
};

let deleteAnnotation = function (annotationId) {

    let deleteAnnotationUrl = '';
    if (fromExtension) {
        deleteAnnotationUrl = YOUR_PROJECT_URL/annotations/${annotationId};
    } else {
        deleteAnnotationUrl = YOUR_PROJECT_URL/annotations/${annotationId};
    }

    $.ajax({
        url: deleteAnnotationUrl,
        type: 'DELETE',
        success: function (result) {
            console.log(result);
        },
        error: function (result) {
            console.log(result);
        }
    });
};
October 10, 20201 minuteMonika VaghasiyaMonika Vaghasiya
How to Integrate the Stripe Customer Portal

The Stripe Customer Portal is very useful for managing customer subscriptions like Upgrade, Downgrade, and Renew.

Customers can review their invoices directly and also check their history.

Portal billing setting

Do login into your stripe account

Navigate to the portal settings to configure the portal, and do below billing settings

setting

Create Product

First of all, we need to create products. Follow the below process for creating products.

Click on the “Products” menu from the sidebar and click on the “Add Product” button on the top right corner of the products page and create a product.

Here is an example of how to create a product.

Create two or three products as shown below.

product

Select product In portal settings

If you want to allow your customer to change their subscription by an upgrade, downgrade, cancel or renew you need to set products in your portal setting.

Now navigate to customer portal settings again, in the Products section, you will find a dropdown “Find or add a product..”, click on it you will find the plan you have added, select the price of this product.

portal settings

Don’t forget to save all these settings.

Then do the setup of your business information, also do branding settings in the “Appearance” section, and save it.

Once you are done with settings, you can preview the customer portal by clicking the Preview button beside the save button.

This will launch a preview of the portal so you can see how customers will use it for managing their subscriptions and billing details.

Integrate into Laravel

  • Get you API keys
    • Go to “Developers > API keys” here you will find your “Publishable key” and “Secret key

api keys

  • Create customer using stripe dashboard or by API
    • Create customer by Stripe API.
    • First of all, you’ll need to set your stripe secret key. For development mode, you can use test mode keys, but for production, you need to use your live mode keys
\Stripe\Stripe::setApiKey('sk_test_YOUR_KEY');
$customer = \Stripe\Customer::create([undefined]);
  • Once you create a customer using stripe API, now you can create a billing session for that customer using stripe API.
    • Create a billing session of the customer by API
\Stripe\Stripe::setApiKey('sk_test_YOUR_KEY'); 
\Stripe\BillingPortal\Session::create([    
      'customer'   => 'cus_HnKDAQNjBniyFh',    
      'return_url' => 'https://example.com/subscription'
]);

You’ll get a response, like the below object:

{
  "id": "pts_c5cfgf8gjfgf73m5748g6",
  "object"    : "billing_portal.session",
  "created"   : 453543534,   
  "customer"  : "cus_bGFsnjJDcSiJu",   
  "livemode"  : false,   
  "return_url": "https://example.com/subscription" 
}

In the response body, there is a URL attribute:

Now redirect your customer to this URL immediately. For security purposes, this URL will expire in a few minutes.

After redirecting the customer to this URL, the portal will open and customers can manage their subscriptions and billing details in the portal. customers can return to the app by clicking the Return link on your company’s name or logo within the portal on the left side. They’ll redirect to the return_url you have provided at the time of creating the session or redirect URL set in your portal settings.

Listen to Webhooks

You must have a question, what is this Webhook!!!

It’s just an event, which will fire when a customer does any changes in his/her subscription in the portal, we can listen to this event in our app and make appropriate changes.

For example,

If a customer cancels his/her subscription in the portal, then how we will know about it!!

For it, when customers do any changes in his/her subscription

“customer.subscription.updated” event will be fired and we can listen for this event and, get to know the customer has changed subscription so we need to do appropriate changes in our app also.

Set webhook in your app

In the webhooks.php (in routes folder) file set up a route to handle webhook.

You can use the Laravel Cashier Package (https://laravel.com/docs/8.x/billing)to handle webhooks.

To set up a webhook for your portal navigate to the “Developers > Webhooks” menu you will find the below screen, here I have added a webhook to handle subscription cancel and update events, it will fire when customers update subscription, and you will receive it.

webhook

Click on the “Add endpoint” button and the below pop up will open. In Endpoint URL set the route you have created in the webhooks.php file. Select subscription updated and deleted events.

webhook endpoint

All done.

For more details, you can use stripe customer portal integration

July 25, 20203 minutesMonika VaghasiyaMonika Vaghasiya