WP Manifestindependent plugin directory
manifest / content / sqo-yt-research

SQO YT Research

YouTube research plugin for WordPress

by Elliott Richmond, Square One Software · github.com/eirichmond/sqo-yt-research · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/eirichmond/sqo-yt-research/archive/refs/heads/main.zip

Readme

SQO YT Research

Snapshot YouTube keyword research into custom tables, browse it with DataViews, and export JSON for AI review. Also benchmarks your own channel's videos and suggests new video ideas by comparing the two.

What it does

Keyword research: Runs a YouTube Data API v3 query for a keyword (videos uploaded in the last 7 days, ordered by view count, top 10) and stores the result as a dated snapshot. Each snapshot captures per-video: title, URL, channel, subscriber count, views, likes, duration, category, tags, channel keywords, full description, and publish date.

My Channel benchmarking: Connects to your own YouTube channel via OAuth and syncs its full upload history into a dated stats table, so you can track how each video performs over time. Performance is ranked by views per day since publish, not raw views — this corrects for the age bias in a plain view-count sort (a 2-year-old video will always out-total a 2-week-old one on raw views alone). When connected, syncs also pull averageViewDuration from the YouTube Analytics API, which the public Data API can't provide.

AI suggestions: For any keyword snapshot, generates 10 video ideas (title, description, thumbnail text) by comparing that snapshot's top videos against your own best-performing videos (by views/day), via the Anthropic API.

The admin page (top-level "YT Research" menu) has two tabs — Research for the keyword-snapshot flow above, and My Channel for the benchmark/OAuth/sync flow.

Requirements

  • WordPress 6.7+
  • PHP 8.2+
  • A Google Cloud API key with YouTube Data API v3 enabled (keyword research)
  • A Google Cloud OAuth 2.0 Web application client with YouTube Data API v3 and YouTube Analytics API enabled (My Channel benchmarking)
  • The ai-provider-for-anthropic plugin, active and configured with an API key (AI suggestions only — everything else works without it)

Install

  1. Drop the plugin folder into wp-content/plugins/ and activate (activation creates the custom tables).
  2. The build/ directory ships pre-built. If you're working from source, run npm install && npm run build.
  3. Open YT Research in the admin menu, expand Settings, paste your Data API key, save.
  4. Enter a keyword and hit Run query.

My Channel setup (OAuth)

The public Data API can't tell you which of your own videos are actually doing well relative to their age, and it can't return watch-time metrics at all — that needs YouTube Analytics API access via OAuth, scoped to your own channel.

  1. In Google Cloud Console, on the same project as your Data API key (or a new one): enable YouTube Data API v3 and YouTube Analytics API.
  2. Under APIs & Services → Credentials, create an OAuth client ID of type Web application — not "Desktop app", which has no redirect URI support and will not work here.
  3. Add an Authorized redirect URI of {your site}/wp-json/sqo-yt/v1/channel/oauth/callback.
    • Google's redirect URI policy rejects reserved/local TLDs (e.g. .test, .localhost) — only localhost/127.0.0.1 are exempt. If your local dev site uses one of these (Laravel Valet's .test included), you'll need a temporary reverse proxy to localhost for the OAuth round-trip, and the sqo_yt_research_oauth_redirect_uri filter to point the plugin at it. Production domains aren't affected.
  4. On the My Channel tab, expand Google OAuth settings, paste the Client ID and Secret, save.
  5. Click Connect channel, complete Google's consent screen (grants read-only YouTube + YouTube Analytics scopes), and you'll land back on My Channel showing "Connected as {channel name}".
  6. Click Sync my channel to pull your full upload back-catalogue. Re-sync any time to add a new dated stats row to every video's history (views/day is recalculated fresh each sync).

Tokens auto-refresh on use; Disconnect clears them.

Data

  • {prefix}sqoyt_snapshots — one row per keyword query (keyword, queried_at UTC, video_count)
  • {prefix}sqoyt_videos — one row per researched video, keyed to its snapshot
  • {prefix}sqoyt_channel_videos — one row per own-channel video (title, description, tags, category, duration, published_at, first/last synced)
  • {prefix}sqoyt_channel_video_stats — one dated row per own-channel video per sync (views, likes, comments, subscribers_at_sync, views_per_day, avg_view_duration_seconds) — the full history behind the "View history" action on the My Channel table
  • {prefix}sqoyt_oauth_tokens — the connected channel's OAuth access/refresh tokens (one row; single-channel only)

Directly queryable, e.g.:

SELECT channel_title, AVG(views) FROM wp_sqoyt_videos GROUP BY channel_title ORDER BY AVG(views) DESC;
SELECT title, views_per_day FROM wp_sqoyt_channel_videos ORDER BY views_per_day DESC LIMIT 10;

REST routes

All under sqo-yt/v1, all require manage_options unless noted:

Research

  • GET /snapshots — list snapshots
  • POST /snapshots — run a query ({ "keyword": "WordPress" })
  • DELETE /snapshots/{id} — delete a snapshot and its videos
  • GET /snapshots/{id}/videos — video rows
  • GET /snapshots/{id}/export — full JSON payload (what the Download JSON button uses)
  • POST /snapshots/{id}/suggestions — generate 10 AI video ideas from this snapshot vs. your top own videos (errors clearly if the AI plugin is inactive or no benchmark sync has run yet)

My Channel

  • GET /channel/videos — own-channel videos with latest stats
  • GET /channel/videos/{id}/history — dated stats history for one video
  • POST /channel/sync — pull uploads + stats (+ Analytics metrics if connected)
  • GET /channel/oauth/status — connection status
  • GET /channel/oauth/authorize — starts the OAuth flow (redirects to Google)
  • GET /channel/oauth/callbackpublic, no manage_options required — this is where Google redirects back to; protected instead by a CSRF state token issued to the originating admin user
  • POST /channel/oauth/disconnect — clears stored tokens
  • GET /channel/suggestions/status — whether the AI plugin is active/available

Quota

  • Data API (10,000 units/day free): each keyword query costs ~103 units (search 100, video details 1, channels 1, categories 1) — roughly 97 queries/day. A full channel sync costs ~1 unit per 50 videos (playlistItems.list) plus 1 unit per 50 videos for videos.list details — negligible even for a large channel.
  • Analytics API (separate 50,000 units/day pool, doesn't share with Data API): one reports.query call per synced video; cost per call is small (single metric, no dimensions), so this isn't a practical limit for a personal-channel sync.

Notes and known trade-offs

  • order=viewCount ranks by lifetime views, not weekly velocity. A slow-burner from 6 days ago can outrank this week's fast riser.
  • Subscriber counts can be hidden by channels; these store as NULL and display as "hidden".
  • Impressions and click-through-rate (YouTube Studio's own "Reach" tab) are not available — confirmed against Google's Analytics API metrics reference and a live 400 error during development. averageViewDuration is the only own-channel metric this plugin can pull beyond what the public Data API already provides.
  • AI suggestions are prompts, not data-backed predictions — treat them as a starting point.
  • Deleting the plugin (not deactivating) drops all tables and options via uninstall.php.
  • The Data API key and OAuth client secret are stored as plain options, readable by any manage_options user via the REST settings endpoint. Fine for a personal site; restrict the Data API key by API in Google Cloud console regardless.

Read the full README on GitHub →