Konu

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

ruby
# 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

ruby
# 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")
bash
# .env
FASTOG_API_KEY=sk_your_full_api_key_here
FASTOG_HMAC_SECRET=your_64_char_hex_secret_here

Controller

ruby
# 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

erb
<!-- 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

erb
<!-- app/views/layouts/application.html.erb -->
<head>
  <%= yield :head %>
</head>

Yardımcı

ruby
# app/helpers/fastog_helper.rb
module QuickogHelper
  def og_image_url(template:, **params)
    QuickogSigner.generate_signed_og_url({ template: template }.merge(params))
  end
end
erb
<!-- In view -->
<meta property="og:image" content="<%= og_image_url(template: 'blog', title: @post.title) %>" />

E-Ticaret Örneği

ruby
# 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

ruby
# 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ı

ruby
# config/routes.rb
get "api/og", to: "api/og#generate"
ruby
# 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

erb
<!-- 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.

Tam API Referansı

Ücretsiz deneyin — kayıt gerekmez

Dinamik OG görsellerini saniyeler içinde önizleyin ve test edin.

Ücretsiz OG Görsel Test Aracını Aç

A BeCaSimulations site