Skip to content

Commit

Permalink
Support chat using Zendesk Messaging - attempt 2 (#77024)
Browse files Browse the repository at this point in the history
Reverts #77016

Second attempt at #76777

We're switching from Happy Chat to Zendesk Messaging for live chat support. This PR is big, but it's also the smallest I could get given the scope of the project. Any cleanup of Happy Chat code, old contact forms, etc. will be done as a follow-up. I want to keep this PR as easy to revert as possible if needed.
  • Loading branch information
klimeryk committed May 18, 2023
1 parent 5246d91 commit 5d9ee37
Show file tree
Hide file tree
Showing 42 changed files with 679 additions and 344 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,12 @@ public function register_rest_api() {
$controller = new WP_REST_Help_Center_Forum();
$controller->register_rest_route();

require_once __DIR__ . '/class-wp-rest-help-center-support-history.php';
$controller = new WP_REST_Help_Center_Support_History();
require_once __DIR__ . '/class-wp-rest-help-center-support-activity.php';
$controller = new WP_REST_Help_Center_Support_Activity();
$controller->register_rest_route();

require_once __DIR__ . '/class-wp-rest-help-center-user-fields.php';
$controller = new WP_REST_Help_Center_User_Fields();
$controller->register_rest_route();
}
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,37 @@ public function register_rest_route() {
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'get_chat_authentication' ),
'permission_callback' => array( $this, 'permission_callback' ),
'args' => array(
'type' => array(
'type' => 'string',
'default' => 'happychat',
'required' => false,
),
'test_mode' => array(
'type' => 'boolean',
'default' => false,
'required' => false,
),
),
)
);
}

/**
* Callback to authorize user for chat.
*
* @param \WP_REST_Request $request The request sent to the API.
*
* @return WP_REST_Response
*/
public function get_chat_authentication() {
public function get_chat_authentication( \WP_REST_Request $request ) {
$query_parameters = array(
'test_mode' => $request['test_mode'],
'type' => $request['type'],
);

$body = Client::wpcom_json_api_request_as_user(
'help/authenticate/chat',
'help/authenticate/chat?' . http_build_query( $query_parameters ),
'2',
array(
'method' => 'POST',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* WP_REST_Help_Center_Support_Activity file.
*
* @package A8C\FSE
*/

namespace A8C\FSE;

use Automattic\Jetpack\Connection\Client;

/**
* Class WP_REST_Help_Center_Support_Activity.
*/
class WP_REST_Help_Center_Support_Activity extends \WP_REST_Controller {
/**
* WP_REST_Help_Center_Support_Activity constructor.
*/
public function __construct() {
$this->namespace = 'help-center';
$this->rest_base = '/support-activity';
}

/**
* Register available routes.
*/
public function register_rest_route() {
register_rest_route(
$this->namespace,
$this->rest_base,
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_support_activity' ),
'permission_callback' => 'is_user_logged_in',
)
);
}

/**
* Get support activity through Jetpack.
*/
public function get_support_activity() {
$body = Client::wpcom_json_api_request_as_user( '/support-activity' );

if ( is_wp_error( $body ) ) {
return $body;
}

$response = json_decode( wp_remote_retrieve_body( $body ) );

return rest_ensure_response( $response );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,26 @@ public function register_rest_route() {
'permission_callback' => array( $this, 'permission_callback' ),
)
);

register_rest_route(
$this->namespace,
$this->rest_base . '/messaging',
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_messaging_support_eligibility' ),
'permission_callback' => array( $this, 'permission_callback' ),
'args' => array(
'group' => array(
'type' => 'string',
'required' => true,
),
'environment' => array(
'type' => 'string',
'required' => true,
),
),
)
);
}

/**
Expand Down Expand Up @@ -88,6 +108,27 @@ public function get_all_support_eligibility() {
return rest_ensure_response( $response );
}

/**
* Should return messaging eligibility
*
* @param \WP_REST_Request $request The request sent to the API.
*
* @return WP_REST_Response
*/
public function get_messaging_support_eligibility( \WP_REST_Request $request ) {
$query_parameters = array(
'group' => $request['group'],
'environment' => $request['environment'],
);
$body = Client::wpcom_json_api_request_as_user( 'help/messaging/is-available?' . http_build_query( $query_parameters ) );
if ( is_wp_error( $body ) ) {
return $body;
}
$response = json_decode( wp_remote_retrieve_body( $body ) );

return rest_ensure_response( $response );
}

/**
* Callback to determine whether the request can proceed.
*
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
/**
* WP_REST_Help_Center_User_Fields file.
*
* @package A8C\FSE
*/

namespace A8C\FSE;

use Automattic\Jetpack\Connection\Client;

/**
* Class WP_REST_Help_Center_User_Fields.
*/
class WP_REST_Help_Center_User_Fields extends \WP_REST_Controller {
/**
* WP_REST_Help_Center_User_Fields constructor.
*/
public function __construct() {
$this->namespace = 'help-center';
$this->rest_base = '/zendesk/user-fields';
}

/**
* Register available routes.
*/
public function register_rest_route() {
register_rest_route(
$this->namespace,
$this->rest_base,
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array( $this, 'update_user_fields' ),
'permission_callback' => array( $this, 'permission_callback' ),
'args' => array(
'fields' => array(
'type' => 'object',
'required' => true,
),
),
)
);
}

/**
* Callback to update user fields in Zendesk
*
* @param \WP_REST_Request $request The request sent to the API.
*
* @return WP_REST_Response
*/
public function update_user_fields( \WP_REST_Request $request ) {
$body = Client::wpcom_json_api_request_as_user(
'help/zendesk/update-user-fields',
'2',
array(
'method' => 'POST',
),
$request['fields']
);

if ( is_wp_error( $body ) ) {
return $body;
}
$response = json_decode( wp_remote_retrieve_body( $body ) );
return rest_ensure_response( $response );
}

/**
* Callback to determine whether the user has permission to access.
*/
public function permission_callback() {
return is_user_logged_in();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
window.configData = {
env_id: 'development',
env_id: 'production',
i18n_default_locale_slug: 'en',
google_analytics_key: 'UA-10673494-15',
zendesk_support_chat_key: 'cec07bc9-4da6-4dd2-afa7-c7e01ae73584',
client_slug: 'browser',
twemoji_cdn_url: 'https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/',
site_filter: [],
Expand Down Expand Up @@ -39,7 +40,7 @@ window.configData = {
is_running_in_jetpack_site: false,
gutenboarding_url: '/new',
features: {
happychat: true,
happychat: false,
},
signup_url: '/',
discover_blog_id: 53424024,
Expand Down
2 changes: 1 addition & 1 deletion apps/happychat/src/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
gutenboarding_url: '/new',
hostname: 'widgets.wp.com',
features: {
happychat: true,
happychat: false,
},
};
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function get_config_chat_key( keyType: KeyType ): keyof ConfigData {

export const ZendeskJetpackChat: React.VFC< { keyType: KeyType } > = ( { keyType } ) => {
const [ error, setError ] = useState( false );
const { data: isStaffed } = useJpPresalesAvailabilityQuery( setError );
const { data: isStaffed } = useJpPresalesAvailabilityQuery( true, setError );
const zendeskChatKey: string | false = useMemo( () => {
return config( get_config_chat_key( keyType ) );
}, [ keyType ] );
Expand Down
8 changes: 7 additions & 1 deletion client/components/presales-zendesk-chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ interface Props {
chatKey: string | false;
}

const ZENDESK_SCRIPT_ID = 'ze-snippet';

const ZendeskChat = ( { chatKey }: Props ) => {
useEffect( () => {
if ( ! chatKey ) {
return;
}

if ( document.getElementById( ZENDESK_SCRIPT_ID ) ) {
return;
}

loadScript(
'https://static.zdassets.com/ekr/snippet.js?key=' + encodeURIComponent( chatKey ),
undefined,
{ id: 'ze-snippet' }
{ id: ZENDESK_SCRIPT_ID }
);
}, [ chatKey ] );

Expand Down
6 changes: 5 additions & 1 deletion client/lib/jetpack/use-jp-presales-availability-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ async function fetchWithRetry(
}
}

export function useJpPresalesAvailabilityQuery( setError?: Dispatch< SetStateAction< boolean > > ) {
export function useJpPresalesAvailabilityQuery(
enabled = true,
setError?: Dispatch< SetStateAction< boolean > >
) {
//adding a safeguard to ensure if there's an unkown error with the widget it won't crash the whole app
try {
return useQuery< boolean, Error >(
Expand All @@ -58,6 +61,7 @@ export function useJpPresalesAvailabilityQuery( setError?: Dispatch< SetStateAct
return data.is_available;
},
{
enabled,
meta: { persist: false },
}
);
Expand Down
Loading

0 comments on commit 5d9ee37

Please sign in to comment.