Skip to content

The WordPress example is a plugin. It adds the REST route POST /wp-json/nexafon/v1/user-token, which signs a user token for the logged-in WordPress user with the PHP helper (nexafon/nexafon-php) and accepts only users with the nexafon_use capability sending the REST nonce, and the shortcode [nexafon_inbox], which loads the web SDK and places the inbox and softphone on any page.

examples/wordpress/nexafon-example/nexafon-example.php
<?php
/**
* Plugin Name: Nexafon example
* Description: Nexafon's inbox and softphone on any page with the [nexafon_inbox] shortcode, signed in as the WordPress user.
* Version: 0.1.0
* Requires PHP: 8.1
*/
declare(strict_types=1);
use Nexafon\Tokens;
if (!defined('ABSPATH')) {
exit;
}
require_once __DIR__ . '/vendor/autoload.php';
// Settings come from wp-config.php constants or the server's environment, so the secret key never sits in the
// database next to other plugins' options.
function nexafon_example_setting(string $name, string $default = ''): string
{
if (defined($name)) {
return (string) constant($name);
}
$value = getenv($name);
return $value === false || $value === '' ? $default : $value;
}
// Only the site's staff act as Nexafon members: customers and subscribers are signed-in users too.
const NEXAFON_EXAMPLE_CAPABILITY = 'nexafon_use';
register_activation_hook(__FILE__, function (): void {
get_role('administrator')?->add_cap(NEXAFON_EXAMPLE_CAPABILITY);
});
function nexafon_example_can_use(): bool
{
return current_user_can(NEXAFON_EXAMPLE_CAPABILITY);
}
add_action('rest_api_init', function (): void {
register_rest_route('nexafon/v1', '/user-token', [
'methods' => 'POST',
'permission_callback' => 'nexafon_example_can_use',
'callback' => function (): WP_REST_Response {
$user = wp_get_current_user();
// Nexafon links a new user to the member with this email. WordPress confirms a changed email, but other
// plugins (WooCommerce's account page, checkout) and admins set it unconfirmed, so the site has to say so.
$token = Tokens::createUserToken([
'userId' => 'wp-' . $user->ID,
'name' => $user->display_name,
'role' => nexafon_example_setting('NEXAFON_USER_ROLE', 'agent'),
'email' => $user->user_email,
'emailVerified' => filter_var(nexafon_example_setting('NEXAFON_EMAILS_VERIFIED'), FILTER_VALIDATE_BOOLEAN),
], ['secretKey' => nexafon_example_setting('NEXAFON_SECRET_KEY')]);
$response = new WP_REST_Response(['token' => $token]);
$response->header('Cache-Control', 'no-store');
return $response;
},
]);
});
add_shortcode('nexafon_inbox', function (): string {
if (!nexafon_example_can_use()) {
return '';
}
$cdn = rtrim(nexafon_example_setting('NEXAFON_EMBED_CDN_URL'), '/');
wp_enqueue_script('nexafon', $cdn . '/v1/nexafon.js', [], null, ['in_footer' => true]);
$config = [
'publishableKey' => nexafon_example_setting('NEXAFON_PUBLISHABLE_KEY'),
'tokenUrl' => rest_url('nexafon/v1/user-token'),
'nonce' => wp_create_nonce('wp_rest'),
];
wp_add_inline_script('nexafon', sprintf(
'(function (c) { Nexafon.init({ publishableKey: c.publishableKey, getUserToken: function () { return fetch(c.tokenUrl, { method: "POST", headers: { "X-WP-Nonce": c.nonce } }).then(function (r) { if (!r.ok) { throw new Error("The token endpoint answered " + r.status) } return r.json() }).then(function (b) { return b.token }) } }) })(%s);',
wp_json_encode($config)
));
return '<div class="nexafon-example" style="display:grid;gap:16px;grid-template-columns:1fr 340px">'
. '<nexafon-inbox style="height:640px"></nexafon-inbox><nexafon-softphone></nexafon-softphone></div>';
});

Keep the secret key out of the database and the theme: define NEXAFON_PUBLISHABLE_KEY, NEXAFON_SECRET_KEY, NEXAFON_EMBED_CDN_URL and NEXAFON_USER_ROLE in wp-config.php or the server’s environment. Add the site’s origin to the workspace’s embed domains and the publishable key’s allowed origins.

A signed-in WordPress user is not necessarily one of your staff: subscribers and shop customers sign in too. Two rules keep them out of your workspace:

  • Gate the token route on a capability, not on being signed in. The plugin checks nexafon_use, which activating it gives to administrators. Give it to your staff’s roles (wp cap add editor nexafon_use), never to subscribers or customers.
  • Send emailVerified: true only when the site has confirmed the address. Nexafon matches a user to a member by email the first time they sign in, so whoever can set an account’s email to a member’s address can act as that member. WordPress confirms an email change made on the profile page, but an admin or a plugin such as WooCommerce (account details, checkout) changes it without asking. The plugin sends true only when NEXAFON_EMAILS_VERIFIED is set; without it, Nexafon refuses a user’s first sign-in.

To install it on your own site, copy nexafon-example/ to wp-content/plugins/ and run composer require nexafon/nexafon-php in it. The full plugin is examples/wordpress.