mirror of
https://github.com/tiennm99/claude-status-webhook.git
synced 2026-04-17 13:21:01 +00:00
refactor: remove migration route and logic after successful migration
This commit is contained in:
@@ -33,7 +33,6 @@ Cloudflare Workers with two entry points exported from `src/index.js`:
|
|||||||
| GET | `/` | inline | Health check |
|
| GET | `/` | inline | Health check |
|
||||||
| POST | `/webhook/telegram` | `bot-commands.js` | grammY `webhookCallback("cloudflare-mod")` |
|
| POST | `/webhook/telegram` | `bot-commands.js` | grammY `webhookCallback("cloudflare-mod")` |
|
||||||
| POST | `/webhook/status/:secret` | `statuspage-webhook.js` | Receives Statuspage webhooks (URL secret) |
|
| POST | `/webhook/status/:secret` | `statuspage-webhook.js` | Receives Statuspage webhooks (URL secret) |
|
||||||
| POST | `/migrate/:secret` | inline | One-time KV migration (remove after use) |
|
|
||||||
|
|
||||||
### Data Flow
|
### Data Flow
|
||||||
|
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -105,16 +105,6 @@ It will prompt for your bot token and worker URL. You should see `{"ok":true}` f
|
|||||||
|
|
||||||
Replace `<WEBHOOK_SECRET>` with the secret you set in step 4.
|
Replace `<WEBHOOK_SECRET>` with the secret you set in step 4.
|
||||||
|
|
||||||
### 8. Run migration (if upgrading)
|
|
||||||
|
|
||||||
If you have existing subscribers from an older version, run the migration endpoint once:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST https://<WORKER_URL>/migrate/<WEBHOOK_SECRET>
|
|
||||||
```
|
|
||||||
|
|
||||||
This converts the old single-key format to per-subscriber KV keys. Remove the `/migrate` route from `src/index.js` after confirming success.
|
|
||||||
|
|
||||||
## Local Development
|
## Local Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
11
src/index.js
11
src/index.js
@@ -2,8 +2,6 @@ import { Hono } from "hono";
|
|||||||
import { handleTelegramWebhook } from "./bot-commands.js";
|
import { handleTelegramWebhook } from "./bot-commands.js";
|
||||||
import { handleStatuspageWebhook } from "./statuspage-webhook.js";
|
import { handleStatuspageWebhook } from "./statuspage-webhook.js";
|
||||||
import { handleQueue } from "./queue-consumer.js";
|
import { handleQueue } from "./queue-consumer.js";
|
||||||
import { migrateFromSingleKey } from "./kv-store.js";
|
|
||||||
import { timingSafeEqual } from "./crypto-utils.js";
|
|
||||||
|
|
||||||
const app = new Hono();
|
const app = new Hono();
|
||||||
|
|
||||||
@@ -24,15 +22,6 @@ app.get("/", (c) => c.text("Claude Status Bot is running"));
|
|||||||
app.post("/webhook/telegram", (c) => handleTelegramWebhook(c));
|
app.post("/webhook/telegram", (c) => handleTelegramWebhook(c));
|
||||||
app.post("/webhook/status/:secret", (c) => handleStatuspageWebhook(c));
|
app.post("/webhook/status/:secret", (c) => handleStatuspageWebhook(c));
|
||||||
|
|
||||||
// One-time migration route — remove after migration is confirmed
|
|
||||||
app.post("/migrate/:secret", async (c) => {
|
|
||||||
const secret = c.req.param("secret");
|
|
||||||
if (!await timingSafeEqual(secret, c.env.WEBHOOK_SECRET)) {
|
|
||||||
return c.text("Unauthorized", 401);
|
|
||||||
}
|
|
||||||
const count = await migrateFromSingleKey(c.env.claude_status);
|
|
||||||
return c.json({ migrated: count });
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
fetch: app.fetch,
|
fetch: app.fetch,
|
||||||
|
|||||||
@@ -136,31 +136,3 @@ export async function getSubscribersByType(kv, eventType, componentName = null)
|
|||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* One-time migration from single-key "subscribers" to per-key format.
|
|
||||||
* Returns count of migrated entries.
|
|
||||||
*/
|
|
||||||
export async function migrateFromSingleKey(kv) {
|
|
||||||
const old = await kv.get("subscribers", "json");
|
|
||||||
if (!old) return 0;
|
|
||||||
|
|
||||||
const entries = Object.entries(old);
|
|
||||||
for (const [compositeKey, value] of entries) {
|
|
||||||
const data = { types: value.types || [], components: value.components || [] };
|
|
||||||
await kv.put(`${KEY_PREFIX}${compositeKey}`, JSON.stringify(data), {
|
|
||||||
metadata: buildMetadata(data.types, data.components),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify migrated count before deleting old key
|
|
||||||
const migrated = await listAllSubscriberKeys(kv);
|
|
||||||
if (migrated.length >= entries.length) {
|
|
||||||
await kv.delete("subscribers");
|
|
||||||
console.log(`Migration complete: ${entries.length} subscribers migrated`);
|
|
||||||
} else {
|
|
||||||
console.error(`Migration verification failed: expected ${entries.length}, got ${migrated.length}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entries.length;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user