I am working on a Laravel application which sends out SMS, and has several other integrations. The integrations are per company listed in the organization table. I have created a table of integrations and linked those with relationships to the organizations table.
Is there a better way to do this? Refactor somehow? I was thinking of using a class that extends the Twilio client class, and then putting the credentials in there. So it would be just simple to call TwilioClient and thats it. On the backend (class) it would do all the heavy lifting of checking the db and getting the credentials.
Right now this is what I have.
public function test()
{
$integration = Integration::where('provider', '=', 'Twilio')->first();
$credentials = $integration->credentials;
$client = new Client($credentials['sid'], $credentials['token']);
$s = $client->lookups->v1->phoneNumbers("+14801234567")->fetch(
["addons" => ["ekata_reverse_phone"]]);
return $s->addOns;
}
Ideally I would like to avoid putting this code in each area that has an integration. Twilio is just an example. It could be AWS, or Azure, or any other PHP/REST/Graph integration, etc.
$integration = Integration::where('provider', '=', 'Twilio')->first();
$credentials = $integration->credentials;
$client = new Client($credentials['sid'], $credentials['token']);
It would be great to be able to call something like:
$client = new IntegrationClient('Twilio');
From there is would do all of the work on the backend.
I appreciate the patience. I am still learning on this and any help is greatly appreciated.
Following on from our comments.
I feel like each class you are using an integration in already explicitly knows which integration it wants; it just needs one that is configured for your tenant.
The way I typically do this (and have done with Twilio) is to bind instances of the Twilio Client to an instantiated version of the client with credentials and all.
The way I would see this working in your code would be like so:
// AppServiceProvider.php
// In your boot function
$this->app->bind(Client::class, function () {
$integration = Integration::where('provider', 'Twilio')->first();
$credentials = $integration->credentials;
new Client($credentials['sid'], $credentials['token']));
});
Now in your class that needs to use Twilio:
private $client;
public function __construct(Client $client)
{
$this->client = $client;
}
public function test()
{
$s = $this->client->lookups->v1->phoneNumbers("+14801234567")->fetch(
["addons" => ["ekata_reverse_phone"]]
);
return $s->addOns;
}
The binding in your AppServiceProvider will tell the Laravel container that whenever a class is asking for the Twilio client, then execute that callback and provide the result. This means that your class receives an instantiated version of the client rather than an unconfigured one.