Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

リンクをわかりやすく見せる部品(リンクカード)が欲しい #7455

Open
komagata opened this issue Feb 28, 2024 · 33 comments
Assignees

Comments

@komagata
Copy link
Member

komagata commented Feb 28, 2024

↓こういうやつが欲しい。

ブログや日報など、Markdownエディターを使ってるところで使えるようにする。

下記のnpmを試してみてください〜(書式も下記のnpmに従います)

https://www.npmjs.com/package/@luckrya/markdown-it-link-to-card

@komagata komagata changed the title リンクをわかりやすくだす部品(WebCard)が欲しい リンクをわかりやすく見せる部品(WebCard)が欲しい Feb 28, 2024
@komagata komagata changed the title リンクをわかりやすく見せる部品(WebCard)が欲しい リンクをわかりやすく見せる部品(リンクカード)が欲しい Feb 28, 2024
@komagata komagata added the 3 label Feb 28, 2024
@mousu-a
Copy link
Contributor

mousu-a commented Mar 5, 2024

@komagata
お疲れ様です。
実装の方針について確認させていただきたいです🙏

luckrya/markdown-it-link-to-card
リンクカードの実装に使うこちらのnpmなんですが、使われている言語がTypeScriptなためそのまま使えなさそうです。
下記のAPI(JavaScript)の方で実装するという形で良かったのでしょうか?
不安に思ったので確認させていただきたいです🙇‍♂️

Usage(TypeScript)

import MarkdownIt from "markdown-it";
import { linkToCardPlugin } from "@luckrya/markdown-it-link-to-card";
import type { LinkToCardPluginOptions } from "@luckrya/markdown-it-link-to-card";

const md = MarkdownIt({ html: true }).use<LinkToCardPluginOptions>(
  linkToCardPlugin,
  {
    // options
    size: "small",
  }
);

const rendered = md.render(`

# Home

...

### Reference

  - [github](https://github.com)
  - [bing](https://cn.bing.com/)
  - [知乎 - 发现页](https://www.zhihu.com/explore)
  - [markdown-it-link-to-card](https://github.com/luckrya/markdown-it-link-to-card)

<br />

  - [github](@:https://github.com)
  - [bing](@:https://cn.bing.com)
  - [知乎 - 发现页](@:https://www.zhihu.com/explore)
  - [markdown-it-link-to-card](@:https://github.com/luckrya/markdown-it-link-to-card)

`);

API(JavaScript)

import { generateCard } from "@luckrya/markdown-it-link-to-card";

generateCard("https://github.com", {
  linkTitle: "Github Home",
  showTitle: true,
  size: "small",
}).then(({ dom }) => {
  // card dom fragment
  console.log(dom);
});

@komagata
Copy link
Member Author

komagata commented Mar 9, 2024

@mousu-a 後からこのIssueを追った人にもわかるようにGitHub外でのやりとり(ミーティングやDiscordや口頭など)で決まったことがあればこちらにメモとして残すようにしてみてください〜。

@mousu-a
Copy link
Contributor

mousu-a commented Mar 10, 2024

後からこのIssueを追った人にもわかるようにGitHub外でのやりとり(ミーティングやDiscordや口頭など)で決まったことがあればこちらにメモとして残すようにしてみてください〜。

ありがとうございます🙏

以下ミーティングで決まった方針です!ログとして残します。

概要

リンクカードの実装方針に不安があり、komagataさんに相談させていただいた。

詳細

上にあるように、リンクカードの実装使うnpmがTypeScriptで書かれていたため、Usageとして例に上がっているこちらのコードではなく、
https://github.com/luckrya/markdown-it-link-to-card?tab=readme-ov-file#usage

APIとして提示されているこちらのコードを使って実装するものだと思い込んでいました。
https://github.com/luckrya/markdown-it-link-to-card?tab=readme-ov-file#api

そちらをミーティングにてkomagataさんに相談させていただいたところ、「なにか他に別の手段がありそう、探してみてほしい。というよりこの場合のAPIというのが(何に使うのか?)よくわからない」とのこと。
それとチーム開発メンバーのAntiSatoriさんから「TypeScriptは実行時にJavaScriptにコンパイルされるため、TypeScriptで書かれたコードでも問題はなさそう」とのご指摘をいただいたので、
現在は「TypeScriptで書いた(Usageにあるような)リンクカード関連のコードをJavaScriptのファイルでimportして使う」形で実装を進めています。

@mousu-a
Copy link
Contributor

mousu-a commented Mar 14, 2024

ログ

こちらご紹介いただいたnpmがTypeScriptなのですが、komagataさんより「TypeScriptを使ってしまうと、RailsエンジニアコースでもTypeScriptのカリキュラムを作る必要があり、あえて導入しないようにしているので、TypeScriptはbootcampに導入しない方向で進めていただければありがたいです〜。」とのことです。

TypeScriptを使わずにnpmを使って導入するという方向で進めていきます🙏

@mousu-a
Copy link
Contributor

mousu-a commented Mar 21, 2024

@komagata

お疲れ様です!
リンクカードの実装、ようやく方向性が見えてきたのですが、npmの問題点が見つかりました。それについての対処法について、お考えをお聞きしたいです。

npmの問題点

リンクカードを生成する際にCORSでブロックされる

  • npmを使ってリンクカードを生成する際に、npmの内部で受け取ったURLへリクエスト、レスポンスを受け取る処理を行っています。(XHRを使っています)
  • しかし上記の処理がCORSによってブロックされリクエストが失敗、リンクカードが生成出来ません。

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

対処法

間にRailsのコントローラーを挟む

  • JSと外部サイトとのリクエストの間にRailsのコントローラーを挟むことでCORSによるブロックが発生しないようにする想定です。(レスポンスヘッダーにAccess-Control-Allow-Originの設定を組み込めるためCORSによるブロックが発生しなくなります)

詳細

  • テキストの中にリンクを見つけたら頭にhttp://localhost:3000/api/linkcard/index?url=をつけて、リクエストをRailsのコントローラーに送るようにする。
    • http://localhost:3000/api/linkcard/index?url=リンク
  • Railsのコントローラーでparams[url]からリンクを取得し、外部サイトへリクエストを送り、レスポンスを受け取る。
# コード例
# JS → Railsコントローラー → 外部サイトの順にリクエスト
class API::LinkcardController < ApplicationController
  def index
    uri = URI.parse(params['url'])
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = uri.scheme == 'https'

    headers = { 'Content-Type' => 'application/json' }
    response = http.get(uri.path, headers)

    render json: response.body, status: :ok
  end
end

懸念点

  • 上記のやり方でリンクカードの生成には成功したのですが、リクエスト先がRailsのコントローラーになるので、リンクカードのリンク先がRailsのコントローラーになってしまいました。
  • これに関しては対処法を2つ考えています。
    • リンクカードのオプションでリンク先を設定する
    • リンクカードを生成したあとに、リンクカードのリンク先をいじる(正規表現などを使う予定です)
    • 前者は探していますが今の所方法がなさそうなので後者での対応を考えています。

ザックリこんな方針で進めています。
このまま進めて良いものかと思い質問させていただきました。

  • npmの問題点について
  • それへの対処法について

気になるところなどあればお考えをお聞きしたいです!
大丈夫そうであればこのまま進めたいと思います!


こちらの日報でこれらの問題について、メンターのyuuuさんにお話を伺っていました。
共有させていただきます🙏

https://bootcamp.fjord.jp/reports/91320

@komagata
Copy link
Member Author

komagata commented Mar 22, 2024

@mousu-a まず、この npmを使う人ほぼ全員がCROSの問題にあたるとおもいます。
そこをみんながどうしてるのかを調べるのがよさそうです。

@mousu-a
Copy link
Contributor

mousu-a commented Mar 22, 2024

@komagata

一通り調べたつもりですが、確実にYESと言えるほど理解度が高くないのでもう少し調べてみます🙏

@mousu-a
Copy link
Contributor

mousu-a commented Mar 22, 2024

@komagata

お疲れ様です。一通り調べましたがやはりサーバーサイドを間に通してリクエストをするのが良さそうだと思うのですがいかがでしょうか。以下詳細になります。

npmのCORS対策

調べましたが、やはりこのnpmでCORS関連の記述は出てこないようです。
そもそもこのnpmのドキュメントが本家のREADME以外に全くないという感じです。(READMEにも書いておらず、使っている人も見つかりませんでした😓)
コードを見てもそれらしき記述は見つかりませんでした。
どうやらnpmのコードはクライアントサイドの実装しかないようです。
それにリクエストにXHRを使っているので、クライアントサイドの方で(CORS対策について)出来ることはないという認識です。(cookieを必要としない限り)

@luckrya/markdown-it-link-to-card examples - CodeSandbox

こんなサイトがありましたが、この中では予め用意したデータを使ってリンクカードを生成していたので参考にならずじまいでした。。(外部サイトにリクエストを送っていないのでそもそも前提条件が違いました)

他のリンクカードのCORS問題はどうしてるのか?

  • プロキシサーバーを間に挟んで、クライアントサイドで完結させる
  • サーバーサイドを間に挟む

主にこの二つがありそうです。
クライアントサイドで完結させる手段としては、間にプロキシサーバーを用意し、そこにリクエストを送りプロキシサーバーから外部サイトへリクエストを送るようにすることでCORSを避ける、という手段もあるようです。
サーバーサイドに関しては上のコメントで述べている通りです。

ただ結局は、サーバーサイドかサーバーサイドの代わりになるものを用意してそれを間に挟もう、という試みなのは変わらなさそうです。

この場合Railsのコントローラーを間に挟むのは下策でしょうか?ご意見を伺いたいです🙇‍♂️

@komagata
Copy link
Member Author

@mousu-a まずパラメーターにURLを渡してどのページでも表示するというのはセキュリティ上危険なのでできないです。

それだったらリンクカードをrailsで表示するページをつくって、別のページからはIFRAMEで表示する方がいいとおもいます。
ただそれだとnpmを使う意味(便利さ)がないので、ほかのnpmを探してみるのはいかがでしょうか。

@mousu-a
Copy link
Contributor

mousu-a commented Mar 24, 2024

@komagata

質問が2つあります🙏ご意見を伺いたいです🙇‍♂️

まずパラメーターにURLを渡してどのページでも表示するというのはセキュリティ上危険なのでできないです。

  1. リクエストを受け取ったRailsのコントローラーで、「リンクかどうか?」を正規表現でチェックする、危ない記号である「<>, ”’, :;」これらをサニタイズする、などをしてもダメなのでしょうか?

ほかのnpmを探してみるのはいかがでしょうか。

  1. CORSの問題はnpmを変えてどうにかなるものでなく、ブラウザのJSから外部サイトへリクエストを送る時点で必ず発生してしまいます。
    Node.jsで外部サイトへリクエストを送ればCORSは発生しませんが、それですとbootcampの既存のMarkdownItPlugin(ブラウザ用のJS)との互換性が保てません。。(webpackerによりブラウザ用にJSファイルがコンパイルされているため、ブラウザ用のJSファイルからNode.jsで書かれたJSファイルをimportすることができません)

これらの理由から、必ずブラウザ用にコンパイルされたJSから外部サイトへリクエストを送る必要がある(そしてその場合CORSが発生する)、という認識です。
なので、ブラウザ用のJS→サーバー(Railsなど)→外部サイト の流れでリクエストを送ることは必須になるものと思っているのですがいかがでしょうか?

他のリンクカード実装例

Zennのリンクカードなどでは外部サービス(Cloud Functions)を使って外部サイトへのアクセスをしているみたいです。
Zennのカードリンクのレスポンスが遅い件

QiitaXは見つかりませんでした。。

認識が間違っているところなどあればご指摘いただけますと幸いです🙇‍♂️

@komagata
Copy link
Member Author

@mousu-a

リクエストを受け取ったRailsのコントローラーで、「リンクかどうか?」を正規表現でチェックする、危ない記号である「<>, ”’, :;」これらをサニタイズする、などをしてもダメなのでしょうか?

はい。
同じサイト内だったらいいですが、外部のサイトをそのまま出すのは相当な理由がない限りNGです。

CORSの問題はnpmを変えてどうにかなるものでなく、ブラウザのJSから外部サイトへリクエストを送る時点で必ず発生してしまいます。
Node.jsで外部サイトへリクエストを送ればCORSは発生しませんが、それですとbootcampの既存のMarkdownItPlugin(ブラウザ用のJS)との互換性が保てません。。(webpackerによりブラウザ用にJSファイルがコンパイルされているため、ブラウザ用のJSファイルからNode.jsで書かれたJSファイルをimportすることができません)

同じような実装の似た他のnpmを使ってほしいと思っているわけではないです。

QiitaやXは見つかりませんでした。。

なるほどです。

Railsのコントローラーを挟む場合の実装方法は一例考えがありますが、勉強になるとおもうので @mousu-a さんもサイトにリンクカード的なものを追加したい場合、どのような実装がいいのか考えてみてください。

@komagata
Copy link
Member Author

@mousu-a すみません、ちょっとややこしいですよね。
仕様を作ってみたのでこちらで進めていただければありがたいです。仕様に不明点などありましたらお気軽におっしゃっていただければと思います。

リンクカード · fjordllc/bootcamp Wiki

@machida リンクカードのHTMLや表示について問題点あればおっしゃっていただければとおもいます~。

@mousu-a
Copy link
Contributor

mousu-a commented May 12, 2024

@komagata
うおお〜😭
すみません、お忙しい中ありがとうございます!

仕様に不明点などありましたらお気軽におっしゃっていただければと思います。

ありがとうございます!わからないところあれば質問させていただきます🙇‍♂️

@mousu-a
Copy link
Contributor

mousu-a commented May 12, 2024

@komagata

お疲れ様です。すみません、早速ですが質問が2つあります。
リンクカード実装の方向性について確認させていただきたいです🙏

質問1

リンクカードの実装は、テキスト中に[TITLE](URL)があれば該当箇所をリンクカードのHTMLに置換する、という形で宜しいのでしょうか?

適用前:

テキストテキスト
[TITLE](URL)
テキストテキスト

適用後:

<p>テキストテキスト</p>
<div class="link-card">
  <div class="link-card__title">
    <a href="URL" target="_blank">TITLE</a>
  </div>
  <div class="link-card__description">DESCRIPTION</div>
  <div class="link-card__favicon"><img src="FAVICON" /></div>
  <div class="link-card__site-title">
    <a href="SITE URL" target="_blank">SITE TITLE</a>
  </div>
  <div class="link-card__image"><img src="IMAGE" /></div>
</div>
<p>テキストテキスト</p>

質問2

リンクカードwikiにて、

markdownでの記法はFBCで使っているmarkdown-itのプラグインとして実装する。

とありますが、md.use(Plugin)のような形で使えるよう実装してほしい、ということでしょうか?
それともマークダウンを適用する流れで一緒に適用出来るように実装してほしい、ということでしょうか?
例:

# markdown-initializer.js

	# md.use(Plugin)の場合
	
	md.use(MarkdownItEmoji)


	# マークダウンを適用する流れで一緒に適用する場合(例として既存の実装をピックアップしました🙏)
	
	MarkdownItTaskListsInitializer.initialize()

よろしくお願いいたします🙇‍♂️

@komagata
Copy link
Member Author

@mousu-a

質問1

NOです。

下記の「リンクカード記法」の部分を参照してください。

https://github.com/fjordllc/bootcamp/wiki/%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%AB%E3%83%BC%E3%83%89#%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%AB%E3%83%BC%E3%83%89%E8%A1%A8%E7%A4%BA

質問2

markdown-itのプラグインとは何なのか、markdown-itの公式サイトなどを参考に調べてみてください。

@mousu-a
Copy link
Contributor

mousu-a commented May 22, 2024

ミーティングを経てのログ

  • 前記の質問の意味はmarkdown-itを勉強していけば理解できると思う
  • 判断に困ったらZENNのリンクカードを参考に
  • 既存のmarkdownの実装(プルリク)を参考にしてみよう

@mousu-a
Copy link
Contributor

mousu-a commented Jun 20, 2024

@komagata
お疲れ様です!
すみません、実装の仕方について確認させていただきたいです。
リンクカードの実装についてですが、このような認識で合っていますでしょうか?

リンクカード:考えている実装

// markdown-initializer.js
import MarkdownItLinkcard from 'markdown-it-linkcard'
~
md.use(MarkdownItLinkcard)
~

// markdown-it-linkcard.js
export default  (md) => {
	~リンクカードの実装~
}

bootcamp内での既存の実装例

// markdown-initializer.js
import MarkDownItContainerDetails from 'markdown-it-container-details'
~
md.use(MarkDownItContainerDetails)
~

// markdown-it-container-details.js
export default (md) => {
  ~プラグインの実装~
}

@komagata
Copy link
Member Author

komagata commented Jun 23, 2024

@mousu-a linkはcontainer(block要素)じゃなくてinline要素なので違うと思います。

import MarkdownItLinkcard from 'markdown-it-linkcard'

これは下記がいいとおもいます。

import MarkdownItLinkCard from 'markdown-it-link-card'

別の点で、これも、

import MarkdownItContainerDetails from 'markdown-it-container-details'

こちらの間違いかなとおもいます。

@mousu-a
Copy link
Contributor

mousu-a commented Jul 9, 2024

@komagata
質問させていただきたいです。
リンクカードの生成条件についての確認になります。

①1行に@[TITLE](URL)のみ存在する場合(記法の前後に文字が存在しない)

aaa
@[TITLE](URL)
aaa

@[TITLE](URL)の前後に文字がある場合(文の中に記法が存在する場合)

aaa @[TITLE](URL) aaa

リンクカード生成にあたり、この2つが状況として考えられると思います。

自分の認識としては、
①の場合のみリンクカードを生成する。
②の場合は"表示できない場合"として扱い、普通のリンクとして表示する。
という風に考えているのですがいかがでしょうか。

komagataさんのご意見を伺いたいです🙇‍♂️

捕捉情報

ZENNでは1行にURLのみ存在する場合(①の場合)のみリンクカードを生成するという形になっています。

@mousu-a
Copy link
Contributor

mousu-a commented Jul 9, 2024

ログ 上記質問に対するkomagataさんの回答

①1行に@[title](url)のみ存在する場合
@[title](url)の前後に文字がある場合
どちらの場合でもリンクカードを作成するように実装する

@mousu-a
Copy link
Contributor

mousu-a commented Jul 17, 2024

MTGログ 下記質問に対するkomagataさんの回答

質問1

リンクカードWikiの「表示できない場合」とは具体的に何を指すのか?

  • fetchが失敗したとき(おそらく[URL]が存在しないサイトにつながっている場合)?
  • fetchしたけれど相手サイトがOGPを設定しておらずmetadataが取得出来なかったとき?

回答

  • 他(ZENN)のリンクカード実装に合わせる
    • ZENNでは存在しないサイトでもリンクカードを生成する。
      (ただしクリックしてもサイトは存在しないためアクセスはできない)

捕捉

上記のいずれの状況もユーザーにとってハイコンテキストなため、ユーザーからは見えないのが望ましい。


質問2

マークダウン記法がネストしている場合はリンクカードは生成されるのか?

:::details ネタバレ注意!
@TITLE
:::

回答

マークダウン記法がネストしている状態でもリンクカードは生成する。

@mousu-a
Copy link
Contributor

mousu-a commented Aug 8, 2024

@komagata

お疲れ様です。
質問があります!2つあります。
よろしくお願いします🙏

1つ目

メタデータAPIのこちらのレスポンスですが、これらのkeyはogpのproperty値を参考にしているのでしょうか?

{
  site_title: "Moeny Forward Developers Blog",
  site_url: "https://xxx.com",
  favicon: "https://xxx.com/favicon.ico",
  url: "https://xxx.com/xxxx",
  title: "ChatGPTのAPIがオープンになったので(略)",
  description: "xxxxxxx",
  image: "https://xxx.com/xxx.png"
}

補足情報

OGP

<meta property="og:url" content=" ページの URL" />
<meta property="og:type" content=" ページの種類" />
<meta property="og:title" content=" ページの タイトル" />
<meta property="og:description" content=" ページの説明文" />
<meta property="og:site_name" content="サイト名" />
<meta property="og:image" content=" サムネイル画像の URL" />

2つ目

もしそうであれば、差し支えなければsite_titlesite_nameに変更させていただきたいのですがどうでしょうか。

補足情報

というのも、レスポンスのkeyとogpのproperty値がほとんど一致しているためそれに即した実装を考えているのですがsite_titleだけ違うためちょっと引っかかってしまうな、というところで質問いたしました。

まだ未完成ではありますが、このような実装を考えています。

# リクエスト
uri = Addressable::URI.parse(url).normalize
res = Net::HTTP.get_response(uri)

# nokogiriでdoc化
doc = Nokogiri::HTML(res.body)
# OGPのmetatagを抽出
og_meta_tags = doc.css('meta[property^="og:"]')

# レスポンスを生成
js_response = { site_title: '', site_url: '', favicon: '', url: '', title: '', description: '', image: '' }
og_meta_tags.each do |meta|
  js_response.each do |key, _value|
    # レスポンスのkeyと、metadataのpropertyが一致したら contentの値をvalueにセット
    js_response[key] = meta['content'] if meta['property'] == "og:#{key}"
  end
end

@komagata
Copy link
Member Author

komagata commented Aug 21, 2024

@mousu-a 厳密な仕様って感じではないので、やりやすいように変えてしまって大丈夫です〜

@komagata komagata moved this to 作業中 in bootcamp Aug 21, 2024
@mousu-a
Copy link
Contributor

mousu-a commented Sep 4, 2024

メモ

TweetのURLだけ特別仕様として実装する

@mousu-a
Copy link
Contributor

mousu-a commented Sep 7, 2024

@machida
お疲れ様です!先日のMTGでお話していたTweetのリンクカード(埋め込みTweet)のデザインについてお聞きしたいです。
お手すきの際にご確認をお願いいたします🙇‍♂️

質問:Tweetのリンクカード(埋め込みTweet)だけ特別仕様とするかどうか?

現状Tweetのリンクカードだけ、このようにTwitterのoEmbedAPIを使用しデザインが特別仕様となっています。
Tweetのリンクカードも他のリンクカードとデザインを統一する形にした方がいいでしょうか?

  • Tweetのリンクカード(埋め込みTweet)(oEmbedAPIによりデザイン適用済み)
Pasted Graphic 1

説明:Tweetのリンクカード(埋め込みTweet)の実装方法

oEmbedAPIを通してTweetURLにリクエストを送ることで、このようなデータを取得することができます。

  • レスポンスのボディ
{"url":"https:\/\/twitter.com\/mousuFBC\/status\/1799277839138926685","author_name":"mousu","author_url":"https:\/\/twitter.com\/mousuFBC","html":"\u003Cblockquote class=\"twitter-tweet\"\u003E\u003Cp lang=\"ja\" dir=\"ltr\"\u003EGem ViewComponentを勉強中!\u003Cbr\u003Eまだフワフワした全体像が掴めただけで何もわかっていない\uD83D\uDE05\u003Cbr\u003E焦らずやっていくぞ\uD83D\uDCAA\u003C\/p\u003E&mdash; mousu (@mousuFBC) \u003Ca href=\"https:\/\/twitter.com\/mousuFBC\/status\/1799277839138926685?ref_src=twsrc%5Etfw\"\u003EJune 8, 2024\u003C\/a\u003E\u003C\/blockquote\u003E\n\u003Cscript async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"\u003E\u003C\/script\u003E\n\n","width":550,"height":null,"type":"rich","cache_age":"3153600000","provider_name":"Twitter","provider_url":"https:\/\/twitter.com","version":"1.0"}
  • レスポンスのボディからHTML部分だけを抽出したもの
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Gem ViewComponentを勉強中!<br>まだフワフワした全体像が掴めただけで何もわかっていない😅<br>焦らずやっていくぞ💪</p>&mdash; mousu (@mousuFBC) <a href="https://twitter.com/mousuFBC/status/1799277839138926685?ref_src=twsrc%5Etfw">June 8, 2024</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

↑のHTML中のscriptタグを実行することで、blockquoteタグがiframeタグに置き代わり、埋め込みツイートのデザインが適用されています。

懸念点

Tweetのリンクカードも他のリンクカードとデザインを統一する場合、リンクカードのmetadataが必要となります。

{
  site_name: "Moeny Forward Developers Blog",
  site_url: "https://xxx.com",
  favicon: "https://xxx.com/favicon.ico",
  url: "https://xxx.com/xxxx",
  title: "ChatGPTのAPIがオープンになったので(略)",
  description: "xxxxxxx",
  image: "https://xxx.com/xxx.png"
}

前述したAPIを介したリクエストでは取得出来るmetadataが少なく、リンクカードとして成立させにくい、という問題があります。
具体的にはfavicon, site_name, title, imageが足りていません。ただ他のもので代替することはできそうです。

  • faviconhttps://publish.twitter.com/oembed?url=https://twitter.com に追加でリクエストすれば取って来れそうです。
  • site_name#{author_name}さんのTweetのようにすれば良さそうです。
  • titleはdescriptionと同じで良さそうです。
  • image(Tweetしたユーザーのicon)はまだ取れる方法を見つけられていません😢

ZENNでの実装

ZENNではoEmbedAPIを使いTweetのリンクカード(埋め込みTweet)を特別仕様としています。
Pasted Graphic

以上のことを踏まえて、Tweetのリンクカード(埋め込みTweet)も他のリンクカードとデザインを統一させるかどうかをお聞きしたいです🙏

@machida
Copy link
Member

machida commented Sep 11, 2024

@mousu-a

Twitterのデザインは別にし、TwitterはTwitterに適した見た目にしたいと思います。もし、Twitterは何もしなかったら勝手にデザインが入るようになっているのであれば、それを確認したいです。

リンクカードのデザインは僕の方でやります。

確認、デザインがしやすいように、リンクカード、Twitterを入れた投稿をfixtureに入れておいてください。それをcommitしたら、メンションをお願いします。実際に手元でコードを見て確認します。

よろしくお願いします🙏

@mousu-a
Copy link
Contributor

mousu-a commented Sep 11, 2024

@machida
まだテストやリファクタリングは出来ていないのですが、macihdaさんの確認のために一度commit、プルリクを作ってお見せした方がいいでしょうか?
(実装に変更があれば手戻りが発生してしまうのかなと思った次第です)

@machida
Copy link
Member

machida commented Sep 11, 2024

@mousu-a キリのいいところで大丈夫ですー
どこをキリのいいところとするかで迷ったら@komagataさんと相談してください🙏

@mousu-a
Copy link
Contributor

mousu-a commented Sep 16, 2024

@komagata

お疲れ様です。
1つ質問をさせていただきたいです。

質問

リンクカード記法の[TITLE](URL)の値、

@[TITLE](URL)

metadata(レスポンス)のtitleurlの値

{
  site_name: "Moeny Forward Developers Blog",
  site_url: "https://xxx.com",
  favicon: "https://xxx.com/favicon.ico",
  url: "https://xxx.com/xxxx",
  title: "ChatGPTのAPIがオープンになったので(略)",
  description: "xxxxxxx",
  image: "https://xxx.com/xxx.png"
}

この2つは同じものと考えてもいいのでしょうか?

補足

同じものなのであれば、今回実装するAPIコントローラーのレスポンスは上記wikiの通り用意し、今回は(リンクカードの実装では)レスポンスのtitleurlを使わずにリンクカード記法のTITLEURLを使う、という風な実装を考えています。

というのも、存在しないサイトのリンクカードを生成する時、リンクカード記法のTITLEURLのみをmetadataとして用いてリンクカードを生成したいからです。
(存在しないサイトのリンクカードを生成する場合、空のレスポンスが返るため)

@mousu-a
Copy link
Contributor

mousu-a commented Sep 18, 2024

📝
リンクカードの仕様を@[TITLE](URL) → @[card](URL)という記法に変更。リンクカードのtitleはmetadataAPIのレスポンスのtitleを使う。

@mousu-a
Copy link
Contributor

mousu-a commented Oct 26, 2024

@komagata
すみません、こちらで質問させていただいたことと同じなのですが、具体的な内容がわからないメモの残し方をしてしまい、リンクカードの具体的なイメージについてもう一度お聞きしたいです🙇

質問

@[card](url)の前後に文字がある場合でもリンクカードを生成するという仕様になっていますが、具体的なイメージとしてはどちらでしたでしょうか?

例1

aaa リンクカード記法 bbb
↓
aaa
リンクカード
bbb

例2

aaa リンクカード記法 bbb
↓
リンクカード

補足説明

Markdown-it のプラグインとして実装する際に、inlineruleとして実装すると例1のようになります。
blockruleとして実装すると例2のようになります。

個人的には例1(inlineruleとしてプラグインを実装する)が正しい形なのかなという認識です。


お手間をとらせてしまい申し訳ありません🙇
よろしくお願いいたします。

@machida
Copy link
Member

machida commented Oct 29, 2024

@mousu-a @komagata

仕様を変更させてください。

inlineで @[card](URL) がある場合、つまり、@[card](URL) この前後に文字がある場合はリンクカードにする、という仕様は無しにしてください。

理由は、inline の場合、p や li の中にリンクカードが生成されるのは、マークアップ的にinvaridなHTMLになるからです。

あああ @[card](URL) あああ

の場合は、

<p>あああ</p>
[リンクカード]
<p>あああ</p>

という表示になるなら HTML は validにはなるので、そこまでしてあげたらユーザーには優しいですが、そもそも変換前の Markdown のコードの時点で invalid な HTML であるため、このように変更してあげる気遣いは不要です。

あああ @[card](URL) あああ

このコードの場合、現在のコード(machidaのPR)では以下のように出力されます。

<p>あああ @<a href="URL">card</a> あああ</p>

このままでいいと思います。
Zennもこのようになります。


あああ
@[card](URL)
あああ

このコードの場合は、

<p>あああ
<br>
[リンクカード]
<br>
あああ</p>

というHTMLに変換されるのも、invalidなHTMLなのでNGです。

<p>あああ</p>
[リンクカード]
<p>あああ</p>

このように変換されると、 HTML は valid にはなるので、そこまでしてあげたらユーザーには優しいですが、そもそも変換前の Markdown のコードの時点で invalid な HTML であるため、このように変更してあげなくてもいいとは思います。

ただ、Zennではこのように変換されるようにはなっていました(FBCがそこまでやってあげなくてもいいとは思いますが、簡単にできるならやってあげたい)。

現在のコード(machidaのPR)では、

<p>あああ
<br>
@<a href="URL">card</a>
<br>
あああ</p>

このように表示されます。


少し別の話になりますが、
現在の mousu さんのコードは、

あああ

@[card](URL)

あああ

の場合、

<p>あああ</p>
<p>[リンクカード]</p>
<p>あああ</p>

このように出力されます。
p の中に[リンクカード]があるので、これも invalid な HTML です。

僕の PR で[リンクカード]を囲うpを削除するコードを含めています。
以下のように出力されます。

<p>あああ</p>
[リンクカード]
<p>あああ</p>

機能を修正する場合は、差分が出てマージが難しくなるので
#8143
こちらをマージした上で作業をお願いします。

Copy link

github-actions bot commented Jan 6, 2025

このissue|PRは60日間更新がないため7日後にcloseします。closeしたくない場合はstaleラベルを外してください。

@github-actions github-actions bot added the stale label Jan 6, 2025
@mousu-a mousu-a removed the stale label Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 作業中
Development

No branches or pull requests

3 participants