Mirror of
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: accept since and end date (#1)

* feat: accept since and end date

* feat: update generate script

* Update scripts/generate-digest.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestion from @trueberryless

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

authored by

Felix Schneider
coderabbitai[bot]
and committed by
GitHub
56369003 30e898de

+34 -17
+21 -9
scripts/generate-digest.ts
··· 39 39 40 40 const now = new Date(); 41 41 const marks = [6, 14, 22]; 42 + const windowSize = 8 * 60 * 60 * 1000; // 8 hours: event fetch window 43 + const snapWindow = 2 * 60 * 60 * 1000; // 2 hours: snap-to-future threshold 42 44 43 45 const candidates: Date[] = []; 44 46 [-1, 0, 1].forEach((dayOffset) => { ··· 50 52 }); 51 53 }); 52 54 53 - const nearestMark = candidates.reduce((prev, curr) => 54 - Math.abs(curr.getTime() - now.getTime()) < 55 - Math.abs(prev.getTime() - now.getTime()) 56 - ? curr 57 - : prev, 58 - ); 55 + const futureMark = candidates 56 + .filter((d) => d.getTime() >= now.getTime()) 57 + .sort((a, b) => a.getTime() - b.getTime())[0]; 59 58 60 - const windowSize = 8 * 60 * 60 * 1000; 59 + const pastMark = candidates 60 + .filter((d) => d.getTime() < now.getTime()) 61 + .sort((a, b) => b.getTime() - a.getTime())[0]; 62 + 63 + if (!futureMark || !pastMark) { 64 + throw new Error("Failed to compute time marks from candidates"); 65 + } 66 + 67 + const diffToFuture = futureMark.getTime() - now.getTime(); 68 + const nearestMark = diffToFuture <= snapWindow ? futureMark : pastMark; 69 + 61 70 const startTime = new Date(nearestMark.getTime() - windowSize); 62 71 72 + console.log(`\x1b[34m[INFO]\x1b[0m Target Mark: ${nearestMark.toISOString()}`); 73 + console.log(`\x1b[34m[INFO]\x1b[0m Window: ${startTime.toISOString()} -> ${nearestMark.toISOString()}`); 74 + 63 75 try { 64 76 const [gh, bs] = await Promise.all([ 65 - fetchGitHubEvents(startTime), 66 - fetchBlueskyEvents(startTime), 77 + fetchGitHubEvents(startTime, nearestMark), 78 + fetchBlueskyEvents(startTime, nearestMark), 67 79 ]); 68 80 69 81 const allEvents = [...gh, ...bs];
+13 -8
src/lib/events.ts
··· 30 30 } 31 31 32 32 function sanitizeBrand(text: string): string { 33 - return cleanText.replace(/npmx/gi, "npmx").trim().replace(/^["'„“]+|["'”„“]+$/g, ""); 33 + const cleanText = text.trim().replace(/^["'„“]+|["'”„“]+$/g, ""); 34 + return cleanText.replace(/npmx/gi, "npmx"); 34 35 } 35 36 36 37 async function requestInference(payload: object) { ··· 53 54 return response.json(); 54 55 } 55 56 56 - export async function fetchGitHubEvents(since: Date): Promise<Event[]> { 57 + export async function fetchGitHubEvents(since: Date, end: Date): Promise<Event[]> { 57 58 const owner = "npmx-dev"; 58 59 const repo = "npmx.dev"; 59 60 const token = getRequiredEnv("GITHUB_TOKEN"); 60 61 const events: Event[] = []; 61 62 62 63 const startIso = since.toISOString().split(".")[0] + "Z"; 63 - const endIso = new Date().toISOString().split(".")[0] + "Z"; 64 + const endIso = end.toISOString().split(".")[0] + "Z"; 64 65 65 66 const query = encodeURIComponent( 66 67 `repo:${owner}/${repo} is:closed reason:completed -is:unmerged closed:${startIso}..${endIso}`, ··· 100 101 return events; 101 102 } 102 103 103 - export async function fetchBlueskyEvents(since: Date): Promise<Event[]> { 104 + export async function fetchBlueskyEvents(since: Date, end: Date): Promise<Event[]> { 104 105 const handle = "npmx.dev"; 105 106 const events: Event[] = []; 106 107 ··· 120 121 121 122 const posts = feed.reduce((acc: Event[], item: any) => { 122 123 const timestamp = item.reason?.indexedAt || item.post.indexedAt; 123 - if (new Date(timestamp) >= since) { 124 + const itemDate = new Date(timestamp); 125 + if (itemDate >= since && itemDate <= end) { 124 126 const author = item.post.author.handle; 125 127 acc.push({ 126 128 source: "bluesky", ··· 215 217 216 218 try { 217 219 const data = await requestInference({ 218 - messages: [{ role: "user", content: prompt }], 220 + messages: [ 221 + { role: "system", content: "You provide raw text headlines without any quotation marks or wrapping characters." }, 222 + { role: "user", content: prompt } 223 + ], 219 224 model: "gpt-4o-mini", 220 - temperature: 0.8, 225 + temperature: 0.7, 221 226 max_tokens: 30, 222 227 }); 223 228 224 - return sanitizeBrand(data.choices[0].message.content); 229 + return sanitizeBrand(data.choices[0].message.content.trim()); 225 230 } catch { 226 231 LOG.error("Failed to generate title"); 227 232 return sanitizeBrand(topic.title);