0 || $referrals > 0 || $access > 0 || $moved; } /** * Subject line. Leads with the single most interesting number. * * @param array $data Collected digest data. * @return string */ public static function subject( array $data ) { $agents = (int) ( $data['agents']['total'] ?? 0 ); $score = isset( $data['score']['now'] ) && null !== $data['score']['now'] ? (int) $data['score']['now'] : null; if ( $agents > 0 && null !== $score ) { return sprintf( /* translators: 1: number of AI agent requests this week, 2: readiness score. */ __( 'Your site’s AI week: %1$s agent reads, score %2$d', 'agentimus' ), number_format_i18n( $agents ), $score ); } if ( $agents > 0 ) { return sprintf( /* translators: %s: number of AI agent requests this week. */ __( 'Your site’s AI week: %s agent reads', 'agentimus' ), number_format_i18n( $agents ) ); } return __( 'Your site’s AI week', 'agentimus' ); } /** * The email body. * * @param array $data Collected digest data. * @return string HTML. */ public static function html( array $data ) { $out = self::open( $data ); $out .= self::section_agents( $data ); $out .= self::section_referrals( $data ); $out .= self::section_impostors( $data ); $out .= self::section_access( $data ); $out .= self::section_score( $data ); $out .= self::section_nudge( $data ); $out .= self::footer( $data ); return $out; } /* ------------------------------------------------------------------ */ /** Head + intro. On the first-ever digest, one line explains why it exists. */ private static function open( array $data ) { $site = (string) ( $data['site_name'] ?? '' ); $period = isset( $data['period'] ) && is_array( $data['period'] ) ? $data['period'] : array(); $range = isset( $period['label'] ) ? (string) $period['label'] : ''; $h = '
'; $h .= ''; $f .= ''; $f .= '
'; $h .= ''; $h .= ''; return $h; } /** Agent reads + top clients. A zero section stays out — a zero row is noise. */ private static function section_agents( array $data ) { $a = isset( $data['agents'] ) && is_array( $data['agents'] ) ? $data['agents'] : array(); $total = (int) ( $a['total'] ?? 0 ); if ( 0 === $total ) { return ''; } $line = sprintf( /* translators: %s: number of requests from AI agents and crawlers. */ _n( 'AI agents and crawlers read your site %s time.', 'AI agents and crawlers read your site %s times.', $total, 'agentimus' ), number_format_i18n( $total ) ); $body = self::stat_row( $line, self::compare( $total, isset( $a['prev'] ) ? $a['prev'] : null ) ); $clients = array_slice( (array) ( $a['by_client'] ?? array() ), 0, self::TOP_ROWS ); if ( $clients ) { $body .= '
'; $h .= '

' . esc_html( $site ) . ( '' !== $range ? ' · ' . esc_html( $range ) : '' ) . '

'; $h .= '

' . esc_html__( 'What AI did on your site this week', 'agentimus' ) . '

'; if ( ! empty( $data['first'] ) ) { $h .= '

' . esc_html__( 'This is the first weekly note from Agentimus. It arrives once a week, and only when there is something to report. One click at the bottom stops it for good.', 'agentimus' ) . '

'; } $h .= '
'; foreach ( $clients as $c ) { $body .= '' . ''; } $body .= '
' . esc_html( (string) ( $c['label'] ?? '' ) ) . '' . esc_html( number_format_i18n( (int) ( $c['hits'] ?? 0 ) ) ) . '
'; } return self::section( __( 'Agent visits', 'agentimus' ), $body ); } /** Humans arriving from AI answers. */ private static function section_referrals( array $data ) { $r = isset( $data['referrals'] ) && is_array( $data['referrals'] ) ? $data['referrals'] : array(); $total = (int) ( $r['total'] ?? 0 ); if ( 0 === $total ) { return ''; } $line = sprintf( /* translators: %s: number of visitors who arrived from an AI assistant. */ _n( '%s visitor arrived from an AI answer.', '%s visitors arrived from AI answers.', $total, 'agentimus' ), number_format_i18n( $total ) ); $body = self::stat_row( $line, self::compare( $total, isset( $r['prev'] ) ? $r['prev'] : null ) ); $names = array(); foreach ( array_slice( (array) ( $r['by_source'] ?? array() ), 0, self::TOP_ROWS ) as $s ) { $name = (string) ( $s['label'] ?? '' ); if ( '' !== $name ) { $names[] = $name; } } if ( $names ) { $body .= '

' . esc_html( sprintf( /* translators: %s: comma-separated list of AI assistants. */ __( 'Sent by: %s', 'agentimus' ), implode( ', ', $names ) ) ) . '

'; } return self::section( __( 'People from AI answers', 'agentimus' ), $body ); } /** Requests that claimed a known crawler and failed its operator's identity check. */ private static function section_impostors( array $data ) { $total = (int) ( $data['impostors']['total'] ?? 0 ); if ( 0 === $total ) { return ''; } $line = sprintf( /* translators: %s: number of requests that faked a known crawler. */ _n( '%s request pretended to be a known crawler and failed the identity check.', '%s requests pretended to be a known crawler and failed the identity check.', $total, 'agentimus' ), number_format_i18n( $total ) ); return self::section( __( 'Impostors', 'agentimus' ), self::stat_row( $line, '' ) ); } /** Authenticated agent activity. The store is event-keyed, so say "events", never "calls". */ private static function section_access( array $data ) { $events = (int) ( $data['access']['events'] ?? 0 ); if ( 0 === $events ) { return ''; } $line = sprintf( /* translators: %s: number of authenticated agent activity events. */ _n( 'Your connected agents were active this week: %s event.', 'Your connected agents were active this week: %s events.', $events, 'agentimus' ), number_format_i18n( $events ) ); return self::section( __( 'Connected agents', 'agentimus' ), self::stat_row( $line, '' ) ); } /** Readiness score + movement since the last digest. */ private static function section_score( array $data ) { $s = isset( $data['score'] ) && is_array( $data['score'] ) ? $data['score'] : array(); if ( ! isset( $s['now'] ) || null === $s['now'] ) { return ''; } $now = (int) $s['now']; $prev = isset( $s['prev'] ) && null !== $s['prev'] ? (int) $s['prev'] : null; $big = '' . esc_html( (string) $now ) . '' . ' / 100'; if ( null === $prev ) { $note = esc_html__( 'This is the first digest, so there is no earlier score to compare against yet. Next week this line shows the change.', 'agentimus' ); } elseif ( $now > $prev ) { /* translators: %d: the score in the previous digest. */ $note = esc_html( sprintf( __( 'Up from %d last week.', 'agentimus' ), $prev ) ); } elseif ( $now < $prev ) { /* translators: %d: the score in the previous digest. */ $note = esc_html( sprintf( __( 'Down from %d last week.', 'agentimus' ), $prev ) ); } else { $note = esc_html__( 'Unchanged since last week.', 'agentimus' ); } $body = '

' . $big . '

' . $note . '

'; return self::section( __( 'AI readiness score', 'agentimus' ), $body ); } /** One actionable nudge — the current top-ranked improvement, if any. */ private static function section_nudge( array $data ) { $n = isset( $data['nudge'] ) && is_array( $data['nudge'] ) ? $data['nudge'] : array(); if ( empty( $n['label'] ) ) { return ''; } $body = '

' . esc_html( (string) $n['label'] ) . ''; if ( ! empty( $n['detail'] ) ) { $body .= '
' . esc_html( (string) $n['detail'] ); } $body .= '

'; return self::section( __( 'One thing worth doing', 'agentimus' ), $body ); } /** Dashboard button + the always-present stop link. */ private static function footer( array $data ) { $links = isset( $data['links'] ) && is_array( $data['links'] ) ? $data['links'] : array(); $dashboard = (string) ( $links['dashboard'] ?? '' ); $stop = (string) ( $links['stop'] ?? '' ); $f = '
'; if ( '' !== $dashboard ) { $f .= '' . esc_html__( 'Open the dashboard', 'agentimus' ) . ''; } $f .= '
'; $f .= '

' . esc_html__( 'Agentimus sends this note once a week, built only from data stored on your own site. Nothing leaves your server except this email.', 'agentimus' ); if ( '' !== $stop ) { $f .= ' ' . esc_html__( 'Stop these emails', 'agentimus' ) . ''; } $f .= '

'; return $f; } /* ------------------------------------------------------------------ */ /** A titled section row. */ private static function section( $title, $body ) { return '' . '

' . esc_html( $title ) . '

' . $body . ''; } /** A lead stat line with an optional comparison note under it. */ private static function stat_row( $line, $compare ) { $html = '

' . esc_html( $line ) . '

'; if ( '' !== $compare ) { $html .= '

' . esc_html( $compare ) . '

'; } return $html; } /** * Plain-words comparison against the prior week. NULL prev = no full prior * week to compare against (first digest, or retention shorter than two * weeks) — say nothing rather than guess. * * @param int $now This week's count. * @param int|null $prev Prior week's count, or null when unknowable. * @return string */ private static function compare( $now, $prev ) { if ( null === $prev ) { return ''; } $prev = (int) $prev; if ( $now > $prev ) { /* translators: %s: the prior week's count. */ return sprintf( __( 'Up from %s the week before.', 'agentimus' ), number_format_i18n( $prev ) ); } if ( $now < $prev ) { /* translators: %s: the prior week's count. */ return sprintf( __( 'Down from %s the week before.', 'agentimus' ), number_format_i18n( $prev ) ); } return __( 'Same as the week before.', 'agentimus' ); } }