rails-index-now 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad4c124b41275b81f3299ce0afd7b1721638e238173b81bcae8df2548f1f2167
4
- data.tar.gz: db7d4b448d2c646de1a875976ad3c005ca6206796864f4f5990877f4d7529073
3
+ metadata.gz: 29bd23e10568ddc7089481dcd364de4a24521ab19dbab5b6c3e32be9d76abc3f
4
+ data.tar.gz: fa96fb54b6ec5e07b8ca025fd20d04addafb1f94eeb0a950f44ee35f4821527d
5
5
  SHA512:
6
- metadata.gz: 3a9c62210fcb82e0a3bbe815bc81865b4b579c559e31863831bed609ae2da6d8718afcae6469c8ea48aebd528840b6ed61f41b49ec3de9771c2a3bc2eeff8e82
7
- data.tar.gz: 55932415ba6e8795add3d1f1bed9b47c2ed1953fe9cc39069b7784d65342fd6f0ae3083187a26e46a4f215f2539aeae0910e44385f048d8f96d9541e4542a873
6
+ metadata.gz: c0acabbc857d732648c638c570039330e4d170a78302c2d6e8be00ff1a22c6379e9a38163ebd0d5d7e1609c17946b1cf395f527ea86f385433bf089f45453fde
7
+ data.tar.gz: 18945e05c71b28de394f334a87e3a378010a6fdc8654c69912039a708e378b642fd22235a0f4ebe32482ee9c4fd5e62699f75b9814d9532512618e08902936e4
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/rails-index-now.svg)](https://badge.fury.io/rb/rails-index-now)
4
4
  [![Build Status](https://github.com/aleksdavtian/rails-index-now/workflows/CI/badge.svg)](https://github.com/aleksdavtian/rails-index-now/actions)
5
5
 
6
- A modern, lightweight Rails gem for seamless integration with Microsoft's IndexNow protocol. Get your content indexed by search engines instantly, without waiting for crawlers.
6
+ A modern, plug-and-play Rails Engine for seamless integration with Microsoft's IndexNow protocol. Get your content indexed by search engines instantly, with automatic API key verification and zero manual configuration.
7
7
 
8
8
  ## What is IndexNow?
9
9
 
@@ -19,6 +19,13 @@ A modern, lightweight Rails gem for seamless integration with Microsoft's IndexN
19
19
 
20
20
  Traditional search engine indexing relies on crawlers periodically visiting your site. With IndexNow, you proactively tell search engines exactly what has changed, when it changed, making the indexing process nearly instantaneous.
21
21
 
22
+ ### Why This Rails Engine?
23
+
24
+ - **🚀 Plug-and-Play**: No manual controller or route setup required
25
+ - **🔐 Automatic Verification**: The engine automatically serves your API key file at the correct URL
26
+ - **⚡ Zero Configuration**: Just add the gem, run the generator, and you're ready
27
+ - **🛡️ Production Ready**: Built-in error handling, logging, and environment controls
28
+
22
29
  ## Installation
23
30
 
24
31
  Add this line to your application's Gemfile:
@@ -39,42 +46,59 @@ Or install it yourself as:
39
46
  gem install rails-index-now
40
47
  ```
41
48
 
42
- ## Configuration
49
+ ## Quick Setup
50
+
51
+ ### 1. Install the Gem
43
52
 
44
- Generate the initializer file:
53
+ Add to your Gemfile and run `bundle install`:
54
+
55
+ ```ruby
56
+ gem 'rails-index-now'
57
+ ```
58
+
59
+ ### 2. Generate Configuration
45
60
 
46
61
  ```bash
47
62
  rails generate index_now:install
48
63
  ```
49
64
 
50
- This creates `config/initializers/index_now.rb`. Configure your IndexNow settings:
65
+ ### 3. Configure Your API Key
66
+
67
+ Get your free API key from [Bing IndexNow](https://www.bing.com/indexnow/getstarted) and add it to your environment:
68
+
69
+ ```bash
70
+ # .env or your environment
71
+ INDEXNOW_API_KEY=your_api_key_here
72
+ ```
73
+
74
+ **That's it!** The engine automatically:
75
+ - ✅ Serves your API key at `/your_api_key_here.txt` (for IndexNow verification)
76
+ - ✅ Handles all routing and controller logic
77
+ - ✅ Configures sensible defaults for all environments
78
+
79
+ ### Configuration Options
80
+
81
+ The generator creates `config/initializers/index_now.rb` with these options:
51
82
 
52
83
  ```ruby
53
84
  Rails::Index::Now.configure do |config|
54
85
  # Required: Your IndexNow API key
55
- # Get one free at https://www.indexnow.org/
56
- config.api_key = ENV['INDEXNOW_API_KEY']
86
+ config.api_key = ENV.fetch("INDEXNOW_API_KEY", nil)
87
+
88
+ # Required: Key file name (automatically set from your API key)
89
+ config.key_file_name = "#{ENV.fetch('INDEXNOW_API_KEY', 'your-api-key')}.txt"
57
90
 
58
91
  # Optional: Set a specific host for all submissions
59
- # If not set, the gem will extract the host from submitted URLs
60
- config.host = "yourdomain.com"
92
+ # config.host = "yourdomain.com"
61
93
 
62
- # Optional: Disable IndexNow in specific environments
63
- # Recommended for test and development environments
94
+ # Optional: Disable IndexNow in specific environments
64
95
  config.disabled = Rails.env.test? || Rails.env.development?
65
96
 
66
97
  # Optional: Set a custom logger
67
- # Defaults to Rails.logger
68
- config.logger = Rails.logger
98
+ # config.logger = Rails.logger
69
99
  end
70
100
  ```
71
101
 
72
- ### Getting Your IndexNow API Key
73
-
74
- 1. Visit [IndexNow.org](https://www.indexnow.org/)
75
- 2. Generate a free API key
76
- 3. Add the key to your environment variables or Rails credentials
77
-
78
102
  ## Usage
79
103
 
80
104
  ### Basic Usage
@@ -92,12 +116,12 @@ Rails::Index::Now.submit([
92
116
  ])
93
117
  ```
94
118
 
95
- ### Background Processing (Recommended)
119
+ ### Background Processing (Optional)
96
120
 
97
- For production applications, use background jobs to avoid blocking web requests:
121
+ For production applications, use background jobs to avoid blocking web requests. **Note: This requires ActiveJob to be available in your application.**
98
122
 
99
123
  ```ruby
100
- # Submit URLs asynchronously using ActiveJob
124
+ # Submit URLs asynchronously using ActiveJob (requires ActiveJob)
101
125
  Rails::Index::Now.submit_async("https://yourdomain.com/articles/123")
102
126
 
103
127
  Rails::Index::Now.submit_async([
@@ -106,26 +130,23 @@ Rails::Index::Now.submit_async([
106
130
  ])
107
131
  ```
108
132
 
109
- The gem works seamlessly with any ActiveJob backend (Sidekiq, SolidQueue, GoodJob, etc.).
133
+ The gem works seamlessly with any ActiveJob backend (Sidekiq, SolidQueue, GoodJob, etc.) when ActiveJob is available.
110
134
 
111
- ### Real-World Rails Integration
135
+ ### Rails Model Integration
112
136
 
113
- Here's how to integrate IndexNow with your Rails models for automatic indexing:
137
+ The magic happens when you integrate IndexNow with your Rails models. Here's a complete example:
114
138
 
115
139
  ```ruby
116
140
  class Article < ApplicationRecord
117
- # Submit to IndexNow after creating or updating articles
141
+ # Automatically notify search engines when articles are created or updated
118
142
  after_commit :submit_to_index_now, on: [:create, :update]
119
143
 
120
- # Also submit when articles are published
121
- after_commit :submit_to_index_now, if: :saved_change_to_published_at?
122
-
123
144
  private
124
145
 
125
146
  def submit_to_index_now
126
147
  return unless published? && Rails.env.production?
127
148
 
128
- # Submit asynchronously to avoid blocking the web request
149
+ # The engine handles everything - just submit the URL!
129
150
  Rails::Index::Now.submit_async(article_url)
130
151
  end
131
152
 
@@ -138,12 +159,18 @@ class Article < ApplicationRecord
138
159
  end
139
160
  ```
140
161
 
162
+ **What happens automatically:**
163
+ 1. 🔥 Your article gets saved
164
+ 2. 🚀 `after_commit` triggers IndexNow submission
165
+ 3. 🎯 Search engines are notified within seconds
166
+ 4. ✅ Your content appears in search results faster
167
+
141
168
  ### Advanced Usage
142
169
 
143
- For more complex scenarios, you can also use the job directly:
170
+ For more complex scenarios, you can also use the job directly (requires ActiveJob):
144
171
 
145
172
  ```ruby
146
- # Use the provided ActiveJob directly
173
+ # Use the provided ActiveJob directly (requires ActiveJob)
147
174
  Rails::Index::Now::SubmitJob.perform_later([
148
175
  "https://yourdomain.com/page1",
149
176
  "https://yourdomain.com/page2"
@@ -153,6 +180,8 @@ Rails::Index::Now::SubmitJob.perform_later([
153
180
  Rails::Index::Now::SubmitJob.perform_now(["https://yourdomain.com/page"])
154
181
  ```
155
182
 
183
+ **Note:** If ActiveJob is not available, use the synchronous `submit` method instead.
184
+
156
185
  ### Error Handling
157
186
 
158
187
  The gem includes comprehensive error handling and logging:
@@ -169,22 +198,25 @@ Rails::Index::Now.submit("invalid-url")
169
198
 
170
199
  ## Framework Compatibility
171
200
 
172
- This gem is designed specifically for Rails applications and requires:
201
+ This Rails Engine requires:
173
202
 
174
- - **Rails 6.0+** (for ActiveJob support)
203
+ - **Rails 5.0+** (for Rails Engine support)
175
204
  - **Ruby 2.7+**
205
+ - **ActiveJob** (optional, only needed for `submit_async` functionality)
176
206
 
177
- The gem automatically integrates with your existing Rails infrastructure:
207
+ The engine automatically integrates with your Rails application:
178
208
 
179
- - **ActiveJob**: Works with any ActiveJob backend (Sidekiq, SolidQueue, etc.)
180
- - **Logging**: Uses Rails.logger by default
181
- - **Environment Awareness**: Easy to disable in development/test environments
182
- - **Rails Generators**: Includes installation generator for easy setup
209
+ - **🔄 Automatic Routing**: No need to manually add routes - the engine handles it
210
+ - **🎛️ Controller Integration**: Built-in controller serves API key verification file
211
+ - **⚡ ActiveJob**: Optional - enables `submit_async` method with any backend (Sidekiq, SolidQueue, etc.)
212
+ - **📝 Smart Logging**: Uses Rails.logger with helpful [IndexNow] prefixes
213
+ - **🌍 Environment Awareness**: Easy to disable in development/test environments
214
+ - **🛠️ Rails Generators**: One-command setup with `rails generate index_now:install`
183
215
 
184
216
  ## Performance Considerations
185
217
 
186
- - **Asynchronous by Design**: The `submit_async` method queues jobs to avoid blocking web requests
187
- - **Lightweight**: Zero external dependencies beyond Rails
218
+ - **Asynchronous by Design**: The `submit_async` method queues jobs to avoid blocking web requests (when ActiveJob is available)
219
+ - **Lightweight**: Zero runtime dependencies - uses only Ruby standard library
188
220
  - **Efficient**: Batches multiple URLs in single API calls when possible
189
221
  - **Fault Tolerant**: Gracefully handles network failures and API errors
190
222
 
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Index
5
+ module Now
6
+ class VerificationController < ActionController::Base
7
+ # Skip CSRF protection for this simple text response
8
+ skip_before_action :verify_authenticity_token, only: [:index_now_key]
9
+
10
+ def index_now_key
11
+ config = Rails::Index::Now.configuration
12
+
13
+ unless config.engine_valid?
14
+ render plain: "IndexNow configuration invalid", status: :internal_server_error
15
+ return
16
+ end
17
+
18
+ render plain: config.api_key, content_type: "text/plain"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails::Index::Now::Engine.routes.draw do
4
+ # This route will be dynamically configured based on the key_file_name
5
+ # The actual route registration happens in the engine's initialization
6
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module IndexNow
6
+ module Generators
7
+ class InstallGenerator < ::Rails::Generators::Base
8
+ source_root File.expand_path("templates", __dir__)
9
+
10
+ desc "Creates an IndexNow initializer file"
11
+
12
+ def create_initializer_file
13
+ template "index_now.rb", "config/initializers/index_now.rb"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # IndexNow Configuration
4
+ # See https://github.com/your-username/rails-index-now for full documentation
5
+
6
+ Rails::Index::Now.configure do |config|
7
+ # Required: Your IndexNow API key
8
+ # You can get one from https://www.bing.com/indexnow/getstarted
9
+ config.api_key = ENV.fetch("INDEXNOW_API_KEY", nil)
10
+
11
+ # Required: Key file name for IndexNow verification
12
+ # This should be "YOUR_API_KEY.txt" (replace YOUR_API_KEY with your actual key)
13
+ # The gem will automatically serve this file at /YOUR_API_KEY.txt
14
+ config.key_file_name = "#{ENV.fetch("INDEXNOW_API_KEY", "your-api-key")}.txt"
15
+
16
+ # Optional: Set a specific host for all submissions
17
+ # If not set, the gem will extract the host from the submitted URLs
18
+ # config.host = "example.com"
19
+
20
+ # Optional: Disable IndexNow in specific environments
21
+ # Recommended for test and development environments
22
+ config.disabled = Rails.env.test? || Rails.env.development?
23
+
24
+ # Optional: Set a custom logger
25
+ # Defaults to Rails.logger if available, otherwise STDOUT
26
+ # config.logger = Rails.logger
27
+ end
@@ -4,13 +4,14 @@ module Rails
4
4
  module Index
5
5
  module Now
6
6
  class Configuration
7
- attr_accessor :api_key, :host, :disabled, :logger
7
+ attr_accessor :api_key, :host, :disabled, :logger, :key_file_name
8
8
 
9
9
  def initialize
10
10
  @api_key = nil
11
11
  @host = nil
12
12
  @disabled = false
13
13
  @logger = default_logger
14
+ @key_file_name = nil
14
15
  end
15
16
 
16
17
  def disabled?
@@ -21,6 +22,10 @@ module Rails
21
22
  !api_key.nil? && !api_key.empty?
22
23
  end
23
24
 
25
+ def engine_valid?
26
+ valid? && !key_file_name.nil? && !key_file_name.empty?
27
+ end
28
+
24
29
  private
25
30
 
26
31
  def default_logger
@@ -5,9 +5,14 @@
5
5
 
6
6
  Rails::Index::Now.configure do |config|
7
7
  # Required: Your IndexNow API key
8
- # You can get one from https://www.indexnow.org/
8
+ # You can get one from https://www.bing.com/indexnow/getstarted
9
9
  config.api_key = ENV.fetch("INDEXNOW_API_KEY", nil)
10
10
 
11
+ # Required: Key file name for IndexNow verification
12
+ # This should be "YOUR_API_KEY.txt" (replace YOUR_API_KEY with your actual key)
13
+ # The gem will automatically serve this file at /YOUR_API_KEY.txt
14
+ config.key_file_name = "#{ENV.fetch("INDEXNOW_API_KEY", "your-api-key")}.txt"
15
+
11
16
  # Optional: Set a specific host for all submissions
12
17
  # If not set, the gem will extract the host from the submitted URLs
13
18
  # config.host = "example.com"
@@ -1,13 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rails/railtie"
3
+ require "rails/engine"
4
4
 
5
5
  module Rails
6
6
  module Index
7
7
  module Now
8
- class Railtie < ::Rails::Railtie
8
+ class Engine < ::Rails::Engine
9
+ isolate_namespace Rails::Index::Now
10
+
9
11
  generators do
10
- require_relative "generators/install_generator"
12
+ require "generators/index_now/install_generator"
13
+ end
14
+
15
+ initializer "rails_index_now.add_routes" do |app|
16
+ app.routes.prepend do
17
+ config = Rails::Index::Now.configuration
18
+ if config.engine_valid?
19
+ get "/#{config.key_file_name}",
20
+ to: "rails/index/now/verification#index_now_key"
21
+ end
22
+ end
11
23
  end
12
24
  end
13
25
  end
@@ -3,7 +3,7 @@
3
3
  module Rails
4
4
  module Index
5
5
  module Now
6
- VERSION = "0.1.0"
6
+ VERSION = "0.1.2"
7
7
  end
8
8
  end
9
9
  end
@@ -4,7 +4,7 @@ require_relative "now/version"
4
4
  require_relative "now/configuration"
5
5
  require_relative "now/client"
6
6
  require_relative "now/submit_job" if defined?(ActiveJob::Base)
7
- require_relative "now/railtie" if defined?(Rails::Railtie)
7
+ require_relative "now/railtie" if defined?(Rails::Engine)
8
8
 
9
9
  module Rails
10
10
  module Index
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-index-now
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleks Ulanov
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-07-26 00:00:00.000000000 Z
10
+ date: 2025-07-27 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Instantly notify search engines like Bing and DuckDuckGo of content changes
13
13
  in your Rails app. This gem provides a simple client and Active Job integration
@@ -26,6 +26,10 @@ files:
26
26
  - LICENSE.txt
27
27
  - README.md
28
28
  - Rakefile
29
+ - app/controllers/rails/index/now/verification_controller.rb
30
+ - config/routes.rb
31
+ - lib/generators/index_now/install_generator.rb
32
+ - lib/generators/index_now/templates/index_now.rb
29
33
  - lib/rails/index/now.rb
30
34
  - lib/rails/index/now/client.rb
31
35
  - lib/rails/index/now/configuration.rb