ググって出てきた記事が軒並み古くて役に立たなかったので、令和八年最新版として書いておく。

やり方

  1. CPANMのインストール
    curl -L https://cpanmin.us | perl - App::cpanminus
    
  2. CPANMのパスを.cshrcに書く
    私はZSHを使っているため.zshrcに書いているが、デフォルト環境はcshのはずなので.cshrcに書けば成り立つと思う。
    echo PATH=${HOME}/perl5/bin:${PATH}
    
  3. local::libをインストールする
    local::libはroot以外にあるCPANモジュールを使うためのものらしい。これを自分のホームディレクトリ配下に入れるようにコマンドを流す。
    cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
    

使い方

以下のようなコマンドを流すとパスを指定してCPANモジュールを取得・展開できる。

# 書式
cpanm -l <パス> <モジュール名>

例えば以下を流すとpwd配下にextlibディレクトリが生成され、IP::Geolocation::MMDBがダウンロードされて展開される。勿論、依存関係も勝手に解決してくれる。

cpanm -l extlib IP::Geolocation::MMDB

モジュールを利用するときはライブラリの配置されているルートを指定し、次にモジュール名を指定するとうまくいくようだ。

use lib './extlib/lib/perl5';
use IP::Geolocation::MMDB;

あとがき

https://cpanmin.us/を見に行くと以下の記述があり、辿ってみると日本の人が作っていてちょっと驚いた。

# This is a pre-compiled source code for the cpanm (cpanminus) program.
# For more details about how to install cpanm, go to the following URL:
#
# https://github.com/miyagawa/cpanminus

先日2026年のBluesky予測という記事が発表され、とても素晴らしい理念だと思ったので感想をつづってみる。

SNS疲れについては過去にもネット疲れの一つのような感じで軽く触れたが、昨今SNSに疲れを感じている人は少なくないと思う。本記事では、Blueskyが提唱する『インターネットを再び良くする』という理念への個人的な感銘を書いていく。

情報の掃きだめの打破

現在のSNSは憂鬱で、攻撃的で、人間味のない「情報の掃き溜め」になってしまい、Instagramではフォローしている投稿がほとんど表示されなくなり、Xでは非同意ポルノが氾濫している。オンラインコミュニティは延々とスクロールし続けて可処分時間を溶かす装置となった。

これらの実装は全て人間がやってきたことだから、つまり同じ人間により覆すことができるという考えをBlueskyは持っているようだ。

Blueskyでは似た分野の投稿を集める機能を開発する予定があるそうで、これによって見知らぬ人たちと一緒にライブ体験を共有し、瞬時に友人になったかのような感覚を味わうことができると言っている。

きっとこれは、かつてMMORPGにあった祭りのようなものだろう。その場の熱気で見知らぬ人が集まり、思い思いに熱狂する、そういった事ができるのだろう。

つまりBlueskyは玉石混交で様々な情報がごちゃごちゃになった場所、自分がその時に見たい情報やフォロイーの動静といった、自分が求める情報だけが整然と並ぶ場所を目指しているのだろう。

南アフリカにはポンテタワー[1]と呼ばれるビルがある。ポンテタワーは中央の吹き抜けに数階分のゴミが堆積した高層ビルだ。今のSNSはまさにそういった状態で、Blueskyとしてはそういった状況を打破したい、この現状はよくないと思っているというわけだ。

これはある意味でXのおすすめタブのような新しい出会いに出会う機会は減るが、逆に言えば常に新規性のある情報に触れ続け、それを浪費し、三日前に見たもののことなど既に覚えてすらいないような状況より、遥かに健全だ。

インターネット上の小さな奇跡との出会い

Blueskyでは「ウェブ上で見つけたり自分で作った素晴らしいものを共有するための場所」を目指したいと考えているそうで、それは「『これはすごい!』と感動できるような、デジタルの小さな奇跡に出会う場所」だそうだ。

これが何かというと、恐らく個人の創作や、簡単なプログラム開発といった趣味の成果物の話だと私は考えている。

つまりバズることを目的に、世間を煽る創作をしたり、コンビニの冷蔵庫に入ったりすることではないということだ。みんな芸人をやめて普通に振舞おうということかもしれない。

Xではきわどいネタを無限に投稿しバズっている人がいるが、あの人たちが本心でやっているかというと、個人的には懐疑的だ。広告塔になり、自分の製品が売れるからとか、単に目立って承認欲求が満たされるからしている可能性は十分にあるだろう。

私は千人、一万人にリーチするより、ごく限られた数名にリーチする方が価値があると思う。これは人口に膾炙してしまうと聞きたくない意見が聞こえてきたり、そもそも全部を全部見るのが不可能になるからだ。

「あなたの記事で助かりました」「あなたのイラストのここが好きです」と数回言われる分には把握できるし、もしその人がずっと見ていてくれれば、友達や仲間になれるかもしれない。しかし数が多いとどうだろう?もはや個人を意識することはないだろう。数字が伸びたから満足みたいなところに行きつくと思う。

勿論、商業ならそれでいいだろう。企業や個人事業主、大手同人サークルで売れれば売れるほどいいならそれでいい。でも趣味ならどうか?むしろひっそりやりたくないか?というのは思う。

主役はSNSではなく、その先にあるものである

ソーシャルプラットフォームが自らを「ワールドワイドウェブの主役」だと思い込み始めた時から、インターネットはおかしくなり始めました。

そう思い込んでいるのかどうかはわかりかねるが、これも非常に共感できた部分だ。

例えばイラストレーターはpixivに絵を上げ、一般人は日々の体験をTwitterに書き、動画はYoutubeやInstagramにアップする。つまり以前はWebサイトで発信していた事柄が創作も発信もSNS上で完結するようになった。

それに情報を探すときですらSNSが使われるようになっている。例えば2022年3月2日の日経にあるアメリカでは検索ワードにRedditをつける話や、2016年2月19日の日本の若者はGoogleを使わずにTwitterで検索をするという話も出ていることから、SNSは徐々にワールドワイドウェブの主役として、のし上がってきたことがうかがえる。

しかしプラットフォームでは大半の人は見るだけで、投稿者は再生数や売り上げを競うゲームになっている。その為に対立が煽られ炎上したりもするし、フォローしてもフォローしたコンテンツでないものが流れてきたり、コンテンツを見ていて気が付いたら全く違う場所にいたりする。

果たしてこんなものが主役であっていいのかという思いがある。勿論、古い人間の考え、老害の言うことだという意見もあるだろう。実際にそうだと思うし、だからこそ私はBlueskyの言うことに共感しているのだと思う。

私はSNSを無限にスクロールしコンテンツを浪費することよりは、たまにフィードに流れてきた興味深いリンクをクリックして、小さな奇跡を見つける方がより価値があると思う。

それはSNSで見つかる小さな奇跡と何が違うのかと言われれば、それを上手く説明することはできない。しかし、インターネット老人としてはそう思うのだ。

Blueskyで見つけたものに刺激を受け、Blueskyでの活動が減る

穏やかで、非消費的な世界では小さな奇跡を見つけ、それに刺激を受け、何かに取り組むことも増えるかもしれない。

そういった中ではSNSの滞在時間は減る。別の取り組みが始まるのだ。すると、人はきっとSNSで受けた刺激をもとに何か生産的な活動を行い、それをSNSに投稿する再生産を行うようになるだろう。

すると、SNSは穏やかになるかもしれない。何故なら活動中はSNSを利用していないからだ。

結果としてSNSは脇役となり、メインのアクティビティは別のものになるだろう。SNSに誘導され、SNSの利益になる活動ではなく、自身の利益になる、より有益な活動が生まれるはずだ。

Blueskyは次のように、ユーザーをSNSに閉じ込める罠をなくし、可処分時間を自分が意図したことに有効活用できるようになるということを述べている。これは実に素晴らしい考えだと思う。人間は他人に操作され、あたかも自分が思っていると勘違いした状態で行動すべきではないのだ。

ユーザーを罠にかけて閉じ込めるように設計されたプラットフォームから離れ、「インターネットは生活を消費するために構築されるべきではない」とはっきり言えるような空間へと人々が移動するにつれ、ダラダラとしたスクロールは減り、より意図的な利用が増えると予測しています。

あとがき

内容には感動したが、反面どこで儲けるのかが気になった。自鯖勢は自分で運用コストを負担しているので別として、一般の人々は本体側に行くだろうからね。

まぁそこはさておきとして、元記事中にある次の文章はとても美しい文章だと思った。

しかし、もし人間の選択によってインターネットが悪くなったのであれば、人間が別の何かを選択することで、インターネットを再び良くすることができるはずです。
インターネットを形作ってきたのは人間です。
そして、人々はそれをより良くすることができるはずです。

また次の文章も非常に気が利いていて面白い。

このために、皆様から絶えずご要望をいただいている下書き機能を追加します。

どうしてそんなに時間がかかったの?という質問に対しては、まだ気の利いた答えを用意している最中ですが、準備ができしだい公開予定です。


  1. 南アフリカの都市である、ヨハネスブルグで最も治安が悪いといわれるヒルブロウ地区にあるタワーマンション。かつては中央の吹き抜けに地上五階までゴミが溜まっていたといわれている。以前は入って五秒で殺されるなど、非常に治安が悪いことで知られていたが、近年では観光ツアーが組まれるほどに改善している。
更新日:
投稿日:

他のサーバーを見ていて、ウチでもMastodonに翻訳ボタンを生やして機能させたくなったのでやってみた結果のログ。

内容としてはDeepLのアカウントを作成し、APIキーを取得し、Mastodonの.env.productionに追記して反映するだけなので、5分くらいあればできる。

月50万文字まで翻訳できるので、たまに短文の翻訳に使う程度なら必要十分だろう。

確認環境

  • Mastodon v4.5.4

やり方

  1. DeepL ProのAPIタブを開き、無料プランに登録する。クレジットカードが必要だが、意図的にProプランにしなければ課金されないらしいので、恐らく害はないだろう。
  2. 適当にDeepLのAPIキーを取得する。xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx:fxみたいな形式のやつ
  3. 以下のコマンドで疎通確認
    export API_KEY={APIキー}
    curl -X POST https://api-free.deepl.com/v2/translate \
     --header "Content-Type: application/json" \
     --header "Authorization: DeepL-Auth-Key $API_KEY" \
     --data '{
         "text": ["Hello world!"],
         "target_lang": "JA"
     }'
    
  4. Mastodonの.env.productionに下記を追記
    DEEPL_PLAN=free
    DEEPL_API_KEY=XXXXXX-XXXX-XXXXX:fx
    
  5. リビルド
    RAILS_ENV=production bundle exec rails assets:clobber
    RAILS_ENV=production bundle exec rails assets:precompile
    
  6. 再起動
    sudo systemctl restart mastodon-web
    
  7. 動作確認して動いていればOK

トラブルシューティング

クレカ登録時に「決済手段を認証できませんでした。別の決済手段を選択してやりなおしてください。 (Error Code: OFQUTG)」と言われる

ブラウザを変えるといける可能性がある。

これはWindows Edgeで試してこう言われ、何度試しても無理だったが、Android Edgeで試したら一発で行けたからだ。原因としては、StripeのSDKが以下のようなエラー吐いてたのが関係していたのではないかと思っている。

Applying inline style violates the following Content Security Policy directive 'style-src 'self''. Either the 'unsafe-inline' keyword, a hash ('sha256-XXXXXXXXXXXXXXXXXX='), or a nonce ('nonce-...') is required to enable inline execution. Note that hashes do not apply to event handlers, style attributes and javascript: navigations unless the 'unsafe-hashes' keyword is present. The action has been blocked.

あとがき

別にEdgeについてるBing翻訳機能でもいいのだが、こっちのほうが操作が楽だし、DeepL翻訳がうまくいかなければ、Bing翻訳という手も使えると思えばアリだろう。

2026-01-30追記

Misskeyをはじめとした互換性のないサーバーからの投稿配信すべてに翻訳ボタンが生えてきて邪魔なので結局取り去ることに…。翻訳ボタンが必要なケースは私のユースケースでは少ないので、この結果は微妙だった…。

参考にしたもの

自分の投稿にあるタグの使用回数を知りたかったのでMastodonの本番DBを見る方法を調べた記録。

確認環境

Mastodon v4.5.4

やり方

postgresになってmastodon_productionを開くと見れる。

sudo su - postgres
psql mastodon_production

テーブル一覧は恐らくhttps://mstdn.example.com/pghero/で見れるものがそれだと思う。

DBスキーマ

有志が公開しているMastodonのER図を参考にさせてもらった。

今回打ったクエリ

自分が投稿しているタグの総数が知りたかったので、こんな感じにしてみた。たぶん自インスタンスのdomainnullと思われる。適当なので知らんけど。

SELECT
  tags.name
  ,COUNT(*) as post_count
FROM statuses
  INNER JOIN statuses_tags
    ON statuses.id = statuses_tags.status_id
  INNER JOIN tags
    ON statuses_tags.tag_id = tags.id
WHERE
  statuses.account_id = (SELECT id FROM accounts WHERE username = 'Lycolia' AND domain IS NULL)
GROUP BY
  tags.name
ORDER BY
  post_count DESC;

クエリの結果

ゾンビランドサガと三宮に対する言及がめちゃくちゃ多いことがよく分かった。

タグ名 使用回数
ゾンビランドサガ 225
三宮 205
神戸 123
兵庫 101
自炊 93
兵庫食材 72
交通 64
サイト運営 32
神戸食材 25
鉄道 22
映画 15
映画館 14
買い物 9
姫路 7
災害 5
夜景 4
経県値 4
lastfm 3
markov 3
web 3
御影 2
明石 2
尼崎 2
カメラ 2
ai 2
ui 2
せちまなと打って性格がわかるらしい 1
しなちくシステム無料ガチャ 1
加古川 1
回線 1
眼鏡っ娘を見るとストレスが減るらしい 1
気動車 1
このタグをみた人は好きな天ぷらを答える 1
阪神 1
山歩しよう 1
児島 1
shindanmaker 1
page42 1
notestocklogincode 1
notestock 1
土産 1
飯屋 1
last 1
fediverseプロフ帳 1
無事下山 1
ガルクラ 1
ガジェット 1
ガルクラタイプ診断 1
ガルクラ総集編 1
ソンビランドサガ 1
インターネット 1
ネットワーク 1
プロフィール帳 1
プロフ帳 1
ライフハック 1

参考

投稿日:

一年ぶりくらいにGitHub Actionsを使ってnpmパッケージを更新しようとしたら何かこけたので、通るようにした時にやったこと。

事象

なんかこんな感じのエラーが出てnpm publishに失敗した。

npm notice 1.6kB package.json
npm notice Tarball Details
npm notice name: @lycolia/ts-boilerplate-generator-cli
npm notice version: 0.28.1
npm notice filename: lycolia-ts-boilerplate-generator-cli-0.28.1.tgz
npm notice package size: 14.8 kB
npm notice unpacked size: 79.1 kB
npm notice shasum: 2ba5920ab2b46695bd996e86bf67b6a7cdb980cd
npm notice integrity: sha512-YHU4X10pXE7HP[...]RKmFhCpP4Gnmw==
npm notice total files: 25
npm notice
npm notice Publishing to https://registry.npmjs.org/ with tag latest and default access
npm notice Access token expired or revoked. Please try logging in again.
npm error code E404
npm error 404 Not Found - PUT https://registry.npmjs.org/@lycolia%2fts-boilerplate-generator-cli - Not found
npm error 404
npm error 404
npm error 404
npm error 404 Note that you can also install from a
npm error 404 tarball, folder, http url, or git url.

npm error A complete log of this run can be found in: /home/runner/.npm/_logs/2026-01-27T00_45_59_837Z-debug-0.log
Error: Process completed with exit code 1.

'@lycolia/ts-boilerplate-generator-cli@0.28.1' is not in this registry.

起きていたこと

  1. npmjsにあるAccess Tokensが全部消えてた
  2. Trusted publishing for npm packagesという話で、OIDC[1]を使ってGitHubと連携しないとGitHubなどのCI/CD、つまり自動化処理・バッチ処理からnpm publishできなくなっていた
  3. これに対応するためにはnpm CLI version 11.5.1か、それ以降が必要
  4. またnpmjsのOIDC連携をするためには2FA認証が必須で、そのためにはパスキーが必要
  5. Access Tokenは最大90日までになり、無制限のものはなくなった
    • Access Tokenでnpm publishを行う場合、2FAしていないとできない

対応に必要なこと

  1. npmjsに2FA登録する。要パスキー
  2. npmjsからGitHubリポジトリへのOIDC連携
  3. GitHubリポジトリにあるnpm publishしているyamlの修正
  4. npmのバージョンアップ

やったこと

  1. npmjsにパスキーを登録
  2. npmjsからGitHubリポジトリへのOIDC連携
    1. パッケージのSettingsタブを開き、Trusted publisherにリポジトリ情報を登録する
      Enviroment nameは第三者向けの項目[2]なので、設定しなくていい
    2. Set up connectionボタンを押して連携する
  3. GitHub Actionsのワークフローを直す
    1. permissionsの部分を足し、npm publishenvは不要なので削除
       name: npm publish on push to main
       on:
       push:
           branches:
           - main
      +permissions:
      +  id-token: write
      +  contents: read
       jobs:
       publish-to-npm:
           runs-on: ubuntu-latest
           steps:
           - uses: actions/checkout@v4
           - uses: actions/setup-node@v4
               with:
               node-version-file: '.nvmrc'
               cache: npm
               cache-dependency-path: package-lock.json
               registry-url: 'https://registry.npmjs.org'
           - name: npm continuous install
               run: npm ci
           - name: npm build
               run: npm run build
           - name: run publish
               run: npm publish
      -        env:
      -          NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH }}
      
  4. .nvmrcのNode.jsのバージョンをv24.13.0にした
    • このバージョンにすると自動的にnpmのバージョンが適合したため
  5. この後、GitHub Actionsを使ってnpm publishに成功すると、パッケージページやバージョン履歴ページには次のような表示が出るようになる

パスキー使いたくない問題

パスキーは端末依存で環境間共有の面倒さやGoogle縛りになるのが嫌などで入れたくない人も少なくないだろう。私もそう思う。正直パスキーありきのサービスは困る。

取り敢えず私の場合はEdgeを使っていて、Android Edgeへのパスキー共有はできないものの、いったんpublishするだけなら問題ないので、Edgeのパスキーを使うことにした。

どうしてもパスキーを使いたい、ほかの環境でも同期したいが、Googleに頼りたくない場合はKeePassXCというOSSを使うのが一つの手だ。

KeePassXCは暗号化されたデータベースファイルにIDとパスワードや、パスキーを記録するソフトウェアだ。複数環境への同期はNASなりSSHなり、クラウドストレージなどに鍵DBを保存して、それぞれの環境から読み書きすることで実現できる。

KeePassXCにはEdgeの拡張もあり、PCの中でKeePassXCを起動していればEdgeの拡張と同期してIDパスワードやパスキーを上手く管理してくれるようだった。ただ拡張機能が起動する前にKeePassXCが起動していないと手動で接続しないといけないなど、地味に面倒だった。

ただ調べた限りKeePassXCには公式のAndroidアプリがなく、サードパーティーアプリは毎回鍵ファイルを読みに行く実装のようで、オフライン時にも使うことのあるスマホでは運用に厳しさを感じた。逆に完全オフライン版もあるが、これはこれでAndroid側でDBを更新した時に別環境に飛ばすのが手間になるだろうからイマイチだ。

もう一つの選択肢としてはBitwardenを使う方法もある。こちらは公式がAndroidアプリを出しているほか、同期用のストレージを自前で用意する手間もかからない。

Bitwardenは、いわば1Passwordの無料版みたいな感じと言えるだろう。なお、BitwardenにはOSS版もあるので、セルフホスト運用もできるようだが、詳しくは調べていない。

私はBitwardenを軽く試してみたが、Edgeの自動入力機能に干渉しており、EdgeのパスワードDBを消し去らないとEdgeとBitwarden両方のパスワード入力補助が出てきて非常に邪魔だったことや、アニメーション設定をOFFにしても入力フィールドが飛び跳ねるアニメーションが出てきて嫌だったので、結局諦めた。せめて独立して動いてほしかった。

トラブルシューティング

Edgeで2FA認証しようとしたらパスキーがこけた

画像のような状態になった場合、何度かやり直すといけた。

「Two-factor authentication or granular access token with bypass 2fa enabled is required to publish packages.」と言われる

パスキーを使った2FAを登録することで解決した。

「npm error code EOTP」と言われる

npm notice Publishing to https://registry.npmjs.org/ with tag latest and default access
npm error code EOTP
npm error This operation requires a one-time password from your authenticator.
npm error You can provide a one-time password by passing --otp=<code> to the command you ran.
npm error If you already provided a one-time password then it is likely that you either typoed
npm error it, or it timed out. Please try again.

このようなエラーが出る場合、GitHub ActionsのWorkflowsのyamlファイルのルートに以下の記述が足りないので足す。

permissions:
  id-token: write  # Required for OIDC
  contents: read

「npm error code ENEEDAUTH」と言われる

npm error code ENEEDAUTH
npm error need auth This command requires you to be logged in to https://registry.npmjs.org/
npm error need auth You need to authorize this machine using `npm adduser`

このようなエラーが出る場合、npmのバージョンが古いので11.5.1以上にすることで解決する。

あとがき

正直npmjsを利用するのはもうやめようかと思う。ぶっちゃけもうNode.jsと積極的に関わりたくないし、代替技術を探したいと感じた。少なくともプライベートではそう思う。

TypeScriptに限界を感じてきたでも書いたが、Node.jsのエコシステム周りには甚だうんざりしてきており、今回の件でより、さらに、もっと嫌になった。

取り敢えず静的解析とかそういうのは欲しいし、テストもしたい、ほんでLinuxフレンドリーで、Windowsでも動いてくれるとなおよい。簡単なツールを書くことが多いのもありコンパイル言語よりはインタプリタ言語のほうが好ましい。

そう考えるとやはり浮かんでくるのはPHPになってくるあたり、21年前に触れた私の初めてのプログラミング言語との出会いに戻ってくるあたりが面白い。PHPerはPHPerから逃れられない宿命でもあるのかもしれない。

今は肩書上フロントエンドエンジニアとかいうのを仕事にしているが、そこまで性に合っていない気もしてきているし、Web系のバックエンドではPHPの仕事もまだまだあるので、これを機にPHPに戻るのも一つありだとは思った。

関係ない話、何ならadiaryのせいでTypeScriptよりPerlの方が好感を持ててきているまであるので、私はたぶんどうかしているのだと思う。


  1. OpenID Connectの略。いわゆるOAuthを使って別サービスのアカウントで連携処理を行うもの。
  2. OIDC連携はnpmjsのアカウントとリポジトリを紐づけるためのもので、publisher以外の人間が作業する場合に必要になるものと思われるが詳しくは調べていない。