LINE botの作成方法

アプリケーションのUIとしてLINE botを作成する手順を示します。 LINE Developersの準備 LINE Developersにログインし、新規プロバイダーと「Messaging API」チャネルを作成します。 作成したチャネルから「チャネルアクセストークン」と「チャネルシークレット」を控えます。 サーバーサイドアプリケーションの構築 Python (Flask) や Node.js (Express) などで、LINEからのWebhookリクエストを受け取るサーバーを準備します。 ユーザーからのメッセージ(テキスト、画像など)を受信し、応答するロジックを実装します。 ロジックの実装 受信したメッセージを解析します。例えば、「肉じゃがを追加して」のようなテキストや、共有されたレシピ画像・URLを処理する部分です。 解析結果に応じて、このドキュメントで定義されている献立生成や修正の機能を呼び出します。 デプロイと設定 作成したアプリケーションをHerokuやAWSなどのサーバーにデプロイします。 デプロイしたアプリケーションのURLを、LINE Developersコンソールの「Webhook URL」に設定します。 これで、LINEを通じて献立のリクエストや修正ができるようになります。

August 20, 2025 · 1 min · moai

org-roamで異なるファイルへの見出しへのリンク取得方法

org_roamで異なるファイルへの見出しへのリンク取得方法が知りたい。 見出しをorg-roamのnodeにする =org-id-get-create=コマンドを実行する。 すると以下のようなIDが振られる。 適当な見出し :ID: cc9f43cb-6891-4322-90d5-82571fde8668 見出しに対するリンクを貼る org-roam-node-insert コマンド使って絞り込みます。 C-c n i (org-roam-node-insert) を実行します。 目的の見出しを選択して RET を押します。

August 20, 2025 · 1 min · moai

解決編:pandocでdocxをorgファイルに変換する際に何故かquoteで囲われてしまう。

Pandocは文書形式の相互変換が便利ななツールです。 私も普段から利用していますが、先日、Word(.docx)ファイルからorg-mode(.org)ファイルへ変換する際に面倒な問題に遭遇しました。 この記事では、その試行錯誤の道のりと解決策をまとめます。 課題 : 箇条書きが、意図せず#+begin_quote…#+end_quoteブロックで囲まれてしまう docx形式で作成した箇条書きリストを、Pandocを使ってorgファイルに変換したところ、2つの大きな問題が発生しました。 ネストした箇条書きが、意図せず#+begin_quote…#+end_quoteブロックで囲まれてしまう。 各リスト項目の間に、不要な空行が入ってしまい、間延びした表示になる。 問題の出力例: コード スニペット #+begin_quote 親項目1 #+begin_quote 子項目A #+end_quote #+begin_quote 子項目B #+end_quote #+end_quote このような出力は、見た目が崩れるだけでなく、構造的にも意図しない「引用」となってしまい、org-modeでの再利用性を著しく損ないます。 最終結論 この問題は、PandocのLuaフィルタを使い、変換プロセス中にリストのネストを引用としないことで解決しました。 原因は、以下の2点でした。 Word文書のインデント構造が、PandocによってリストのネストではなくBlockQuote(引用ブロック)として解釈されていた。 リストの各項目がPara(段落)要素で構成されており、これがorg-mode出力時に項目間の空行を生んでいた。 最終的に完成したLuaフィルタと実行コマンドは記事の最後にまとめてあります。 試行錯誤1:単純なBlockQuoteの解除 最初に考えたのは、「問題となっているBlockQuoteを単純に解除すればよいのでは?」というアプローチでした。 しかし、単純な条件のフィルタではうまくいかず、原因を特定する必要に迫られました。 まず、 pandoc -t native コマンドで文書の内部構造をダンプしてみると、問題の箇所は以下のような構造になっていることがわかりました。 , BulletList [ [ BlockQuote [ Para [ Str “\12456\12450\12525\12496\12452\12463\12434\36092\20837\12377\12427” ] ] , BulletList [ [ BlockQuote [ Para [ Str “\12489\12524\12483\12469\12540\12434\25448\12390\12427” ] ] ] , [ BlockQuote [ Para [ Str “\12362\12418\12385\12419\12384\12394\12434\37096\23627\12398\30495\12435\20013\12395\25345\12387\12390\12367\12427” ] ] ] , [ BlockQuote [ Para [ Str ...

August 17, 2025 · 2 min · moai

私について

山崎 遼介 (Yosuke Yamazaki) プロダクトと組織の両面を理解し、実装から事業インパクトまで貢献することを得意としています。 バックエンド・フロントエンドの実装経験や、インフラ・非同期処理に関する知識を活かし、エンジニア、EM、スクラムマスターとしての経験を基に、認証・認可領域のプロダクト戦略を実行しています。 また、組織横断での標準化やプロセス改善も推進しています。 スキル AWS Go Java React Ruby on Rails UXデザイン エンジニア採用 プロジェクトマネジメント 経歴 freee株式会社 (現職) プロダクトマネージャー SIer (前職) Webアプリケーションの開発、運用、インフラ構築、トラブルシューティングに従事。 学歴 慶應義塾大学大学院 理工学研究科 (2009-2011)

August 17, 2025 · 1 min · moai

elispにおける『,』の意義

`,` には、どのような意味があるのでしょうか? 例えば以下のようなコードを考えてみます。 (setq org-roam-capture-templates `(("d" "default" plain "%?" :target (file+head "sketches/nodes/%<%Y%m%d%H%M%S>-${slug}.org" ,(my-org-roam-hugo-header "${title}" "sketches/nodes"))) ("p" "post" plain "%?" :target (file+head "posts/%<%Y%m%d%H%M%S>-${slug}.org" ,(my-org-roam-hugo-header "${title}" "posts"))))) (setq org-roam-dailies-capture-templates `(("d" "default" entry "* %?" :target (file+head "%<%Y-%m-%d>.org" ,(my-org-roam-hugo-header "%<%Y-%m-%d>" "sketches/dailies"))))) 前提:バッククオート (`) の機能 まず、カンマを理解するには、その外側を囲んでいるバッククオート (`` ` ``) の役割を知る必要があります。 バッククオートは、内部の式を「評価させない」ための記号です。つまり、`(setq …)` のような関数呼び出しとは異なり、バッククオートで囲まれたリストはコードとして実行されず、そのままデータ(リスト構造)として扱われます。 この例では、`org-roam-capture-templates` という変数に、テンプレート定義のリストを「データとして」設定しようとしています。 本題:カンマ (,) による部分的な評価 ここで登場するのがカンマ (`,`) です。カンマは、バッククオートの「評価しない」という原則に対する唯一の例外を指定します。 カンマは、直後にある式を「この部分だけは評価(実行)せよ」とEmacs Lispに指示するマーカーです。提示されたコードを見てみましょう。 ... ,(my-org-roam-hugo-header "${title}" "sketches/nodes") ... この部分では、カンマの働きにより `my-org-roam-hugo-header` 関数が呼び出され、その *返り値*(この場合は生成されたヘッダー文字列)がリストのその位置に挿入されます。 もしカンマがなければ、`(my-org-roam-hugo-header …)` という式自体がリストの一要素として扱われてしまい、関数が実行されることはありません。これでは意図したテンプレートは完成しません。 結論:静的なデータ構造に関数の実行結果を埋め込む記法 結論として、バッククオート (`) とカンマ (,) はセットで使われ、「基本的には評価しないデータ構造を定義しつつ、特定の部分だけ動的に生成した値で置き換えたい」という場面で活躍します。 したがって、このカンマは バッククオート構文の中で関数を呼び出し、その結果を埋め込むために不可欠な記号 と言えます。

August 17, 2025 · 1 min · moai

google docを個人のorg-roamのnodeとして取り込む自動化

はじめに 本記事では、Google Drive上のGoogleドキュメントを自動で取得し、個人のorg-roamナレッジベースにノートとして取り込むための自動化スクリプト fetch_drive_data.sh について解説します。 外出先のモバイルで調査した内容をうまくナレッジにするには? 解きたかった課題は「外出先で調査・思索した内容を、いかに効率よく個人のナレッジベース(org-roam)に集約するか」という点です。 現在スマートフォンでの情報収集やアイデアメモが大きな比重を占めています。 例えばスマートフォンのGeminiアプリは、調査や文章生成に非常に強力なツールです。 しかし、その内容をorg-roamのナレッジにするのは煩雑な手順が必要です。 google docsにエクスポートして orgフォーマットに直し org-roamのnodeとして追加する このような手順を行う必要があります。手動で5ステップほどでしょうか。 少し多いですね。 一方で、GeminiアプリはGeminiの応答をGoogleドキュメントとして手軽にエクスポートできます。 Googleドキュメントとして保存する操作は、どのデバイスからでも非常に簡単です。 そのため、手軽なナレッジ追加自体は簡単に思えます。 これをうまく結合させようと思ったのが開発の発端でした。 ここからアイディアを発展させて特定のGoogle DriveをGeminiなどで調査した外部情報の「一時受け入れボックス(インボックス)」として機能させることを思いつきました。 orgzly の利用は却下した 当初は orgzly のようなモバイルアプリも検討しました。 これはorgファイルを直接モバイルでも扱えるようにするものです。 しかし、このアイディアは却下しました。 スマートフォン上で直接orgファイルのフォーマットを整えながら編集するのは、操作が煩雑に感じられたためです。 しかもGeminiアプリからの転記作業も必要です。 また、 orgzly データの同期は syncthing を用いるものが一般的なようでしたが、このアプリケーションがセキュアかどうか判断しかねたのです。 そのため、 orgzly を利用するのはやめました。 rcloneを利用してナレッジの取り込む方針とした 上記のアイディアを検討した結果、 rclone で取り込むことにしました。 そうすると必要なのはorg-roamにnodeとして取り込みを自動化する処理です。 ここまでくればあとは開発するのみです。 諸々ゴニョゴニョする必要はありますが、力技です。 具体的には以下の処理です。 rclone を使って、指定したGoogle Driveフォルダからドキュメントを一括でダウンロードする。 ダウンロードしたファイルを pandoc でorg-mode形式に変換する。 変換したファイルにorg-roam用のプロパティ(IDなど)を付与し、ノートとして所定のディレクトリに配置する。 この流れをシェルスクリプトに落とし込みます。 モバイルでGoogle Driveに保存、PCで取り込みという体験の完成 このshell scriptによってこのようなフローが実現できます。 モバイルで行うこと 調査したことをGoogle Driveに保存 PCで行うこと shellの実行 これによりモバイルで生まれた着想や調査結果を、コマンド一つでシームレスにナレッジに統合する仕組みの完成です。 参考)スクリプトの全体像 以下が、今回開発した fetch_drive_data.sh の全容です。参考に貼っておきます。 #!/bin/bash # fetch_drive_data.sh: 指定したGoogle Driveフォルダ内のすべてのGoogleドキュメントを # 一括ダウンロードし、org-roamノートに変換してDBを同期するスクリプト # --- 設定 --- # Google DriveのフォルダIDを指定 FOLDER_ID="${your_folder_id}" # org-roamのノートが保存されているディレクトリパスを指定 ORG_ROAM_DIR="org_sources/sketches/nodes/" # 作成されるorgノートに設定するHugoのセクション HUGO_NODES_SECTION="sketches/nodes" # --- 初期化 --- set -e # エラーが発生したらスクリプトを終了 TEMP_DIR=$(mktemp -d) TMP_RCLONE_CONF="/tmp/rclone.conf.$$" # スクリプト終了時に一時ファイルを必ず削除する trap 'rm -f "$TMP_RCLONE_CONF"; rm -rf "$TEMP_DIR"' EXIT # --- rclone設定 --- echo "1. rcloneの設定を読み込み中..." pass show rclone/config > "$TMP_RCLONE_CONF" export RCLONE_CONFIG="$TMP_RCLONE_CONF" echo "設定読み込み完了。" # --- 一括ダウンロード --- echo "2. Google Driveからドキュメントを一括ダウンロード中 (Folder ID: ${FOLDER_ID})..." # --include "*.gdoc" でGoogleドキュメントのみを対象にする rclone copy "gdrive:" --drive-root-folder-id "${FOLDER_ID}" "${TEMP_DIR}" -P -v # ダウンロードされたファイルがあるか確認 if [ -z "$(find "$TEMP_DIR" -name "*.docx")" ]; then echo "ダウンロードされたdocxファイルが見つかりません。処理を終了します。" exit 0 fi echo "一括ダウンロード完了。" # --- ローカルでのループ処理 --- echo "3. ダウンロードした各ファイルの処理を開始..." for DOCX_FILE in "$TEMP_DIR"/*.docx; do echo "--------------------------------------------------" echo "処理中: $(basename "$DOCX_FILE")" # 3a. pandocでorgに変換 BASENAME=$(basename "$DOCX_FILE" .docx) echo " - pandocでorgに変換中..." PANDOC_ORG_FILE="${TEMP_DIR}/${BASENAME}.org" pandoc -f docx -t org "$DOCX_FILE" -o "$PANDOC_ORG_FILE" --wrap=none # 3b. org-roam用ファイルを作成 echo " - org-roamノートを作成中..." ROAM_ID=$(uuidgen) ROAM_BASENAME=$(echo "${BASENAME}" | tr ' ' '_') ROAM_FILE_PATH="${ORG_ROAM_DIR}$(date +%Y%m%d%H%M%S)-${ROAM_BASENAME}.org" { echo ":PROPERTIES:" echo ":ID: ${ROAM_ID}" echo ":END:" echo "#+title: ${BASENAME}" echo "#+HUGO_SECTION: ${HUGO_NODES_SECTION}" echo "#+AUTHOR: moai" echo "#+HUGO_AUTO_SET_LASTMOD: t" echo "#+hugo_paired_shortcodes: reasoning" echo "" cat "$PANDOC_ORG_FILE" } > "$ROAM_FILE_PATH" echo " - ノート作成完了: ${ROAM_FILE_PATH}" done echo "--------------------------------------------------" echo "全てのファイルの処理が完了しました。" # --- DB同期とHugoエクスポート --- echo "4. org-roamデータベースを更新し、Hugoコンテンツをエクスポート中..." emacs --batch -l ~/.emacs.d/init.el --eval '(progn (org-roam-db-sync) (my-hugo-export-all-org-sources))' echo "DB同期とHugoエクスポートが完了しました。" # --- Google Driveのクリーンアップ --- echo "5. 処理済みのドキュメントをGoogle Driveから削除中..." rclone delete "gdrive:" --drive-root-folder-id "${FOLDER_ID}" --include "*.gdoc" -P -v echo "Google Driveのクリーンアップが完了しました。" echo "全ての処理が正常に完了しました。" 実際にはこのshellをmakeコマンドにして実行できるようにしています。 ...

August 17, 2025 · 2 min · moai

Hugoサイトの目次(TOC)制御:PaperModテーマでの設定方法

TOCはどうやって表示できるようにするのが良いのだろうか? Hugoでブログに目次(Table of Contents, TOC)は重要です。TOCがあることで記事の読みやすさを向上できるからです。 でも、このときに疑問があります。 このTOCの制御する方法とは? また複数の選択肢があった場合にどこでやるのが良いのだろうか? こういう事を考えてみたいと思います。 TOCの制御方法はPaperModの機能で実現するのが良い。 この記事の結論としてはPaperModの機能で実現するのが良いとしました。 config/_default/hugo.toml に以下の設定を加える方法です。 [params] UseHugoToc = true showtoc = true なぜこのような設定にしたのでしょうか? その結論を得るための前提の方法の洗い出し、各選択肢の比較と最終的にPaperModの機能で良いとした理由を記述します。 HugoのブログのTOC表示の選択肢は3つある。 Hugoのブログでは3つの選択肢があります。 Hugo自身の設定 Hugoテーマ(本サイトではPaperMod)の機能 コンテンツ変換ツールでTOCをMarkdownに挿入する 私の場合、 ox-hugo でEmacs Org modeからMarkdownへ変換しています。 色々ありますね。 ox-hugoでのTOC生成を試し、却下した 当初、私は ox-hugo の機能を使ってTOCを生成しようと考えました。 Orgファイルのプロパティとして以下の設定を加える方法です。 #+TOC: headlines 3 しかし、この方法にはいくつかの課題がありました。 課題点 生成されるMarkdownファイルに、TOCがHTMLの = <div class“ox-hugo-toc”>…</div> == のように直接書き込まれてしまう。 これにより、Markdownファイルが冗長になる。 Hugoやテーマ側での動的なTOC制御(サイドバーでの追従表示など)が効かなくなる。 Hugoの強みは、コンテンツ(Markdown)とプレゼンテーション(テーマ)を分離できる点にあります。 コンテンツファイルに直接HTMLを埋め込むこの方法は、その思想とは少しずれていると感じました。 また、この試行錯誤をしたときにはHugo自体にTOCを生成する機能があるとは知りませんでした。 最終的な解決策:HugoとPaperModのTOC機能を利用する そこで、TOCの生成と表示はHugoとテーマ側に一任する方針に切り替えました。 本サイトで利用しているPaperModテーマには、TOCを制御する機能があります。 設定は config/_default/hugo.toml ファイルで行います。 [params] UseHugoToc = true showtoc = true UseHugoToc = true : Hugoの組み込みTOC生成機能を使用することをPaperModに伝えます。 showtoc = true : 記事ページでTOCを表示します。 この設定により、各記事のMarkdownファイルに特別な記述が不要になります。 また、Hugoが自動で見出しを解析してTOCを生成し、PaperModがそれを適切な場所に表示してくれます。 ...

August 17, 2025 · 1 min · moai

LLMを活用した求人検索ガイド

ステップの概要 探索ステップ Deep Researchに利用するプロンプトを作成します。 上記のプロンプトを使ってLLMにDeep Researchさせます。 深堀りステップ プロンプト例 改善案と追加のヒント ステップの概要 探索: AIに自身の興味・関心事を伝え、それに基づいた求人検索用のプロンプトを作成させる。そのプロンプトを使い、世の中の求人候補を広くリストアップする。 深掘り: 気になる企業を個別に調査する。LLMに事業の成長性、福利厚生、業務委託の有無などを質問し、理解を深めてから応募する。 探索ステップ Deep Researchに利用するプロンプトを作成します。 まずはプロンプト自体をLLMに作成させます。 プロンプト作成のプロンプトは以下です。 プロンプト作成依頼文 私の興味のある業種で求人を検索したいです。Deep Resarchで検索するうえで利用可能なプロンプトを作成してくれますか? 出力されたプロンプト具体例 この具体例を使って、Deep Researchを実行します。 私の興味に合致した企業・組織・事業をリストアップしてください。対象はスタートアップ、大手企業の新規事業、NPO、研究機関を含みます。 【興味のある領域】 意味や価値の定義が揺らいでいる領域(例:教育、介護、創造性、メンタルヘルスなど) 現実世界との物理的接続がある領域(例:IoT、ロボティクス、農業、物流など) データの世界に物理環境を再現するような領域(例:デジタルツイン、行動モデル設計、AR/VR) 【重視したい観点】 データ化しづらい現場の知見や構造の革新 LLMやAIを活用して構造を読み替えるような事業 プロセスや構造が未整備・未標準で、仮説検証の余地がある領域 社会的意義や中長期的に意味のある課題に取り組んでいること 【条件】 日本語での求人があることが望ましい リモート勤務可能であれば尚良い 年収900万円以上が理想(ただしリストアップ時点では必須ではない) 【出力フォーマット】 企業名(URLあれば) 主な事業内容 該当する興味との関連 求人有無とそのURL(ある場合) 上記のプロンプトを使ってLLMにDeep Researchさせます。 上記のプロンプト自体の質が、結果に反映されます。 深堀りステップ 興味ある項目を個別の企業ごとに聞いていく プロンプト例 〇〇という企業の競合について教えてください。それに対してどのようなポジションを取っているのでしょうか? 出力はいろいろです。 ...

August 17, 2025 · 1 min · moai

rclone設定トラブルシューティングのまとめ

今回rcloneの設定で発生した問題と、その解決に至るまでの手順は以下の通りです。 状況1:ポート使用中エラー (address already in use) 問題: `rclone config` 実行時、認証用ポートが他のプロセスで使用中のため起動できない。 対処: `rclone authorize` コマンドを直接実行し、手動認証を試みたが、次の問題が発生した。 状況2:リダイレクトURI不一致エラー (redirect_uri_mismatch) 問題: `rclone authorize` で表示されたURLにアクセスすると、Googleからエラー `400: redirect_uri_mismatch` が返される。これは、rcloneが要求するリダイレクト先URLがGoogle Cloudプロジェクトに登録されていないことが原因。 対処: `rclone config` の対話モードで、自動設定(`Use auto config?`)を「No (n)」にし、手動認証を試みた。 状況3:ヘッドレス環境としての誤認識 問題: 手動設定を選択してもGoogleの認証URLが表示されず、「ブラウザのあるマシンで `rclone authorize` を実行してください」というサーバー環境向けの指示が表示される。rcloneが実行環境を誤認識していることが原因。 根本原因の推定: rcloneに標準で組み込まれているクライアントIDが、Googleのセキュリティポリシー変更などにより正常に機能しなくなっている可能性が高い。 根本的解決策:専用のOAuthクライアントIDの作成と利用 手順1:Google Cloud PlatformでOAuthクライアントIDを作成 プロジェクト作成: Google Cloud Platformにログインし、新規プロジェクトを作成する。 APIの有効化: 「APIとサービス」から「Google Drive API」を検索し、有効化する。 OAuth同意画面の設定: User Typeを「外部」に設定する。 アプリ名、ユーザーサポートメールなどを入力する。 認証情報の作成: 「認証情報を作成」から「OAuthクライアントID」を選択する。 アプリケーションの種類を「デスクトップアプリ」に設定して作成する。 表示された「クライアントID」と「クライアントシークレット」を控える。 手順2:作成したクライアントIDでrcloneを設定 `rclone config` を再度実行し、新しいリモート接続の作成を開始する。 `client_id`と`client_secret`を尋ねられた際、手順1で控えた自身の値を入力して認証を進める。 状況4:Googleによるアプリ未審査エラー 問題: 自作のクライアントIDで認証を進めると、「このアプリは現在テスト中で、承認されたテスターのみがアクセスできます」というエラーがGoogleから表示される。 原因: 作成したOAuthクライアントIDが「テストモード」のため、許可されたテストユーザー以外からのアクセスがブロックされている。 手順3:テストユーザーに自身のアカウントを追加(最終解決策) 再度、Google Cloud Platformの「OAuth同意画面」を開く。 「テストユーザー」の項目で「+ ADD USERS」をクリックし、rcloneで認証したい自身のGoogleアカウントのメールアドレスを追加する。 上記設定後、rcloneの認証プロセスを再実行することで、認証が正常に完了した。 ...

August 17, 2025 · 1 min · moai