0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 13:08:40 +08:00
discourse/app/jobs/regular/generate_topic_og_image.rb
Penar Musaraj 2d895de297
FEATURE: generated OpenGraph images for topics (#39194)
Adds the ability to automatically generate Open Graph images for topics
that don't have their own image. When enabled via the
generate_topic_og_image site setting, a background job creates a branded
1200×630 PNG for each new topic OP.

Key changes:
- TopicOgImageGenerator builds an SVG and converts it to PNG via
ImageMagick
  - Images generated via GenerateTopicOgImage Sidekiq job
- Generated images handled via og_image_upload_id column on the topics
table
- TopicView#image_url falls back to the generated OG image when no topic
image is available

This includes a preview for admins so they can see if they like this
feature or not:


https://github.com/user-attachments/assets/62d17704-4ee5-4859-ac37-b127fe27b85c


And it also respects the site's default theme: 

<img width="1200" height="630" alt="image"
src="https://github.com/user-attachments/assets/678f5c5d-e593-4385-b800-141196dfc221"
/>

---------

Co-authored-by: discourse-patch-triage[bot] <272280883+discourse-patch-triage[bot]@users.noreply.github.com>
Co-authored-by: Gabriel Grubba <gabriel@discourse.org>
2026-06-26 10:37:10 -04:00

31 lines
975 B
Ruby
Vendored

# frozen_string_literal: true
module Jobs
class GenerateTopicOgImage < ::Jobs::Base
sidekiq_options queue: "ultra_low"
def execute(args)
return if !SiteSetting.generate_topic_og_image
topic_id = args[:topic_id]
raise Discourse::InvalidParameters.new(:topic_id) if topic_id.blank?
topic = Topic.find_by(id: topic_id)
return if topic.nil?
if topic.image_upload_id.present?
topic.clear_generated_og_image!
return
end
return if !TopicOgImageGenerator.eligible?(topic)
generator = TopicOgImageGenerator.new(topic)
upload = generator.generate
return if upload.nil? || upload.errors.any?
old_upload_id = topic.og_image_upload_id
topic.update_column(:og_image_upload_id, upload.id)
UploadReference.ensure_exist!(upload_ids: [upload.id], target: topic)
UploadReference.where(target: topic, upload_id: old_upload_id).delete_all if old_upload_id
end
end
end