Skip to content

Commit a35932e

Browse files
committed
Add WhatsApp OTP
1 parent b3a931e commit a35932e

File tree

6 files changed

+164
-0
lines changed

6 files changed

+164
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ $otp = new OtpVerifier('966000000000');
7777
$otp->send();
7878
```
7979

80+
- WhatsApp:\
81+
Add a message template named `otp_code`, type (`Authentication`) with your app supported languages.
82+
8083
---
8184

8285
## Contributing

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"prefer-stable":true,
2121
"require": {
2222
"php": ">=7.1|^8.0",
23+
"adrii/whatsapp-api": "^0.7.0",
2324
"guzzlehttp/guzzle": "^7.3",
2425
"illuminate/contracts": "^6|^7|^8|^9|^10",
2526
"illuminate/support": "^6|^7|^8|^9|^10"

config/sendables.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,16 @@
100100
'firebase' => [
101101
'apiKey' => '',
102102
],
103+
104+
/**
105+
* WhatsApp
106+
*
107+
* URL: https://business.facebook.com
108+
*/
109+
'whatsapp' => [
110+
'phoneNumberId' => '',
111+
'accessToken' => '',
112+
'graphVersion' => '',
113+
],
103114
]
104115
];
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace HasanAlyazidi\Sendables\Services\WhatsApp;
4+
5+
use HasanAlyazidi\Sendables\OTP\Providers\SystemOtpProvider;
6+
use HasanAlyazidi\Sendables\SMS\Providers\ISMSProvider;
7+
8+
class WhatsAppOtpProvidor extends SystemOtpProvider
9+
{
10+
public function smsProvider(string $message, string $code): ISMSProvider
11+
{
12+
return new WhatsAppOtpTemplateProvider($message, $code, $this->mobile);
13+
}
14+
15+
public function getClientType(): string
16+
{
17+
return 'whatsapp';
18+
}
19+
20+
public function getCodeDigitsCount(): int
21+
{
22+
return 6;
23+
}
24+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
namespace HasanAlyazidi\Sendables\Services\WhatsApp;
4+
5+
use Adrii\Whatsapp\Whatsapp;
6+
use HasanAlyazidi\Sendables\SMS\Providers\ISMSProvider;
7+
use SendablesHelpers;
8+
use Throwable;
9+
10+
class WhatsAppOtpTemplateProvider implements ISMSProvider
11+
{
12+
protected $message;
13+
protected $code;
14+
protected $mobileNumbers;
15+
16+
protected $ws;
17+
protected $isMassageSent = false;
18+
19+
/**
20+
* Our SMS Provider
21+
*
22+
* @param string $message
23+
* @param array|string $mobileNumbers
24+
*/
25+
public function __construct(string $message, string $code, $mobileNumbers) {
26+
$this->message = $message;
27+
$this->code = $code;
28+
$this->mobileNumbers = is_array($mobileNumbers) ? $mobileNumbers : [$mobileNumbers];
29+
30+
$this->initWhatsApp();
31+
}
32+
33+
public function send(): void
34+
{
35+
foreach ($this->mobileNumbers as $mobileNumber) {
36+
$this->sendWhatsAppMessage($mobileNumber);
37+
}
38+
}
39+
40+
public function isSent(): bool
41+
{
42+
return $this->isMassageSent;
43+
}
44+
45+
protected function getPhoneNumberId(): string
46+
{
47+
return $this->getConfigValue('phoneNumberId');
48+
}
49+
50+
protected function getAccessToken(): string
51+
{
52+
return $this->getConfigValue('accessToken');
53+
}
54+
55+
protected function getGraphVersion(): string
56+
{
57+
return $this->getConfigValue('graphVersion');
58+
}
59+
60+
protected function sendWhatsAppMessage(string $mobileNumber): void
61+
{
62+
try {
63+
$bodyComponent = [
64+
'type' => 'body',
65+
'parameters' => [
66+
[
67+
'type' => 'text',
68+
'text' => $this->code,
69+
],
70+
],
71+
];
72+
73+
$buttonComponent = [
74+
'type' => 'button',
75+
'sub_type' => 'url',
76+
'index' => '0',
77+
'parameters' => [
78+
[
79+
'type' => 'text',
80+
'text' => $this->code,
81+
],
82+
],
83+
];
84+
85+
$this->ws->send_message()
86+
->addComponent($bodyComponent, $buttonComponent);
87+
88+
$response = $this->ws->send_message()
89+
->template('otp_code', $mobileNumber, SendablesHelpers::getCurrentLocale());
90+
91+
$this->isMassageSent = isset($response[2]) && $response[2] === 'OK';
92+
93+
if (!$this->isMassageSent) {
94+
throw new \Exception('OTP not sent, response: ' . json_encode($response));
95+
}
96+
} catch (Throwable $ex) {
97+
$class = self::class;
98+
\Log::error("Error in `$class`: " . $ex->getMessage());
99+
}
100+
}
101+
102+
protected function initWhatsApp(): void
103+
{
104+
$this->ws = new Whatsapp(
105+
$this->getPhoneNumberId(),
106+
$this->getAccessToken(),
107+
$this->getGraphVersion()
108+
);
109+
}
110+
111+
protected function getConfigValue(string $key): ?string
112+
{
113+
return config("sendables.services.whatsapp.$key");
114+
}
115+
}

src/helpers.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,14 @@ public static function removeLeadingPlus($value)
5454
{
5555
return ltrim($value, '+');
5656
}
57+
58+
/**
59+
* Get app current locale
60+
*
61+
* @return string
62+
*/
63+
public static function getCurrentLocale()
64+
{
65+
return config('app.locale');
66+
}
5767
}

0 commit comments

Comments
 (0)