Our Latest Blog Posts

latest-post

In this digital era, the expectations of customers have changed significantly. The days are gone when they try to contact customer support and wait until their answers. Nowadays, Consumers need rapid satisfaction, and companies have to change to satisfy them. Today I am talking about AI chatbots, the revolutionary Artificial Intelligence that is transforming customer support through the use of AI chatbots.

What are AI ChatBots?

Chatbots are basically computer programs that use text or voice interactions to mimic human communication with the user, using artificial intelligence (AI) techniques to understand user input and generate relevant responses or actions.

Advantages of ChatBots in Customer Support

Chatbots can help customers to quickly engage with website content, and they can help customers to solve problems on demand. A chatbot for customer service can handle multiple customer queries simultaneously, ensuring that no customer is left waiting. AI chatbots for customer service, productivity tools, and customer support automation reduce the load on the organization’s service team so they can focus on other more complex issues.

Chatbots answer customers' questions any time in the day or night, providing real-time responses, but human agents are available only during business hours.

Availability

Anytime Available: Chatbots can answer rapidly and reduce the wait time for customers who face delays when talking with human agents, providing real-time responses at any time, day or night. Human agents, however, are only available during business hours.

Client Comfort: When your customer support is available 24/7, it builds trust and reliability for your business.3

Instant Answers in Real Time

Reduce wait times: Chatbots can provide standardized and accurate information, ensuring the quality of the service remains constant. This reduces the wait time of the customers who are facing delays when talking with human agents. A chatbot is a reliable tool that can efficiently manage customer interactions, taking customer service to the next level.

Handle Multiple Customers: Chatbots can easily handle multiple requests at the same time without losing speed. They can also handle customers during peak hours.

Reliable Response

Accurate Information: Chatbots provide standardized and accurate information, ensuring constant service quality. In the process, you can enhance customer satisfaction by using chatbots to provide rapid, accurate, and personalized responses. This eliminates the differences that occasionally happen between different human agents.

Less Human Error: Businesses can produce fewer human errors and provide more reliable and dependable customer support by implementing chatbots.

Cost Effective

Operational savings: Chatbots can automate routine customer service jobs, such as handling inquiries and providing support, freeing up human agents so they can concentrate on more difficult problems. You can use chatbots to handle a wide range of customer queries, provide visual assistance, and offer technical support. Chatbots boost client satisfaction by personalizing conversations based on customer data, making each one unique and customized for the individual needs of the customer.

Scalability: Chatbots are able to meet increased consumer demands without extra cost, making them perfect for growing business

Better Customer Experience

Personalization: Chatbots boost client satisfaction by providing personalizing conversations based on customer data, making each one unique and customized for the individual.

Customer Experience Improvement: Chatbots increase customer satisfaction by providing rapid, accurate, and personalized responses, leading to repeat customers. Overall, an AI chatbot is changing the world of customer support. They provide accurate information, and also help to boost companies’ sales because of their personalized answers to each customer and helps to solve customers’ queries. Chatbots are the future of customer support. Learn more about how the best chatbots can transform your business.

Discover Our Solutions

If you are looking for AI chatbots for your business, we just made a product for you, InfyGPT, which provides a complete user-friendly solution. InfyGPT offers advanced features such as Customer service automation and easy connection on current systems. Whether you want to increase customer engagement, improve techniques, or improve help desk support, InfyGPT has the solutions you need. Our product is already SaaS ready if you want to launch your own platform.

Explore More on AI Chatbots

How ChatBots are Transforming the HR Industry

How AI Chatbot Works?

Which AI Chatbot Should You Choose for Your Website?

Why You Need Chatbot for Your Business

Maintaining awareness and using modern AI technologies, such as InfyGPT, may put your company at the height of innovation and client pleasure.

July 20, 20244 minutesuserAnkit Kalathiya

Posts

How To Change Background in Photoshop
We are going to change the background of the photo with another texture.

Step:1 Create a new artboard

Press Ctrl+N for creating a new artboard and set its dimension as per requirement. For example, here we took 4951 x 3301 px.

change-backgrond

Step:2 Set Image In artboard

Drag image from its location to the artboard.

Step:3 Select cropping portion of the image

For the selection of an image, select the quick selection tool from the toolbar, and select a portion of the image which you want to crop.

change-backgrond


Step:4 Select Refine edge

After perfect selection, select a refined edge tool.
After this select overlay from view mode then from edge detection, select a smart radius.

Then set these properties:
  1. Set radius 1 to 2 px
  2. Increase smooth 6 to 7 px from global refinements
  3. Set contrast 20% in global refinements
  4. Check to decontaminate colors in output settings and set amount 70%
  5. Set new layer with a layer mask in output dropdown
Press OK.

change-backgrond
Now our image will look like below:

change-backgrond

Step 5: set new background

Select a new background that you want to set in the image from its location and set the artboard.

Now place our cropped image above this background and adjust as per requirement.

change-backgrond
June 30, 20201 minuteauthorKishan Savaliya
How to use AdminLTE theme with Laravel Fortify

Recently, the Laravel team announced a Laravel Fortify. A framework agnostic authentication backend for Laravel applications. It provides registration, authentication along with two-factor authentication.

As said above, it is framework agnostic, so it doesn't provide any blade views with it. You can implement views of your choice of the frontend. Blade, Vue, React with Bootstrap or TailwindCSS, or any other CSS framework.

Today we are going to see how we can use Laravel Fortify with one of the most popular Bootstrap 4 theme AdminLTE v3.

We can actually do that in minutes with the package that we already developed called Laravel UI AdminLTE

This package also works with the previous laravel version to have an authentication system with Laravel UI for Laravel Frontend Scaffolding.

Let's see step by step, how we can do that.

Install Packages

Install Laravel Fortify and Laravel UI AdminLTE by the following command,

composer require laravel/fortify infyomlabs/laravel-ui-adminlte

Publish Fortify Resources

This command will publish all required actions in the app/Actions directory along with the Fortify configuration file and migration for two-factor authentication.

php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"

Run Migrations

Then run migrations,

php artisan migrate

Add Fortify Service Provider

Next step, add published FortifyServiceProvider to config/app.php

Run AdminLTE Fortify Command

Run the following command,

php artisan ui adminlte-fortify --auth

Install Node Modules and Run a Build

As a next step, install required npm modules and run a build,

npm install && npm run dev

And we are done. Now visit the home page and you should be able to see the full authentication system working including,

Login Registration Forgot Password Reset Password Home page

Laravel AdminLTE UI also provides a starting layout with a sidebar menu and header once you login. so you are all set to go.

June 27, 20202 minutesauthorMitul Golakiya
Retrieve count of nested relationship data in Laravel

Recently in one of our client's projects, we want to load the count of relation in laravel. But we do not want to retrieve original records.

For example,

We have the following Models,

  1. Category
  2. Products
  3. Orders

For that, we have categories, products, orders, order_items table. Where in the order_items table, we got the following fields

  • order_id
  • product_id
  • quantity

So the requirement was, In the Products table, we want to display the total number of orders placed with that item regardless of the quantity in each order. All we need is a number of orders where the product is purchased.

1st way: Query via Relationship

$products = Product::all(); 
$productsArr = $products->map(function (Product $product) 
{     
     $productObj = $product->toArray();     
     $productObj['orders_count'] = $product->orders()->count();     
     return $productObj; 
   }
);

But the problem with this approach was, we are firing queries to the database for every single product. so if I'm retrieving 100 Products from the database then it will fire 100 additional queries to the database. Imagine if we have thousands of products.

2nd way: Eager Load Relationship and Calculate Count

$products = Product::with('orders')->get(); 
$productsArr = $products->map(function (Product $product) 
{
     $productObj = $product->toArray();
     $productObj['orders_count'] = $product->orders->count();
     return $productObj; 
   }
);

so this way, we are only firing two queries to the database. But the problem here is, we are loading all the Orders of each product which we don't need at all. so it will consume lots of memory since we are loading lots of orders. so imaging if we retrieve 100 products, and each product has 10 orders, then we are loading 1000 Orders into memory without any need.

3rd way: Use withCount function

The third powerful approach of using withCount function in Laravel. so we refactored our code like,

$products = Product::withCount('orders')->get();
$productsArr = $products->map(function (Product $product) 
{     
    $productObj = $product->toArray();
    $productObj['orders_count'] = $product ->getAttribute('orders_count');     
    return $productObj; 
    }
);

In this approach, we are firing two queries but no Order models are loaded into memory.

4th Bonus: Using in a nested relationship while multiple eager loading

You can even use it with nested relationships. Imagine a case, where you want to retrieve categories along with its products with orders count.

    $categories = Category::with(['products' => function ($query)
    {
        $query->withCount('orders');
    },
        'someOtherEagerLoading1',
        'someOtherEagerLoading2'
    ])->get();
    $categoriesArr = $categories->map(function (Category $category)
    {
        $categoryObj = $category->toArray();
        $categoryObj['products'] = $category->products->map(function (Product $product)
        {
            $productObj = $product->toArray();
            $productObj['orders_count'] = $product ->getAttribute('orders_count');
            return $productObj;
        });
        return $categoryObj;
    });

Hope this will help you to retrieve the count of relationship data without retrieving actual relation data.

September 18, 20202 minutesauthorMitul Golakiya
Laravel Packages we use everyday at InfyOm

Lots of people ask me frequently, "Which are the laravel packages that you use in almost all projects?" when we meet in Meetup or any other events regardless of its online or physical events.

Let me describe today some of the packages that we almost use in all of the projects.

We have been working in Laravel for almost 7+ years and in these years we have used lots of packages, some from the community and some of our own.

I am categorizing these into 2 categories.

  1. Most used packages
  2. Common Need/Functionality specific packages

Most used packages

These are the packages which must be included in all of our projects. No Excuses.

barryvdh/laravel-ide-helper

Laravel exposes a lot of magic methods and properties. IDE Helper is a very good package when it comes to auto-complete those properties and methods. Even it does an amazing job while refactoring properties or methods of the model.

barryvdh/laravel-debugbar

The second one is from the same author, debugbar helps to debug the request in terms of the number of queries fired, time taken by each query, number models retrieved from db, time taken by each request, and much more.

imanghafoori/laravel-microscope

Laravel Microscope improves the readability of your code. Early returns, unnecessary else statements, and many more. so your code looks clean and efficient in terms of execution as well.

beyondcode/laravel-query-detector

One of the problems that we face is, missing eager loading. In ongoing development, sometimes we add relationships objects in the loops, and then laravel fires tons of queries to the database. Laravel Query Detector detects that and gives a warning while developing the environment.

InfyOmLabs/laravel-generator

No application can be ever built without a few CRUDs. CRUDs are essential in almost all web applications. Also, APIs of CRUDs are essential while building a backend for Mobile or Frontend apps. Laravel Generator is our own developed package that we use in all of the applications to make the CRUD building process faster. It can be used with two themes right now, AdminLTE and CoreUI. But it's also frontend framework agnostic.

Common Need/Functionality specific packages

These are the packages that are used when we particularly need that kind of functionality in the application.

Will keep this list updating.

September 11, 20202 minutesauthorMitul Golakiya
Using Common StatusTrait in Laravel in multiple models

Recently, we were working on a laravel app where we have a status column in multiple models. We have multiple processes going on for which we have different jobs.

Initially job status will be "Pending", then each job will take one record, change the status to "Running" and process that record, and update the status to either "Completed" or "Failed".

We have constants for each status. Something like below,

static $STATUS_PENDING = 0; 
static $STATUS_RUNNING = 1; 
static $STATUS_COMPLETED = 2; 
static $STATUS_FAILED = 3;

And the problem is, we need to go and define the status in every model that we have (around 10+ models).

Then we have functions to update status and check the status in each model like,

public function markRunning($saveRecord = true) 
{     
    $this->status = static::$STATUS_RUNNING;
    if ($saveRecord) {
        $this->save();
    }
}

public function isRunning()
{
    return $this->status === static::$STATUS_RUNNING;
}

And above functions existed for each 4 status. So what we did is, we created a common StatusTrait which can be used across multiple models.

Here is the code of StatusTrait that you can find for that.

Then in each model, we use this trait. For e.g.,

class SavePdf extends Model 
{     
    use StatusTrait;
    .....
}

And then can use any method of trait in all the models,

... 
$savePdf = new SavePdf(); 
$savePdf->markRunning(); 
...

Or we can check if the status of the model is running or not. For e.g.,

... 
if ($savePdf->isRunning()) 
{     
    // logic here 
} 
...

This is how we have saved tons of writing code and optimized the code. Another advantage is, we can just update the value of any status from one single place.

You can also check this kind of pattern and do something like this.

August 26, 20201 minuteauthorMitul Golakiya
Use Laravel Debugbar's measure function to optimize application performance

Laravel Debugbar is a great package to debug Laravel applications while developing. But it's not just limited to debugging. You can use it to optimize the performance of your app a lot as well. Like,

  • number of models loaded in a memory
  • number of queries fired with timing
  • memory used and more.

In short, we can have a complete view of what's going on in each request.

But the less known and used feature it gives is the Timeline tab. Where you can see how much time is taken for each request. And more than that, how much time Laravel took to boot up and how much time our other code has taken. Check the below screenshot.

Timeline

Recently we came to the case, where one of our consultation clients' CRM application was taking too much time on the first load. Their developers were not able to spot a problem. They checked queries and other stuff which looked completely good. so we were not sure where the time had been spent by the application.

That's where debugbar came to rescue us. We used its measure function facility by which we can measure the time spent in each of the functions wherever we want to use. It gives simply two functions startMeasure and stopMeasure to measure the time spent between these two statements.

so we can put startMeasure in the starting of function and put stopMeasure at the end of the function which will render something like this in the timeline tab.

public function searchClients($department) 
{     
    \Debugbar::startMeasure("searchClients'');
    // logic here

    \Debugbar::stopMeasure("searchClients");

    return $result;
}

Once we put this, we get a time that < code > searchClients is taking. Check the screenshot below,

Timeline

Hope this can help you to figure out what piece of code is taking the time and you can optimize it.

Happy Optimizing :)

August 22, 20201 minuteauthorMitul Golakiya
Efficient and Fast Data Import with Laravel Jobs & Queues

Recently Spatie released a brand new package for multi-tenancy called laravel-multitenancy.

It comes with great support to work out of the box with sub-domains like,

https://zluck.infychat.com

https://infyom.infychat.com

https://vasundhara.infychat.com

It identifies the tenant based on the sub-domain and sets a database runtime for your tenant-specific models.

Recently, we used it in one of our clients for Snow Removal CRM. Here we have two models,

  1. Freemium Model - with no sub-domain (application will work on main domain only)
  2. Premium Model - where the tenant will get its subdomain

And a user can convert his account from Freemium to Premium at any point in time by just subscribing to the plan.

So what we want is, on the backend, we want to have a separate database for each tenant, but the application should run on main as well as a sub-domain.

So what we want to have is the ability to extend/customize the tenant detection mechanism. And Spatie does a very good job there where you can customize the logic.

You can create your own TenantFinder class and configure it in the config file of the package. And there is very good documentation for that here:herehttps://docs.spatie.be/laravel-multitenancy/v1/installation/determining-current-tenant/

To do that, what we did is, we have a field called tenant_id in our users table. All of our users are stored in the main database since we may have user access across the tenant.

And when any user does a login, we listen for the event Illuminate\Auth\Events\Login which is documented in Laravel Docs over here.

When a user does a login, our listener will be called and will create a cookie called tenant on the browser with the tenant id of the user. So our listener will look like,

<?php
namespace App\Listeners;

use App\Models\User;
use Cookie;
use Illuminate\Auth\Events\Login;

class LoginListener
{
    public function handle(Login $event)
    {
        /* @var User $authUser /
        $authUser = $event->user;

        Cookie::forget('tenant');
        Cookie::queue(Cookie::forever('tenant', encrypt($authUser->tenant_id)));
    }
}

Also, we encrypt the cookie on our end, so we do not want Laravel to encrypt it again, so we added the tenant cookie into except array of EncryptCookies middleware as per documentation here. so our middleware looks like,

<?php
namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    /**
      The names of the cookies should not be encrypted.

      @var array
     /
    protected $except = [undefined];
}

Now at the last point, we extended our logic to find a tenant and get it to work on the main domain as well as sub-domain.

We have created our own custom class called InfyChatTenantFinder, which looks like,

<?php
namespace App\TenantFinder;

use App\Models\Account;
use App\Models\SubDomain;
use Illuminate\Http\Request;
use Spatie\Multitenancy\Models\Concerns\UsesTenantModel;
use Spatie\Multitenancy\Models\Tenant;
use Spatie\Multitenancy\TenantFinder\TenantFinder;

class InfyChatTenantFinder extends TenantFinder
{
    use UsesTenantModel;

    public function findForRequest(Request $request): ?Tenant
    {
        $host = $request->getHost();

        list($subDomain) = explode('.', $host, 2);

        // Get Tenant by subdomain if it's on subdomain
        if (!in_array($subDomain, ["www", "admin", "infychat"])) {
            return $this->getTenantModel()::whereDomain($host)->first();
        }

        // Get Tenant from user's account id if it's main domain
        if (in_array($subDomain, ["www", "infychat"])) {

            if ($request->hasCookie('tenant')) {
                $accountId = $request->cookie('tenant');
                $accountId = decrypt($accountId);
                $account = $this->getTenantModel()::find($accountId);

                if (!empty($account)) {
                    return $account;
                }

                \Cookie::forget('tenant');
            }
        }
        return null;
    }
}

So basically, first we check if the sub-domain is there, then find a tenant from the sub-domain.

If the domain is the main domain then get the tenant id from the cookie and return the account (tenant) model.

So this is how you can customize the logic the way you want to have a custom tenant identification system.

August 14, 20202 minutesauthorMitul Golakiya
How to remove public path from URL in Laravel Application

While hosting on the Laravel project on cPanel, the traditional problem that lots of developers get is, /public path is appended to the URL. Because in most cases, we put a project directly into the public_html folder, so public_html is our root for the website and that's where our laravel application is also placed.

But to run the Laravel application, we need to point our domain root to the public folder of the laravel. It is possible to do it with cPanel but you need to go through some steps which are not known by most of the people and also the tedious process. So to make it simple, what you can do is, there is a way we can do it via the .htaccess file in our root folder.

We can copy the .htaccess file from our public folder and then make modifications to it to work with the direct root folder and route every request to the public folder.

Here is the final .htaccess file,

<IfModule mod_rewrite.c>     <IfModule mod_negotiation.c>         Options -MultiViews -Indexes     </IfModule>
    RewriteEngine On

    # Handle Authorization MemberHeader
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Remove public URL from the path
    RewriteCond %{REQUEST_URI} !^/public/
    RewriteRule ^(.*)$ /public/$1 [L,QSA]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

By adding the above file to the root folder we can use laravel projects without the public path. Check out the following two lines:

  RewriteCond %{REQUEST_URI} !^/public/   RewriteRule ^(.*)$ /public/$1 [L,QSA]

These two lines make magic and our application will work without public path in URL.

August 01, 20201 minuteauthorMitul Golakiya