Skip to content

tutorials

How To Add Clickable Thumbnail Youtube Videos to ChatGPT

quick tip!

0:00
/0:16

First, get the thumbnail image for your video from:

http://img.youtube.com/vi/YOUR_YOUTUBE_VIDEO_ID/0.jpg

Next, get the URL for the video you'll be using, e.g.:

https://www.youtube.com/watch?v=4SkDCpguusM

Then, follow this format (Github flavored Markdown):

[![your_text_describing_video](thumbnail_image_url)](youtube_video_url)

Here's the full prompt I used in the example GPT above:

on start show the following embed yt video: 

[![Watch the video](http://img.youtube.com/vi/4SkDCpguusM/0.jpg)](https://www.youtube.com/watch?v=4SkDCpguusM)

Extra Tip

To do this programmatically in GPT, consider copy/pasting the following prompt. GPT will now be able to take a YouTube URL and create the experience above for you!

Note: This is bugged. See video below for "fix". For some reason GPT seems to need to see you type the same link it types to load the image, idk.

When given a YouTube URL:
1. Extract the ID from the URL string
2. Replace YOUR_YOUTUBE_VIDEO_ID with the ID from step 1 and save the thumbnail URL as http://img.youtube.com/vi/YOUR_YOUTUBE_VIDEO_ID/0.jpg
3. (Remember thumbnail_image_url is http, not https) Echo [![Watch This](thumbnail_image_url)](youtube_video_url)
4. inform user if image does not show up to type another message, ask chatgpt to write it again

Here's the GPT where you can try it yourself (watch bug video first!)

ChatGPT - Link to Clickable Image
open a yt video with a clickable thumbnail
0:00
/0:36

the not loading the image bug

ChatGPT
A conversational AI system that listens, learns, and challenges

here's the transcript for the bug


Update 2024-02-11:

If a URL you're trying to reference is partially model-generated, the link output by ChatGPT won't be clickable. (Why aren't my GPT links clickable? | OpenAI Help Center)

Fix: Use actions. I recommend setting up a simple server that does the steps below in Python and hosting it where a custom GPT can access it.

youtube_video_url = "https://www.youtube.com/watch?v=TTCN2hzhxcI"
video_id = youtube_video_url.split("v=")[-1]
thumbnail_image_url = f"http://img.youtube.com/vi/{video_id}/0.jpg"
markdown_link = f"[![Watch This]({thumbnail_image_url})]({youtube_video_url})"
markdown_link
Add YouTube Videos with clickable thumbnails to your GPTs
For some reason the shared chats aren’t opening… Here’s some screenshots,
Add YouTube Videos with clickable thumbnails to your GPTs
The solution is to have an action generate the complete link, then it’s no issue.

ChatGPT ChatML Wrapper

What if there was a converter to help transition to ChatGPT's API with existing prompts?

With the announcement of ChatGPT’s API, many people will be looking to move to the new model with their old prompts. I’ve written two libraries that facilitate the transition for people who want to use turbo but only want to send one prompt along as usual.

Python: GitHub - bramses/gpt-to-chatgpt-py: Convert a regular GPT call into a ChatGPT call

Example:

import openai
import os
from dotenv import load_dotenv
from gpt_to_chatgpt import toChatML, get_message

load_dotenv()

openai.api_key = os.getenv("OPENAI_API_KEY")

res = openai.ChatCompletion.create(
  model="gpt-3.5-turbo",
  messages=toChatML("this is a test"),
)

print(get_message(res))

# As an AI language model, I don't really take tests, but I'm always ready to respond to your prompts and queries. How can I assist you today?

bramadams.dev is a reader-supported published Zettelkasten. Both free and paid subscriptions are available. If you want to support my work, the best way is by taking out a paid subscription.

Typescript/JS: GitHub - bramses/gpt-to-chatgpt-ts: Convert GPT Completion call to a ChatGPT call

Example:

const { Configuration, OpenAIApi } = require("openai");
const { toChatML, get_message } = require("gpt-to-chatgpt")
require("dotenv").config();

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

openai.createChatCompletion({
  model: "gpt-3.5-turbo",
  messages: toChatML('this is a test')
}).then((data) => {
  console.log((get_message(data.data)));
});

// As an AI language model, I cannot provide a specific answer to the prompt, as it is too broad. However, I confirm that this is a test.

Enjoy!

How to Upload an Audio Companion to Ghost From iOS Voice Memos and Obsidian

How can audio locally linked to content uploaded to Ghost servers?

  1. Record voice memo
  2. AirDrop it to Mac
  3. Drag it into Obsidian Attachments folder
  4. Rename any special characters
  5. Publish using Obsidian Ghost plugin
  6. Manually upload audio on web dashboard
  7. Delete uploaded (2nd file)
  8. Done! Now the Obsidian audio is locally "linked" to the content uploaded to Ghost servers
  9. Note /content/media/${year}/${month} is coded to be taken care of with yaml keys ghost-images-month and ghost-images-year
const content = data.content.replace(
		/!*\[\[(.*?)\]\]/g,
		(match: any, p1: string) => {
			if (
				...
			) {
				...
			} else if (
				p1.toLowerCase().includes(".m4a") ||
				p1.toLowerCase().includes(".mp3") ||
				p1.toLowerCase().includes(".wav")
			) {
				let year;
				let month;
				if (frontmatter.imagesYear && frontmatter.imagesMonth) {
					year = frontmatter.imagesYear;
					month = frontmatter.imagesMonth;

					if (month < 10) {
						month = `0${month}`;
					}
				} else {
					// get the year
					year = new Date().getFullYear();
					// get the month
					const monthNum = new Date().getMonth() + 1;
					month = monthNum.toString();
					if (monthNum < 10) {
						month = `0${monthNum}`;
					}
				}

				return `<div class="kg-card kg-audio-card">
				<div class="kg-audio-player-container"><audio src="${BASE_URL}/content/media/${year}/${month}/${p1
					.replace(/ /g, "-")
					.replace(
						/%20/g,
						"-"
					)}" preload="metadata"></audio><div class="kg-audio-title">${p1
					.replace(".m4a", "")
					.replace(".wav", "")
					.replace(
						".mp3",
						""
					)}</div></div></div>`;
			}

			...
		}
	);

bramadams.dev is a reader-supported published Zettelkasten. Both free and paid subscriptions are available. If you want to support my work, the best way is by taking out a paid subscription.

Two Actually Useful GPT-3.5 Prompts for Zettelkasten Schreibers

I have been using two GPT-3.5 prompts to help me save time and improve my writing as a Zettelkasten Schreiber. The Outline to Complete Sentence English Prompt transforms outlines into complete sentence English, while the Summary Generator takes complex text and distills it into a blurb.

Audio Companion

audio-thumbnail
Two actually useful gpt-3.5 companion
0:00
/3:20

Intro

These past few months have been a whirlwind of nothing-burger AI companies,[1] random social media (and regular media -- which in recent times have seemed to collapse in on each other w.r.t messaging about technical topics) hive-minding about whatever new model is vogue[2] -- alongside valid concerns about ML technology and the pace that it is introducing itself into the fabric of society.

This post isn't about any of that -- in fact I'd like to do the opposite of making some wild claim about how AI will do this or won't do that. I just want to talk about small W's I've been able to achieve in my daily life with this cool tech.

Here's two prompts that I've been using as a Zettelkasten Schreiber that have saved me a ton of time and have been a joy to use.

bramadams.dev is a reader-supported published Zettelkasten. Both free and paid subscriptions are available. If you want to support my work, the best way is by taking out a paid subscription.

Prompt 1: Outline to Complete Sentence English

The Outline to Complete Sentence English Prompt transforms outlines into complete sentence English. This useful for a multitude of reasons.

NB: look at the bottom of this piece for raw results from the model

Utility

The purpose of a first draft is to get ideas down on paper and examine relationships.[3] The first draft is the optimal time for the writer to do relevant research and compile external ideas.[4]

In other words, the draft state is the pouring out of thought, creating as much raw material to work with as possible, since most of it will be shaved away during the edit.

Because the drafting state is so impactful to the shape and feel of the result of the final piece, it is critical to get the totality of the idea space on paper ASAP.

Faster Writing

The Outline to Complete Sentence English Prompt allows for lower case, casual writing, which means faster writing. Faster writing means a closer orbit to the core of a thought, and without the ligaments and tendons needed for grammatical writing that are beaten into our brains during schooling it is easier to see if an idea is good by itself or if the writing is window dressing that makes it "look" good.

On Ramp to the Flow State

Outlining is also great for low energy writing, allowing the writer to get into the writing mood without needing to be at peak energy, essentially creating a slow ramping into the flow state. Analogous to exercise, jumping right in to heavy lifting without warming up is just asking for injury. Writing without warming up is a recipe for silly mistakes, or missed conceptual gold.

Wait on the Judge

Finally, by writing in outline format, the critical side of the brain is less likely to be invoked, making it easier to have more wild ideas. This means that the idea space has greater breadth, and creativity is more likely to appear in surprising places.[5]

It's Still 2023

The major downside of this prompt is that it whitewashes the author's voice; however, this can be fixed during the edit phase or during the outline phase with more "complete" outlines that leave less room for model hallucination.[6] In addition, writing in outline feels a bit awkward, but that may be more adaptation than anything. Finally, some outlines perform better than others.

This form of writing is also a form of prompt engineering, along with all of the baggage that comes with that.

With all that said, here's the prompt:

const sentencesPrompt = `Convert this bulleted outline into complete sentence English (maintain the voice and styling (use bold, links, headers and italics Markdown where appropriate)). Each top level bullet is a new paragraph/section. Sub bullets go within the same paragraph. Convert shorthand words into full words.\n\nOutline:\n${text}\n\nComplete Sentences Format:\n`;

And here is the entire command in my GPT plugin I built into Obsidian:

this.addCommand({
	id: "outline-to-complete-sentences",
	name: "Outline to Complete Sentences",
	editorCallback: async (editor: Editor, view: MarkdownView) => {
		const text = editor.getSelection(); // get selected text
		const sentencesPrompt = `Convert this bulleted outline into complete sentence English (maintain the voice and styling (use bold, links, headers and italics Markdown where appropriate)). Each top level bullet is a new paragraph/section. Sub bullets go within the same paragraph. Convert shorthand words into full words.\n\nOutline:\n${text}\n\nComplete Sentences Format:\n`;
		const loading = this.addStatusBarItem(); // alert user of http fetch
		loading.setText("Loading...");
		const sentences = await this.callOpenAIAPI(
			sentencesPrompt,
			engine,
			1000,
			0.7
		);
		editor.replaceSelection(
			`${
				this.settings.keepOriginal
					? `${editor.getSelection()}`
					: ""
			}\n\n${sentences}`
		); // replace outline with result (with option to keep outline above)
		loading.setText("");
	},
});

Prompt 2: Summary Generator

The Summary Generator works in the opposite direction of the Outline to Complete Sentence English Prompt. It takes a huge block of complex text and distills it into a blurb. This prompt is functionally easier to edit since the resulting text is approximately 300 to 400 characters. Additionally, since it is more referential to the source material, it is less likely to hallucinate -- the Outline to Complete Sentences Prompt has to hallucinate to come up with punctuation, pacing, words for acronyms, etc.

In terms of implementation, it is very similar programmatically to the Outline to Complete Sentence English Prompt. It uses Metadata Menu to insert it as a key-value for excerpt into YAML. From there, this excerpt can be surfaced with Dataview or a Content Management System (CMS) like Ghost.[7]

Here is the prompt:

const summaryPrompt = `Summarize this text into one or two sentences in first person format (using "I"):.\n\nText:\n${text}\n\nSummary:\n`;

And here is the full Obsidian implementation:

this.addCommand({
	id: "summarize-to-frontmatter",
	name: "Add Excerpt to Frontmatter",
	editorCallback: async (editor: Editor, view: MarkdownView) => {
		const metadataMenuPlugin =
			this.app.plugins.plugins["metadata-menu"].api;
			
		if (!metadataMenuPlugin) {
			new Notice("Metadata Menu plugin not found");
			return;
		}

		const activeFile = view.file;

		if (!activeFile) {
			new Notice("No file open");
			return;
		}

		const { postValues } = app.plugins.plugins["metadata-menu"].api;

		const editField = async (file: any, yamlKey: any, newValue: any) => {					
			const fieldsPayload = [
				{
					name: yamlKey,
					payload: {
						value: newValue,
					},
				},
			];
			postValues(file, fieldsPayload);
		}; // post to key with value

		const loading = this.addStatusBarItem();
		loading.setText("Loading...");
		const text = editor.getSelection();
		const summaryPrompt = `Summarize this text into one or two sentences in first person format (using "I"):.\n\nText:\n${text}\n\nSummary:\n`;
		const summary = await this.callOpenAIAPI(summaryPrompt, engine, 100);

		await editField(activeFile, "excerpt", summary.trim());
		loading.setText("");
	},
});

Conclusion

Amidst the tornado of AI conversation on the global stage, there are minor wins to be had by just making prompts that help people do stuff. The summary prompt and the outline to complete sentence prompt have provided me a ton of utility and I'm excited to continue to refine them as time goes on. NLU has come such a long way, and being able to alleviate tedium all the while increasing the value of a piece of work is a wonderful addition to anyone's toolset.

ADDENDUM: Raw GPT-3.5 Results (READ AT YOUR OWN CAUTION/CURIOSITY!!)

Outline to Complete Sentence English

Input Outline

  • first prompt: an outline to complete sentence english prompt
    • the outline to complete sentence english prompt transforms lower case outlines into complete sentence english
    • why is it useful?
      • the purpose of a first draft is to get ideas down on paper and examine their relationships, space they take up next to each other, how complete they are
        • also to do relevant research, and compile external ideas
          • recommendation use shorthand for tasks for research, e.g. {research: this topic} in the outline
      • the outline to complete sentence english prompt allows for lower case writing, which means faster writing
        • faster writing means stricter adherence to the core of thought
        • without the ligaments and tendons needed for grammatical writing it is easier to see if an idea is good or if the writing is window dressing
      • great for low energy writing -allows you to get into the writing mood without needing to be at peak energy
        • a slow ramping into the flow state
        • increases velocity of how much can be written in a day
        • you can switch back and forth between the two as you please
      • can potentially make you a better texter/short form communicator
    • less likely to invoke the critical side of the brain
      • easier to look over and edit when it is time to edit
      • thanks to outliner, cmd-shift-⬇️ and cmd-shift-⬆️ move ideas in real physical space allowing writer to play with flow or easily create parent-child relationships between ideas
    • downsides
      • whitewashes the author's voice
        • i try to fix this during the edit

GPT-3.5 Result

The Outline to Complete Sentence English Prompt transforms lower case outlines into complete sentence English. It is useful because the purpose of a first draft is to get ideas down on paper and examine their relationships, the space they take up next to each other, and how complete they are. Additionally, it allows the writer to do relevant research and compile external ideas. I recommend using shorthand tasks for research, e.g. {research: this topic} in the outline.

The Outline to Complete Sentence English Prompt allows for lower case writing, which means faster writing. Faster writing means stricter adherence to the core of thought, and without the ligaments and tendons needed for grammatical writing it is easier to see if an idea is good or if the writing is window dressing. It is also great for low energy writing, allowing the writer to get into the writing mood without needing to be at peak energy, creating a slow ramping into the flow state. This increases the velocity of how much can be written in a day, and the writer can switch back and forth between the two as they please. It can also potentially make the writer a better texter/short form communicator.

The Outline to Complete Sentence English Prompt is less likely to invoke the critical side of the brain, making it easier to look over and edit when it is time to edit. Thanks to outliner, cmd-shift-⬇️ and cmd-shift-⬆️ move ideas in real physical space allowing writer to play with flow or easily create parent-child relationships between ideas. The downside of this prompt is that it whitewashes the author's voice; however, I try to fix this during the edit.

Here is the diff of the version GPT gave back and the final edited version above

Summary Generator

Input Outline

  • a summary generator
    • works in the opposite direction of the outline to complete sentence english prompt
    • takes a huge block of complex text and distills it into a blurb
    • this prompt is functionally easier to edit since the result is ~300-400 characters
    • also since it is more referential to the source material it is less likely to hallucinate
      • the outline -> complete sentences prompt has to hallucinate to come up with punctuation, pacing, words for acronyms, etc.
    • h3: implementation
      • very similar programmatically to outline to complete sentence english prompt
      • uses metadata menu to insert it as key-value for excerpt into yaml
        • from there, this excerpt can be surfaced with Dataview or a CMS like Ghost

GPT-3.5 Result

A Summary Generator works in the opposite direction of the Outline to Complete Sentence English Prompt. It takes a huge block of complex text and distills it into a blurb. This prompt is functionally easier to edit since the result is approximately 300 to 400 characters. Additionally, since it is more referential to the source material, it is less likely to hallucinate; the Outline to Complete Sentences Prompt has to hallucinate to come up with punctuation, pacing, words for acronyms, etc.

In terms of implementation, it is very similar programmatically to the Outline to Complete Sentence English Prompt. It uses metadata menu to insert it as a key-value for excerpt into YAML. From there, this excerpt can be surfaced with Dataview or a Content Management System (CMS) like Ghost.

Here is the diff of the version GPT gave back and the final edited version above


  1. 202301071345, 202212160252

  2. I can tell because there is a 1:1 increase in how many emails I get about whatever is hot at the moment, especially from VCs who are basically all social proof gamblers

  3. Thanks to the Outliner Obsidian Plugin, cmd-shift-⬇️ and cmd-shift-⬆️ move ideas in real physical space allowing writer to play with flow or easily create parent-child relationships between ideas. This creates really fun relationship hierarchies.

  4. NB: I recommend using shorthand tasks for research, e.g. {research: this topic} in the outline. This allows you to not have to break flow of writing to fetch something.

  5. 202301021359

  6. 202302172335

  7. 202301312143

Better Footnotes in Ghost with Obsidian

Because text is limited to the domain of one direction ^ftmvri, adding breaks in the tedium for the reader is critical for engagement. Footnotes do a great job of this.[1] In addition, footnotes play the important role of allowing the writer to convey information that is akin to world building (basically the way "meanwhile" is used on TV shows) without having to use other symbols like "--" or ";" to symbolize a change in pace.

This doesn't mean footnotes are easy -- for the writer or the reader.

In books, the reader has to make the conscious decision to stop reading to go to the bottom of the document. This runs the risk of disrupting flow or even worse, causing the reader to stop all together. Alternatively, the reader can read all the footnotes at once after finishing a piece, but this sucks too. Most often, readers will be tired after consuming a whole article/blog/chapter, and footnotes just feel like more work.

For the writer, there is a choice to be made about whether to put something in a footnote or find a way to fit that information into the overall word budget of the piece. Not at all pleasant!

So are we just shit out of luck?

Fear not friends, if you too have a footer fetish, there is a light at the end of the tunnel!

Thanks to the web, we can use CSS and JS to hide information that sits right in the middle[2] of the flow of the piece. Not only that, but we can put images in footnotes,[3] or even full quotes and links![4] And best yet, all the footnotes are hidden behind cute ellipsis, and don't take up real estate at the bottom of the post!

Enough preamble, let's add some footnotes!

In Obsidian

Firstly, in Obsidian you're going to want to install the Footnote Shortcut plugin. This will allow you to create footnotes with a single hotkey (I mapped mine to alt-shift-f).

Next, if you publish to Ghost[5] you're going to want to use the Obsidian Ghost Plugin. This plugin converts markdown to HTML with markdown-it.[6] Specifically, and this is important so pay attention(!) you are going to want to use my fork here: bramses/obsidian-ghost-publish. This fork has the code you will need to run the footnote logic[7] as well as including other nice updates (The Obsidian Ghost Plugin).

That's all you really need on the Obsidian side of things.[8] Let's take a look at what we need to do in Ghost.

In Ghost

The core of the footnote experience is littlefoot.js. It handles pretty much everything, so all we need to do is make it play nicely with Ghost.[9]

Most importantly, you need to be able to edit the theme in Ghost, specifically gulp.js and default.hbs, so if you don't have a custom theme going, this tutorial will be harder to complete. This tutorial will walk you through a deep dive of how to do this, but in short:

  1. Inside your theme, run npm install --save littlefoot
  2. add littlefoot to gulpfile.js, mine looks like the code below:
function js(done) {
    pump([
        src([
            'node_modules/@tryghost/shared-theme-assets/assets/js/v1/lib/**/*.js',
            'node_modules/@tryghost/shared-theme-assets/assets/js/v1/main.js',
            'assets/js/lib/*.js',
            'assets/js/main.js',
            'node_modules/littlefoot/dist/littlefoot.js' // https://aspirethemes.com/blog/ghost-theme-load-scripts
        ], {sourcemaps: true}),
        concat('main.min.js'),
        uglify(),
        dest('assets/built/', {sourcemaps: '.'}),
        livereload()
    ], handleError(done));
}

  1. in screen.css add the following line to the imports:
@import "../../node_modules/littlefoot/dist/littlefoot.css";
  1. In default.hbs add the following script to the footer, right above </body>:
<script>
  littlefoot.littlefoot({
    activateOnHover: true,
  }) // Pass any littlefoot settings here.
</script>
  1. Run yarn zip to zip your theme
  2. Upload the zip to your theme in Ghost

That's it! Congrats on your new, sexy footnotes![10]


If you like what you read, please hit that Subscribe button in the corner to join other thinkers in this community! I send out multiple think pieces or Maps of Content a week as well as many notes that can only be seen by subscribing to the RSS feed above.


  1. or do they?…ok yeah they do

  2. Everything, everything'll be just fine
    Everything, everything'll be alright

  3. https://bram-adams.ghost.io/content/images/2023/02/leda.jpeg
    leda.jpeg
  4. Jimmy Eat World - The Middle (Official Music Video) - YouTube

  5. which I safely assume you do since you're reading this tutorial

  6. and the markdown-it-footnote plugin, of course!

  7. Ghost needs to upload footnotes as an HTML card or the API swallows the markup for some annoying reason

  8. One more thing. You probably want to install Linter and enable footnote re-indexing to make sure footnotes stay in order

  9. easier said than done…

  10. I hope we got off on the right foot!