Add Google Analytics and Search Console integration
- Implemented Groq_AI_Google_Analytics_Data_Client for fetching GA4 data. - Created Groq_AI_Google_Search_Console_Client for retrieving Search Console data. - Added Google OAuth client for authentication with Google APIs. - Enhanced Groq_AI_Settings_Manager to include Google OAuth settings. - Introduced term context building methods in Groq_AI_Google_Context_Builder. - Developed JavaScript functionality for term generation in the admin interface. - Added methods for generating term prompts and handling responses. - Improved error handling and response parsing for Google API interactions.
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
class Groq_AI_Google_Analytics_Data_Client {
|
||||
/** @var Groq_AI_Google_OAuth_Client */
|
||||
private $oauth;
|
||||
|
||||
public function __construct( Groq_AI_Google_OAuth_Client $oauth ) {
|
||||
$this->oauth = $oauth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple connectivity check for GA4 Data API.
|
||||
*
|
||||
* @param array $settings
|
||||
* @param string $property_id
|
||||
* @param string $start_date
|
||||
* @param string $end_date
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_property_sessions_summary( $settings, $property_id, $start_date, $end_date ) {
|
||||
$property_id = trim( (string) $property_id );
|
||||
if ( '' === $property_id ) {
|
||||
return new WP_Error( 'groq_ai_ga_missing', __( 'GA4 property ID ontbreekt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$token = $this->oauth->get_access_token( $settings );
|
||||
if ( is_wp_error( $token ) ) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
$endpoint = 'https://analyticsdata.googleapis.com/v1beta/properties/' . rawurlencode( $property_id ) . ':runReport';
|
||||
$body = [
|
||||
'dateRanges' => [
|
||||
[
|
||||
'startDate' => $start_date,
|
||||
'endDate' => $end_date,
|
||||
],
|
||||
],
|
||||
'metrics' => [
|
||||
[ 'name' => 'sessions' ],
|
||||
[ 'name' => 'engagedSessions' ],
|
||||
],
|
||||
'limit' => 1,
|
||||
];
|
||||
|
||||
$response = wp_remote_post(
|
||||
$endpoint,
|
||||
[
|
||||
'timeout' => 20,
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => wp_json_encode( $body ),
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$status_code = wp_remote_retrieve_response_code( $response );
|
||||
$raw_body = wp_remote_retrieve_body( $response );
|
||||
$data = json_decode( (string) $raw_body, true );
|
||||
|
||||
if ( 200 !== $status_code || ! is_array( $data ) ) {
|
||||
return new WP_Error( 'groq_ai_ga_error', __( 'GA4 Data API call mislukt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$rows = isset( $data['rows'] ) && is_array( $data['rows'] ) ? $data['rows'] : [];
|
||||
$sessions = 0;
|
||||
$engaged = 0;
|
||||
foreach ( $rows as $row ) {
|
||||
$metric_values = isset( $row['metricValues'] ) && is_array( $row['metricValues'] ) ? $row['metricValues'] : [];
|
||||
if ( isset( $metric_values[0]['value'] ) ) {
|
||||
$sessions += absint( $metric_values[0]['value'] );
|
||||
}
|
||||
if ( isset( $metric_values[1]['value'] ) ) {
|
||||
$engaged += absint( $metric_values[1]['value'] );
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'sessions' => $sessions,
|
||||
'engagedSessions' => $engaged,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns approximate GA4 sessions for a landing page path.
|
||||
*
|
||||
* @param array $settings
|
||||
* @param string $property_id
|
||||
* @param string $page_path e.g. /product-category/foo/
|
||||
* @param string $start_date YYYY-MM-DD
|
||||
* @param string $end_date YYYY-MM-DD
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_sessions_for_landing_page_path( $settings, $property_id, $page_path, $start_date, $end_date ) {
|
||||
$property_id = trim( (string) $property_id );
|
||||
$page_path = trim( (string) $page_path );
|
||||
|
||||
if ( '' === $property_id || '' === $page_path ) {
|
||||
return new WP_Error( 'groq_ai_ga_missing', __( 'GA4 property ID of page path ontbreekt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$token = $this->oauth->get_access_token( $settings );
|
||||
if ( is_wp_error( $token ) ) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
$endpoint = 'https://analyticsdata.googleapis.com/v1beta/properties/' . rawurlencode( $property_id ) . ':runReport';
|
||||
|
||||
$body = [
|
||||
'dateRanges' => [
|
||||
[
|
||||
'startDate' => $start_date,
|
||||
'endDate' => $end_date,
|
||||
],
|
||||
],
|
||||
'dimensions' => [
|
||||
[ 'name' => 'landingPagePlusQueryString' ],
|
||||
],
|
||||
'metrics' => [
|
||||
[ 'name' => 'sessions' ],
|
||||
[ 'name' => 'engagedSessions' ],
|
||||
],
|
||||
'dimensionFilter' => [
|
||||
'filter' => [
|
||||
'fieldName' => 'landingPagePlusQueryString',
|
||||
'stringFilter' => [
|
||||
'matchType' => 'CONTAINS',
|
||||
'value' => $page_path,
|
||||
],
|
||||
],
|
||||
],
|
||||
'limit' => 5,
|
||||
];
|
||||
|
||||
$response = wp_remote_post(
|
||||
$endpoint,
|
||||
[
|
||||
'timeout' => 20,
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => wp_json_encode( $body ),
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$status_code = wp_remote_retrieve_response_code( $response );
|
||||
$raw_body = wp_remote_retrieve_body( $response );
|
||||
$data = json_decode( (string) $raw_body, true );
|
||||
|
||||
if ( 200 !== $status_code || ! is_array( $data ) ) {
|
||||
return new WP_Error( 'groq_ai_ga_error', __( 'GA4 Data API call mislukt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$rows = isset( $data['rows'] ) && is_array( $data['rows'] ) ? $data['rows'] : [];
|
||||
$sessions = 0;
|
||||
$engaged = 0;
|
||||
foreach ( $rows as $row ) {
|
||||
$metric_values = isset( $row['metricValues'] ) && is_array( $row['metricValues'] ) ? $row['metricValues'] : [];
|
||||
if ( isset( $metric_values[0]['value'] ) ) {
|
||||
$sessions += absint( $metric_values[0]['value'] );
|
||||
}
|
||||
if ( isset( $metric_values[1]['value'] ) ) {
|
||||
$engaged += absint( $metric_values[1]['value'] );
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'sessions' => $sessions,
|
||||
'engagedSessions' => $engaged,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
class Groq_AI_Google_Context_Builder {
|
||||
/** @var Groq_AI_Google_Search_Console_Client */
|
||||
private $gsc;
|
||||
|
||||
/** @var Groq_AI_Google_Analytics_Data_Client */
|
||||
private $ga;
|
||||
|
||||
public function __construct( Groq_AI_Google_Search_Console_Client $gsc, Groq_AI_Google_Analytics_Data_Client $ga ) {
|
||||
$this->gsc = $gsc;
|
||||
$this->ga = $ga;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $existing
|
||||
* @param WP_Term $term
|
||||
* @param array $settings
|
||||
* @return string
|
||||
*/
|
||||
public function build_term_google_context( $existing, $term, $settings ) {
|
||||
if ( ! $term || ! is_object( $term ) ) {
|
||||
return (string) $existing;
|
||||
}
|
||||
|
||||
$enabled_gsc = ! empty( $settings['google_enable_gsc'] );
|
||||
$enabled_ga = ! empty( $settings['google_enable_ga'] );
|
||||
|
||||
if ( ! $enabled_gsc && ! $enabled_ga ) {
|
||||
return (string) $existing;
|
||||
}
|
||||
|
||||
$term_id = isset( $term->term_id ) ? absint( $term->term_id ) : 0;
|
||||
$taxonomy = isset( $term->taxonomy ) ? sanitize_key( (string) $term->taxonomy ) : '';
|
||||
|
||||
$range_days = 28;
|
||||
$end_date = gmdate( 'Y-m-d' );
|
||||
$start_date = gmdate( 'Y-m-d', time() - ( $range_days * DAY_IN_SECONDS ) );
|
||||
|
||||
$term_link = get_term_link( $term );
|
||||
if ( is_wp_error( $term_link ) ) {
|
||||
$term_link = '';
|
||||
}
|
||||
|
||||
$page_path = '';
|
||||
if ( is_string( $term_link ) && '' !== $term_link ) {
|
||||
$parts = wp_parse_url( $term_link );
|
||||
if ( is_array( $parts ) && isset( $parts['path'] ) ) {
|
||||
$page_path = (string) $parts['path'];
|
||||
}
|
||||
}
|
||||
|
||||
$cache_key = 'groq_ai_google_term_ctx_' . md5( $taxonomy . '|' . $term_id . '|' . $start_date . '|' . $end_date );
|
||||
$cached = get_transient( $cache_key );
|
||||
if ( is_string( $cached ) && '' !== $cached ) {
|
||||
return trim( (string) $existing . "\n\n" . $cached );
|
||||
}
|
||||
|
||||
$lines = [];
|
||||
$lines[] = sprintf(
|
||||
/* translators: %d: days */
|
||||
__( 'Google data (laatste %d dagen):', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
|
||||
$range_days
|
||||
);
|
||||
|
||||
if ( $enabled_gsc ) {
|
||||
$site_url = isset( $settings['google_gsc_site_url'] ) ? trim( (string) $settings['google_gsc_site_url'] ) : '';
|
||||
if ( '' !== $site_url && '' !== $term_link ) {
|
||||
$queries = $this->gsc->get_top_queries_for_page( $settings, $site_url, $term_link, $start_date, $end_date, 10 );
|
||||
if ( is_wp_error( $queries ) ) {
|
||||
$lines[] = __( 'Search Console: kon queries niet ophalen.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
|
||||
} elseif ( empty( $queries ) ) {
|
||||
$lines[] = __( 'Search Console: geen query data gevonden voor deze pagina.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
|
||||
} else {
|
||||
$lines[] = __( 'Search Console top zoekopdrachten (query → clicks/impr):', GROQ_AI_PRODUCT_TEXT_DOMAIN );
|
||||
foreach ( $queries as $row ) {
|
||||
$q = isset( $row['query'] ) ? (string) $row['query'] : '';
|
||||
$c = isset( $row['clicks'] ) ? (float) $row['clicks'] : 0.0;
|
||||
$i = isset( $row['impressions'] ) ? (float) $row['impressions'] : 0.0;
|
||||
if ( '' === $q ) {
|
||||
continue;
|
||||
}
|
||||
$lines[] = sprintf( '- %s → %d/%d', $q, (int) round( $c ), (int) round( $i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $enabled_ga ) {
|
||||
$property_id = isset( $settings['google_ga4_property_id'] ) ? trim( (string) $settings['google_ga4_property_id'] ) : '';
|
||||
if ( '' !== $property_id && '' !== $page_path ) {
|
||||
$stats = $this->ga->get_sessions_for_landing_page_path( $settings, $property_id, $page_path, $start_date, $end_date );
|
||||
if ( is_wp_error( $stats ) ) {
|
||||
$lines[] = __( 'Analytics: kon sessies niet ophalen.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
|
||||
} else {
|
||||
$sessions = isset( $stats['sessions'] ) ? absint( $stats['sessions'] ) : 0;
|
||||
$engaged = isset( $stats['engagedSessions'] ) ? absint( $stats['engagedSessions'] ) : 0;
|
||||
$lines[] = sprintf( __( 'Analytics (GA4): sessies ~%1$d, engaged sessies ~%2$d', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $sessions, $engaged );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we only have the header, skip.
|
||||
if ( count( $lines ) <= 1 ) {
|
||||
return (string) $existing;
|
||||
}
|
||||
|
||||
$context = implode( "\n", $lines );
|
||||
set_transient( $cache_key, $context, 15 * MINUTE_IN_SECONDS );
|
||||
|
||||
return trim( (string) $existing . "\n\n" . $context );
|
||||
}
|
||||
}
|
||||
101
includes/Services/Google/class-groq-ai-google-oauth-client.php
Normal file
101
includes/Services/Google/class-groq-ai-google-oauth-client.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
class Groq_AI_Google_OAuth_Client {
|
||||
/**
|
||||
* @param array $settings
|
||||
* @return string|WP_Error
|
||||
*/
|
||||
public function get_access_token( $settings ) {
|
||||
$client_id = isset( $settings['google_oauth_client_id'] ) ? trim( (string) $settings['google_oauth_client_id'] ) : '';
|
||||
$client_secret = isset( $settings['google_oauth_client_secret'] ) ? trim( (string) $settings['google_oauth_client_secret'] ) : '';
|
||||
$refresh_token = isset( $settings['google_oauth_refresh_token'] ) ? trim( (string) $settings['google_oauth_refresh_token'] ) : '';
|
||||
|
||||
if ( '' === $client_id || '' === $client_secret || '' === $refresh_token ) {
|
||||
return new WP_Error( 'groq_ai_google_oauth_missing', __( 'Google OAuth is niet (volledig) geconfigureerd.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$cache_key = 'groq_ai_google_access_token_' . md5( $client_id . '|' . $refresh_token );
|
||||
$cached = get_transient( $cache_key );
|
||||
if ( is_string( $cached ) && '' !== $cached ) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
$response = wp_remote_post(
|
||||
'https://oauth2.googleapis.com/token',
|
||||
[
|
||||
'timeout' => 20,
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
],
|
||||
'body' => [
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => $client_secret,
|
||||
'refresh_token' => $refresh_token,
|
||||
'grant_type' => 'refresh_token',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$status_code = wp_remote_retrieve_response_code( $response );
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
$data = json_decode( (string) $body, true );
|
||||
|
||||
if ( 200 !== $status_code || ! is_array( $data ) ) {
|
||||
return new WP_Error( 'groq_ai_google_oauth_refresh_failed', __( 'Google token refresh mislukt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$access_token = isset( $data['access_token'] ) ? sanitize_text_field( (string) $data['access_token'] ) : '';
|
||||
$expires_in = isset( $data['expires_in'] ) ? absint( $data['expires_in'] ) : 0;
|
||||
|
||||
if ( '' === $access_token ) {
|
||||
return new WP_Error( 'groq_ai_google_oauth_refresh_failed', __( 'Geen access token ontvangen van Google.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$ttl = max( 60, $expires_in - 60 );
|
||||
set_transient( $cache_key, $access_token, $ttl );
|
||||
|
||||
return $access_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diagnostics helper: returns scopes for a given access token.
|
||||
*
|
||||
* @param string $access_token
|
||||
* @return array|WP_Error { 'scope' => string, 'expires_in' => int }
|
||||
*/
|
||||
public function get_access_token_info( $access_token ) {
|
||||
$access_token = trim( (string) $access_token );
|
||||
if ( '' === $access_token ) {
|
||||
return new WP_Error( 'groq_ai_google_tokeninfo_missing', __( 'Geen access token om te inspecteren.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$response = wp_remote_get(
|
||||
add_query_arg( [ 'access_token' => $access_token ], 'https://oauth2.googleapis.com/tokeninfo' ),
|
||||
[ 'timeout' => 15 ]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$status_code = wp_remote_retrieve_response_code( $response );
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
$data = json_decode( (string) $body, true );
|
||||
|
||||
if ( 200 !== $status_code || ! is_array( $data ) ) {
|
||||
return new WP_Error( 'groq_ai_google_tokeninfo_failed', __( 'Kon tokeninfo niet ophalen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$scope = isset( $data['scope'] ) ? trim( (string) $data['scope'] ) : '';
|
||||
$expires_in = isset( $data['expires_in'] ) ? absint( $data['expires_in'] ) : 0;
|
||||
|
||||
return [
|
||||
'scope' => $scope,
|
||||
'expires_in' => $expires_in,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
class Groq_AI_Google_Search_Console_Client {
|
||||
/** @var Groq_AI_Google_OAuth_Client */
|
||||
private $oauth;
|
||||
|
||||
public function __construct( Groq_AI_Google_OAuth_Client $oauth ) {
|
||||
$this->oauth = $oauth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $status_code
|
||||
* @param string $raw_body
|
||||
* @return WP_Error
|
||||
*/
|
||||
private function build_http_error( $status_code, $raw_body ) {
|
||||
$status_code = absint( $status_code );
|
||||
$raw_body = (string) $raw_body;
|
||||
|
||||
$message = __( 'Search Console API call mislukt.', GROQ_AI_PRODUCT_TEXT_DOMAIN );
|
||||
$details = '';
|
||||
|
||||
$data = json_decode( $raw_body, true );
|
||||
if ( is_array( $data ) ) {
|
||||
// Google APIs often respond with: { error: { code, message, status, details/errors } }
|
||||
$err = isset( $data['error'] ) && is_array( $data['error'] ) ? $data['error'] : [];
|
||||
$google_message = isset( $err['message'] ) ? trim( (string) $err['message'] ) : '';
|
||||
$google_status = isset( $err['status'] ) ? trim( (string) $err['status'] ) : '';
|
||||
if ( '' !== $google_status || '' !== $google_message ) {
|
||||
$details = trim( $google_status . ( $google_status && $google_message ? ': ' : '' ) . $google_message );
|
||||
}
|
||||
}
|
||||
|
||||
if ( '' !== $details ) {
|
||||
$message = sprintf(
|
||||
/* translators: 1: HTTP status, 2: details */
|
||||
__( 'Search Console API call mislukt (HTTP %1$d): %2$s', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
|
||||
$status_code,
|
||||
$details
|
||||
);
|
||||
} else {
|
||||
$message = sprintf(
|
||||
/* translators: %d: HTTP status */
|
||||
__( 'Search Console API call mislukt (HTTP %d).', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
|
||||
return new WP_Error( 'groq_ai_gsc_error', $message );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
* @return array|WP_Error Array of siteUrl strings.
|
||||
*/
|
||||
public function list_sites( $settings ) {
|
||||
$token = $this->oauth->get_access_token( $settings );
|
||||
if ( is_wp_error( $token ) ) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
$response = wp_remote_get(
|
||||
'https://searchconsole.googleapis.com/webmasters/v3/sites',
|
||||
[
|
||||
'timeout' => 20,
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$status_code = wp_remote_retrieve_response_code( $response );
|
||||
$raw_body = wp_remote_retrieve_body( $response );
|
||||
$data = json_decode( (string) $raw_body, true );
|
||||
|
||||
if ( 200 !== $status_code || ! is_array( $data ) ) {
|
||||
return $this->build_http_error( $status_code, $raw_body );
|
||||
}
|
||||
|
||||
$entries = isset( $data['siteEntry'] ) && is_array( $data['siteEntry'] ) ? $data['siteEntry'] : [];
|
||||
$sites = [];
|
||||
foreach ( $entries as $entry ) {
|
||||
if ( ! is_array( $entry ) ) {
|
||||
continue;
|
||||
}
|
||||
$site_url = isset( $entry['siteUrl'] ) ? trim( (string) $entry['siteUrl'] ) : '';
|
||||
if ( '' !== $site_url ) {
|
||||
$sites[] = $site_url;
|
||||
}
|
||||
}
|
||||
|
||||
$sites = array_values( array_unique( $sites ) );
|
||||
sort( $sites, SORT_NATURAL | SORT_FLAG_CASE );
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
* @param string $site_url
|
||||
* @param string $page_url
|
||||
* @param string $start_date YYYY-MM-DD
|
||||
* @param string $end_date YYYY-MM-DD
|
||||
* @param int $limit
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_top_queries_for_page( $settings, $site_url, $page_url, $start_date, $end_date, $limit = 10 ) {
|
||||
$site_url = trim( (string) $site_url );
|
||||
$page_url = trim( (string) $page_url );
|
||||
$limit = max( 1, min( 25, absint( $limit ) ) );
|
||||
|
||||
if ( '' === $site_url || '' === $page_url ) {
|
||||
return new WP_Error( 'groq_ai_gsc_missing', __( 'Search Console site URL of pagina URL ontbreekt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) );
|
||||
}
|
||||
|
||||
$token = $this->oauth->get_access_token( $settings );
|
||||
if ( is_wp_error( $token ) ) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
$endpoint = 'https://searchconsole.googleapis.com/webmasters/v3/sites/' . rawurlencode( $site_url ) . '/searchAnalytics/query';
|
||||
|
||||
$body = [
|
||||
'startDate' => $start_date,
|
||||
'endDate' => $end_date,
|
||||
'dimensions' => [ 'query' ],
|
||||
'rowLimit' => $limit,
|
||||
'dimensionFilterGroups' => [
|
||||
[
|
||||
'filters' => [
|
||||
[
|
||||
'dimension' => 'page',
|
||||
'operator' => 'equals',
|
||||
'expression' => $page_url,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'aggregationType' => 'auto',
|
||||
];
|
||||
|
||||
$response = wp_remote_post(
|
||||
$endpoint,
|
||||
[
|
||||
'timeout' => 20,
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'body' => wp_json_encode( $body ),
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$status_code = wp_remote_retrieve_response_code( $response );
|
||||
$raw_body = wp_remote_retrieve_body( $response );
|
||||
$data = json_decode( (string) $raw_body, true );
|
||||
|
||||
if ( 200 !== $status_code || ! is_array( $data ) ) {
|
||||
return $this->build_http_error( $status_code, $raw_body );
|
||||
}
|
||||
|
||||
$rows = isset( $data['rows'] ) && is_array( $data['rows'] ) ? $data['rows'] : [];
|
||||
$result = [];
|
||||
|
||||
foreach ( $rows as $row ) {
|
||||
if ( ! is_array( $row ) ) {
|
||||
continue;
|
||||
}
|
||||
$keys = isset( $row['keys'] ) && is_array( $row['keys'] ) ? $row['keys'] : [];
|
||||
$query = isset( $keys[0] ) ? sanitize_text_field( (string) $keys[0] ) : '';
|
||||
if ( '' === $query ) {
|
||||
continue;
|
||||
}
|
||||
$result[] = [
|
||||
'query' => $query,
|
||||
'clicks' => isset( $row['clicks'] ) ? (float) $row['clicks'] : 0.0,
|
||||
'impressions' => isset( $row['impressions'] ) ? (float) $row['impressions'] : 0.0,
|
||||
'ctr' => isset( $row['ctr'] ) ? (float) $row['ctr'] : 0.0,
|
||||
'position' => isset( $row['position'] ) ? (float) $row['position'] : 0.0,
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user