I use Obsidian daily to manage all sorts of information, from high-level project plans to individual software tickets for personal projects. My most-used feature is Daily Notes to manage my tasks, log events at the office, etc. It’s become my work hub during the day.

I’m also a frequent user of ChatGPT. Whenever my ChatGPT conversations involve projects or info I track in Obsidian, I want to be able to search them along with any other information in my vault, link to them from my project documentation, and generally treat them like everything else I track.

I’ve been doing all of this for a while now with ChatKeeper, a tool I created to synchronize my entire chat history with my Obsidian documents. It’s come a long way since its initial release in September 2024 — it can find and update my conversations and images in-place in my vault, even if I move or rename them, support deep linking to individual conversation “turns”, and do a bunch of other useful things. It’s been incredibly helpful to me and to a nicely growing list of other folks who spend time at the intersection of Obsidian and ChatGPT.

ChatKeeper already creates an index of conversations both by last update and by conversation start date. But because I spend so much time in my Daily Notes, I figured it would be helpful to have each day list the conversations I participated in.

Below I provide a Dataview script that does exactly this. You can copy and paste the same script into your Daily Note template and be up and running immediately. Depending upon your Obsidian theme, it will end up looking something like this:

Screenshot of my own results

How The Dataview Script Works

When ChatKeeper brings your conversations into your vault, it includes properties at the top of each note. Among other things, this includes:

The Dataview script works by finding all notes with both the chatGPT_conversation tag and a chatGPT_dates property containing the given day.

What You Need

  1. Michael Brenan’s Dataview Plugin for Obsidian
  2. A copy of ChatKeeper (available for Windows, Mac, and Linux)
  3. Daily Notes that contain the date somewhere in the name of the note, in the format YYYY-MM-DD. The note name may contain other information, too.

The last requirement about the note name is there so that you can go back to earlier, existing daily notes and paste the script into them in order to produce a conversation list. This would not be possible if the daily note plugin simply inserts the date into the script because your template has already been evaluated for your existing daily notes.

Setup (one time)

  1. If you don’t already have Dataview installed and configured, follow these instructions to:
    • Enable and install “community plugins” in Obsidian.
    • Find and install Dataview.
    • Make sure that DataView is enabled.
    • In your DataView settings, make sure that “Enable JavaScript queries” is enabled.
  2. Download and install ChatKeeper.
    • It’s currently a “command line application” (although a graphical version is in the works). Don’t worry if you’re new to the command line - ChatKeeper comes with plenty of help, linked below.
    • Make sure ChatKeeper works for you by opening a terminal window where you downloaded or installed it and run chatkeeper with no arguments. It should give you some help text and list its version and release date at the top.
    • (Optional) Purchase and install a “forever license” to enable all of its features. The full list of features is here. The unlicensed version is limited to exporting 30 conversations.
  3. Add the following Dataview script to your Daily Note template (copy and paste the entire script, and make sure it ends up in a “dataviewjs-annotated codeblock” surrounded in triple-backticks as described here.

Copy Script to Clipboard


// Extract a date in the format YYYY-MM-DD from the current file name
// Note: if your daily notes don't contain that anywhere, you'll need to tweak this
const fileName = dv.current().file.name;
const fileDatePattern = /\d{4}-\d{2}-\d{2}/;
const matchResult = fileName.match(fileDatePattern);

if (matchResult) {
  // if we get this far, then matchResult[0] contains this note's date in YYYY-MM-DD format
  const extractedDateString = matchResult[0];


  // Get all pages that include the "chatGPT_conversation" tag.
  const conversationPages = dv.pages("")
    .filter(page => {
      // Ensure page.tags is treated as an array.
      let pageTags = page.tags;
      if (typeof pageTags === "string") {
        pageTags = [pageTags];
      }
      return pageTags && pageTags.includes("chatGPT_conversation");
    })
    .filter(page =>
      page.chatGPT_dates &&
      // Check that at least one date in chatGPT_dates matches after normalization.
      page.chatGPT_dates.some(dateValue => {
        // Convert the dateValue to a string (if it's not already) and extract the "YYYY-MM-DD" portion
        const dateStr = dateValue.toString();
        const normalized = (dateStr.match(/^(\d{4}-\d{2}-\d{2})/) || [])[1];
        return normalized === extractedDateString;
      })
    );

  if (conversationPages.length > 0) {
    dv.header(3, `Today's Conversations`);
    dv.table(
      ["Conversation Title", "Conversation Started"],
     conversationPages.map(page => [
        // Explicit Markdown link using Obsidian internal link syntax
        `[[${page.file.path}|${page.chatGPT_conversation_title}]]`,
        page.chatGPT_create_time
      ])    );
  } else {
    dv.paragraph("No conversation pages found for this date.");
  }
} else {
  dv.span("No valid date found in the file name.");
}

Bringing Your Conversations Into Your Vault

  1. Export your conversations from ChatGPT.
  2. Use ChatKeeper to import them to your vault / update them in place.
    • There are a lot of options to control the import. Details can be seen at:
    • For my own imports, I use chatkeeper keep MY_EXPORT.ZIP MY_VAULT_PATH -p "ChatGPT Conversations" --images samedir - this puts my conversations into the “ChatGPT Conversations” folder in my vault and saves any generated images alongside each conversation that generated them.
  3. Repeat from step 1 as often as you wish to keep your conversations in sync. I find I do this roughly every week or so.

Feedback

This works great for me, but I am not a Dataview or Javascript expert. I’m sure there are plenty of potential improvements possible, and I’d love to hear about them. If you come up with some, please let me know!