Bulk Import Zotero Library Annotations into Obsidian with Zotero Integration plugin

I am using this plugin GitHub - mgmeyers/obsidian-zotero-integration: Insert and import citations, bibliographies, notes, and PDF annotations from Zotero into Obsidian.

And I need to findout a way to import a full library at once and not adding each article one by one.

I don’t think it’s possible.
One can run javascript within Zotero as well but to hook that onto a plugin (that is not Zotero Integration)… I don’t know if you can get any answers on here.

Might want to check out Zotero Forums (for a non-Obsidian way).
Then you might be able to convert any files garnered (with some templating rules) into Obsidian as a second step.

It is actually possible, because Zotero Integration has an API called runImport. I have a bulk importing script, that will import the item corresponding to each citekey under a specific heading in a note.

If you can somehow make a list of all the citekeys for all items in Zotero, then the bulk importing script could import them all.

One way to do this would be to combine my citation dictionary script with the aforementioned bulk import script.

Here’s the bulk import script, which uses dataview and templater:

<%*
// Dataview API
const dv = this.app.plugins.plugins["dataview"].api;

// Path to note
const path = "01 - Inbox/Reading list";

// List heading to import (change this to match the list corresponding to items you want to import)
const heading = "📗 Ready to import"

// Dataview query
const query = `list without ID link(file.link, L.text) from "${path}" flatten file.lists as L where meta(L.section).subpath = "${heading}"`

// Running the query
let DQL = await dv.tryQuery(query);
//console.log("DQL", DQL);

// Storing the values
const itemsToImport = DQL.values;

// Regex for citekey
const citekeyRegex = /\@([^\|]+)/;

// Import every item under the heading
if (itemsToImport.length > 0) {
    for (const item in itemsToImport) {
        const citekey = itemsToImport[item].display.match(citekeyRegex)[1];
        app.plugins.getPlugin('obsidian-zotero-desktop-connector').runImport('Literature note', citekey);
        new Notice(`Imported ${citekey}`);
    }
} else {
    new Notice("Nothing to import");
}
%>
3 Likes

Alternatively, it might be possible to select all items by switching to classic view in the citation picker dialog. I know it’s possible to do bulk imports this way, but I have never done a full library import.

Oh, this is from the iOS method I read about a few months ago? Good on you, bud. :clap:


Took the liberty of renaming title to Bulk Import Zotero Library Annotations into Obsidian with Zotero Integration plugin.

1 Like

Yeah, that’s the one (although it’s also for Android) :+1: The bulk import script is more recent, though. Both combined, they could fairly easily import an entire Zotero library. But I am not sure how long it would take, or if there would be any performance issues.

Anyway, @jrv, I would give the classic view for the citation picker a try first, and if that doesn’t work, I can try combining these scripts into a one step process.

1 Like

Okay, I took a shot at this for fun, and it works! Here’s a script in javascript that will tell Zotero Integration to create a literature note on every item in a bibtex export from Zotero.

You can run it in Obsidian using any of the plugins that can execute javascript code. I tested it through Templater, but a Quickadd macro would also be a good choice.

There’s two things you need to do:

  1. Specify the absolute path to a better bibtex export from Zotero
  2. Specify the name of the import format Zotero Integration should use
    Both are marked “todo” in the script, so just search for that.
const fs = require('fs');

function extractCitekeys(bibtexFile) {
  const bibtexData = fs.readFileSync(bibtexFile, 'utf-8');
  const regex = /@([a-zA-Z]*)\s*\{\s*([a-zA-Z0-9_:.#$%&-+?<>~/]*)/gm;
  let match;
  let citeKeys = [];

  while ((match = regex.exec(bibtexData))) {
    const citekey = match[2].trim();
    citeKeys.push(citekey);
  }

  return citeKeys;
}

// Usage
// (todo) Replace this path with the actual absolute path to your bibliography
const bibtexFile = "C:/Users/Your/Full/Path/To/Bibliography.bib";
const itemsToImport = extractCitekeys(bibtexFile);

// Import every item in the bibtex file
if (itemsToImport.length > 0) {
	let itemCount = itemsToImport.length;
    new Notice(`Importing ${itemCount} items`, 5000);
    for (const citekey of itemsToImport) {
        itemCount--;
        // (todo) Replace 'Testing ground' below with the name of your import format that Zotero Integration should use
        app.plugins.getPlugin('obsidian-zotero-desktop-connector').runImport('Testing ground', citekey);
         // If you are importing from a group library, add a number after the citekey that corresponds to the order of libraries in the Zotero UI, starting from My Library as 1. So if your group library is directly below "My Library", it's libraryID is 2. In that case, you would need this:
        // app.plugins.getPlugin('obsidian-zotero-desktop-connector').runImport('Testing ground', citekey, 2);
        new Notice(`Imported ${citekey}, ${itemCount} remaining`);
    }
    new Notice("Import complete!", 3000);
} else {
    new Notice("Nothing to import");
}

:warning: Warning

  1. I only tested this on a small collection, as I did not want to create almost 2000 files in my vault.
  2. Re-importing existing files will update / overwrite them, depending on the output path in your import format settings and depending on whether you have persistent fields in your template.
  3. You can probably do the same thing using the classic view in Zotero’s citation picker. Therefore, the value of this is mainly in a) a proof of concept, and b) automation workflows.
1 Like

Hey,

amazing script which could possibly save a lot of people a ton of work :wink:
Unfortunately I have some errors running it, seems to be that it cant find the entries in the export file but they are definitely there - any idea what else I could try? :slight_smile:

Hi,
Thanks, glad you like it, but unfortunate that it didn’t work for you the first time around. Did you export the .bib file from Zotero using the Better Bibtex format? That’s what I used. Can you share a sample entry from your bibtex file here (anonymized as needed)?

Don’t think I replied above, so here it goes :point_up:

Looking more closely at the error, it seems that Zotero Integration can’t find these items in Zotero. Are they there, or perhaps in a group library?

Hey yes I used a group library but I found another way :slight_smile: You can use the normal zotero plugin and in the window to select a paper there is a button “mulitple sources” you can select that and mark everything you want to import. That solved the problem for me :slight_smile:

1 Like

That’s great, and I did actually recommend that option when I shared the script:

But just for posteriority, the reason the script wasn’t working for you was because the items were in a group library. The API actually has a third parameter, which defaults to the main library: runImport(name: string, citekey: string, library: number = 1).

So when importing items from a group, you have to put in the libraryID (a number) of the group library. 1 is “My Library”, 2 is the first group library below that in Zotero’s UI, and so on. I added a comment to the script above, showcasing the usage.

1 Like