Javascript経由で別のウェブサイトにDiscourseコメントを埋め込む

<div data-theme-toc="true"> </div>

Discourse には、Javascript API を使用して IFRAME を作成することにより、リモートサイトにトピックのコメントを埋め込む機能があります。この機能の動作例については、[Coding Horror のブログ](http://blog.codinghorror.com/welcome-to-the-internet-of-compromised-things/#discourse-comments)をご覧ください。このブログは [Ghost](https://ghost.org/) で実行されていますが、コメントは彼の [Discourse フォーラム](http://discourse.codinghorror.com/t/welcome-to-the-internet-of-compromised-things/3550)から埋め込まれています。

この設定で注意すべき重要な点は、**ユーザーが返信を投稿するには、フォーラムに移動する必要がある**ことです。これは意図的なものであり、Discourse フォーラムでの投稿インターフェースは、現在 Javascript 経由で埋め込むことができるものよりもはるかにリッチであると考えているためです。

このガイドでは、ご自身のブログまたはウェブサイトでコメントの埋め込みを設定する方法を紹介します。

### 仕組み

Discourse では、トピックは多くの投稿で構成されています。別のサイトに Discourse を*埋め込む*場合、ドキュメント(ブログエントリ、HTML ページなど)を単一の*トピック*にリンクします。そのトピックに人々が投稿すると、そのコメントは埋め込み元のページに自動的に表示されます。

埋め込みが検出されたときに Discourse にトピックを自動的に作成させるか、事前にトピックを自分で作成するかを選択できます。

### Discourse の埋め込み設定(簡単な設定)

次の設定では、`=DISCOURSE=` で実行されている Discourse フォーラムからのコメントフィードを、架空のブログ URL `http://example.com/blog/entry-123.html` のページに埋め込みます。

[wrap=placeholder key=DISCOURSE default=discourse.example.com] のドメイン [/wrap]
[wrap=placeholder key=BLOG default=example.com] のドメイン [/wrap]

1. Discourse インストールで **管理 > カスタマイズ > 埋め込み** にアクセスします。https://=DISCOURSE=/admin/customize/embedding

2. 少なくとも 1 つの **埋め込みホスト** を作成します。これは、コメントを埋め込みたいホスト名(ドメイン)である必要があります。この場合のホストは `=BLOG=` です。`http://` やパスを含まないことに注意してください。

    - **パス許可リスト** を使用すると、埋め込みを受け入れるリモートホスト上のパスを指定できます。

   - **カテゴリに投稿** - ホストを入力する際にカテゴリを指定すると、そのホストからインポートされた投稿は自動的にそのカテゴリに格納されます。異なるホストが異なるカテゴリに投稿できます。

   - **タグ** - 指定したホストから作成されるトピックに自動的に適用されるタグを設定できます。

   - **投稿者** - ホストごとにトピック作成ユーザーをオプションで上書きできます。設定されていない場合は、**投稿とトピック** タブのデフォルトが使用されます。
  
3. **投稿とトピック** タブに移動し、**トピック作成用のユーザー名** フィールドに入力します。これは、新しい埋め込みが検出されたときにトピックを作成するユーザーです。Discourse に `eviltrout` というユーザーがいると仮定すると、値は `eviltrout` になります。

4. `http://=BLOG=/blog/entry-123.html` にある Web ページに次の HTML を挿入します。

```html
<div id='discourse-comments'></div>

<script type="text/javascript">
  DiscourseEmbed = {
    discourseUrl: 'https://discourse.example.com/',
    discourseEmbedUrl: 'http://example.com/blog/entry-123.html',
    // className: 'CLASS_NAME',
  };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  })();
</script>

スニペットの構成可能な部分は DiscourseEmbed オブジェクト内にあります。discourseUrl は、末尾のスラッシュを含む Discourse の基本への完全なパスです。discourseEmbedUrl は、現在コメントフィードを埋め込んでいるドキュメントです。

これを正しく設定すると、http://=BLOG=/blog/entry-123.html に最初にアクセスしたときに、ブログ投稿のコメントを読み込もうとします。コメントがないため、バックグラウンドで新しいトピックを作成するように Discourse に指示します。eviltrout によって新しいトピックが作成され、最初の投稿の内容がブログからクロールされ、テキストが自動的に抽出されます。

新しいトピックが作成されると、ユーザーはそのトピックに投稿でき、次回 http://=BLOG=/blog/entry-123.html にアクセスしたときにコメントが自動的に表示されます。

className はオプションで、埋め込みに任意のクラスを追加するため、CSS でカスタマイズできます。

:bulb: ヒント: ブログに複数の著者がいる場合は、各ページに <meta name="discourse-username" content="author_username"> タグを追加できます。Discourse がトピックを作成するためにページをクロールするとき、このメタタグを使用して投稿者を確認し、管理設定で設定されたデフォルトのユーザー名を上書きします。

複数のページへの埋め込み

上記の例では、Javascript スニペットを埋め込む際に http://=BLOG=/blog/entry-123.html の URL をハードコードしました。通常、これは不十分です。多くのサイトには自動的に生成されるページがたくさんあるためです。たとえば、ブログでは通常、各エントリに独自のページが割り当てられます。これをサポートするには、コメントを表示したい各ページに同じスニペットを配置しますが、discourseEmbedUrl に渡される値を現在のページの URL に置き換えます。私のブログでは、discourseEmbedUrl に次の値を使用しています: 'http://eviltrout.com<%= current_page.url %>' -- 新しいブログページが作成されると、Discourse 上にそれらのページに対応する新しいトピックが自動的に作成されます。

埋め込まれたコンテンツのスタイリング

埋め込まれたコメント用のスタイルシートを追加する機能があります。管理 > カスタマイズ > テーマ > [あなたのテーマ] > CSS/HTML の編集 のテーマエディタの 埋め込み CSS セクションを使用して、埋め込まれたコメントとともに提供されるカスタムスタイルシートを追加できます。デフォルトでは、レイアウトは白背景で見栄えが良いと思いますが、サイトに固有のレイアウトがある場合は、自分でスタイルを設定したい場合があります。

(オプション) ポーリング用のフィードの追加

前述のように、Discourse は埋め込まれたサイトのコンテンツを自動的にクロールします。ただし、HTML の解析が難しく、投稿のコンテンツを正しく抽出できない場合があります。多くのブログやウェブサイトは、シンジケーションのために RSS/Atom フィードをサポートしており、Discourse はこれを使用してブログ投稿のコンテンツをより正確に抽出できます。

Discourse には、RSS ポーリングプラグイン(デフォルトで含まれています)が同梱されています。Discourse を埋め込んでいるサイトに RSS または Atom フィードが設定されている場合は、rss_polling_enabled サイト設定を有効にし、管理 > プラグイン > RSS ポーリング 経由でフィードの URL を追加できます。フィード URL が追加されると、Discourse はフィードを解析し、埋め込み設定に追加した許可ホストに基づいて適切なカテゴリに投稿を発行します。

(代替構成) 既存のトピックへのリンク

一部のユーザーは、Discourse にトピックを自動的に作成させたくないと考えています。自分でトピックを作成し、埋め込みコードに関連付けるトピックを伝えるだけのようにしたいと考えています。これを実現するには、埋め込みコードを少し変更します。

<div id='discourse-comments'></div>

<script type="text/javascript">
  window.DiscourseEmbed = {
    discourseUrl: 'https://=DISCOURSE=/',
    topicId: 12345
  };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = window.DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  })();
</script>

唯一の違いは、discourseEmbedUrl を Discourse からのトピック ID に置き換えた点です。これを実行すると、トピックは作成されず、そのトピックのコメントが自動的に表示されます。

リファラーポリシーの設定

最近(2020 年 9 月)の ブラウザのデフォルトのリファラーポリシーの変更により、Discourse は iframe のリファラーポリシーを明示的に \"no-referrer-when-downgrade\" に設定するようにデフォルトが変更されました。セキュリティ上の理由でサイトがより厳密なリファラーポリシーを必要とする場合は、埋め込みスクリプトの DiscourseEmbed オブジェクトに discourseReferrerPolicy の値を設定することで設定できます。例:

DiscourseEmbed = { discourseUrl: 'https://forum.example.com/',
                                  discourseEmbedUrl: '<your_posts_canonical_URL>',
                                  discourseReferrerPolicy: 'strict-origin-when-cross-origin'};

埋め込み詳細のプログラムによるクエリ

埋め込みの詳細をクエリするための API エンドポイントがあり、embed_url をパラメーターとして使用します。

curl 'https://meta.discourse.org/embed/info?embed_url=https://blog.discourse.org/2021/04/discourse-team-grows-to-50' -H 'API-KEY: logapikeygoeshere' -H 'API-USERNAME: apiusernamehere' 

応答は次のようになります。

{
  "topic_id": 187794,
  "post_id": 925017,
  "topic_slug": "discourse-team-grows-to-50-blog",
  "comment_count": 2
}

プライベートサイトからのコメントの埋め込み

プライベートな Discourse インスタンスの場合、Discourse がブログのドメインのサブドメイン上にある場合、Discourse にログインしているユーザーにはコメントが表示されます。Discourse にログインしていないユーザーには、「接続が拒否されました」というメッセージが表示されます。Discourse とブログが完全に別のドメインにある場合、プライベートフォーラムのコメントは表示されません。

トラブルシューティング

Discourse の埋め込みでユーザーが抱える最も一般的な問題は、追加した埋め込みホストに対して正しい値を設定することです。それがサイトのドメインのみであり、余分なスラッシュや無効な文字が含まれていないことを必ず再確認してください。

「いいね!」 116
Deeply integrating Discourse into website
Is it possible to test Discourse Embed comment on localhost?
Discourse 1.4 Released!
Is it possible to use Discourse as a "commenting system"?
Trouble connecting drupal and discourse
Create topic when a link is clicked
Learning Management Systems
Using Discourse in a web app
Using Discourse as a comment system
Comment Reply Threading / Linking on the WordPress Side
Discourse blog comments like your blog comments
Can be integrated with liquid templates?
Embedded Comments iframe Height
Use Discourse as the comments section of a Jekyll site?
Using Discourse to power comments in an event system or blog?
Using Discourse as commenting system via JavaScript: Delay load or load on scroll
Cannot get embedding to work
News Plugin :newspaper:
Embedded topic comments are missing if containing page's URL includes a fragment identifier
Imported topic via embedding will not render normally
Integrating Discourse with a larger social network app?
What is Discourse Blog built with?
Anybody using Discourse for Blog Comments on a Gatsby site?
What software you use for blog.discourse.org?
"Error Embedding" comments
Shared Discourse/Static Site Login
Discourse + Ghost Blog Integration. Is my Understanding Wrong?
Trying to do embedding. Hit with “The referer did not match any of the following hosts:” issue
Looking for Ruby-based CMS recommendations as a compliment to Discourse
[Paid] Embedding: Allowing one RSS feed and one username per host
Discourse comment-like discussion
Discourse embedding error: Failed to execute postMessage on DOMWindow
Discourse + Ghost integration and SEO
Error Embedding
Hide or remove "Listed/Unlisted" comments when embedded
Display all posts in embedding topics with +100 comments
Embedding Topic topic-map or Topic Summary on Other Site
Wordpress integration by iFrame instead of sync
Not generate topic automatically for all blog posts
Link to Discourse topic without displaying Comments (in Drupal)
Which CMS for Discourse
Understanding how embedding works on remote site
Arguments against integrated intranet solutions?
Embed single discourse Topics to articles on news website
Displaying comments embed as a link without using the WP plugin
Get right title embedding comments
Disqus-like commenting on Wordpress
Embedding Discourse Comments *without* Javascript
How to integrate in discourse in zenodo
Co-author topics
How might we better structure #howto?
Issue with image uploads on embedded topics
Getting Discourse URL on embedded comments
Integrating registered users notifications+avatar into static website
Pandoc integration
Can I use Discourse to add Commenting to my Blogs?
How can I get the list of Discourse Topic IDs dynamically
[Question/Request] Featured image url for post
JS embed fails with "Job exception: invalid stored block lengths (Zlib::DataError)"
No `Referer:`, no embedding
Commenting system: integrate Discourse and Webflow
WP Discourse Embed Plugin
Embedding error
Best option to have category "hidden" on Discourse, but otherwise accessible if you have the link?
Topic list on the right side
Create an empty topic via API
Using Discourse for Comments?
Add button with link post forum
Add button with link post forum
Discourse embed crawls cookie warning text
The Gamification of Discourse
Embedding Discourse comment box to blog page
Pinned topic summary is using first-line link text instead of body text
Nextcloud support
Discourse comment button on blog?
Is there a Disqus like comment implementation?
One Discourse instance, Two Blogs?
Embeddable Discourse activity widget
Blog Post Styling
Integration: Discourse comments in Gitbook
Is it possible to autologin discourse via iframe?
Widget to embed in 3rd party websites
How to customize the text in an embedded post?
Benefits to using WP comments over JS embed?
Benefits to using WP comments over JS embed?
What CSS was used for Comments here?
Setting canonical URL when posting/cross-posting
Threaded comments when using Discourse for website comments?
Embedded site stuck at "Loading Discussions"
Embedding Categories in Existing SPA
[Update] Simplify embed feature
Does setting the discourseUrl prevent other clients from creating embedded posts for moved pages?
To use Discourse completely on shopify
I'm unsure of how oneboxing is setup for blog posts to Discourse
I'm unsure of how oneboxing is setup for blog posts to Discourse
Embed my Discourse Forum as IFrame
Discourse blog (article and comments)
Most efficient way to use Discourse for comments on Shopify blog posts?
Is the Discourse content markdown toolbar available as a standalone?
Is there a blog plugin for Discourse's meta blog implementations?
Discourse Comments stuck on "Loading..."
Topic Ratings Plugin
Discourse implementation in create react app
Embed forum
BricksForge and Bricks API Query Builder with Discourse
Wordpress posts are now unlisted from latest update of forum and plugin
Most efficient way to use Discourse for comments on Shopify blog posts?
AI sockpuppet accounts to jumpstart my community?
Should Discourse make an effort to become a viable comment platform?
Problem embeding a topic in a page on another domain
Want to set internal forum on our reactjs member's platform
Embed Discourse using external_id
Expose external_id in embed.js
Grow my community
Forbidden error on embed widget
Strapi discourse integration
Migrating embedded topics from topicId to automatic topic creation
Migrating embedded topics from topicId to automatic topic creation
Problem with "Publish as Unlisted Topics"
RSS Polling
Failed to execute 'postMessage' on 'DOMWindow'
Failed to execute 'postMessage' on 'DOMWindow'
RSS plugin default show full post
Is there a Disqus like comment implementation?
Embending topic in 'another' website. And change redirect page after login
Embedding full threads - possible?
How to customize the text in an embedded post?
How to show the latest discussion on the front page of our main website
Embed Most Recent Replies To Post in Specific Category
Is anyone using Discourse in higher ed for courses?
Embed a list of Discourse topics onto an external site
Is Discourse a full website or just a forum add-in?
Is Discourse a full website or just a forum add-in?
Can I send an external URL to the Discourse API for it to return topics linking to that URL?
How to use Discourse API for article forums and independent community spaces
How to Enable Terms of Service and Privacy Policy Pages in Discourse?
Bug with URLs in Embedded Comments
Blog posts would be nicer if authored by an identifiable person
Structuring an active support community migrating from Facebook
Where in Discourse can users publicly share PII?
"Show Full Post" button doesn't work in subfolder installations
"Show Full Post" button doesn't work in subfolder installations
Embed comments from Discourse in your single page app
JavaScript embed won’t display embed, console log shows: Failed to execute postMessage on DOMWindow…
Can i use / embed discourse to make comments on pages hosted for example on Aquia
Emoji are huge when embedding
Set topic title with Discourse Embed
Embedding Discourse Profile via Javascript
WP-discourse: comments are not pulled over
discourseEmbed, does not match recipient window origin
Statamic integration
How to embed whole forum in another site
Possible to add comment count (to a Ghost blog)?
How can I delete or undelete topics?
Link existing forum topic to new WordPress post
How to enable Discourse comments via JavaScript in Wordpress?
How to link the existing discourse comments to wordpress posts?
Embed whole forum
WP Discourse Embed Plugin
WP Discourse Embed Plugin
Synchronising log out of discourse when logging out of WordPress
Topic as widget
Discourse a a comment system with React Native and Meteor
A post's TopicEmbed isn't destroyed when the post is deleted
Pages from Google search are not rendering
Controlling amount of embedded text
Zendesk Article Comment in Discourse Integration
Flood of new topics from Embedded Discourse
Discourse topics as Dokuwiki talk pages
Multiple cors origins on hosted discourse?
WordPress / Discourse API Strategy: Get Reply Count via API Efficiently
Error Embedding for existing posts
Making embedded JavaScript based discourse commenting responsive
[paid] Preference to create & embed a topic via JavaScript only when a user clicks the "Start Discussion" link
Embedding: Discussion not showing up for new posts
Allowing WP comments while showing Discourse comments too
Handling large pictures of embedded comments inside jquery window
"Error Embedding" comments
Embedded comments not displayed due to X-Frame-Options DENY
Failed to execute postMessage on DOMWindow: The target origin provided does not match
Embedding Discourse сomments with GitBook