Made a service for Deno Deploy to create a self-introduction page
Tags: deno, denodeploy
Published: 2021-09-01 06:06:11

As the number of pages you have accounts for increases, such as DEV, Twitter, GitHub, etc., it becomes difficult to display links to other services on each service.
In such a case, it is easier to manage if you create a "link list" profile page somewhere and post links to it.

There is an existing service, Linktree.

https://linktr.ee/

However, I personally don't want to manage only links.
I thought it would be nice to be able to display profile items as bullet points as well.

This is why I made it myself, while also learning Deno Deploy.
I've made it available as a service for others to use, so I'll introduce it here.

## Denote

The name is **Denote.**

This is demo: https://denote.deno.dev/denote

The page is like this.

![denote](https://storage.googleapis.com/zenn-user-upload/2f59628847d4d9881ab0417b.png)

The overall balance of the page (the list of items below the icons) is based on Linktree, but the separation of items within the page and the rain are original.
After all, Deno is all about rain at night!

The profile page of kawarimidoll is here: https://denote.deno.dev/kawarimidoll


## API

### Registration & Update
`POST https://denote.deno.dev/`

Instead of separating `POST` and `PUT` for registration and update, I decided to use the same one.
This is because I thought it would be more convenient to automate the process with GitHub Actions, etc. (as described later).

#### Parameters
`name` Page name
`token` Token (to be referenced when updating or deleting the page, cannot be changed)
`config` JSON of settings for list items, main image, etc.

Any token can be used when registering a new page, but when updating, an error will occur if the name and token do not match.

### Delete
`DELETE https://denote.deno.dev/`

#### Parameters
`name` Page name
`token` Token (set when registering)

### Display
`GET https://denote.deno.dev/[name]`

## CLI
You can register, update and delete by throwing a request to the above API using `curl`, etc. However, as the number of configuration items increases, a long JSON file will be placed in the config, making it difficult to operate.

```
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
```

So I created a script that parses a local JSON/YAML file and makes a request to the endpoint.
It can be installed as a CLI tool by `deno install`.

### Usage
https://deno.land/x/denote

#### Install
```
❯ deno install --allow-read --allow-write --allow-net --no-check --force https://deno.land/x/denote/cli/denote.ts
```

#### Registration and update
Use `denote register` to reflect the configuration file to Denote.
The `name` and `token` options are required.
It is possible to specify a file not only your local, but also published on the web due to Deno specifications.
In other words, you can put the configuration in Gist and run `denote register` locally to publish it.

```
❯ denote register ./config.yml --name my-name --token my-token
```

#### Delete
Deletes the page published by denote unregister.
The `name` and `token` options are required.

```
❯ denote unregister --name my-name --token my-token
```

#### Checking on a local server
You can set up a local server with `denote serve`, in case you want to check the display before publishing.

```
❯ denote serve ./config.yml
```

#### Auto run
We can run it without installation by hitting the public URL directly with `deno run`.
So if you run `denote register` in GitHub Actions, you can update Denote automatically.

```yaml
# .github/workflows/denote_profile.yml
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 }}'
```

When doing this, it was difficult to split between new registration and renewal, so I combined Denote's registration and renewal APIs together.

It's running in the kawarimidoll profile repository.

https://github.com/kawarimidoll/kawarimidoll/blob/master/.github/workflows/denote_profile.yml

## Configuration file
The configuration file can be written in JSON or YAML.

There is `example.yml` in the repository (actually, `denote init` just downloads this).

https://github.com/kawarimidoll/denote/blob/main/example.yml

### Required keys
The key "list" is required at the top level.
It is a bit complicated under that, so I will explain it in `example.yml`.

```yaml
# 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
```

- A list has a key of any name under it.
  - The children of this `list` (`id-1` and `id-2` above) are treated as a group.
    - This key will be treated as the ID of the link in the page.
- The group has keys named `icon` and `items`.
  - The `icon` is a string with the name `[iconset-name]/[icon-name]`.
    - Only icons listed in the [icongram](https://icongr.am) can be used.
  - `items` is an array of list items.
- A list item can have the keys `icon`, `text`, and `link`.
  - All three of these are optional.
  - `icon` is an icon that can be displayed in icongram as well as in the group.
  - `text` is the text to be displayed in the list.
  - `link` is the URL of the link destination. If `text` is present, it will be displayed, otherwise the `link` string will be displayed.

### Optional keys
The following keys are optional.

#### name
The name to be displayed at the top of the page.
If omitted, the `name` option set at the time of registration (i.e., the one that goes into `https://denote.deno.dev[name]` when displayed) will be used.
It will also be used as the page name in the HTML file in the form `name | Denote`.

#### image
The URL of the main image.
If omitted, no image is used.
This is also reflected in the OGP setting `og:image`, so it will be displayed in an embedded link.

#### favicon
The URL of the favicon image.
If omitted, the Denote logo will be used.

#### description
The description or comment to be displayed below the name above.
If omitted, no comment will be used.
This is also reflected in the OGP setting `og:description`, so it will be displayed in an embedded link.

#### twitter
This is the twitter user name used in the OGP setting `twitter:site`.
If omitted, it will simply be skipped.

## Closure

At first it was just a simple white background.
I wanted to make it rain at night since it was a deno, so I did some research and made some adjustments.
I'm happy with the result, because I think I was able to give it a nice look.

https://twitter.com/KawarimiDoll/status/1422858096234274816

This is a translation of the following article.
Please leave comments if there are any mistakes in the translation.

https://zenn.dev/kawarimidoll/articles/e00d79b97042ee