Home > Reflections | โฎ๏ธ โญ๏ธ

2025-04-13 | ๐Ÿ’ช Empower ๐Ÿ‘ฅ People

๐Ÿ“š Books

๐Ÿค–๐Ÿค–๐Ÿ“– An AI Book Report Template

  • ๐Ÿ’ป This is the Obsidian templater template Iโ€™m currently using for AI book reports.
  • โž• I use the QuickAdd plugin to call the template.
  • ๐Ÿ“ฑ I use the Commander plugin to put a button on my mobile toolbar
  • ๐Ÿ› ๏ธ Itโ€™s not a perfect work of software craftsmanship; just a practical script that streamlined and automates.
  • โœ… I think itโ€™s working pretty well!
  • โš™๏ธ Workflow
    • โž• Click the plus button on my mobile toolbar (bringing up the QuickAdd menu)
    • ๐Ÿ“– Choose book from the menu
    • ๐Ÿ“ Paste the name of a book (no colons due to filename restrictions) into the text box
    • โณ Wait several long seconds (less than a minute, but thereโ€™s a definite time delay)
    • ๐Ÿ’ฐ Profit!
  • ๐Ÿค– The template will
    • ๐Ÿ“„ create a new file named after the book (in kebab-case)
    • โš™๏ธ set up some frontmatter (yaml at the top of the markdown file) and boilerplate text and links
    • ๐Ÿ—ฃ๏ธ Call the Gemini API asking for a book report (see the prompt below)
      • ๐Ÿ’ฐ using a newer model with a relatively low rate limit & daily cap
    • โœจ Send the result back to Gemini to Emojify it
      • โšก using a good standard model with a very generous rate limit and daily cap
    • ๐Ÿงน Clean up some whitespace
    • โœ๏ธ Insert the result into the new note
    • ๐Ÿ”— (QuickAdd adds a link to the new file wherever my cursor was)
  • โœ๏ธ After that, I may do some light editing, pick some nice emojis for the title, etc - but itโ€™s largely ready to go
  • ๐Ÿ”‘ All you need is a (free) Gemini API key.
<%*  
const filename = tp.file.title  
const kebabCase = filename  
  .toLowerCase()  
  .replaceAll("'", '')  
  .replace(/[^a-z0-9]+/g, '-')  
  .replace(/^-+|-+$/g, '')  
%>---  
share: true  
aliases:  
  - "<% filename %>"  
title: "<% filename %>"  
URL: https://bagrounds.org/books/<%kebabCase%>  
Author:   
tags:  
---  
[[index|Home]] > [[/books/index|Books]]  
# <% filename %>  
<%*  
async function generateTextFromGemini(prompt, apiKey, model = "gemini-2.0-flash", search = false) {  
  const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;  
  
  const body = {  
      "contents": [  
          {  
              "parts": [  
                  {"text": prompt }  
              ]  
          }  
      ],  
      "tools": [  
          {  
              "google_search": {}  
          }  
      ]  
  };  
  if (!search) delete body.tools  
  
  
    const response = await fetch(apiUrl, {  
      method: "POST",  
      headers: {  
        "Content-Type": "application/json",  
      },  
      body: JSON.stringify(body),  
    });  
  
    if (!response.ok) {  
      throw new Error(`HTTP error! status: ${response.status}`);  
    }  
  
    const data = await response.json();  
    const { parts } = data.candidates[0].content;  
    return (parts[1] || parts[0]).text;  
}  
  
const GEMINI_API_KEY = "https://ai.google.dev/gemini-api/docs/api-key"; // Replace with your actual API key.  
  
const prompt = `Write a markdown-formatted (start headings at level H2) book report, followed by a plethora of additional similar, contrasting, and creatively related book recommendations on ${filename}. Be thorough in content discussed but concise and economical with your language. Structure the report with section headings and bulleted lists to avoid long blocks of text.`;  
  
const emojifyPrompt = report => `Enhance the selected markdown content by inserting relevant emojis: "${report}".  
Each emoji should go before the word, phrase, or sentence it represents, followed by a space.  
Put at least 1 emoji at the beginning of each section heading, bullet point, or line of text.  
Insert emojis in long blocks of text.  
Only return the text with the emojis.  
Ensure the placement of emojis doesn't conflict with markdown syntax.`;  
  
const model = 'gemini-2.5-pro-exp-03-25'  
// const model = 'gemini-2.0-flash-thinking-exp-01-21'  
  
try {  
    const report = await generateTextFromGemini(prompt, GEMINI_API_KEY, model, true);   
    const emojified = await generateTextFromGemini(emojifyPrompt(report), GEMINI_API_KEY);  
  
    const clean = emojified  
        .replaceAll(/(?<!^ *)( +)/gm, ' ')  
        .replaceAll(/ +$/gm, '')  
        .replaceAll(/\n\n\n+/g, '\n\n')  
  
    tR += clean;  
} catch (error) {  
    tR += `Error: ${error.message}`;  
}  
%>  
  
## ๐Ÿ’ฌ [[software/gemini|Gemini]] Prompt (<% model %>)  
> <% prompt %>.  
  
<%*  
await tp.file.rename(kebabCase)  
%>  

๐Ÿคช Emojify Template

  • ๐Ÿค” Choosing and ๐Ÿ–ฑ๏ธ inserting the ๐Ÿ‘Œ perfect emojis can be ๐Ÿ˜ซ tedious.
  • ๐Ÿฅณ Luckily, ๐Ÿ˜ˆ๐Ÿค–Skynet ๐Ÿ˜‡๐Ÿค– Gemini is pretty ๐Ÿ‘ good with emojis.
  • Similar to above, I use ๐Ÿ‘จโ€โœˆ๏ธ Commander to put a ๐Ÿ–ฒ๏ธ button with a ๐ŸŽจ custom icon on my ๐Ÿ“ฑ mobile toolbar
  • ๐Ÿ‘† Select text. ๐Ÿ™‚ Tap button. โœจ Emojify.
<%*  
async function generateTextFromGemini(prompt, apiKey, model = "gemini-2.0-flash") {  
  const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;  
  
  const requestBody = {  
    contents: [{ parts: [{ text: prompt }] }],  
  };  
  
  try {  
    const response = await fetch(apiUrl, {  
      method: "POST",  
      headers: {  
        "Content-Type": "application/json",  
      },  
      body: JSON.stringify(requestBody),  
    });  
  
    if (!response.ok) {  
      throw new Error(`HTTP error! status: ${response.status} - ${JSON.stringify(await response.json(), null, 1)}`);  
    }  
  
    const data = await response.json();  
    return data.candidates[0].content.parts[0].text;  
  } catch (error) {  
    return `Error: ${error.message}`;  
  }  
}  
  
const GEMINI_API_KEY = "https://ai.google.dev/gemini-api/docs/api-key"; // Replace with your actual API key.  
const selectedText = tp.file.selection();  
  
if (selectedText) {  
  const prompt = `Enhance the selected text by inserting relevant emojis: "${selectedText}".  
  Each emojis should go before the word, phrase, or sentence it represents, followed by a space.  
  Put at least 1 emoji at the beginning of each section heading, bullet point, or line of text.  
  Insert lots of emojis in long blocks of text.  
  Only return the text with the emojis.`;  
  
  const emojifiedText = await generateTextFromGemini(prompt, GEMINI_API_KEY);  
  if (emojifiedText) {  
      tR = emojifiedText;  
  } else {  
    tR += "Failed to emojify text.";  
  }  
} else {  
  tR += "Please select some text to emojify.";  
}  
%>  

๐Ÿชž Reflections

  • โ“ How much value can we get from an AI generated ๐Ÿค– book report ๐Ÿ“?
    • ๐Ÿค” Maybe 10% of the value of the full read in โ€ฆ
      • ๐Ÿ“š Strongmen: Mussolini to the Present is 9h 42m on audible. ๐ŸŽง
      • โฑ๏ธ The read time plugin claims my AI book report ๐Ÿ“ is a 7 minute read.
      • ๐Ÿงฎ (9 * 60 + 42 = 582) / 7 = 83
    • โณ โ€ฆ 1/83rd the time?
    • ๐Ÿš€ Thatโ€™s something like 8x leverage.
    • ๐Ÿ‘ Not bad.
    • ๐ŸŽ And the Gemini API is free.
  • ๐ŸŒ How much value can be created by freely sharing these AI book reports ๐Ÿ“ online?
    • ๐Ÿ“ˆ According to the Google Search Console, traffic ๐Ÿ–ฑ๏ธ (clicks when it comes up in search results) to my website ๐Ÿ’ป has grown from 3 per week to 23 per week over the past 3 months.
    • ๐Ÿ“Š Thatโ€™s a growth rate of (23 - 3) / 3 ~= 7 additional clicks per month.
    • ๐Ÿ”ฎ Extrapolating with linear growth, I might have (23 + 36 x 7 =275) clicks per week 3 years from now.
    • โž• Integrating (summing) over time, that yields (Gemini pause for LaTex) = 5513 (Thanks Wolfram Alpha!) clicks over the next 3 years.
      • โ˜๏ธ๐Ÿ› See the bug in this calculation?
    • ๐Ÿค“ Assuming 1% of my visitors actually read a single AI generated ๐Ÿค– book report ๐Ÿ“ (and the rest read nothing), thatโ€™s 55 AI book reports read.
    • ๐Ÿคฏ โ€ฆdo I get to multiply my earlier 8x leverage per book ๐Ÿ“š by 55 people ๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘, yielding 440x?
    • โ“ What units does this leverage take on? Book ๐Ÿ“– knowledge dissemination rate?
    • ๐Ÿค” Not sureโ€ฆ
    • ๐Ÿ—ณ๏ธ Maybe thatโ€™s 55 more slightly better informed voters by our next election?
    • โค๏ธโ€๐Ÿฉน That probably wonโ€™t do much on its own, but itโ€™s a contribution.
  • ๐Ÿคช Emojify! ๐Ÿช„
  • ๐Ÿง Reviews the aboveโ€ฆ
    • ๐Ÿ› Bug report: I mixed weeks and months! ๐Ÿ—“๏ธ
    • ๐Ÿงฎ I shouldnโ€™t be summing to 36. ๐Ÿค”
    • ๐Ÿ—“๏ธ It should be 3 years x 12 months per year x 4 weeks per month (or more accurately, ๐Ÿ“… 52 weeks per year x 3 years) = 156
    • ๐Ÿ“ˆ So = 89,333 ! ๐Ÿคฏ
    • ๐Ÿ‘“ With the 1% reading rate, we now get 893 more slightly better informed voters by next election. ๐Ÿ—ณ๏ธ
    • ๐Ÿ˜ž Which, to be honest, is qualitatively about as disappointing as 55. ๐Ÿ˜”
    • ๐Ÿ“ And theyโ€™re probably not in swing states. ๐Ÿ—บ๏ธ
    • ๐Ÿ’ป Though maybe I could check readership by state in the Google Search Console. ๐Ÿ˜ด Not tonight though.
  • ๐ŸŽฏ Okay, maybe my next goal should be to figure out how to inject some exponential growth into this formula. ๐Ÿš€
    • ๐Ÿ“ˆ Things grow ๐Ÿš€ exponentially when they go ๐Ÿฆ  viral and ๐Ÿ—ฃ๏ธ people share ๐Ÿ’Œ things with their ๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ friends and ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ family.
    • ๐Ÿ’ฐ Making that happen is the subject keeping many would-be ๐Ÿค‘ billionaires ๐Ÿ’ป busy at ๐Ÿข startups.
    • ๐Ÿ“š But there are plenty of books on the subjectโ€ฆ

๐Ÿฆ Tweet

Hereโ€™s the catchiest tweet I could workshop with AI assistance. ๐Ÿคž Letโ€™s see what happens!