feat(04-04): /start carries the araharah logo (static-asset URL, resilient text fallback) + repo icon assets
This commit is contained in:
+1
-1
@@ -42,7 +42,7 @@ export function createBot(env: Env, opts: { baseFetch?: typeof fetch } = {}): Bo
|
|||||||
const bot = opts.baseFetch
|
const bot = opts.baseFetch
|
||||||
? new Bot(env.BOT_TOKEN, { client: { fetch: opts.baseFetch } })
|
? new Bot(env.BOT_TOKEN, { client: { fetch: opts.baseFetch } })
|
||||||
: new Bot(env.BOT_TOKEN);
|
: new Bot(env.BOT_TOKEN);
|
||||||
registerStart(bot); // /start + /mula (D-04)
|
registerStart(bot, env.MINI_APP_URL); // /start + /mula (D-04) — carries the logo asset
|
||||||
registerHelp(bot); // /help
|
registerHelp(bot); // /help
|
||||||
registerPrivacy(bot); // /privacy + /privasi (D-04)
|
registerPrivacy(bot); // /privacy + /privasi (D-04)
|
||||||
registerLocationFallback(bot, env.chat_sessions); // GEO-02 location reply fallback
|
registerLocationFallback(bot, env.chat_sessions); // GEO-02 location reply fallback
|
||||||
|
|||||||
@@ -6,8 +6,14 @@
|
|||||||
*
|
*
|
||||||
* D-02 (structural, pinned by test/commands.test.mjs): the reply is plain
|
* D-02 (structural, pinned by test/commands.test.mjs): the reply is plain
|
||||||
* text with link previews disabled — no reply menus, no inline button
|
* text with link previews disabled — no reply menus, no inline button
|
||||||
* payloads, no callback routes anywhere in this tree. Telegram commands
|
* payloads, no callback routes anywhere in this tree.
|
||||||
* are the interface until the Mini App launch path lands (Phase 4).
|
*
|
||||||
|
* Device-gate feedback (2026-10-24): /start now carries the app logo —
|
||||||
|
* sendPhoto by its STATIC-ASSET public URL (<MINI_APP_URL>/logo_arah2.png,
|
||||||
|
* deployed from web/public/). Telegram fetches it server-side; the repo
|
||||||
|
* asset stays the single source (assets/logo_arah2.png). Photo send is
|
||||||
|
* resilient: if the fetch/send fails (e.g. asset not deployed yet), the
|
||||||
|
* text reply still goes out — the greeting is never lost.
|
||||||
*
|
*
|
||||||
* All copy comes from src/i18n/strings.ts (D-05) — nothing inline here.
|
* All copy comes from src/i18n/strings.ts (D-05) — nothing inline here.
|
||||||
*/
|
*/
|
||||||
@@ -20,13 +26,35 @@ export function startReplyText(locale: Locale): string {
|
|||||||
return strings[locale].startIntro;
|
return strings[locale].startIntro;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleStart(ctx: Context): Promise<void> {
|
/** The logo's public URL — derived from the same configured origin the
|
||||||
|
* deep link uses (single origin of truth, D-11). Empty when unconfigured
|
||||||
|
* (tests/dev without vars): the caller then skips the photo send. */
|
||||||
|
export function startLogoUrl(origin: string | undefined): string | null {
|
||||||
|
if (!origin) return null;
|
||||||
|
try {
|
||||||
|
return `${new URL(origin).origin}/logo_arah2.png`;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleStart(ctx: Context, origin: string | undefined): Promise<void> {
|
||||||
const locale = pickLocale(ctx.from?.language_code);
|
const locale = pickLocale(ctx.from?.language_code);
|
||||||
await ctx.reply(startReplyText(locale), { link_preview_options: { is_disabled: true } });
|
const text = startReplyText(locale);
|
||||||
|
const logoUrl = startLogoUrl(origin);
|
||||||
|
if (logoUrl !== null) {
|
||||||
|
try {
|
||||||
|
await ctx.replyWithPhoto(logoUrl, { caption: text });
|
||||||
|
return;
|
||||||
|
} catch {
|
||||||
|
// fall through to the text reply — the greeting survives asset loss
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await ctx.reply(text, { link_preview_options: { is_disabled: true } });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Register the command stack entry: /start and its Malay alias /mula. */
|
/** Register the command stack entry: /start and its Malay alias /mula. */
|
||||||
export function registerStart(bot: Bot): void {
|
export function registerStart(bot: Bot, origin?: string): void {
|
||||||
bot.command("start", handleStart);
|
bot.command("start", (ctx) => handleStart(ctx, origin));
|
||||||
bot.command("mula", handleStart);
|
bot.command("mula", (ctx) => handleStart(ctx, origin));
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
Reference in New Issue
Block a user