Skip to content

Commit 2fb87cd

Browse files
authored
Merge pull request #7 from WevrLabs-Group/fix-#5
Fix #5
2 parents 938e6d3 + 55ccebc commit 2fb87cd

File tree

2 files changed

+90
-153
lines changed

2 files changed

+90
-153
lines changed

chatwoot/chatwoot.php

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/***************************************************************************
44
// * *
5-
// * Chatwoot WHMCS Addon (v2.0.3). *
5+
// * Chatwoot WHMCS Addon (v2.0.4). *
66
// * This addon module enables you to integrate Chatwoot with your WHMCS *
77
// and leverage its powerful features. *
88
// * Tested on WHMCS Version: v8.12. *
@@ -23,35 +23,12 @@
2323

2424
use WHMCS\Database\Capsule;
2525

26-
if (!Capsule::schema()->hasTable('mod_chatwoot')) {
27-
try {
28-
Capsule::schema()->create(
29-
'mod_chatwoot',
30-
function ($table) {
31-
$table->increments('id')->unique();
32-
$table->string('setting', 100)->unique();
33-
$table->string('value', 55250)->nullable();
34-
}
35-
);
36-
} catch (\Exception $e) {
37-
return [
38-
"status" => "error",
39-
"description" => "There was an error activating Chatwoot for WHMCS - Unable to create mod_chatwoot table: {$e->getMessage()}",
40-
];
41-
logActivity("Chatwoot: there was an error activating the addon - Unable to create mod_chatwoot table: {$e->getMessage()}");
42-
}
43-
}
44-
45-
if (!Capsule::table('mod_chatwoot')->where('setting', 'signing_hash')->first()) {
46-
Capsule::table('mod_chatwoot')->insert(['setting' => 'signing_hash', 'value' => md5(time())]);
47-
}
48-
4926
function chatwoot_config()
5027
{
5128
return [
5229
"name" => "Chatwoot",
5330
"description" => "Chatwoot is a customer support tool for instant messaging channels that can help businesses provide exceptional customer support. WHMCS module contributed by: <a href='https://wevrlabs.net/?utm_source=addon_link' target='_blank'>WevrLabs Hosting</a>",
54-
"version" => "2.0.3",
31+
"version" => "2.0.4",
5532
"author" => "<a href='https://github.com/WevrLabs-Group/Chatwoot-WHMCS' target='_blank'><img src='https://dash.wevrlabs.net/logo.svg' alt='Contributed by WevrLabs Hosting' width='135px' /></a>",
5633
"fields" => [
5734
'chatwoot_enable' => [
@@ -61,20 +38,28 @@ function chatwoot_config()
6138
'Default' => 'yes',
6239
'Description' => 'Check to activate the chat box.',
6340
],
64-
'chatwoot_jscode' => [
65-
'FriendlyName' => 'Website JS Code',
66-
'Type' => 'textarea',
67-
'Rows' => '15',
68-
'Cols' => '100',
41+
'chatwoot_url' => [
42+
'FriendlyName' => 'Chatwoot URL',
43+
'Type' => 'text',
44+
'Rows' => '',
45+
'Cols' => '',
6946
'Default' => '',
70-
'Description' => 'Paste your website widget JS code in this field. You can obtain it from your Chatwoot Dashboard > Inboxes > Website > Settings.<br /> For help, visit <a href="https://www.chatwoot.com/docs/product/channels/live-chat/create-website-channel" target="_blank">Chatwoot Docs</a>',
47+
'Description' => 'Enter Chatwoot URL. Example: https://www.chatwoot.com',
48+
],
49+
'chatwoot_token' => [
50+
'FriendlyName' => 'Website Widget Token',
51+
'Type' => 'text',
52+
'Rows' => '',
53+
'Cols' => '',
54+
'Default' => '',
55+
'Description' => 'Enter your website widget Token in this field. You can obtain it from your Chatwoot Dashboard > Inboxes > Website > Settings.<br /> For help, visit <a href="https://www.chatwoot.com/hc/user-guide/articles/1677669989-how-to-install-live-chat-on-a-word_press-website" target="_blank">Chatwoot Docs</a>',
7156
],
7257
'chatwoot_verhash' => [
7358
'FriendlyName' => 'Secret Key (Required)',
7459
'Type' => 'text',
7560
'Size' => '',
7661
'Default' => '',
77-
'Description' => 'To make sure the conversations between the customers and the support agents are private and to disallow impersonation, you can setup identity validation in Chatwoot. <br />The key used to generate HMAC hash is unique for each webwidget and you can copy it from Inboxes -> Widget Settings -> Configuration -> Identity Validation -> Copy the token shown there<br />To learn more about this, visit <a href="https://www.chatwoot.com/docs/product/channels/live-chat/sdk/identity-validation" target="_blank">Chatwoot Docs</a>',
62+
'Description' => 'To make sure the conversations between the customers and the support agents are private and to disallow impersonation, you can setup identity validation in Chatwoot. <br />The key used to generate HMAC hash is unique for each webwidget and you can copy it from Inboxes -> Widget Settings -> Configuration -> Identity Validation -> Copy the token shown there<br />To learn more about this, visit <a href="https://www.chatwoot.com/hc/user-guide/articles/1677587479-how-to-enable-identity-validation-in-chatwoot" target="_blank">Chatwoot Docs</a>',
7863
],
7964
'chatwoot_position' => [
8065
'FriendlyName' => 'Chat Box Position',
@@ -88,7 +73,21 @@ function chatwoot_config()
8873
'Type' => 'radio',
8974
'Options' => 'Standard,Expanded Bubble',
9075
'Default' => 'Standard',
91-
'Description' => 'Set the chat box bubble design. Read more at <a href="https://www.chatwoot.com/docs/product/channels/live-chat/sdk/setup#widget-designs" target="_blank">Chatwoot Docs</a>.',
76+
'Description' => 'Set the chat box bubble design. Read more at <a href="https://www.chatwoot.com/hc/user-guide/articles/1677587234-how-to-send-additional-user-information-to-chatwoot-using-sdk" target="_blank">Chatwoot Docs</a>.',
77+
],
78+
'chatwoot_launcherTitle' => [
79+
'FriendlyName' => 'Bubble Launcher Title',
80+
'Type' => 'text',
81+
'Size' => '',
82+
'Default' => '',
83+
'Description' => 'Set the chat box bubble design. Read more at <a href="https://www.chatwoot.com/hc/user-guide/articles/1677587234-how-to-send-additional-user-information-to-chatwoot-using-sdk" target="_blank">Chatwoot Docs</a>.',
84+
],
85+
'chatwoot_dark' => [
86+
'FriendlyName' => 'Enable Dark Mode on Widget',
87+
'Type' => 'yesno',
88+
'Size' => '55',
89+
'Default' => 'no',
90+
'Description' => 'Check to activate dark mode on the chat box.',
9291
],
9392
'chatwoot_lang' => [
9493
'FriendlyName' => 'Dynamic Language',
@@ -124,14 +123,5 @@ function chatwoot_config()
124123

125124
function chatwoot_activate()
126125
{
127-
128-
if (!Capsule::table('mod_chatwoot')->where('setting', 'signing_hash')->first()) {
129-
try {
130-
Capsule::table('mod_chatwoot')->insert(['setting' => 'signing_hash', 'value' => md5(time())]);
131-
} catch (\Exception $e) {
132-
return ["status" => "error", "description" => "There was an error activating Chatwoot for WHMCS - Unable to create mod_chatwoot table: {$e->getMessage()}"];
133-
}
134-
}
135-
136126
return ['status' => 'success', 'description' => "Chatwoot for WHMCS has been successfully activated! Don't forget to configure the settings below!"];
137127
}

chatwoot/hooks.php

Lines changed: 58 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,20 @@
2626
function hook_chatwoot_output($vars)
2727
{
2828

29-
$isenabled = Capsule::table('tbladdonmodules')->select('value')->where('module', '=', 'chatwoot')->where('setting', '=', 'chatwoot_enable')->where('value', 'on')->count();
30-
$chatwoot_jscode = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_jscode')->value('value');
31-
$verification_hash = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_verhash')->value('value');
32-
$chatwoot_position = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_position')->value('value');
33-
$chatwoot_bubble = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_bubble')->value('value');
34-
$chatwoot_lang_setting = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_lang')->value('value');
35-
$chatwoot_admin = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_enableonadmin')->value('value');
36-
$signing_hash = Capsule::table('mod_chatwoot')->where('setting', 'signing_hash')->value('value');
29+
$isenabled = Capsule::table('tbladdonmodules')->select('value')->where('module', '=', 'chatwoot')->where('setting', '=', 'chatwoot_enable')->where('value', 'on')->count();
30+
$chatwoot_url = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_url')->value('value');
31+
$chatwoot_token = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_token')->value('value');
32+
$verification_hash = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_verhash')->value('value');
33+
$chatwoot_position = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_position')->value('value');
34+
$chatwoot_bubble = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_bubble')->value('value');
35+
$chatwoot_launcherTitle = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_launcherTitle')->value('value');
36+
$chatwoot_dark = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_dark')->value('value');
37+
$chatwoot_lang_setting = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_lang')->value('value');
3738

3839
$chatwoot_setlabel = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_setlabel')->value('value');
3940
$chatwoot_setlabelloggedin = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_setlabelloggedin')->value('value');
4041

42+
$chatwoot_admin = Capsule::table('tbladdonmodules')->where('module', 'chatwoot')->where('setting', 'chatwoot_enableonadmin')->value('value');
4143

4244
# ignore if admin
4345
if (empty($chatwoot_admin) && isset($_SESSION['adminid'])) {
@@ -56,6 +58,11 @@ function hook_chatwoot_output($vars)
5658
$chatwoot_bubble = 'expanded_bubble';
5759
}
5860

61+
# dark mode
62+
if ($chatwoot_dark == 'on') {
63+
$chatwoot_dark = 'auto';
64+
}
65+
5966
# widget lang
6067
if ($chatwoot_lang_setting) {
6168
$chatwoot_lang = cw_langCode(ucfirst($vars['language']));
@@ -65,11 +72,7 @@ function hook_chatwoot_output($vars)
6572
$currentUser = new CurrentUser;
6673
$client = $currentUser->client();
6774
$user = $currentUser->user();
68-
$ipaddress = $_SERVER['REMOTE_ADDR'];
69-
$ip = gethostbyaddr($ipaddress);
7075
$currentpage = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
71-
$user_os = getOS();
72-
$user_browser = getBrowser();
7376

7477
# Fetch labels
7578
if (!is_null($user)) {
@@ -79,7 +82,7 @@ function hook_chatwoot_output($vars)
7982
}
8083

8184
# Get client ID and set contact ID
82-
if ($user && $client && $user->isOwner( $client)) {
85+
if ($user && $client && $user->isOwner($client)) {
8386
$ClientID = $client->id;
8487
} elseif ($user) {
8588
//$ownedClients = $user->ownedClients()->all();
@@ -88,8 +91,8 @@ function hook_chatwoot_output($vars)
8891
}
8992

9093
if (!is_null($user)) {
91-
$ClientChatID = hash_hmac("sha256", $ClientID, $signing_hash);
92-
$identifier_hash = hash_hmac("sha256", $ClientChatID, $verification_hash);
94+
$clientChatID = hash_hmac("sha256", $ClientID, $verification_hash);
95+
$identifier_hash = hash_hmac("sha256", $clientChatID, $verification_hash);
9396
}
9497

9598
# build contact info
@@ -135,28 +138,49 @@ function hook_chatwoot_output($vars)
135138
}
136139
}
137140

138-
# Now let's prepare our code for the final output
141+
# prepare widget code
142+
$chatwoot_jscode = "
143+
<script>
144+
window.chatwootSettings = {'position':'$chatwoot_position','type':'$chatwoot_bubble','launcherTitle':'$chatwoot_launcherTitle','darkMode': '$chatwoot_dark'};
145+
(function(d,t) {
146+
var BASE_URL='$chatwoot_url';
147+
var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
148+
g.src=BASE_URL+'/packs/js/sdk.js';
149+
g.defer = true;
150+
g.async = true;
151+
s.parentNode.insertBefore(g,s);
152+
g.onload=function(){
153+
window.chatwootSDK.run({
154+
websiteToken: '$chatwoot_token',
155+
baseUrl: BASE_URL
156+
})
157+
}
158+
})(document,'script');
159+
</script>
160+
";
161+
162+
# Now let's set the final output
139163

140164
if (!is_null($user)) {
141165

142166
$chatwoot_output =
143167
"$chatwoot_jscode
144168
<script>
145169
window.addEventListener('chatwoot:ready', function () {
146-
window.\$chatwoot.setUser('$ClientChatID', {
170+
window.\$chatwoot.setUser('$clientChatID', {
147171
email: '$clientemail',
148172
name: '$clientname',
149173
identifier_hash: '$identifier_hash',
150174
company_name: '$clientcompany',
151175
});
152176
window.\$chatwoot.setCustomAttributes({
153-
ID: '$ClientID',
154-
Phone: '$clientphone',
155-
Language: '$clientlang',
156-
City: '$clientcity',
157-
State: '$clientstate',
177+
'ID': '$ClientID',
178+
'Phone': '$clientphone',
179+
'Language': '$clientlang',
180+
'City': '$clientcity',
181+
'State': '$clientstate',
158182
'Post Code': '$clientpostcode',
159-
Country: '$clientcountry',
183+
'Country': '$clientcountry',
160184
'Active Tickets': '$clienttickets',
161185
'Credit Balance': '$clientcredit',
162186
'Revenue': '$clientrevenue',
@@ -166,37 +190,23 @@ function hook_chatwoot_output($vars)
166190
'Account Overdue': '$clientoverduetotal',
167191
'Email Status': '$clientemailver',
168192
'Is Affiliate': '$clientaffiliate',
169-
'IP Address': '$ip',
170193
'Current Page': '$currentpage',
171-
'User Browser': '$user_browser',
172-
'User System': '$user_os',
173194
});
174-
window.\$chatwoot.deleteCustomAttribute('Test Attribute')
175-
window.\$chatwoot.setLabel('$chatwoot_setlabelloggedin')
195+
window.\$chatwoot.deleteCustomAttribute('Test Attribute');
196+
window.\$chatwoot.setLabel('$chatwoot_setlabelloggedin');
176197
window.\$chatwoot.removeLabel('$chatwoot_setlabel');
177-
window.\$chatwoot.setLocale('$chatwoot_lang')
178-
window.chatwootSettings = {
179-
position: '$chatwoot_position',
180-
type: '$chatwoot_bubble',
181-
}
198+
window.\$chatwoot.setLocale('$chatwoot_lang');
182199
});
183200
</script>";
184201
} else {
185202
$chatwoot_output = "
186203
$chatwoot_jscode
187204
<script>
188205
window.addEventListener('chatwoot:ready', function () {
189-
window.\$chatwoot.setLabel('$chatwoot_label')
190-
window.\$chatwoot.setLocale('$chatwoot_lang')
191-
window.chatwootSettings = {
192-
position: '$chatwoot_position',
193-
type: '$chatwoot_bubble',
194-
};
206+
window.\$chatwoot.setLabel('$chatwoot_label');
207+
window.\$chatwoot.setLocale('$chatwoot_lang');
195208
window.\$chatwoot.setCustomAttributes({
196-
'IP Address': '$ip',
197209
'Current Page': '$currentpage',
198-
'User Browser': '$user_browser',
199-
'User System': '$user_os',
200210
});
201211
});
202212
</script>";
@@ -242,17 +252,17 @@ function hook_chatwoot_logout_output($vars)
242252
$LogoutHook = ($whmcsver > 7) ? 'UserLogout' : 'ClientLogout';
243253

244254
function ViewClientSwitchAccount($vars) {
245-
246-
$url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
247255

248-
if (str_contains($url, '/user/accounts')) {
256+
$url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
257+
258+
if (str_contains($url, '/user/accounts') || str_contains($url, '/login')) {
249259

250260
$output .= <<<HTML
251261
<!-- Chatwoot Logout Code -->
252262
<script>
253-
document.addEventListener('readystatechange', event => {
254-
window.\$chatwoot.reset()
255-
});
263+
document.addEventListener('readystatechange', event => {
264+
window.\$chatwoot.reset()
265+
});
256266
</script>
257267
<!-- Chatwoot End Logout Code -->
258268
HTML;
@@ -271,69 +281,6 @@ function cwoot_whmcs_version() {
271281
return substr($whmcsversion, 0, 1);
272282
}
273283

274-
function getOS()
275-
{
276-
277-
$user_agent = $_SERVER['HTTP_USER_AGENT'];
278-
$os_platform = "Unknown OS Platform";
279-
$os_array = array(
280-
'/windows nt 6.3/i' => 'Windows 8.1',
281-
'/windows nt 6.2/i' => 'Windows 8',
282-
'/windows nt 6.1/i' => 'Windows 7',
283-
'/windows nt 6.0/i' => 'Windows Vista',
284-
'/windows nt 5.2/i' => 'Windows Server 2003/XP x64',
285-
'/windows nt 5.1/i' => 'Windows XP',
286-
'/windows xp/i' => 'Windows XP',
287-
'/windows nt 5.0/i' => 'Windows 2000',
288-
'/windows me/i' => 'Windows ME',
289-
'/win98/i' => 'Windows 98',
290-
'/win95/i' => 'Windows 95',
291-
'/win16/i' => 'Windows 3.11',
292-
'/macintosh|mac os x/i' => 'Mac OS X',
293-
'/mac_powerpc/i' => 'Mac OS 9',
294-
'/linux/i' => 'Linux',
295-
'/ubuntu/i' => 'Ubuntu',
296-
'/iphone/i' => 'iPhone',
297-
'/ipod/i' => 'iPod',
298-
'/ipad/i' => 'iPad',
299-
'/android/i' => 'Android',
300-
'/blackberry/i' => 'BlackBerry',
301-
'/webos/i' => 'Mobile',
302-
);
303-
304-
foreach ($os_array as $regex => $value) {
305-
if (preg_match($regex, $user_agent)) {
306-
$os_platform = $value;
307-
}
308-
}
309-
return $os_platform;
310-
}
311-
312-
function getBrowser()
313-
{
314-
315-
$user_agent = $_SERVER['HTTP_USER_AGENT'];
316-
$browser = "Unknown Browser";
317-
$browser_array = array(
318-
'/msie/i' => 'Internet Explorer',
319-
'/firefox/i' => 'Firefox',
320-
'/safari/i' => 'Safari',
321-
'/chrome/i' => 'Chrome',
322-
'/opera/i' => 'Opera',
323-
'/netscape/i' => 'Netscape',
324-
'/maxthon/i' => 'Maxthon',
325-
'/konqueror/i' => 'Konqueror',
326-
'/mobile/i' => 'Handheld Browser',
327-
);
328-
329-
foreach ($browser_array as $regex => $value) {
330-
if (preg_match($regex, $user_agent)) {
331-
$browser = $value;
332-
}
333-
}
334-
return $browser;
335-
}
336-
337284
# to deal with langs
338285
function cw_langCode($name)
339286
{

0 commit comments

Comments
 (0)