Class: Seo::GscKeywordSyncService
- Inherits:
-
BaseService
- Object
- BaseService
- Seo::GscKeywordSyncService
- Defined in:
- app/services/seo/gsc_keyword_sync_service.rb
Overview
Syncs keyword rankings from Google Search Console for a single SiteMap page.
Used as the primary keyword data source by KeywordSyncService.
Can also be called directly when Ahrefs fallback is not desired.
GSC advantages over Ahrefs for rank tracking:
- Actual Google data (no estimates)
- No per-page API quota limits
- Covers ALL indexed pages including blog posts
- Returns real clicks & impressions (better traffic_share accuracy)
GSC limitations:
- No global search volume (filled by Google Keyword Planner)
- Average position over the period, not a single-day snapshot
- Only shows queries where the site appeared in search results
Constant Summary collapse
- MAX_KEYWORDS =
100- GOOGLE_BATCH_SIZE =
20- LOOKBACK_DAYS =
90
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ GscKeywordSyncService
constructor
A new instance of GscKeywordSyncService.
- #process ⇒ Object
Methods inherited from BaseService
#log_debug, #log_error, #log_info, #log_warning, #logger, #options, #tagged_logger
Constructor Details
#initialize(options = {}) ⇒ GscKeywordSyncService
Returns a new instance of GscKeywordSyncService.
31 32 33 34 35 36 37 |
# File 'app/services/seo/gsc_keyword_sync_service.rb', line 31 def initialize( = {}) super @site_map = [:site_map] @limit = [:limit] || MAX_KEYWORDS @skip_google = [:skip_google] || false raise ArgumentError, 'site_map is required' unless @site_map end |
Instance Method Details
#process ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'app/services/seo/gsc_keyword_sync_service.rb', line 39 def process @logger.info "[GscKeywordSyncService] Syncing #{@site_map.id}: #{@site_map.path}" queries = fetch_queries if queries.blank? @logger.info "[GscKeywordSyncService] No GSC queries for #{@site_map.path}" return { keywords_synced: 0, source: 'gsc' } end @logger.info "[GscKeywordSyncService] #{queries.size} queries from GSC" queries = enrich_with_search_volume(queries) unless @skip_google synced_count = save_keywords(queries) @site_map.update!( seo_synced_at: Time.current, seo_top_keyword: top_keyword_from(queries), seo_top_position: top_position_from(queries) ) @logger.info "[GscKeywordSyncService] Saved #{synced_count} keywords for #{@site_map.path}" { keywords_synced: synced_count, source: 'gsc' } rescue StandardError => e @logger.error "[GscKeywordSyncService] Error for #{@site_map.path}: #{e.}" { keywords_synced: 0, error: e. } end |