<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>ChatGPT → Obsidian</title>
<!-- PWA(必要なら既存のままでOK) -->
<link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#ffffff" />
<style>
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans JP", sans-serif; margin: 24px; line-height: 1.5; }
h1 { font-size: 44px; margin: 0 0 18px; }
.msg { font-size: 20px; margin: 12px 0; }
.btn { font-size: 18px; padding: 12px 18px; border-radius: 10px; border: 1px solid #ccc; background: #fff; cursor: pointer; }
.btnPrimary { border-color: #111; }
.box { margin-top: 14px; padding: 12px; border: 1px solid #ddd; border-radius: 10px; background: #fafafa; white-space: pre-wrap; }
.small { color: #666; font-size: 14px; margin-top: 8px; }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
</style>
</head>
<body>
<h1>ChatGPT → Obsidian</h1>
<p class="msg" id="status">このページを開いたら、下の「クリップボードを読み取る」を押してください。</p>
<div class="row">
<button class="btn btnPrimary" id="readBtn">クリップボードを読み取る</button>
<button class="btn" id="sendBtn" disabled>Dropboxに保存する</button>
</div>
<div class="small">
※ iPhone/Android ではセキュリティ上、ボタン操作なしにクリップボードを読めません(仕様です)。
</div>
<div class="box" id="preview" style="display:none;"></div>
<script>
// ★あなたの Worker URL に変更(すでにある Worker のURLを入れる)
// 例: https://shrill-night-0dd4.yotanishida.workers.dev
const WORKER_URL = "https://shrill-night-0dd4.yotanishida.workers.dev";
const statusEl = document.getElementById("status");
const previewEl = document.getElementById("preview");
const readBtn = document.getElementById("readBtn");
const sendBtn = document.getElementById("sendBtn");
let lastText = "";
function setStatus(msg) {
statusEl.textContent = msg;
}
async function readClipboard() {
try {
const text = await navigator.clipboard.readText();
if (!text || !text.trim()) {
setStatus("クリップボードが空です。ChatGPTの内容をコピーしてから、もう一度押してください。");
previewEl.style.display = "none";
sendBtn.disabled = true;
lastText = "";
return;
}
lastText = text;
previewEl.textContent = text;
previewEl.style.display = "block";
sendBtn.disabled = false;
setStatus("読み取りOK。内容を確認して「Dropboxに保存する」を押してください。");
} catch (e) {
// iOS/Android でよくある:権限・ジェスチャー不足・非対応など
setStatus("クリップボードを読めませんでした。ChatGPTで「コピー」をしてから、このボタンをもう一度押してください。");
previewEl.style.display = "none";
sendBtn.disabled = true;
lastText = "";
}
}
async function sendToWorker() {
if (!lastText.trim()) return;
if (WORKER_URL.includes("https://shrill-night-0dd4.yotanishida.workers.dev")) {
setStatus("WORKER_URL が未設定です。index.html の WORKER_URL をあなたの Worker URL に置き換えてください。");
return;
}
setStatus("Dropboxに保存しています…");
// タイトル(ファイル名用)
const now = new Date();
const pad = (n) => String(n).padStart(2, "0");
const title =
`${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
try {
const res = await fetch(WORKER_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: title,
text: lastText
})
});
const body = await res.text().catch(() => "");
if (!res.ok) {
setStatus(`保存に失敗しました(HTTP ${res.status})。Workerログを確認してください。`);
console.error("Worker error:", res.status, body);
return;
}
setStatus("保存しました!Dropbox/Obsidian側で.mdが増えているか確認してください。");
} catch (e) {
setStatus("通信に失敗しました。ネットワークやWorker URLを確認してください。");
console.error(e);
}
}
readBtn.addEventListener("click", readClipboard);
sendBtn.addEventListener("click", sendToWorker);
</script>
</body>
</html>