# RSS 轮询：插件扩展点（表单出口、导入中的 feed ID、更新路径钩子）

**URL:** https://meta.discourse.org/t/rss-polling-extension-points-for-plugins-feed-form-outlet-feed-id-in-import-update-path-hook/413282
**Category:** Feature
**Tags:** rss-polling
**Created:** [2026年九月24日 21:07 UTC](https://meta.discourse.org/t/rss-polling-extension-points-for-plugins-feed-form-outlet-feed-id-in-import-update-path-hook/413282 "2026-09-24T21:07:15Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Sailor](https://avatars.discourse-cdn.com/v4/letter/s/a587f6/32.png) [@Sailor](https://meta.discourse.org/u/Sailor)
#### Post date: [2026年九月24日 21:07 UTC](https://meta.discourse.org/t/rss-polling-extension-points-for-plugins-feed-form-outlet-feed-id-in-import-update-path-hook/413282/1 "2026-09-24T21:07:15Z")

</div>

我们为 RSS 轮询功能开发了一个小型的配套插件（[discourse-rss-onebox](https://github.com/Peter-Petrik/discourse-rss-onebox)）：导入的博客文章会以文章 onebox 的形式渲染，并支持可选的 feed 摘要、YouTube 描述以及标题格式。由于存在三个功能缺口，我们不得不通过包装核心方法来实现，而不是使用已记录的钩子（hooks）。

1. **Feed 表单中缺少插件出口（plugin outlet）。** [rss-polling-feed-form.gjs#L287-L351](https://github.com/discourse/discourse/blob/6ba633dbf56576959ff3d578048ca9698de153ff/plugins/discourse-rss-polling/admin/assets/javascripts/discourse/components/rss-polling-feed-form.gjs#L287-L351) 中没有 `PluginOutlet`，且更新契约（update contract）只接受一组固定的属性（[update.rb#L9-L14](https://github.com/discourse/discourse/blob/6ba633dbf56576959ff3d578048ca9698de153ff/plugins/discourse-rss-polling/app/services/discourse_rss_polling/rss_feed/update.rb#L9-L14)）。插件无法为每个 feed 添加选项，因此我们的插件需要一个独立的管理页面。如果提供一个出口以及一种持久化额外字段的方式（例如 feed 自定义字段），就能解决这个问题。

2. **Feed ID 从未传递到导入流程中。** 轮询任务（poll job）知道 `rss_feed_id`，但 `TopicEmbed.import`（[poll\_feed.rb#L110](https://github.com/discourse/discourse/blob/6ba633dbf56576959ff3d578048ca9698de153ff/plugins/discourse-rss-polling/app/jobs/jobs/discourse_rss_polling/poll_feed.rb#L110)）和 `topic_embed_import_create_args` 修饰器（modifier）（[topic\_embed.rb#L108](https://github.com/discourse/discourse/blob/6ba633dbf56576959ff3d578048ca9698de153ff/app/models/topic_embed.rb#L108)）从未接收到它。我们包装了轮询任务以捕获该 ID。如果将其作为选项传递下去，插件就可以针对每个 feed 执行操作。

3. **更新路径上缺少钩子。** 当 feed 项的内容发生变化时，`TopicEmbed.import` 会使用 feed 内容修订帖子（[topic\_embed.rb#L147-L152](https://github.com/discourse/discourse/blob/6ba633dbf56576959ff3d578048ca9698de153ff/app/models/topic_embed.rb#L147-L152)），从而绕过了创建修饰器所做的任何处理。如果博主编辑了一篇帖子，插件生成的主题格式会被静默地还原为普通的 feed 文本。如果在更新更改时提供一个镜像 `topic_embed_import_create_args` 的修饰器，就能弥补这一缺陷。

针对第 2 和第 3 点的变通方案是在 `TopicEmbed.import` 和轮询任务之前插入（prepend）代码。这种做法非常脆弱：`main` 分支后来为 `TopicEmbed.import` 添加了一个 `truncate:` 关键字参数，这破坏了任何镜像 2026.7 版本签名的包装器——我们不得不发布一个版本仅仅是为了传递该参数。如果提供已记录的钩子，就可以避免这类破坏性问题。
