Ruby on Rails'te OG Görselleri
FastOG'nin abonelik tabanlı Dinamik API'si ile Ruby on Rails'te OG görselleri oluşturun — bir Dinamik API aboneliği ile (API anahtarınızı panelde oluşturun). Ücretsiz OG Görsel Test Aracı'nda önizleyin, ardından Rails uygulamanızdan HMAC imzalı URL'lerle dinamik Open Graph görselleri oluşturun.
Hızlı Başlangıç
1. İmzalayıcı servisini oluşturun
# app/services/fastog_signer.rb
class QuickogSigner
def self.generate_signed_og_url(params, options = {})
base_url = options[:base_url] || ENV.fetch("FASTOG_BASE_URL", "https://fastog.com/api/v1/og")
api_key = options[:api_key] || ENV.fetch("FASTOG_API_KEY")
hmac_secret = options[:hmac_secret] || ENV.fetch("FASTOG_HMAC_SECRET")
raise "Missing FASTOG_API_KEY or FASTOG_HMAC_SECRET" unless api_key && hmac_secret
all = params.merge(key: api_key)
pairs = all.flat_map do |k, v|
Array(v).sort.map { |vv| "#{enc(k)}=#{enc(vv)}" }
end
canonical = pairs.sort.join("&")
signature = OpenSSL::HMAC.hexdigest("SHA256", hmac_secret, "GET/api/v1/og\n#{canonical}")
"#{base_url}?#{URI.encode_www_form(all.merge(s: signature))}"
end
def self.enc(s)
s.to_s.gsub(/[^A-Za-z0-9\-._~]/) { |c| c.bytes.map { |b| "%%%02X" % b }.join }
end
private_class_method :enc
end
Neden özel bir enc? Büyük harfli onaltılık karakterlerle yüzde kodlaması yapar ve yalnızca -._~ ayrılmamış karakterleri bırakır — böylece boşluklar %20 olur, asla + değil; bu da sunucunun rawurlencode ile eşleşir. CGI.escape veya URI.encode_www_form_component kullanırsanız, her ikisi de boşluklar için + üretir: önce .gsub('+', '%20') ile normalleştirin.
2. Yapılandırma
# config/application.rb
config.fastog = ActiveSupport::OrderedOptions.new
config.fastog.api_key = ENV.fetch("FASTOG_API_KEY", nil)
config.fastog.hmac_secret = ENV.fetch("FASTOG_HMAC_SECRET", nil)
config.fastog.base_url = ENV.fetch("FASTOG_BASE_URL", "https://fastog.com/api/v1/og")
# .env
FASTOG_API_KEY=sk_your_full_api_key_here
FASTOG_HMAC_SECRET=your_64_char_hex_secret_here
Controller
# app/controllers/blog_controller.rb
class BlogController < ApplicationController
def show
@post = Post.find_by!(slug: params[:slug])
@og_image_url = QuickogSigner.generate_signed_og_url(
template: "blog",
title: @post.title,
subtitle: @post.excerpt,
author: @post.author.name
)
end
end
Görünüm
<!-- app/views/blog/show.html.erb -->
<% content_for :head do %>
<meta property="og:image" content="<%= @og_image_url %>" />
<meta property="og:title" content="<%= @post.title %>" />
<meta property="og:description" content="<%= @post.excerpt %>" />
<% end %>
<article>
<h1><%= @post.title %></h1>
<p><%= @post.excerpt %></p>
</article>
Düzen
<!-- app/views/layouts/application.html.erb -->
<head>
<%= yield :head %>
</head>
Yardımcı
# app/helpers/fastog_helper.rb
module QuickogHelper
def og_image_url(template:, **params)
QuickogSigner.generate_signed_og_url({ template: template }.merge(params))
end
end
<!-- In view -->
<meta property="og:image" content="<%= og_image_url(template: 'blog', title: @post.title) %>" />
E-Ticaret Örneği
# app/controllers/products_controller.rb
class ProductsController < ApplicationController
def show
@product = Product.find(params[:id])
@og_image_url = QuickogSigner.generate_signed_og_url(
template: "ecommerce",
title: @product.name,
price: @product.formatted_price,
image: @product.image_url
)
end
end
Blog Yazısı Örneği
# app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find_by!(username: params[:username])
@og_image_url = QuickogSigner.generate_signed_og_url(
template: "blog",
title: @user.name,
subtitle: @user.bio,
author: @user.name
)
end
end
API Uç Noktası
# config/routes.rb
get "api/og", to: "api/og#generate"
# app/controllers/api/og_controller.rb
module Api
class OgController < ApplicationController
skip_before_action :verify_authenticity_token
def generate
title = params[:title]
template = params[:template] || "default"
unless title
return render json: { error: "Missing title" }, status: :bad_request
end
og_image_url = QuickogSigner.generate_signed_og_url(
template: template,
title: title
)
render json: { ogImageUrl: og_image_url }
end
end
end
Turbo/Hotwire
<!-- app/views/blog/_post.html.erb -->
<%= turbo_frame_tag "post_#{@post.id}" do %>
<meta property="og:image" content="<%= og_image_url(template: 'blog', title: @post.title) %>" />
<h2><%= link_to @post.title, blog_path(@post) %></h2>
<% end %>
Sık Karşılaşılan Hatalar
Yanlış Mesajı İmzalamak
❌ Yanlış: "GET/api/v1/og#{canonical}" — yeni satır ayracı eksik.
✅ Doğru: "GET/api/v1/og\n#{canonical}" — yöntem + yol, ardından yeni satır ve kanonik sorgu.
key Öğesini İmzadan Çıkarmak
❌ Yanlış: yalnızca içerik parametrelerinizi imzalamak ve key öğesini daha sonra URL'ye eklemek.
✅ Doğru: key, kanonik sorgu oluşturulmadan önce parametrelere dahil edilir ve son URL'de görünür.
401 missing_signature / invalid_signature
missing_signature (401), key veya s öğesinin URL'de eksik olduğu anlamına gelir. invalid_signature (401), kanonik sorgunun eşleşmediği anlamına gelir — imzalanan mesajdaki yeni satırı, her iki tarafta da aynı hmac_secret değerini ve enc öğesinin boşlukları %20 olarak yüzde kodladığını (asla + olarak değil) doğrulayın.
HMAC Gizli Anahtarını Açığa Çıkarmak
FASTOG_HMAC_SECRET öğesini asla ön uç JavaScript'inde veya istemci tarafı kodunda açığa çıkarmayın.