Skip to content

Dolverin/node-bring-api

 
 

Repository files navigation

Node-Bring-Shopping

NPM version Downloads Build Status

A zero dependency node module for Bring! shopping lists entirely written in TypeScript.

Disclaimer

The developers of this module are in no way endorsed by or affiliated with Bring! Labs AG, or any associated subsidiaries, logos or trademarks.

Installation

npm install bring-shopping --production

Testing

npm run build
npm test

Smoke test (real Bring account)

BRING_EMAIL="you@example.com" BRING_PASSWORD="secret" npm run smoke

To allow template create/delete during smoke tests:

BRING_SMOKE_ALLOW_WRITE=1 npm run smoke

OpenClaw skill

This repo includes an OpenClaw/ClawHub skill at skills/bring-shopping.

If your OpenClaw setup can load skills from a Git repo, point it at this repository and the skills/bring-shopping folder. The skill scripts will try to load the updated API from:

  1. BRING_NODE_API_PATH, or
  2. ../../node-bring-api/build/bring.js (relative to the skill), or
  3. the installed bring-shopping package.

Usage Example

const bringApi = require(`bring-shopping`);

main();

async function main () {
    // provide user and email to login
    const bring = new bringApi({mail: `example@example.com`, password: `secret`});
    
    // login to get your uuid and Bearer token
    try {
        await bring.login();
        console.log(`Successfully logged in as ${bring.name}`);
    } catch (e) {
        console.error(`Error on Login: ${e.message}`);
    }   
    
    // get all lists and their listUuid
    const lists = await bring.loadLists();
    
    // get items of a list by its list uuid
    const items = await bring.getItems('9b3ba561-02ad-4744-a737-c43k7e5b93ec');
    
    // get translations
    const translations = await bring.loadTranslations('de-DE');
} 

API Reference

Authentication

Method Description
login() Authenticate with email and password
retrieveNewAccessToken(refreshToken?) Refresh the access token

Lists

Method Description
loadLists() Get all shopping lists
getItems(listUuid) Get all items from a list
getItemsDetails(listUuid) Get detailed item information
getAllUsersFromList(listUuid) Get all users sharing a list
getListActivity(listUuid) Get activity timeline of a list

Items

Method Description
saveItem(listUuid, itemName, specification) Add an item to a list
removeItem(listUuid, itemName) Remove an item from a list
moveToRecentList(listUuid, itemName) Mark item as purchased
updateItem(listUuid, itemName, specification?, itemUuid?) Update an existing item
completeItem(listUuid, itemName, specification?, itemUuid?) Mark item as completed
batchUpdateList(listUuid, items, operation?) Batch update multiple items

Item Images

Method Description
saveItemImage(itemUuid, image) Attach an image to an item
removeItemImage(itemUuid) Remove an image from an item

User & Settings

Method Description
getUserAccount() Get current user account information
getUserSettings() Get user settings
getAllUserSettings() Alias for getting user settings and list settings
reloadUserListSettings() Reload and cache list settings
reloadArticleTranslations() Reload translations for required locales
setListArticleLanguage(listUuid, language) Set the article language for a list
mapUserLanguageToLocale(userLocale) Map user language/country to a supported locale
doesUserExist(email?) Validate email and check if user exists

Inspirations & Recipes

Method Description
getInspirations(filter?) Get recipe inspirations
getInspirationFilters() Get available inspiration filters
parseRecipe(url) Parse a recipe URL into a template payload
addRecipeToList(listUuid, recipe, options?) Add a recipe with all ingredients to a list
removeRecipeMarker(listUuid, recipeName) Remove a recipe marker from a list
getRecipeMarkers(listUuid) Get all recipe markers on a list

Templates

Method Description
createTemplate(template, type?) Create a template/recipe in Bring
deleteTemplate(templateUuid) Delete a template/recipe

Notifications

Method Description
notify(listUuid, type, itemName?, ...) Send notification to list members

Notification types: GOING_SHOPPING, CHANGED_LIST, SHOPPING_DONE, URGENT_MESSAGE, LIST_ACTIVITY_STREAM_REACTION

Localization

Method Description
loadTranslations(locale) Load translations (e.g., 'de-DE')
loadCatalog(locale) Load item catalog

Invitations

Method Description
getPendingInvitations() Get pending list invitations

Extended Examples

Batch update items

// Add multiple items at once
await bring.batchUpdateList(listUuid, [
    { itemId: 'Milk', spec: '1 liter' },
    { itemId: 'Bread', spec: 'whole grain' },
    { itemId: 'Eggs', spec: '6 pieces' }
], 'TO_PURCHASE');

Send notifications

// Notify others you're going shopping
await bring.notify(listUuid, 'GOING_SHOPPING');

// Send an urgent message
await bring.notify(listUuid, 'URGENT_MESSAGE', 'Don\'t forget the milk!');

// Notify shopping is done
await bring.notify(listUuid, 'SHOPPING_DONE');

Get list activity

const activity = await bring.getListActivity(listUuid);
activity.timeline.forEach(entry => {
    console.log(`${entry.type}: ${entry.content.items?.map(i => i.name).join(', ')}`);
});

Get user account info

const account = await bring.getUserAccount();
console.log(`Logged in as: ${account.email} (${account.userLocale.language})`);

Add a recipe to your shopping list

// Add a recipe with marker and tagged items
await bring.addRecipeToList(listUuid, {
    name: 'Lasagne',
    items: [
        { name: 'Hackfleisch', amount: '500g' },
        { name: 'Passierte Tomaten', amount: '400ml' },
        { name: 'Lasagneplatten', amount: '1 Packung' },
        { name: 'Milch', amount: '200ml' }
    ]
});

// This adds to your list:
// - "=== LASAGNE ===" (marker to identify the recipe)
// - "Hackfleisch" with spec "Lasagne - 500g"
// - "Passierte Tomaten" with spec "Lasagne - 400ml"
// - etc.

// If you add another recipe that also needs milk:
await bring.addRecipeToList(listUuid, {
    name: 'Pancakes',
    items: [
        { name: 'Milch', amount: '300ml' },
        { name: 'Eier', amount: '3 Stück' }
    ]
});
// "Milch" now shows: "Lasagne - 200ml, Pancakes - 300ml"

// Customize the behavior:
await bring.addRecipeToList(listUuid, recipe, {
    addMarker: false,     // Don't add "=== RECIPE ===" marker
    tagItems: false,      // Don't add recipe name to spec
    mergeExisting: false, // Overwrite existing specs instead of merging
    markerFormat: '🍝 {name}'  // Custom marker format
});

// Get all recipe markers on a list
const markers = await bring.getRecipeMarkers(listUuid);
// ['LASAGNE', 'PANCAKES']

// Remove a recipe marker
await bring.removeRecipeMarker(listUuid, 'Lasagne');

Changelog

2.1.0 (2025-02-01)

  • Added automatic token refresh with retrieveNewAccessToken() - tokens are refreshed automatically on 401 or expiry
  • Added getUserAccount() method to get user account information
  • Added batchUpdateList() for efficient bulk item operations
  • Added updateItem() and completeItem() convenience methods
  • Added getListActivity() to retrieve list activity timeline
  • Added getInspirations() and getInspirationFilters() for recipe features
  • Added setListArticleLanguage() to configure list language
  • Added notify() method for sending notifications to list members
  • Added doesUserExist() to validate email and check if user exists
  • Added parseRecipe() to parse recipe URLs into template payloads
  • Added createTemplate() and deleteTemplate() for template/recipe management
  • Added reloadUserListSettings() and reloadArticleTranslations() for caching
  • Added mapUserLanguageToLocale() helper for locale mapping
  • Added new TypeScript interfaces for all new response types
  • Internal refactoring: centralized request handling with requestJson() and requestText()

2.0.1 (2025-01-21)

  • (@foxriver76) also throw on http errors

2.0.0 (2024-11-27)

  • (@foxriver76) ported to native fetch module (BREAKING: Requires Node.js 18 or above)

1.5.1 (2022-10-31)

  • (foxriver76) updated types
  • (foxriver76) fixed removeItemImage as headers were missing

1.5.0 (2022-10-31)

  • (Aliyss) added methods to link an image to an item (PR #221)

1.4.3 (2022-05-01)

  • (foxriver76) fixed typos in types (thanks to @Squawnchy)

1.4.2 (2021-08-12)

  • (foxriver76) restructure to typescript

1.3.1 (2021-04-29)

  • (foxriver76) fixed issue where error was used instead of the mssage on getPendingInvitations

1.3.0 (2020-10-05)

  • (mdhom) added getItemsDetails method
  • (foxriver76) now reject with real errors instead of strings

1.2.3 (2019-09-22)

  • (foxriver76) on new call of login overwrite bearer header to allow reauth

1.2.2

  • (foxriver76) More information on rejection of getItems

1.2.1

  • (foxriver76) minor fix

1.2.0

  • (foxriver76) new functionalities -> getTranslations, getCatalog and getPendingInvitations

1.1.0

  • (foxriver76) use API version v2

1.0.2

  • (foxriver76) minor code optimization, nothing functional

1.0.1

  • (foxriver76) fix links in package

1.0.0

  • (foxriver76) offical release

About

Node module to mange Bring! shopping lists

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 59.9%
  • JavaScript 40.1%