tateisu氏の Hexoの記事とLemmyのコメント欄を連動させた に触発されて。

2021/02/17 13:30 拡張タグの編集を書き換えました。自動投稿に対応させるため。
2021/02/17 13:30 ブラウザ側スクリプトを書き換えました。上記書き換えに伴いトリガー方式が変わったため。

拡張タグの編集

tateisu/lemmyCommentTag.js

ほとんどこのままですが、自分は記事ごとのassetを作っていないので、アセットディレクトリが無ければ作成するという処理を入れています。

あと、communityIdにparseIntを入れた。これは自分のミスでconfig用のJSONのcommunityIdにstring"3"を指定していてエラったので。

そして、lemmyConfigは見せられないので、Netlifyでビルドするとき(JSONが見つからなかったとき)は環境変数LEMMY_COMMENTにJSONそのまま入れて対応している。

Lemmyサイトからデータを取得するプロキシAPI

CORSは確かに存在した。

ここではAWS Lambdaを使ってAPIを建ててみようと思う。完成物はこちらである。

https://0zd8pgyq88.execute-api.ap-northeast-1.amazonaws.com/default/lemmyProxy?domain=${domain}&id=${id}

最後のdomainとidは置換してほしいのと、ほとんどタダとは言え、常識を超えてアクセスするようなことはやめてほしい。

おなじみaxiosをLayersとして導入したが、それ以外はいたってシンプルなコードである。ただのプロキシなので。

1
2
3
4
5
6
7
8
9
10
11
const axios = require('/opt/lambda/nodejs/node_modules/axios');
exports.handler = async (event) => {
const query = event.queryStringParameters;
let domain = query.domain
let id = query.id
const data = await axios.get(`https://${domain}/api/v2/post?id=${id}`)
const json = data.data
// TODO implement
const response = json;
return response;
};

いちいちaxiosをzip圧縮してLambdaにあげるってそんな非効率なことあるか…

そして、トリガーとしてAPI GatewayをHTTPで作成したら、以上のようなURLが発行されると思う。

ブラウザ側スクリプト

1
2
<script src="/hexo-comment-lemmy.js"></script>
<link rel="stylesheet" href="/hexo-comment-lemmy.css">

をthemes/{themeName}/layout/_partial/head.ejsの最下部に書いた。Markdown対応は後ほどやる。はず。

そして、jsとcssをsoueceの直下に置く。

hexo-comment-lemmy.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

async function lemmyComment(domain, id) {
const dom = document.getElementById('lemmyComment')
const url = `https://0zd8pgyq88.execute-api.ap-northeast-1.amazonaws.com/default/lemmyProxy?domain=${domain}&id=${id}`
const promise = await fetch(url)
const json = await promise.json()
let html = `<div class="lemmyComment-comments"><h3>Comments from <a href="https://${domain}" target="_blank">${domain}</a></h3>`
const { comments } = json
for (let comment of comments) {
html = html + `
<div class="lemmyComment-comment">
<p class="lemmyComment-user">
<img src="${comment.creator.avatar}" class="lemmyComment-avatar">
<a href="${comment.creator.actor_id}" target="_blank">${escapeHtml(comment.creator.name)}</a>
</p>
<p class="lemmyComment-content">${escapeHtml(comment.comment.content)}</p>
<a href="https://${domain}/post/${comment.comment.post_id}/comment/${comment.comment.id}" target="_blank" class="lemmyComment-timestamp">${comment.comment.published}</a>
</div>
`
}
dom.innerHTML = html + '</div>'
}
function escapeHtml(str) {
str = str.replace(/&/g, '&amp;');
str = str.replace(/>/g, '&gt;');
str = str.replace(/"/g, '&quot;');
str = str.replace(/'/g, '&#x27;');
str = str.replace(/`/g, '&#x60;');
return str;
}

一応HTMLはエスケープしておいた。

hexo-comment-lemmy.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.lemmyComment-avatar {
height: 1.7rem
}
.lemmyComment-comment {
border: 1px solid;
border-radius: 5px;
padding: 5px;
}
.lemmyComment-comment p {
margin: 0
}
.lemmyComment-comments {
margin-top: 100px;
}

とりあえずこうした。

というわけで、ここにタグを書いてみるので試してみてほしい。