Chủ đề

OG Images trong Ruby on Rails

Tạo OG images trong Ruby on Rails với Dynamic API dựa trên đăng ký của FastOG — với gói đăng ký Dynamic API (tạo API key của bạn trong dashboard). Xem trước trong Free OG Image Tester, sau đó hiển thị các Open Graph images động từ ứng dụng Rails của bạn với các URL được ký bằng HMAC.

Bắt đầu nhanh

1. Tạo dịch vụ ký (signer service)

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

Vì sao cần enc tùy chỉnh? Nó mã hóa phần trăm (percent-encode) với chữ hoa thập lục phân, chỉ để lại các ký tự không dành riêng -._~ — vì vậy khoảng trắng trở thành %20, không bao giờ là +, khớp với rawurlencode của máy chủ. Nếu bạn thay bằng CGI.escape hoặc URI.encode_www_form_component, cả hai đều tạo ra + cho khoảng trắng: hãy chuẩn hóa bằng .gsub('+', '%20') trước.

2. Cấu hình

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

Bộ điều khiển (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

Chế độ xem

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>

Bố cục

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

Trợ giúp

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) %>" />

Ví dụ về Thương mại điện tử

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

Ví dụ Bài Viết Blog

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

Điểm cuối API

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 %>

Các Lỗi Thường Gặp

Ký Sai Nội Dung

❌ Sai: "GET/api/v1/og#{canonical}" — thiếu dấu phân cách dòng mới. ✅ Đúng: "GET/api/v1/og\n#{canonical}" — phương thức + đường dẫn, một dòng mới, sau đó là chuỗi truy vấn chuẩn hóa.

Bỏ Sót key Trong Chữ Ký

❌ Sai: chỉ ký các tham số nội dung của bạn và thêm key vào URL sau đó. ✅ Đúng: key được hợp nhất vào các tham số trước khi chuỗi truy vấn chuẩn hóa được xây dựng và xuất hiện trong URL cuối cùng.

Lỗi 401 missing_signature / invalid_signature

missing_signature (401) nghĩa là key hoặc s bị thiếu trong URL. invalid_signature (401) nghĩa là chuỗi chuẩn hóa không khớp — hãy kiểm tra dòng mới trong thông điệp đã ký, cùng một hmac_secret ở cả hai phía và đảm bảo enc mã hóa phần trăm khoảng trắng thành %20 (không bao giờ +).

Lộ Bí Mật HMAC

Không bao giờ để lộ FASTOG_HMAC_SECRET trong JavaScript phía frontend hoặc mã phía máy khách.

Tài liệu tham khảo API đầy đủ

Dùng thử miễn phí — không cần đăng ký

Xem trước và kiểm tra hình ảnh OG động trong vài giây.

Mở Trình kiểm tra hình ảnh OG miễn phí

A BeCaSimulations site