1import type { StatusFetchAPIResponse } from "https://esm.town/v/nbbaier/tweetFetcher/types.ts";
2import { zValidator } from "npm:@hono/zod-validator";
3import { Hono } from "npm:hono";
18
19 const url = new URL(tweet);
20 url.host = "api.fxtwitter.com";
21
22 const res = await fetch(url);
23 const data = (await res.json()) as StatusFetchAPIResponse;
24
25 return c.json(data.tweet?.text);
1type TwitterCardType = "tweet" | "summary" | "summary_large_image" | "player";
2
3interface APIAuthor {
4 name: string;
5 screen_name: string;
9}
10
11interface APITranslate {
12 text: string;
13 source_lang: string;
15}
16
17interface APIExternalMedia {
18 type: string;
19 url: string;
23}
24
25interface APIPollChoice {
26 label: string;
27 count: number;
29}
30
31interface APIPoll {
32 choices: APIPollChoice[];
33 total_votes: number;
34 ends_at: string;
36}
37
38interface APIPhoto {
39 type: "photo";
40 url: string;
43}
44
45interface APIMosaicPhotoFormats {
46 webp: string;
47 jpeg: string;
48}
49
50interface APIMosaicPhoto {
51 type: "mosaic_photo";
52 width: number;
53 height: number;
54 formats: APIMosaicPhotoFormats;
55}
56
57type APIVideoType = "video" | "gif";
58
59interface APIVideo {
60 type: APIVideoType;
61 url: string;
62 thumbnail_url: string;
67}
68
69interface APIMedia {
70 all?: (APIPhoto | APIVideo)[];
71 external?: APIExternalMedia;
72 photos?: APIPhoto[];
73 videos?: APIVideo[];
74 mosaic?: APIMosaicPhoto;
75}
76
77export interface APITweet {
78 id: string;
79 url: string;
81 created_at: string;
82 created_timestamp: number;
83 author: APIAuthor;
84 replies: number;
85 retweets: number;
92 replying_to: string | null;
93 replying_to_status: string | null;
94 quote?: APITweet;
95 poll?: APIPoll;
96 translation?: APITranslate;
97 media?: APIMedia;
98}
99
100export interface StatusFetchAPIResponse {
101 code: 200 | 401 | 404 | 500;
102 message: "OK" | "PRIVATE_TWEET" | "NOT_FOUND" | "API_FAIL";
103 tweet?: APITweet;
104}
3import { createRoot } from "https://esm.sh/react-dom@18.2.0/client";
4
5// Since we can't directly import the Poe API wrapper, we'll create a mock implementation
6class PoeApi {
7 constructor(tokens: { 'p-b': string, 'p-lat': string }) {
8 this.tokens = tokens;
162 e.preventDefault();
163 try {
164 const client = new PoeApi(tokens);
165 const messageGenerator = client.send_message({
166 bot: 'a2',
178 return (
179 <div style={{ maxWidth: '600px', margin: 'auto', padding: '20px' }}>
180 <h1>🤖 Poe API Wrapper</h1>
181
182 {!tokens['p-b'] && (
246 <html>
247 <head>
248 <title>Poe API Wrapper</title>
249 <meta name="viewport" content="width=device-width, initial-scale=1">
250 </head>
9To use it on your own Val Town SQLite database, [fork it](https://www.val.town/v/stevekrouse/sqlite_admin/fork) to your account.
10
11It uses [basic authentication](https://www.val.town/v/pomdtr/basicAuth) with your [Val Town API Token](https://www.val.town/settings/api) as the password (leave the username field blank).
18 }));
19
20app.get("/api/miniapps", async (c) => {
21 const response = await fetch(`https://client.warpcast.com/v1/top-frameapps?limit=100`).then(r => r.json()).then(r =>
22 r?.result?.frames
91
92export async function sendDailyBriefing(chatId?: string, today?: DateTime) {
93 // Get API keys from environment
94 const apiKey = Deno.env.get("ANTHROPIC_API_KEY");
95 const telegramToken = Deno.env.get("TELEGRAM_TOKEN");
96
100 }
101
102 if (!apiKey) {
103 console.error("Anthropic API key is not configured.");
104 return;
105 }
116
117 // Initialize Anthropic client
118 const anthropic = new Anthropic({ apiKey });
119
120 // Initialize Telegram bot
156
157 // disabled title for now, it seemes unnecessary...
158 // await bot.api.sendMessage(chatId, `*${title}*`, { parse_mode: "Markdown" });
159
160 // Then send the main content
163
164 if (content.length <= MAX_LENGTH) {
165 await bot.api.sendMessage(chatId, content, { parse_mode: "Markdown" });
166 // Store the briefing in chat history
167 await storeChatMessage(
192 // Send each chunk as a separate message and store in chat history
193 for (const chunk of chunks) {
194 await bot.api.sendMessage(chatId, chunk, { parse_mode: "Markdown" });
195 // Store each chunk in chat history
196 await storeChatMessage(
77async function generateFunFacts(previousFacts) {
78 try {
79 // Get API key from environment
80 const apiKey = Deno.env.get("ANTHROPIC_API_KEY");
81 if (!apiKey) {
82 console.error("Anthropic API key is not configured.");
83 return null;
84 }
85
86 // Initialize Anthropic client
87 const anthropic = new Anthropic({ apiKey });
88
89 // Format previous facts for the prompt
86
87/**
88 * Format chat history for Anthropic API
89 */
90function formatChatHistoryForAI(history) {
314bot.on("message", async (ctx) => {
315 try {
316 // Get Anthropic API key from environment
317 const apiKey = Deno.env.get("ANTHROPIC_API_KEY");
318 if (!apiKey) {
319 console.error("Anthropic API key is not configured.");
320 ctx.reply(
321 "I apologize, but I'm not properly configured at the moment. Please inform the household administrator.",
325
326 // Initialize Anthropic client
327 const anthropic = new Anthropic({ apiKey });
328
329 // Get message text and user info
490 // Set webhook if it is not set yet
491 if (!isEndpointSet) {
492 await bot.api.setWebhook(req.url, {
493 secret_token: SECRET_TOKEN,
494 });
27async function generateConciseWeatherSummary(weatherDay) {
28 try {
29 // Get API key from environment
30 const apiKey = Deno.env.get("ANTHROPIC_API_KEY");
31 if (!apiKey) {
32 console.error("Anthropic API key is not configured.");
33 return null;
34 }
35
36 // Initialize Anthropic client
37 const anthropic = new Anthropic({ apiKey });
38
39 const response = await anthropic.messages.create({
97
98export async function sendDailyBriefing(chatId?: string, today?: DateTime) {
99 // Get API keys from environment
100 const apiKey = Deno.env.get("ANTHROPIC_API_KEY");
101 const telegramToken = Deno.env.get("TELEGRAM_TOKEN");
102
106 }
107
108 if (!apiKey) {
109 console.error("Anthropic API key is not configured.");
110 return;
111 }
122
123 // Initialize Anthropic client
124 const anthropic = new Anthropic({ apiKey });
125
126 // Initialize Telegram bot
162
163 // disabled title for now, it seemes unnecessary...
164 // await bot.api.sendMessage(chatId, `*${title}*`, { parse_mode: "Markdown" });
165
166 // Then send the main content
169
170 if (content.length <= MAX_LENGTH) {
171 await bot.api.sendMessage(chatId, content, { parse_mode: "Markdown" });
172 // Store the briefing in chat history
173 await storeChatMessage(
198 // Send each chunk as a separate message and store in chat history
199 for (const chunk of chunks) {
200 await bot.api.sendMessage(chatId, chunk, { parse_mode: "Markdown" });
201 // Store each chunk in chat history
202 await storeChatMessage(