Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature usage observer. #1919

Merged
merged 17 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions inc/Tracker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
/**
* Class for telemetry.
*
* @package ThemeIsle
*/

namespace ThemeIsle\GutenbergBlocks;

/**
* Class Tracker
*/
class Tracker {

/**
* Tracking URL.
*
* @var string
*/
public static $track_url = 'http://localhost:3000/bulk-tracking'; // TODO: Change this to the real URL.

/**
* Send data to the server if the user has opted in.
*
* @param array<array> $events Data to track.
* @param array $options Options.
* @return void
*/
public static function track( $events, $options = array() ) {

if ( ! self::has_consent() && ( ! isset( $options['hasConsent'] ) || ! $options['hasConsent'] ) ) {
return;
}

try {
$payload = array();

$license = apply_filters( 'product_otter_license_key', 'free' );

if ( 'free' !== $license ) {
$license = wp_hash( $license );
}

foreach ( $events as $event ) {
$payload[] = array(
'slug' => 'otter',
'site' => get_site_url(),
'license' => $license,
'data' => $event,
);
}

$args = array(
'headers' => array(
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( $payload ),
);

wp_remote_post( self::$track_url, $args );
} finally {
return;
}
}

/**
* Check if the user has consented to tracking.
*
* @return bool
*/
public static function has_consent() {
return boolval( get_option( 'otter_blocks_logger_flag', false ) );
Soare-Robert-Daniel marked this conversation as resolved.
Show resolved Hide resolved
}
}
13 changes: 13 additions & 0 deletions inc/class-registration.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,18 @@ public function enqueue_block_editor_assets() {

global $wp_roles;

$license = apply_filters( 'product_otter_license_key', 'free' );
$license_hash = 'free' === $license ? 'free' : wp_hash( $license );

// TODO: do this from SDK.
wp_localize_script(
'otter-blocks',
'themeisleTracking',
array(
'trackHash' => $license_hash,
)
);

wp_localize_script(
'otter-blocks',
'themeisleGutenberg',
Expand All @@ -262,6 +274,7 @@ public function enqueue_block_editor_assets() {
'imageSizes' => function_exists( 'is_wpcom_vip' ) ? array( 'thumbnail', 'medium', 'medium_large', 'large' ) : get_intermediate_image_sizes(), // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_intermediate_image_sizes_get_intermediate_image_sizes
'isWPVIP' => function_exists( 'is_wpcom_vip' ),
'canTrack' => 'yes' === get_option( 'otter_blocks_logger_flag', false ) ? true : false,
'trackAPI' => Tracker::$track_url,
'userRoles' => $wp_roles->roles,
'isBlockEditor' => 'post' === $current_screen->base,
'postTypes' => get_post_types( [ 'public' => true ] ),
Expand Down
20 changes: 18 additions & 2 deletions inc/server/class-dashboard-server.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace ThemeIsle\GutenbergBlocks\Server;

use ThemeIsle\GutenbergBlocks\Tracker;

/**
* Class Dashboard_Server
*/
Expand Down Expand Up @@ -38,7 +40,7 @@ class Dashboard_Server {
*/
public function init() {
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
add_action( 'after_switch_theme', array( $this, 'regenerate_styles_on_theme_change' ) );
add_action( 'after_switch_theme', array( $this, 'regenerate_styles_on_theme_change' ), 10, 2 );
}

/**
Expand Down Expand Up @@ -77,10 +79,24 @@ public function rest_regenerate_styles( \WP_REST_Request $request ) {

/**
* Regenerate styles on theme change.
*
* @param string $new_name New theme name.
* @param string $new_theme New theme object.
*
* @since 2.3
*/
public function regenerate_styles_on_theme_change() {
public function regenerate_styles_on_theme_change( $new_name, $new_theme ) {

Tracker::track(
array(
array(
'feature' => 'system',
'featureComponent' => 'theme-change',
'featureValue' => $new_name,
),
)
);

self::regenerate_styles();
}

Expand Down
32 changes: 32 additions & 0 deletions otter-blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,35 @@ function( $links ) {
return $links;
}
);

add_filter( 'themeisle_sdk_enable_telemetry', '__return_true' );

add_filter(
'themeisle_sdk_telemetry_products',
function( $products ) {
$already_registered = false;

// Since Otter can use Neve license, the SDK might not detected it so we need to update it manually.
$license = apply_filters( 'product_otter_license_key', 'free' );
$track_hash = 'free' === $license ? 'free' : wp_hash( $license );

foreach ( $products as &$product ) {
if ( strstr( $product['slug'], 'otter' ) !== false ) {
$already_registered = true;
$product['trackHash'] = $track_hash;
}
}

if ( $already_registered ) {
return $products;
}

// Add Otter Blocks to the list of products to track the usage of AI Block.
$products[] = array(
'slug' => 'otter',
'consent' => false,
'trackHash' => $track_hash,
);
return $products;
}
);
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.5.1",
"@types/object-hash": "^3.0.4",
"@types/wordpress__block-editor": "^11.5.1",
"@types/wordpress__components": "^23.0.1",
"@typescript-eslint/parser": "^6.3.0",
Expand Down
2 changes: 2 additions & 0 deletions plugins/otter-pro/inc/plugins/class-stripe-pro-features.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace ThemeIsle\OtterPro\Plugins;

use ThemeIsle\GutenbergBlocks\Tracker;

/**
* Class Stripe_Pro_Features
*/
Expand Down
1 change: 1 addition & 0 deletions src/blocks/blocks/form/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,7 @@ const Edit = ({
variations={ variations }
onSelect={ ( nextVariation = defaultVariation ) => {
if ( nextVariation ) {
window.oTrk?.add({ feature: 'form', featureComponent: 'variant', featureValue: nextVariation.name });
replaceInnerBlocks(
clientId,
createBlocksFromInnerBlocksTemplate(
Expand Down
15 changes: 12 additions & 3 deletions src/blocks/blocks/form/inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,8 @@ const Inspector = ({
/>,
formOptions,
setFormOption,
useContext( FormContext )
useContext( FormContext ),
attributes
) }
</Fragment>
)
Expand Down Expand Up @@ -518,6 +519,7 @@ const Inspector = ({
{ label: __( 'Sendinblue', 'otter-blocks' ), value: 'sendinblue' }
] }
onChange={ provider => {
window.oTrk?.add({ feature: 'marketing', featureComponent: 'provider', featureValue: provider, groupID: attributes.id });
setFormOption({ provider, listId: '', apiKey: '' });
} }
/>
Expand Down Expand Up @@ -553,6 +555,7 @@ const Inspector = ({
help={ __( 'You can find the key in the provider\'s website', 'otter-blocks' ) }
value={ formOptions.apiKey ? `*************************${formOptions.apiKey.slice( -8 )}` : '' }
onChange={ apiKey => {
window.oTrk?.add({ feature: 'marketing', featureComponent: 'api-key', groupID: attributes.id });
setListIDOptions([]);
setFormOption({
listId: '',
Expand Down Expand Up @@ -593,7 +596,10 @@ const Inspector = ({
label={ __( 'Contact List', 'otter-blocks' ) }
value={ formOptions.listId }
options={ listIDOptions }
onChange={ listId => setFormOption({ listId }) }
onChange={ listId => {
window.oTrk?.set( `${attributes.id}_list`, { feature: 'marketing', featureComponent: 'contact-list', groupID: attributes.id });
setFormOption({ listId });
} }
/>

{ 1 >= listIDOptions?.length && <p> { __( 'No Contact list found. Please create a list in your provider interface or check if the API key is correct.', 'otter-blocks' ) } </p> }
Expand All @@ -608,7 +614,10 @@ const Inspector = ({
{ label: __( 'Subscribe', 'otter-blocks' ), value: 'subscribe' },
{ label: __( 'Submit & Subscribe', 'otter-blocks' ), value: 'submit-subscribe' }
] }
onChange={ action => setFormOption({ action }) }
onChange={ action => {
window.oTrk?.set( `${attributes.id}_action`, { feature: 'marketing', featureComponent: 'action', featureValue: action, groupID: attributes.id });
setFormOption({ action });
} }
/>

{ 'submit-subscribe' === formOptions.action && (
Expand Down
15 changes: 12 additions & 3 deletions src/blocks/blocks/stripe-checkout/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,10 @@ const Edit = ({
<Button
isPrimary
type="submit"
onClick={ saveApiKey }
onClick={() => {
window.oTrk?.add({ feature: 'stripe', featureComponent: 'api-key' });
saveApiKey();
} }
>
{ __( 'Save', 'otter-blocks' ) }
</Button>
Expand Down Expand Up @@ -266,7 +269,10 @@ const Edit = ({
},
...productsList
] }
onChange={ ( product: string ) => setAttributes({ product: 'none' !== product ? product : undefined }) }
onChange={ ( product: string ) =>{
window.oTrk?.add({ feature: 'stripe-checkout', featureComponent: 'product-changed' });
setAttributes({ product: 'none' !== product ? product : undefined });
} }
/>
) }

Expand All @@ -281,7 +287,10 @@ const Edit = ({
},
...pricesList
] }
onChange={ ( price: string ) => setAttributes({ price: 'none' !== price ? price : undefined }) }
onChange={ ( price: string ) => {
window.oTrk?.add({ feature: 'stripe-checkout', featureComponent: 'price-changed' });
setAttributes({ price: 'none' !== price ? price : undefined });
} }
/>
) }

Expand Down
6 changes: 5 additions & 1 deletion src/blocks/blocks/stripe-checkout/inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const Inspector = ({
...productsList
] }
onChange={ product => {
window.oTrk?.add({ feature: 'stripe-checkout', featureComponent: 'product-changed' });
setAttributes({
product: 'none' !== product ? product : undefined,
price: undefined
Expand All @@ -130,7 +131,10 @@ const Inspector = ({
},
...pricesList
] }
onChange={ price => setAttributes({ price: 'none' !== price ? price : undefined }) }
onChange={ price => {
window.oTrk?.add({ feature: 'stripe-checkout', featureComponent: 'price-changed' });
setAttributes({ price: 'none' !== price ? price : undefined });
} }
/>
) }

Expand Down
2 changes: 2 additions & 0 deletions src/blocks/components/prompt/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ const PromptPlaceholder = ( props: PromptPlaceholderProps ) => {

const sendPrompt = regenerate ? sendPromptToOpenAIWithRegenerate : sendPromptToOpenAI;

window.oTrk?.add({ feature: 'ai-generation', featureComponent: 'prompt', featureValue: value }, { consent: true });

sendPrompt?.( value, embeddedPrompt, {
'otter_used_action': 'textTransformation' === promptID ? 'textTransformation::otter_action_prompt' : ( promptID ?? '' ),
'otter_user_content': value
Expand Down
7 changes: 6 additions & 1 deletion src/blocks/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type OtterEventTracking from './helpers/tracking';

declare global {
interface Window {
themeisleGutenberg?: {
Expand All @@ -18,6 +20,8 @@ declare global {
imageSizes: string[]
isWPVIP: boolean
canTrack: boolean
trackHash: string
trackAPI: string
userRoles: {
[key: string]: {
name: string
Expand Down Expand Up @@ -102,7 +106,8 @@ declare global {
},
oSavedStates?: {
[key: string]: any
}
},
oTrk?: OtterEventTracking
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/blocks/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import * as icons from './icons.js';

import useSettings from './use-settings.js';

import './tracking.js';

window.otterUtils = {};

window.otterUtils.blockInit = blockInit;
Expand Down
1 change: 1 addition & 0 deletions src/blocks/helpers/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ function promptRequestBuilder( settings?: OpenAiSettings ) {

// TODO: remove the apiKey from the function definition.
return async( prompt: string, embeddedPrompt: PromptData, metadata: Record<string, string> ) => {

const body = {
...embeddedPrompt,
messages: embeddedPrompt.messages.map( ( message ) => {
Expand Down
1 change: 1 addition & 0 deletions src/blocks/helpers/tracking.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window.oTrk = window?.tiTrk?.with( 'otter' );
3 changes: 3 additions & 0 deletions src/blocks/plugins/ai-content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ const withConditions = createHigherOrderComponent( BlockEdit => {
}

setIsProcessing( prevState => ({ ...prevState, [ actionKey ]: true }) );

window.oTrk?.add({ feature: 'ai-generation', featureComponent: 'ai-toolbar', featureValue: actionKey }, { consent: true });

sendPromptToOpenAI(
content,
injectActionIntoPrompt(
Expand Down
Loading