Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. Alexa Shopping List mit Bring synchronisieren

    NEWS

    • Monatsrückblick - April 2025

    • Minor js-controller 7.0.7 Update in latest repo

    • Save The Date: ioBroker@Smart Living Forum Solingen, 14.06.

    Alexa Shopping List mit Bring synchronisieren

    This topic has been deleted. Only users with topic management privileges can see it.
    • Oreider
      Oreider @icastillo15 last edited by

      @icastillo15

      Vielen Dank!

      Ich teste mit.
      Auf den ersten Blick schaut es super aus!

      1 Reply Last reply Reply Quote 0
      • Fuchsbau
        Fuchsbau @icastillo15 last edited by

        @icastillo15

        Hi icastillo15,

        erstmal 👍 für deine tolle Arbeit,
        Ich hab es eben getestet und bin recht erstaunt wie schnell es Sync.

        Aber Alexa macht es uns nicht einfach.

        Alle was ich per Sprache in die Alexa Liste eintrage wird klein geschrieben.
        Alle was ich per Sprache in Bring eintrage wird Großgeschrieben.

        Vorlagen Artikel in Bring sind Großgeschrieben und auch die automatische Zuordnung in die Bring Kategorien werden nur mit den Großgeschrieben Artikel erkannt.
        Bei Alexa kann ich einen identischen Artikel mehrfach in die Liste eintragen. Bring überprüft und trägt den identischen Artikel nur einmal ein. Bring überprüft auch Groß u. Kleinschreibung und es wird der Artikel nur einmal eingetragen. Dadurch entsteht ein Problem, habe ich z.B.: 3-mal Zitronen in der Alexa Liste, so habe ich in der Bring Liste nur 1-mal Zitronen. Lösche ich Zitronen in Bring, wird nur 1-mal Zitronen in Alexa gelöscht. Ergo, da noch 2-mal Zitrone in der Alexa Liste stehen, steht nach kurzer Zeit 1-mal Zitronen wieder in der Bring Liste.

        Bei identischem Artikel einmal Groß und einmal Kleingeschrieben passiert dasselbe.

        Wäre es nicht sinnvoller nur in eine Richtung zu synchronisieren. Von der Alexa Liste in die Bring Liste (wenn man nur Bring beim Einkaufen nutz). Irgendwie so, dass alle neu eintragen Artikel in der Alexa Liste, mit Anfangsbuchstaben Großgeschriebene zu Bring synchronisiert werden. Und idealerweise dann direkt in der Alexa Liste gelöscht.

        Gruß
        Fuchsbau

        icastillo15 1 Reply Last reply Reply Quote 0
        • icastillo15
          icastillo15 @Fuchsbau last edited by

          @fuchsbau

          Danke für die Rückmeldung und das Testen. Mir war das bisher egal, ob Artikel groß oder kleingeschrieben sind aber du hast natürlich Recht. Es schränkt leider etwas Funktionalität ein. Grundsätzlich brauch ich den Sync aber in beide Richtungen, da ich oder meine Freundin gerne auch mal von unterwegs direkt in Bring Sachen hinzufügen und nicht über Alexa. Das sollte dann synchronisiert bleiben.

          Also du nutzt sowohl Alexa Spracheingabe als auch über die Bring App direkt eine Spracheingabe oder meinst du das über den Alexa Bring Skill? Andernfalls wusste ich noch nicht, dass man auch direkt in Bring eine Spracheingabe hat 😀

          Als Erweiterung vom Script könnte ich mir vorstellen, dass ich vorher noch vor jedem Sync ein Cleanup einbaue. Der würde dann über alle Alexa Items rübergehen und die Groß-Kleinschreibung erzwingen. Dabei könnte man auch gleich dupletten entfernen. Dann sollte im anschließenden Sync alles reibungslos klappen.

          Ich schau mir das heute nochmal an wenn ich Zeit finde 🙂 Ansonsten klasse, dass es bei den anderen soweit für ihre Zwecke funktioniert 👍🏻

          I 1 Reply Last reply Reply Quote 1
          • I
            IOMax @icastillo15 last edited by IOMax

            @icastillo15 Super, vielen Dank, das klappt schonmal sehr gut!

            mcBirne 1 Reply Last reply Reply Quote 0
            • I
              IOMax @icastillo15 last edited by

              @icastillo15 said in Alexa Shopping List mit Bring synchronisieren:

              Dabei könnte man auch gleich dupletten entfernen. Dann sollte im anschließenden Sync alles reibungslos klappen.

              Das wäre top!

              1 Reply Last reply Reply Quote 0
              • mcBirne
                mcBirne @IOMax last edited by

                @iomax so wie ich das sehe reagiert es auf Updates der Listen

                I 1 Reply Last reply Reply Quote 0
                • I
                  IOMax @mcBirne last edited by

                  @mcbirne said in Alexa Shopping List mit Bring synchronisieren:

                  @iomax so wie ich das sehe reagiert es auf Updates der Listen

                  stimmt, habe ich auch gerade gesehen 😉

                  1 Reply Last reply Reply Quote 0
                  • icastillo15
                    icastillo15 last edited by icastillo15

                    Hallo zusammen,

                    ich habe mein Script nochmal aktualisiert. Es werden in Alexa nun automatisch alle Duplikate sofort wieder gelöscht. Außerdem wird nun erzwungen, dass Artikel mit einem Großbuchstaben beginnen.

                    Viel Spaß damit und gerne wieder testen 🙂

                    Kleiner Nachtrag: wenn ich über Alexa Dinge hinzufüge und dann in Bring als erledigt markiere, dann werden diese bei mir in Alexa nicht mehr gelöscht. Das muss ich mir nochmal ansehen - könnte an den Zeitstempeln liegen.

                    Nachtrag 2: ging doch - mein Adapter war nur offline 😎

                    const bringBaseId = 'bring.0.0f0c420c-3298-4911-91f5-7ed0fbbfd36e';
                    const alexa2BaseId = 'alexa2.0.Lists.SHOPPING_LIST';
                    
                    const bringListId = bringBaseId + '.content';
                    const bringListCompletedId = bringBaseId + '.recentContent';
                    const bringAddToList = bringBaseId + '.saveItem';
                    const bringCompleteItem = bringBaseId + '.moveToRecentContent';
                    const alexaAddToList = alexa2BaseId + '.#New';
                    const alexaListId = alexa2BaseId + '.json';
                    
                    //switch off to silence:
                    const printDebug = true;
                    
                    function debug(msg) {
                        if (printDebug) {
                            log(msg)
                        }
                    }
                    
                    const TodoItemStatus = {
                        NeedsAction: 'needs_action',
                        Completed: 'completed',
                    };
                    
                    /**
                     * @typedef bringItem
                     * @type {object}
                     * @property {string} specification
                     * @property {string} name
                     * @property {string} status
                     * @property {boolean} [found] - keep track if found or not.
                     */
                    
                    /**
                     * @typedef alexaItem
                     * @type {object}
                     * @property {string} value
                     * @property {string} id
                     * @property {boolean} completed
                     * @property {number} updatedDateTime
                     * @property {boolean} [found] - keep track if found or not.
                     */
                    
                    /**
                     * Compare alexaItem complete and bringItem status -> returns true if same status.
                     * @param {Array<alexaItem>} alexaList
                     * @param {Array<bringItem>} list
                     * @returns {boolean} true if same status.
                    */
                    function compareCompleted(alexaItem, bringItem) {
                        if (alexaItem.completed && bringItem.status !== TodoItemStatus.Completed) {
                            return false;
                        }
                        if (!alexaItem.completed && bringItem.status !== TodoItemStatus.NeedsAction) {
                            return false;
                        }
                        return true;
                    }
                    
                    function ListCleaner(Eintrag='') {
                        const arr = Eintrag.split(' ');
                        for (let i = 0; i < arr.length; i++) {
                            arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
                        }
                        return arr.join(' ');
                    }
                    
                    /**
                     * sync lists
                     * @param {Array<alexaItem>} alexaList
                     * @param {Array<bringItem>} list
                     * @param {number} timestampBring
                     * @param {string} msource
                     * @param {Array<bringItem>} recentList
                     * @returns {Array<bringItem>} new bring List
                     */
                    function syncLists(alexaList, list, timestampBring, msource, recentList) {
                        const newBringList = [];
                        var empty = true;
                        for (const alexaItem of alexaList) {
                    
                            for (const bringItem of list) {
                                empty = false;
                    
                                if (bringItem.name === alexaItem.value) {
                                    alexaItem.found = true;
                                    bringItem.found = true;
                    
                    
                                    //found item. Update completed state from 'newer' list: 
                                    bringItem.status = TodoItemStatus.NeedsAction;
                                    if (alexaItem.updatedDateTime > timestampBring) {
                                        if (alexaItem.value !== bringItem.name || !compareCompleted(alexaItem, bringItem)) {
                    
                                            if (msource === 'Alexa') {
                                               debug('Updating Bring item: ' + bringItem.name + ' from Alexa');
                                               setState(bringCompleteItem, ListCleaner(bringItem.name));
                                            }                   
                                        }
                                    
                                    } else {
                                        //keep bring:
                    
                                        //update alexa:
                                        if (!compareCompleted(alexaItem, bringItem)) {
                                            if (msource === 'Bring') {
                                                bringItem.status = TodoItemStatus.Completed;
                                                debug('Update  Alexa item: ' + alexaItem.value + ' to ' + (bringItem.status === TodoItemStatus.Completed ? 'done' : 'undone') + ' from Bring.');
                                                setState(`${alexa2BaseId}.items.${alexaItem.id}.completed`, bringItem.status === TodoItemStatus.Completed);
                                            } 
                                        }
                                    }
                                }
                            }
                    
                            for (const bringItemCompleted of recentList) {
                                if (bringItemCompleted.name === alexaItem.value) {
                                    alexaItem.found = true;
                                    bringItemCompleted.found = true;
                    
                                    //found item. Update completed state from 'newer' list: 
                                    bringItemCompleted.status = TodoItemStatus.Completed;
                                    if (alexaItem.updatedDateTime > timestampBring) {
                                        if (alexaItem.value !== bringItemCompleted.name || !compareCompleted(alexaItem, bringItemCompleted)) {
                    
                                            if (msource === 'Alexa') {
                                               debug('Adding Bring item: ' + bringItemCompleted.name + ' from Alexa');
                                               setState(bringAddToList, ListCleaner(bringItemCompleted.name));
                                            }                   
                                        }
                                    
                                    } else {
                                        //keep bring:
                    
                                        //update alexa:
                                        if (!compareCompleted(alexaItem, bringItemCompleted)) {
                                            bringItemCompleted.status = TodoItemStatus.Completed;
                                            if (msource === 'Bring') {
                                                debug('Delete  Alexa item: ' + alexaItem.value + ' from Bring.');
                                                //setState(`${alexa2BaseId}.items.${alexaItem.id}.completed`, bringItemCompleted.status === TodoItemStatus.Completed);
                                                setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                                            } 
                                        }
                                    }
                                }
                            }
                    
                    
                            if (!alexaItem.found) {
                                //alexa item not found:
                                if (alexaItem.completed) {
                                    debug('Delete ' + alexaItem.value + ' because done and not in Bring list.');
                                    setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                                } else {
                                    if (msource === 'Alexa') {
                                        debug('Adding ' + alexaItem.value + ' to Bring list');
                                        setState(bringAddToList, ListCleaner(alexaItem.value));
                                    }
                                }
                            }
                    
                            if (empty === true) {
                                if (alexaItem.updatedDateTime < timestampBring) {
                                    debug('Delete ' + alexaItem.value + ' from Alexa list because Bring list is all done.');
                                    setState(`${alexa2BaseId}.items.${alexaItem.id}.#delete`, true);
                                }
                            }
                        
                        }
                    
                        for (const bringItem of list) {
                            if (!bringItem.found) {
                                if (bringItem.status === TodoItemStatus.Completed) {
                                    //debug('Remove from bring item:  ' + bringItem.name + ' because done and not on alexa list');
                                    //Not executed since I want to keep the recent items inside bring app
                                } else {
                                    if (msource === 'Bring') {
                                        debug('Adding ' + bringItem.name + ' to Alexa list.');
                                        setState(alexaAddToList, ListCleaner(bringItem.name));
                                    }
                                }
                            }
                        }
                    
                        return newBringList;
                    }
                    
                    
                    function doSync(source) {
                        eliminateDuplicated();
                        const alexaList = JSON.parse(getState(alexaListId).val);
                        const state = getState(bringListId);
                        const bringList = JSON.parse(state.val);
                        const state2 = getState(bringListCompletedId);
                        const bringListCompleted = JSON.parse(state2.val);
                    
                        syncLists(alexaList, bringList, state.ts, source, bringListCompleted);
                    }
                    
                    function eliminateDuplicated() {
                        var myAlexaList = JSON.parse(getState(alexaListId).val);
                        var arrayWithDuplicates = [];
                    
                        for(var alexaItem of myAlexaList) {
                            var obj = {};
                            obj["value"] = ListCleaner(alexaItem.value);
                            obj["id"] = alexaItem.id;
                            arrayWithDuplicates.push(obj);       
                        }
                    
                        const lookup = arrayWithDuplicates.reduce((a, e) => {
                        a[e.value] = ++a[e.value] || 0;
                        return a;
                        }, {});
                    
                        const
                            getKey = o => keys.map(k => o[k]).join('|'),
                            keys = ['value'],
                            myarray = arrayWithDuplicates.filter(e => lookup[e.value]),
                            hash = Object.create(null),
                            duplicates = myarray.filter(o =>
                                (k => (hash[k] = (hash[k] || 0) + 1) > 1)
                                (getKey(o))
                            );
                    
                        for(var item of duplicates) {
                            debug('Delete  Alexa item: ' + item.value + ' because duplicated.');
                            setState(`${alexa2BaseId}.items.${item.id}.#delete`, true);
                        }
                    }
                    
                    on({id: bringListId, change: 'any'}, e => {
                        debug('Update triggered from Bring');
                        doSync('Bring');
                    });
                    
                    on({id: alexaListId, change: 'any'}, e => {
                        debug('Update triggered from Alexa');
                        doSync('Alexa');
                    });
                    
                    doSync();
                    
                    
                    Fuchsbau K T Christoph1337 4 Replies Last reply Reply Quote 8
                    • Fuchsbau
                      Fuchsbau @icastillo15 last edited by

                      @icastillo15
                      Chapeau icastillo15, 👍 👏
                      ich habe es eben getestet und es läuft hervorragen.
                      Es ist genial das du es geschafft hast mit der Duplikate Erkennung und Korrektur zur Großschreibung.

                      Mit der Bring Spracheingabe, meinte ich übrigens das Alexa Bring Skill. Das wir mit deinem Skript, jetzt nicht mehr benötigt.

                      Jetzt könne wir nur hoffen, das Amazon die Lücke, das die Einkaufsliste ausgelesen und bearbeite werden kann, nicht schlisst.

                      Von meiner Seite ein großes Dankeschön. 🤝

                      Gruß Fuchsbau

                      1 Reply Last reply Reply Quote 0
                      • K
                        kai.bauder @icastillo15 last edited by

                        @icastillo15 Herzlichen Danke für deine Arbeit!

                        1 Reply Last reply Reply Quote 0
                        • Dicken
                          Dicken last edited by

                          @icastillo15 Danke für deine Arbeit 🙂

                          Doofe Frage: Hab bisher immer AnyList oder ToDoist benutzt, gibt es bei Bring! nicht die Möglichkeit die Einzelnen Artikel zu sortieren? Also kann man nur die Kategorien sortieren?

                          icastillo15 1 Reply Last reply Reply Quote 0
                          • icastillo15
                            icastillo15 @Dicken last edited by

                            @dicken

                            Genau - nach meinem Stand kannst du nur die Kategorien tauschen. Mir reicht das mit der Kachelansicht dann aber völlig als Übersicht. Aber meistens habe ich auch nur kleinere Listen und keine Rieseneinkäufe - wenn nicht gerade Weihnachten ist. Das ist dann wohl sehr individuell 😀

                            Dicken 1 Reply Last reply Reply Quote 0
                            • Dicken
                              Dicken @icastillo15 last edited by

                              @icastillo15 schade, na vllt ergibt sich ja noch eine Lösung mit todoist. In den Augen meiner Frau bin natürlich erstmal ich schuld wenn irgendwas nicht mehr so geht wie vorher 😄 Aber ich geb die Hoffnung nicht aus und versuch mich vllt mal selber an einem Script 🙂

                              1 Reply Last reply Reply Quote 0
                              • daniel.driessen
                                daniel.driessen last edited by daniel.driessen

                                Hallo zusammen,

                                da mich die Änderung seitens Amazon auch nervt habe ich auch mal auf die schnelle ein kleines TypeScript zusammengebastelt.
                                Es ist mit Sicherheit noch nicht perfekt, aber ein Anfang. Da ich es gerade erst fertig gestellt habe, hatte ich auch noch nicht die Möglichkeit und Zeit es ausgiebig zu testen.
                                Gerne stelle ich es aber hier allen Interessierten zur Verfügung.

                                Zusätzliche Info:
                                Der Code-Dokumentationsblock am Anfang des Scripts gibt eine genauere Beschreibung des Scripts.
                                Nachdem Ihr den Inhalt der Textdatei in ein neues TypeScript kopiert habt, sollte es denke ich reichen die 5 Werte im Code-Block "SCRIPT SETUP" anzupassen.
                                JavaScript und TypeScript sind recht neu für mich und mit Sicherheit habe ich auch ungewollt das eine oder andere potentielle Problem ins Script eingebaut.
                                Ihr dürft mir natürlich gerne feedback geben.

                                P.S. Ich habe gerade erst gesehen das @icastillo15 ebenfalls etwas gebastelt hat. Hätte ich mal erst hier gelesen, dann hätte ich mir meine Arbeit vielleicht sparen können.
                                😆 Ich werde sein Script auf jeden Fall in den nächsten Tagen ebenfalls mal testen.
                                Vielleicht kann ich ja was lernen.

                                Grüße

                                Daniel

                                Script-File:
                                Shopping-List Sync.txt

                                Maetzi87 1 Reply Last reply Reply Quote 0
                                • mriceg
                                  mriceg last edited by

                                  Moin. Weiß hier jemand, ob ein Adapter für Anylist oder Todoist in Arbeit ist?

                                  Ich finde es zwar super, dass hier eine Lösung für den Sync zwischen Alexa und Bring erstellt wurde, aber leider gibt es für Bring kein Android-Widget, was für mich (bzw. meine Frau) ein großes Problem ist.

                                  Dicken 1 Reply Last reply Reply Quote 0
                                  • Dicken
                                    Dicken @mriceg last edited by

                                    @mriceg siehe hier 😉

                                    mriceg 1 Reply Last reply Reply Quote 0
                                    • mriceg
                                      mriceg @Dicken last edited by

                                      @dicken Danke, aber damit wird m.E. nicht die Todoist oder Anylist-Liste synchronisiert. Alle anderen Lösungen haben Nachteile, die wir möglichst vermeiden möchten. Das Widget der Alexa-Shoppinglist aktualisiert sich z.B. viel zu langsam und manchmal einige Stunden gar nicht. Die Bring-App hat kein Widget.

                                      Ro75 Dicken 2 Replies Last reply Reply Quote 0
                                      • Ro75
                                        Ro75 @mriceg last edited by

                                        @mriceg sagte in Alexa Shopping List mit Bring synchronisieren:

                                        Alexa-Shoppinglist aktualisiert sich z.B. viel zu langsam

                                        welches meinst du?

                                        Ro75.

                                        mriceg 1 Reply Last reply Reply Quote 0
                                        • Dicken
                                          Dicken @mriceg last edited by

                                          @mriceg naja übergangsweise läuft es bei mir eigentlich ganz gut. Ist halt eine Notlösung bis es was besseres gibt 🙂

                                          1 Reply Last reply Reply Quote 0
                                          • mriceg
                                            mriceg @Ro75 last edited by

                                            @ro75 said in Alexa Shopping List mit Bring synchronisieren:

                                            welches meinst du?

                                            Das Widget von der Alexa-App

                                            Ro75 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            940
                                            Online

                                            31.6k
                                            Users

                                            79.4k
                                            Topics

                                            1.3m
                                            Posts

                                            25
                                            144
                                            13156
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo