Deno Deployに自己紹介ページを作るサービスを作った
本記事はtoranoana.deno #0にて発表したものです。
Zenn、Twitter、GitHubなど、アカウントを持っているページが増えてくると、各サービスに他サービスのリンクを表示するのが大変になってきます。
こういう場合は、どこかに「リンク一覧」のプロフィールページを作り、そこへのリンクを貼るようにすれば管理が楽です。
既存のサービスとして、Linktreeというものがあります。
ただ、個人的にはリンクだけを管理したいわけではありません。
普通にプロフィール項目も箇条書きのように表示できたら良いじゃないかな、と思いました。
ということでDeno Deployの勉強も兼ねて自作しました。
サービスとして他の人も使える形で公開したので紹介します。
Denote
Denote -A minimal profile page generator for Deno Deploy- です。
"Denote"というのはDeno x Note…というのも意識していますが、そもそもdenote
という動詞があるのです。
by weblio
こちらがデモページです。
こんな感じになります。
やっぱりDenoといったら夜の雨だよな〜〜!
全体のバランス(アイコンの下に項目のリストがある構成)はLinktreeを踏襲しましたが、ページ内で項目が分かれていたり、雨が降っていたりするところはオリジナルです。
kawarimidollのプロフィールページはこちら。
OGP設定もしているので、Zenn等に埋め込んだときに良い感じに情報が表示されます。
API
登録・更新
エンドポイント
POST https://denote.deno.dev/
登録と更新をPOST/PUT
で分けず、同一のものとしました。
これは(後述しますが)GitHub Actions等で自動化する際にそちらのほうが都合が良いと考えたためです。
パラメータ
- name ページ名
- token トークン(更新・削除の際に参照される 変更不可)
- config リスト項目やメイン画像などの設定のJSON
新規登録の際は任意のトークンを使用できますが、更新の際は名前・トークンが一致していないとエラーになります。
削除
エンドポイント
DELETE https://denote.deno.dev/
パラメータ
- name ページ名
- token トークン(登録時に設定したもの)
表示
エンドポイント
GET https://denote.deno.dev/[name]
CLI
上記のAPIにcurl
などでリクエストを投げれば登録等をできるのですが、設定項目が増えるとconfig
に長大なJSONが載ることになり、運用が難しくなります。
curl -X POST -d '{"name":"my-name","token":"my-token","config":{"list":{"id-1":{"icon":"fontawesome/font-awesome","items":[{"icon":"jam/info","text":"this is a text with an icon"},{"text":"this is a just text"},{"icon":"octicons/octoface","text":"this is a link to GitHub","link":"https://github.com"},{"text":"this is a link to Twitter","link":"https://twitter.com"},{"link":"https://gitlab.com"}]},"id-2":{"icon":"feather/anchor","items":[{"icon":"clarity/block","text":"this is the second block"},{"icon":"simple/deno"}]}}}}' https://denote.deno.dev
設定項目はテキストベースで管理して、それをDenoteに反映させたいと思いました。
そこで、ローカルのJSON/YAMLファイルをパースして、https://denote.deno.dev
へのリクエストを行うスクリプトを作りました。
deno install
によってCLIツールとしてインストールすることができます。
つかいかた
インストール
下記のコードでdenote
という名前でインストールできます。
名前を変えたい場合は--name hogehoge
でリネーム可能です。
❯ deno install --allow-read --allow-write --allow-net --no-check --force https://deno.land/x/denote/cli/denote.ts
初期設定の生成
denote init
で最小限の設定ファイルを生成します。
ファイルはJSONまたはYAMLですが、YAMLのほうには解説コメントが載ります。
❯ denote init ./config.yml
登録・更新
denote register
で設定ファイルをDenoteへ反映します。
--name
および--token
オプションは必須です。
なお、「設定ファイルをローカルで管理する」と書いていましたが、Denoの仕様上、Web上に公開されているファイルでも指定可能です。
つまり設定をGistに置いて、ローカルからdenote register
を実行して公開するということもできます[1]。
❯ denote register ./config.yml --name my-name --token my-token
削除
denote unregister
で公開されているページを削除します。
--name
および--token
オプションは必須です。
❯ denote unregister --name my-name --token my-token
ローカルサーバーでの確認
denote serve
でローカルサーバーを立てられます。
公開前に表示を確認したい場合にどうぞ。
❯ denote serve ./config.yml
自動実行
CLIを作ったと書きましたが、deno run
で公開URLを直接叩けばインストール不要で実行可能です。
つまりGitHub Actionsでdenote register
を動かせば、自動でDenoteを更新できます。
name: Denote profile
on:
push:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v2
- uses: denoland/setup-deno@v1
- run: >
deno run --allow-read --allow-net --no-check
https://deno.land/x/denote/cli/denote.ts register ./denote.yml
--name kawarimidoll --token '${{ secrets.DENOTE_TOKEN }}'
これをやる際に、新規登録と更新で分岐するのが難しいため、Denoteの登録・更新APIを一緒にしてしまったのでした。
kawarimidollのプロフィールリポジトリで動いています。
設定ファイル
設定ファイルはJSONまたはYAMLで記述します[2]。
リポジトリにexample.yml
を置いています(実はdenote init
はこれをダウンロードしているだけです)。
必須項目
トップレベルにlist
というキーが必須です。
その配下がちょっと複雑なので、example.yml
で説明します。
list:
id-1:
icon: fontawesome/font-awesome
items:
- icon: jam/info
text: this is a text with an icon
- text: this is a just text
- icon: octicons/octoface
text: this is a link to GitHub
link: https://github.com
- text: this is a link to Twitter
link: https://twitter.com
- link: https://gitlab.com
id-2:
icon: feather/anchor
items:
- icon: clarity/block
text: this is the second block
- icon: simple/deno
-
list
は配下に任意の名前のキーを持ちます。- この
list
の子(上記のid-1
とid-2
)がグループとして扱われます。- このキーがページ内リンクのIDとして扱われます。
- この
- グループは
icon
とitems
というキーを持ちます。-
icon
は[iconset-name]/[icon-name]
という名前の文字列です。-
後述する
icongram
というサービスに載っているアイコンのみ使用できます。
-
後述する
-
items
はリスト項目の配列です。
-
- リスト項目は
icon
とtext
とlink
というキーを持つことができます。- これらは3つとも任意です。
-
icon
はグループのものと同じく、icongramで表示できるアイコンです。 -
text
はリストに表示されるテキストです。 -
link
はリンク先のURLです。text
があればそれが、なければlink
の文字列が表示されたリンクとなります。
任意項目
以下のキーは任意です。
name
ページのトップに表示される名前です。
省略した場合は、登録の際にname
オプションに設定したもの(つまり、表示の際のhttps://denote.deno.dev[name]
に入るもの)が使用されます。
また、HTMLファイルのページ名として、name | Denote
の形で使用されます。
image
メイン画像のURLです。
省略した場合は画像なしになります。
OGP設定のog:image
にも反映されるため、埋め込みリンクで表示されます。
favicon
favicon画像のURLです。
省略した場合はDenoteのロゴが使われます。
description
上記name
の下に表示される説明というかコメントです。
省略した場合はコメントなしになります。
OGP設定のog:description
にも反映されるため、埋め込みリンクで表示されます。
OGP設定のtwitter:site
で使用されるtwitterユーザー名です[3]。
省略した場合は単にスキップされます。
技術情報
データの保存
DynamoDBに受け取ったデータを保存しています。
これは公式のチュートリアルをかなり参考にしました。
ルーティングにsiftを使っているのもチュートリアルそのままです。
ただし、受け取ったデータは全てをそのまま保存するのではなく、token
はHash化、config
はgzip圧縮しています。
自作ライブラリでタグを生成
siftでJSX/TSXを書けるのですが、HTMLタグペアを書きたくない…という思いが強いので、自作のライブラリを使用しています。
以下の記事で公開したものです。
github-contributions-apiで使うために作ったものですが、結構気に入っています。
icongramからアイコンを表示
アイコンの表示にはicongramというサービスを使っています。
- 👍 メリット
- 共通の表記(
https://icongr.am/[icon-set]/[icon-name].svg
)で複数のサービスのアイコンを呼び出せる - 各種サービスの巨大なCSSを読み込むことなく必要なアイコンだけを表示できる
- 共通の表記(
- 👎 デメリット
- 最新のアイコンが反映されていない
- Herokuにホスティングされており表示にラグが出る場合あり
おわりに
じつは最初のアイデアから2点の方針転換がありました。
ひとつはサーバーの扱いです。
最初はkt3k/deploy_dirを使い、設定項目も全て含めた単一のサーバーファイルを生成していました。
これだと表示は高速なのですが、生成されるserver.js
を都度コミットしなければならない構成でした。
自分専用ならそれでも良いのですが、https://denote.deno.dev/xxx
のパスで色んな人がアクセスできるようにしたほうが面白いかな?と考えて方針転換しました。
結果的にDynamoDBの勉強もすることができてよかったです。
また、見た目も最初は白背景のシンプルな感じでした。
せっかくDenoなので夜にして雨を降らせたいな〜と思っていろいろ調べて調整しました。
結果的に良い感じの見た目に仕上げることができたと思うので満足です。
ちょっとまだイケてない部分があるかもしれませんが、是非(使用|Star|フォロー|フィードバック)してもらえると非常に嬉しいです。
今後もDenoでいろいろ作っていきますのでよろしくおねがいします🥳
Discussion