Teruhiro Komaki's Diary (Archive)

2024年03月

author
Teruhiro Komaki komaki.dev
2024年 03月 31日 日曜日
16時00分

FileMakerなどのインストーラをダウンロードする速度が遅い場合の対応

FileMakerのインストーラをダウンロードする速度が遅かったので、どうにか方法を考えました。

GCPの無料枠の対象になるように、インスタンス(e2-micro/オレゴン:us-west1)を立てて、そのインスタンスから#curlでインストーラを取得するのはどうかと。

いまいち原因がわかりませんが、自宅 -> AWSの通信が異常に遅いこともあり、GCPでかつUSのリージョンの方が良いだろうと思いました。

現在は、以下の通り…

自宅 -(ブラウザ)-> ダウンロードURL

を、以下のようにしてみようと…

自宅 -(SSH)-> GCP(US) -(curl)-> ダウンロードURL

  • 1 つの非プリエンプティブル e2-micro VM インスタンス(1 か月あたり)。
    次の米国リージョンのいずれかで利用できます。
    • オレゴン: us-west1
    • アイオワ: us-central1
    • サウスカロライナ: us-east1
  • 30 GB-月の標準永続ディスク
  • 1 GB の北米から全リージョン宛ての下りネットワーク(1 か月あたり、中国とオーストラリアを除く)
Google Cloud の無料プログラム

curlでダウンロード

平均、90Mでダウンロードでき、一瞬でダウンロード完了しました。

teruhiro@instance-20240331-071923:~/tmp$ curl -O https://fmdl.filemaker.com/maint/107-85rel/xxx.dmg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  443M  100  443M    0     0  90.8M      0  0:00:04  0:00:04 --:--:-- 90.9M

Cloud Storageにアップロード

gcloudコマンドでアップロードします。

gcloud storage cp xxx.dmg gs://your-bucket/

Compute EngineからCloud Storageにアップロードできない場合

以下のスクショのアクセススコープの設定を確認してください。

確認手順

  • インスタンスを停止する
  • インスタンスを編集する
  • アイデンティティと API へのアクセスの項目に移動する
  • アクセススコープの設定を確認する
  • デフォルトのアクセス権を許可が選択されている場合
  • API ごとにアクセス権を設定を選択する
  • ストレージ読み取り / 書き込みに変更する
  • 編集を保存する
Compute Engineの設定(アクセススコープ)
Compute Engineの設定(アクセススコープ)

せっかくなので、インスタンスは削除せずに、定期的に利用したいと思います。

参考情報

author
Teruhiro Komaki komaki.dev
2024年 03月 28日 木曜日
09時00分

metaタグのtheme-colorを設定しました

metaタグのtheme-colorで、ブラウザのカラーを設定できるということで、自分で運営しているブログなどに設定してみました。

もともと #ffffff だった値を #000000FF に変更しました。

<meta name="theme-color" content="#000000FF">
metaタグ theme-color
metaタグ theme-color
Safariで表示 変更前
Safariで表示 変更前
Safariで表示 変更後
Safariで表示 変更後

metaタグのtheme-colorについて

theme-color Meta Tag | Can I use... Support tables for HTML5, CSS3, etc

安定の CSS-TricksMDN を確認するのが良いですね。

Starting with Version 15, Safari supports the theme-color <meta> tag both on macOS and iOS.
That’s exciting news because now the first desktop browser supports this <meta> tag and it also supports the media attribute and the prefers-color-scheme media feature.
I never really took much note of the theme-color meta tag, but now is a good time to learn about its features and limitations and try to discover some interesting use cases.


Google翻訳
バージョン 15 以降、Safari は macOS と iOS の両方でテーマカラーの <meta> タグをサポートします。
これは興味深いニュースです。なぜなら、最初のデスクトップ ブラウザがこの <meta> タグをサポートし、メディア属性と優先カラー スキーム メディア機能もサポートしているからです。
私はテーマカラー メタ タグにあまり注目したことがありませんでしたが、その機能と制限について学び、いくつかの興味深い使用例を見つけてみる良い機会になりました。

Meta Theme Color and Trickery | CSS-Tricks - CSS-Tricks

theme-color の値は <meta> 要素の name 属性において、ユーザーエージェントがページやその周辺のユーザーインターフェイスの表示をカスタマイズするために使用すべき推奨色を示します。
指定された場合、 content 属性には有効な CSS の <color> が含まれていなければなりません。

theme-color - HTML: ハイパーテキストマークアップ言語 | MDN
author
Teruhiro Komaki komaki.dev
2024年 03月 27日 水曜日
06時00分

防犯カメラをつけました

少し前に、#防犯カメラを買ったので、自宅につけてみました。

アマゾンで、#Ringというカメラを買いました。

ドアベル&セキュリティカメラ | Ring

バッテリーが意外と長持ちで、驚いています。

アプリで、バッテリーの残量を確認できるものの、マメに確認することは難しくて…

「そろそろバッテリーが切れるかな…」と思っていたら、通知メールがきました。

スクリーンショット
スクリーンショット

通知メールが来たおかげで、無事バッテリーの交換ができました。

助かりました…

author
Teruhiro Komaki komaki.dev
2024年 03月 21日 木曜日
10時00分

FileMaker Data API を実行ステップや、FileMaker Data APIの戻り値の日付フォーマットについて

FileMaker Data API で、ID による単一レコードの取得、レコードの取得、およびレコード検索のエンドポイントに FileMaker Data API によって返される日付およびタイムスタンプフィールドの形式を制御するオプションの dateformats 引数が含まれるようになりました: 米国は 0、ファイルロケールは 1、ISO8601 は 2 です。
指定されていない場合、デフォルト値は 0 です。

Claris FileMaker Server 19.6.1 リリースノート

For FileMaker Data API, the Get a Single Record by ID, Get Records, and Find Records endpoints now include the optional dateformats parameter, which controls the format of date and timestamp fields returned by FileMaker Data API: 0 for US, 1 for file locale, or 2 for ISO8601.
If not specified, the default value is 0.

Claris FileMaker Server 19.6.1 Release Notes

dateformats = 0 の場合は、米国

{
  "layouts": "blank",
  "query": [
    {
      "日付": "03/01/2024"
    }
  ],
  "dateformats": 0 <- 米国
}
{
  "response": {
    "dataInfo": {
      "database": "blank",
      "layout": "blank",
      "table": "blank",
      "totalRecordCount": 1,
      "foundCount": 1,
      "returnedCount": 1
    },
    "data": [
      {
        "fieldData": {
          "タイムスタンプ": "03/01/2024 09:10:20", <- 米国
          "日付": "03/01/2024" <- 米国
        },
        "portalData": {},
        "recordId": "1",
        "modId": "4"
      }
    ]
  },
  "messages": [
    {
      "code": "0",
      "message": "OK"
    }
  ]
}

dateformats = 1 の場合は、ファイルロケール

{
  "layouts": "blank",
  "query": [
    {
      "日付": "03/01/2024"
    }
  ],
  "dateformats": 1 <- ファイルロケール
}
{
  "response": {
    "dataInfo": {
      "database": "blank",
      "layout": "blank",
      "table": "blank",
      "totalRecordCount": 1,
      "foundCount": 1,
      "returnedCount": 1
    },
    "data": [
      {
        "fieldData": {
          "タイムスタンプ": "2024/03/01 09:10:20", <- ファイルロケール
          "日付": "2024/03/01" <- ファイルロケール
        },
        "portalData": {},
        "recordId": "1",
        "modId": "4"
      }
    ]
  },
  "messages": [
    {
      "code": "0",
      "message": "OK"
    }
  ]
}

dateformats = 2 の場合は、ISO8601

{
  "layouts": "blank",
  "query": [
    {
      "日付": "03/01/2024"
    }
  ],
  "dateformats": 2 <- ISO8601
}
{
  "response": {
    "dataInfo": {
      "database": "blank",
      "layout": "blank",
      "table": "blank",
      "totalRecordCount": 1,
      "foundCount": 1,
      "returnedCount": 1
    },
    "data": [
      {
        "fieldData": {
          "タイムスタンプ": "2024-03-01T09:10:20", <- ISO8601
          "日付": "2024-03-01" <- ISO8601
        },
        "portalData": {},
        "recordId": "1",
        "modId": "4"
      }
    ]
  },
  "messages": [
    {
      "code": "0",
      "message": "OK"
    }
  ]
}
author
Teruhiro Komaki komaki.dev
2024年 03月 19日 火曜日
17時00分

Claris IDの更新トークンを使ってFileMaker Cloud の Claris ID Tokenを更新する

ひとつまえの投稿でも伝えた通り、Claris IDのRefresh Tokenを使って、Claris ID Tokenを更新したいので、API周りを調べていました。

curlコマンドで更新する方法がわかったので、簡易的にHTMLで公開することにしました。

Generating a Claris ID Token with FileMaker Cloud | frudens Inc.

スクリーンショット
スクリーンショット
Claris ID Tokenを生成するミニアプリのサムネイル
Claris ID Tokenを生成するミニアプリのサムネイル
author
Teruhiro Komaki komaki.dev
2024年 03月 19日 火曜日
09時00分

Claris ID Tokenの有効期限について

Refresh Tokenは、1年間有効。Claris ID Tokenは、1時間有効。

スクリーンショット
スクリーンショット

FileMaker CloudのClaris ID Tokenを更新する

Amazon Cognito User Pools の API Reference InitiateAuth に記載があります。

InitiateAuth - Amazon Cognito User Pools

以下のcurlコマンドを実行すると、Claris ID Tokenを更新することができます。

json='
{
  "ClientId": "4l9rvl4mv5es1eep1qe97cautn",
  "AuthFlow": "REFRESH_TOKEN_AUTH",
  "AuthParameters": {
    "REFRESH_TOKEN": "eyJjdHkiOiJK...",
    "DEVICE_KEY": null
  }
}'
curl 'https://cognito-idp.us-west-2.amazonaws.com/' \
  -H 'authority: cognito-idp.us-west-2.amazonaws.com' \
  -H 'content-type: application/x-amz-json-1.1' \
  -H 'x-amz-target: AWSCognitoIdentityProviderService.InitiateAuth' \
  --data-raw "${json}"

戻り値は、以下のJSONになります。

{
  "AuthenticationResult": {
    "AccessToken": "eyJraWQiOiJ6a...",
    "ExpiresIn": 3600,
    "IdToken": "eyJraWQiOiIya1...",
    "TokenType": "Bearer"
  },
  "ChallengeParameters": {}
}

FileMaker CloudのClaris ID Tokenをサインアウト(ログアウト)する

同じく、Amazon Cognito User Pools の API Reference GlobalSignOut に記載があります。

GlobalSignOut - Amazon Cognito User Pools

json='
{
  "AccessToken": "eyJraWQiOiJ6a1VrW..."
}'
curl 'https://cognito-idp.us-west-2.amazonaws.com/' \
  -H 'authority: cognito-idp.us-west-2.amazonaws.com' \
  -H 'content-type: application/x-amz-json-1.1' \
  -H 'x-amz-target: AWSCognitoIdentityProviderService.GlobalSignOut' \
  --data-raw "${json}"

戻り値は、以下のJSONになります。

{}

curlから実行できるということは…

FileMakerのURLから挿入で、実行できるということになります。

Claris ID Tokenを取得するための簡易的なアプリを作成しましたので、追って会社のブログでリリースしたいと思います。

author
Teruhiro Komaki komaki.dev
2024年 03月 16日 土曜日
00時30分

Twitterのように短文を投稿する日記を開始した

このWebサイトは、2024年03月13日から投稿を開始しました。

2024年03月13日 16時00分 | 小巻の日記

日々の生活のなかで、気になったことや、思いついたことを、適当に書きなぐっているわけですが、気づいたら、毎日、投稿しています。

ちゃんとしたブログとなってしまうと、どうしても腰が重くなってしまいますが、TwitterやMastodonのように、気軽に発信できるような構成にした点が良かったのかもしれません。

Webサイトの構成は、ブログなのですが、#日記っぽく見えるように、苦手な#CSSを頑張りました。

本当は、Tailwindを使いたかったのですが、なかなか勉強する時間がとれず、やむなく普通の#CSSで書きました。


昨日は、次男がストライダーに乗って、すっごく嬉しそうにしていました。

長男も、まだストライダーに乗りたいって言っているので、取り合いになりそうな予感が…

ストライダーの2台目を買おうかどうか…

author
Teruhiro Komaki komaki.dev
2024年 03月 15日 金曜日
23時00分

ドメインを取得しても、安易にメールアドレスを作らない方がよいと思う

みなさん、自分のWebサイトを公開するために、#ドメインを取得すると思いますが、その際に気を付けていることがあります。

それは…

安易にメールアドレスを作らないことです。

自分が生きているうちは、基本的に、#ドメインの更新を忘れることはないと思います。

しかし、私たちは、いつどこでなにが起こるか分からない環境にいます。

外を歩いていたら、突然事故にあって亡くなる可能性だってあるわけです。もし、自分の身に万が一のことがあり、ドメインの更新ができなかった場合、どうなるでしょうか?

更新期限が過ぎてしまい、#ドメインは失効し、第三者に#ドメインが渡ってしまいます。

その第三者が、メールをキャッチオールするように設定すれば、その#ドメインのメールを全て受信できてしまいます。

たとえば、Cloudflareの場合、以下のように記載されている通り、管理画面から簡単に設定できます。

Cloudflare Email Routing
容易なアドレス作成とメール転送が無料で
ドメインのカスタムメールアドレスを作成します。
設定されていないアドレス用のキャッチオールアドレスをオプションで追加します。
お好みの受信箱へメールを転送します。
すべて、プライマリメールアドレスを決して露出することなく行います。

Email Routing | アドレス作成とメール転送が簡単に | Cloudflare

失効のリスクのほかに、メインのメールアドレスとして使ってしまうと、将来にわたり、#ドメインを捨てることが難しい状況になります。

そのため、#ドメインを取得した際に、安易にメールアドレスを作ると、万が一のリスクがあるので、十分に気をつけましょう…

gandi.netの以下のブログを見ると、近しいことが書いてありました。

Facebook や Twitter などのソーシャル メディアのプロフィールは、一部の金融機関と同様に、電子メール アドレスにリンクされています。
個人アカウントとは別に、電子メール アドレスは、(有効期限が切れていない) ドメイン名などのオンライン資産を管理するアカウントにリンクできます。
ユーザーまたはオンライン サービスが (場合によっては自動的に) ホストされているドメイン名に電子メールを送信しようとしたときに、そのドメインが存在しない場合、電子メールはバウンスされます。
その結果、ドメイン名の有効期限が切れると、そのドメイン名に送信される可能性のある電子メールにとっても魅力的なものになります。
再登録された期限切れドメインに設定されたキャッチオール電子メール アドレスは、あらゆる電子メールをキャプチャすることができ、ソーシャル メディア プロファイル、銀行口座、ドメイン名、IP アドレス ブロックへのアクセスを他人に与えてしまう可能性があります。

The domain name afterlife

私は、家族ができ、子供が大きくなるにつれて、自分の#死後のことを意識するようになりました。

少し大げさかもしれませんが、#ドメインやメールアドレスだけでなく、パスワードマネージャーなど、家族が困らないように、日々意識して準備しておいても良いのかもしれません…

1Passwordのファミリープランを検討しないと。

author
Teruhiro Komaki komaki.dev
2024年 03月 15日 金曜日
15時50分

Googleのリフレッシュトークンの有効期限について

#FileMakerから、#Google#APIを利用する際に、#リフレッシュトークン(更新トークン)をFileMakerの内部で管理します。

その際に、お客様から「#リフレッシュトークンは、更新する必要がなく、ずっと使えるの?」と良く質問を頂きます。

ということで、リンクを張っておきます。

リフレッシュトークンの有効期限について

付与された更新トークンが機能しなくなる可能性を想定したコードを記述する必要があります。更新トークンが機能しなくなる理由は、次のいずれかです。

  • ユーザーがアプリのアクセス権を取り消した。
  • 更新トークンが 6 か月間使用されていません。
  • ユーザーがパスワードを変更し、更新トークンに Gmail スコープが含まれている。
  • ユーザーアカウントが付与されている(有効な)更新トークンの最大数を超えています。
  • 管理者がアプリのスコープでリクエストされたサービスのいずれかを制限付きに設定した場合(エラーは admin_policy_enforced)。
OAuth 2.0 を使用して Google API にアクセスする | Authorization | Google for Developers
スクリーンショット
スクリーンショット

ということで、基本的には一度取得した#リフレッシュトークンは、無効化されることがないという認識です。

author
Teruhiro Komaki komaki.dev
2024年 03月 15日 金曜日
13時00分

CSSの属性セレクターについて

#CSSは、必要に迫られたり、分からないことがあれば、適宜勉強するという程度なので、かなり素人です。

何かのきっかけで、属性セレクターを見つけました。

CSS の属性セレクター (attribute selector) は、指定された属性が存在するかどうか、またはその値に基づいて要素を選択します。

属性セレクター - CSS: カスケーディングスタイルシート | MDN
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>CSS</title>
  <style>
    :root {
      --color-primary: #cfe2ff;
      --color-success: #d1e7dd;
      --color-warning: #fff3cd;

      --bg-color: var(--color-primary);
    }

    [param=a] {
      --bg-color: var(--color-success);
    }

    [param=b] {
      --bg-color: var(--color-warning);
    }

    .color {
      background-color: var(--bg-color);
    }

  </style>
</head>
<body>
<div>
  <p class="color">test</p>
  <p class="color" param="">test</p>
  <p class="color" param="invalid">test</p>
  <p class="color" param="a">test</p>
  <p class="color" param="b">test</p>
</div>
</body>
</html>

スクショもはっておきます。

スクリーンショット
スクリーンショット

Bootstrapは、ダークモードを始めとするカラーモードをサポートするようになりました!
v5.3.0では、独自のカラーモード・トグラーを実装することができ(Bootstrapのドキュメントにある例は下記を参照)、適切と思われるさまざまなカラーモードを適用することができます。
ライトモード(デフォルト)とダークモードをサポートしています。
カラーモードは、<html>要素上でグローバルに切り替えることも、data-bs-theme属性のおかげで、特定のコンポーネントや要素上で切り替えることもできます。

カラーモード · Bootstrap v5.3
author
Teruhiro Komaki komaki.dev
2024年 03月 15日 金曜日
00時30分

EleventyのPaginationについて

このサイトは、#Eleventyを使って、HTMLを生成しています。

#EleventyPaginationという機能を使い、、以下のスクショのように、年、月、日、タグのページを動的に生成しています。

スクリーンショット
スクリーンショット

タグのページを動的に生成する書き方は、以下のページに丁寧に書かれています。

Quick Tip #004—Zero Maintenance Tag Pages for your Blog — Eleventy

以下のようなFront Matterを書けば、動的にタグのページが生成されます。

すばらしく簡単です!

---
pagination:
  data: collections
  size: 1
  alias: tag
permalink: /tags/{{ tag }}/
---
<h1>Tagged “{{ tag }}”</h1>

<ol>
{% set taglist = collections[ tag ] %}
  {% for post in taglist | reverse %}
    <li><a href="{{ post.url }}">{{ post.data.title }}</a></li>
  {% endfor %}
</ol>

実装するなかで、ひとつ課題がありました。

以下のようにcollectionApi.getAll()をしても、Paginationの結果がNページある場合においても、1ページしか取得できない問題に遭遇しました。

eleventyConfig.addCollection('allPost', (collectionApi) => {
    const posts = collectionApi.getAll()
    for (const post of posts) {
      console.log(post.data.title)
    }
    return posts
  });

調べてみると、以下のIssueに答えがありました。

Collections.all only lists first page created with pagination, not others · Issue #253 · 11ty/eleventy

以下のように、Paginationを設定しているファイルのFront MatterにaddAllPagesToCollections: trueを追加することで、すべてのPaginationのページが取得できました。

---
pagination:
  addAllPagesToCollections: true
---
author
Teruhiro Komaki komaki.dev
2024年 03月 14日 木曜日
19時00分

Data Matrixに対応している、jsQRを使ってブラウザでQRコードを読み取る

16時00分に、投稿をした際には#jsQRを使ってみたのですが、#QRコードに追加して、#Data Matrixも読めるようにしたいなと思いました。

2024年03月13日 16時00分 | 小巻の日記

探してみると、以下の#ZXingというライブラリが見つかりました。

zxing-js/library: Multi-format 1D/2D barcode image processing library, usable in JavaScript ecosystem.

以下のデモサイトにアクセスすると、カメラを使ってテストできます。

ZXing TypeScript | Decoding from camera stream

#Data Matrixのサンプルで確認しましたら、無事読み込めました。

スクリーンショット
スクリーンショット

こちらのライブラリを活用すると、#FileMaker Goなどのクライアントが不要になりそうな予感がします…

ZXing TypeScript | Demo & Examples

author
Teruhiro Komaki komaki.dev
2024年 03月 14日 木曜日
17時00分

お客様のFileMaker Cloud環境で、スケジュールを設定する際には注意

お客様が、#FileMaker Cloud環境で#FileMakerを利用している場合において、少しハマったことがあったので、メモしておきます。

#FileMaker Cloudは、オンプレミスの#FileMaker Serverと違って、Admin Consoleにログインする際にも、ファイルを開く際にも、Claris IDでログインする必要があります。

以下のような手順をすると、どうなるか想像してみてください。

#FileMaker CloudのAdmin Consoleで設定したスケジュールが失敗する手順

  1. お客様のClaris Customer Consoleに、開発者として、一時的にユーザーAを追加してもらう。
  2. ユーザーAとして、お客様のAdmin Consoleにログインし、スケジュール設定を追加する。
  3. スケジュールが正常に動いていることを確認する。
  4. お客様のClaris Customer Consoleから、ユーザーAを削除する。
  5. スケジュールは、作成者であるユーザーAとして、実行される。
  6. ユーザーAは、お客様のClaris Customer Consoleにはいないため、スケジュールが失敗する。

#FileMaker Cloudの場合、上記のようなことが起こります…

そのため、お客様のアカウントにて、スケジュールを作って頂くようにしましょう。

author
Teruhiro Komaki komaki.dev
2024年 03月 14日 木曜日
15時50分

タイトルを考えることのコスト

タイトルを考えることって、以外にコストが高いのではないか?と思いまして…

このサイトは、タイトルという概念を持っておらず、投稿日時をパースして、自動的にタイトルにしています。

具体的には、以下のような文字列をタイトルにしています。

2024年03月14日 15時50分

今まで、色々と#ブログを書いてきましたが、#WordPressの投稿一覧に、下書きのまま眠っている記事が山のようにあります。

書きたいことが見つかったら、すぐに、その内容を投稿する。

本当は、これくらい簡単なことで良いような気がしています。

いつかのタイミングで、投稿や伝えたいことを整理して、一つの記事にまとめて投稿する。という運用で良いのではないかと…

author
Teruhiro Komaki komaki.dev
2024年 03月 14日 木曜日
15時30分

しゃぶ葉に行った

久しぶりのランチで#しゃぶ葉に行ってきました!

しゃぶ葉 希望ヶ丘店 | 店舗検索 | すかいらーくグループ

最後の締めのデザートに、白玉を食べるのですが、少し芯が残っているのですよね…

白玉以外の要素は、完璧なので、本当にもったいないんだよな…


そんなことは、どうでも良くてですね…

今回のような、どうでも良い投稿って、今までは#Mastodonに投稿していましたが、今後は、こちらのサイトに投稿していくことにします。

#Mastodonって、GoogleやBingなどのインデックス登録が微妙で、結局アクセスされることがないのではないか?と思いまして…

意味のある投稿も、あまり意味のない投稿も含めて、ゆるく投稿していきたいと思います。

author
Teruhiro Komaki komaki.dev
2024年 03月 14日 木曜日
01時00分

mozaic.fmのイベントに行けなかった

#mozaic_fmが10周年とのことで、2024年03月08日にイベントがあったみたいです。

子供が生まれてから、なかなか自由に動けないので、いろんなイベントに参加できないのが残念でなりません…

行きたかったな。

#mozaic_fmは、毎回、本当に濃い内容のお話で、楽しく聞いています。

第 143 回のテーマは mozaic.fm 10 周年記念イベントです。
2024/03/08 に五反田ゲンロンカフェで実施したイベントの様子を配信します。
Session 2 は、会場限定のコンテンツのため、本編には含まれていません。

ep143 mozaic.fm 10 周年記念イベント | mozaic.fm

mozaic.fm 10 周年記念イベント開催後記 | blog.jxck.io

author
Teruhiro Komaki komaki.dev
2024年 03月 13日 水曜日
16時00分

WebRTCを使ってブラウザでQRコードを読み取る

ブラウザで#QRコードを読み取る方法を模索している。
以下の記事が参考になりました。

[HTML5 JavaScript QR WebRTC]JavaScriptでQRコードリーダーを作ってみる | MD-Blog | MONSTER DIVE

早速、#jsQRを素振りしてみる。

cozmo/jsQR: A pure javascript QR code reading library. This library takes in raw images and will locate, extract and parse any QR code found within.

デモサイトがあったので、開いて確認してみる。

QRコードのサンプルとして、以下のサイトを開いて、テストをする。

QRコード例 – エクスサポート情報サイト

無事、認識できた。

スクリーンショット
スクリーンショット

手元で動かしたかったので、HTMLをコピーして、若干修正して、以下のHTMLを保存して開いて確認する。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>jsQR Demo</title>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jsQR.min.js"></script>
  <link href="https://fonts.googleapis.com/css?family=Ropa+Sans" rel="stylesheet">
  <style>
    body {
      font-family: 'Ropa Sans', sans-serif;
      color: #333;
      max-width: 640px;
      margin: 0 auto;
      position: relative;
    }

    #githubLink {
      position: absolute;
      right: 0;
      top: 12px;
      color: #2D99FF;
    }

    h1 {
      margin: 10px 0;
      font-size: 40px;
    }

    #loadingMessage {
      text-align: center;
      padding: 40px;
      background-color: #eee;
    }

    #canvas {
      width: 100%;
    }

    #output {
      margin-top: 20px;
      background: #eee;
      padding: 10px;
      padding-bottom: 0;
    }

    #output div {
      padding-bottom: 10px;
      word-wrap: break-word;
    }

    #noQRFound {
      text-align: center;
    }
  </style>
</head>
<body>
<h1>jsQR Demo</h1>
<a id="githubLink" href="https://github.com/cozmo/jsQR">View documentation on Github</a>
<p>Pure JavaScript QR code decoding library.</p>
<div id="loadingMessage">🎥 Unable to access video stream (please make sure you have a webcam enabled)</div>
<canvas id="canvas" hidden></canvas>
<div id="output" hidden>
  <div id="outputMessage">No QR code detected.</div>
  <div hidden><b>Data:</b> <span id="outputData"></span></div>
</div>
<script>
  var video = document.createElement('video');
  var canvasElement = document.getElementById('canvas');
  var canvas = canvasElement.getContext('2d');
  var loadingMessage = document.getElementById('loadingMessage');
  var outputContainer = document.getElementById('output');
  var outputMessage = document.getElementById('outputMessage');
  var outputData = document.getElementById('outputData');

  function drawLine(begin, end, color) {
    canvas.beginPath();
    canvas.moveTo(begin.x, begin.y);
    canvas.lineTo(end.x, end.y);
    canvas.lineWidth = 4;
    canvas.strokeStyle = color;
    canvas.stroke();
  }

  // Use facingMode: environment to attemt to get the front camera on phones
  navigator.mediaDevices.getUserMedia({video: {facingMode: 'environment'}}).then(function(stream) {
    video.srcObject = stream;
    video.setAttribute('playsinline', true); // required to tell iOS safari we don't want fullscreen
    video.play();
    requestAnimationFrame(tick);
  });

  function tick() {
    loadingMessage.innerText = '⌛ Loading video...';
    if (video.readyState === video.HAVE_ENOUGH_DATA) {
      loadingMessage.hidden = true;
      canvasElement.hidden = false;
      outputContainer.hidden = false;

      canvasElement.height = video.videoHeight;
      canvasElement.width = video.videoWidth;
      canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);
      var imageData = canvas.getImageData(0, 0, canvasElement.width, canvasElement.height);
      var code = jsQR(imageData.data, imageData.width, imageData.height, {
        inversionAttempts: 'dontInvert',
      });
      if (code) {
        drawLine(code.location.topLeftCorner, code.location.topRightCorner, '#FF3B58');
        drawLine(code.location.topRightCorner, code.location.bottomRightCorner, '#FF3B58');
        drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, '#FF3B58');
        drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, '#FF3B58');
        outputMessage.hidden = true;
        outputData.parentElement.hidden = false;
        outputData.innerText = code.data;

        // 追加
        if (true) {
          if (code.data) {
            console.log(`QRコードの値は「${code.data}」です。`);
          }
        }

      } else {
        outputMessage.hidden = false;
        outputData.parentElement.hidden = true;
      }
    }
    requestAnimationFrame(tick);
  }
</script>
</body>
</html>

確認のため、追加したコードが無事動きました。これで実装できそうです。

スクリーンショット
スクリーンショット