GANZ WICHTIG: Ihr müsst eure eigene listUUID verwenden! Dieses erhaltet ihr, indem ihr euch auf https://web.getbring.com anmeldet.
Bis zum 1. Juli 2024 war es relativ einfach die bring! Einkaufsliste mit seiner Alexa zu nutzen.
Es reichte lediglich der Befehl: “Alexa, füge Milch zu meiner Bring! Einkaufsliste.
Doch seit dem 1. Juli 2024 hat Amazon mitgeteilt, die Integrationen von Alexa mit Listen- und Notizen-Apps von Drittanbietern einzustellen. Natürlich kann man Bring! weiterhin verwenden, es bedarf nur einen Zwischenschritt. Man muss zuerst den Skill per Command aktivieren: “Alexa, öffne die Bring! Einkaufsliste“
Danach kann man wie gewohnt alle Artikel auf die Einkaufsliste setzen:
„Füge Milch hinzu”
- “Füge Brot hinzu”
- “Setze Kartoffeln auf meine Einkaufsliste”
- “Nimm Weißbrot von meiner Liste”
- “Entferne Basilikum von der Liste”
- “Lösche Erdbeeren”
Man könnte aber auch den Befehl in einem einzigen Satz geben: “Alexa, öffne Bring! und setze Gulasch auf meine Einkaufsliste.” Wichtig hierbei ist, dass du Alexa zuerst explizit darum bittest Bring! zu öffnen, bevor du deine Einkaufsliste bearbeitest.
Mit nodeRED wird das jetzt jedoch anders!
Automatisierung der Einkaufsliste: Synchronisation von Alexa zu Bring mit Node-RED
Bevor wir beginnen, stelle sicher, dass Du folgende Voraussetzungen erfüllst:
- Ein Amazon Alexa Konto.
- Ein Bring-Konto.
- Die benötigten Node-RED Nodes:
node-red-contrib-bring
- node-red-contrib-alexa-remote2
Füge die alexa-remote-account
Node hinzu und konfiguriere sie mit deinem Amazon-Konto.
Füge die bringCredentials
Node hinzu und gebe deine Bring-Anmeldedaten ein.
Alle 60 Minuten (kann beliebig geändert werden) rufen wir die Alexa-Shopping-List ab.
Die dort enthaltenen Einträge werden für die Verarbeitung in Bring! konvertiert.
{
"id": "3ced098e48d3c420",
"type": "function",
"z": "9ae5928.011d07",
"name": "Format for Bring",
"func": "let items = msg.payload.map(item => {\n return {\n itemName: item.value,\n quantity: 1, // Default quantity\n listUUID: \"loremipsum-000c-45df-8736-loremipsum\",\n alexaItemId: item.id // Add Alexa item ID for later use\n };\n});\nmsg.payload = items;\nreturn msg;",
"outputs": 1,
"x": 660,
"y": 1340,
"wires": [
[
"c4f7f2dc0d728a78"
]
]
}
Die Nachrichten werden gesplittet und an die Node für die Bring! Einkaufsliste übergeben.
Mit einer kurzen Wartezeit (damit hier nichts schneller verarbeitet wird, bevor die Einträge nicht ordentlich synchronisiert worden sind) formatieren wir die Einträge der Alexa-Shopping-List, splitten sie ebenfalls, und geben den payload an die Node “Remote Alexa Item” weiter.
{
"id": "a41ca26d0c71359e",
"type": "function",
"z": "9ae5928.011d07",
"name": "Prepare Items for Deletion",
"func": "if (Array.isArray(msg.payload)) {\n let itemsToDelete = msg.payload.map(item => {\n if (item.id) {\n return {\n listUUID: \"loremipsum-000c-45df-8736-loremipsum\",\n alexaItemId: item.id\n };\n } else {\n node.warn(\"Item is missing 'id' property:\", item);\n return null;\n }\n }).filter(item => item !== null);\n\n msg.payload = itemsToDelete;\n return msg;\n} else {\n node.error(\"msg.payload is not an array\");\n return null;\n}",
"outputs": 1,
"x": 920,
"y": 1420,
"wires": [
[
"4321060b26bef210"
]
]
}
Mit diesem Flow haben wir erfolgreich eine Automatisierung erstellt, die die Alexa-Einkaufsliste mit der Bring-App synchronisiert und die Einträge anschließend aus der Alexa-Liste löscht. Diese Lösung spart dir Zeit und sorgt dafür, dass deine Einkaufslisten immer auf dem neuesten Stand sind.
Zudem reicht es künftig nur noch aus, indem wir sagen: “Alexa, füge Klopapier zur Einkaufsliste”.
Keine Umwege mehr über gesonderte Sprachbefehle.
Kompletter Flow:
[{"id":"e247897a0c907800","type":"inject","z":"9ae5928.011d07","name":"Sync Alexa to Bring","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"str"}],"repeat":"3600","crontab":"","once":true,"onceDelay":"0.1","topic":"","payload":"","payloadType":"date","x":340,"y":2740,"wires":[["afd8a286bdd569a8"]]},{"id":"afd8a286bdd569a8","type":"alexa-remote-list","z":"9ae5928.011d07","name":"Get Alexa Shopping List","account":"","config":{"option":"getListItems","value":{"list":{"type":"str","value":"loremipsum="}}},"x":580,"y":2740,"wires":[["c80359a643c91552","e8e0ac0952384ea4"]]},{"id":"c80359a643c91552","type":"function","z":"9ae5928.011d07","name":"Format for Bring","func":"let items = msg.payload.map(item => {\n return {\n itemName: item.value,\n quantity: 1, // Default quantity\n listUUID: \"loremipsum-000c-45df-8736-loremipsum\",\n alexaItemId: item.id // Add Alexa item ID for later use\n };\n});\nmsg.payload = items;\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":800,"y":2740,"wires":[["808b0ef85db604b3"]]},{"id":"808b0ef85db604b3","type":"split","z":"9ae5928.011d07","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":980,"y":2740,"wires":[["3d16a287119efadc","808c2efa1cafd225"]]},{"id":"3d16a287119efadc","type":"debug","z":"9ae5928.011d07","name":"Display List","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1170,"y":2720,"wires":[]},{"id":"808c2efa1cafd225","type":"saveItem","z":"9ae5928.011d07","name":"","bringCredentials":"","x":1160,"y":2760,"wires":[[]]},{"id":"e8e0ac0952384ea4","type":"delay","z":"9ae5928.011d07","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":810,"y":2820,"wires":[["3e8639976d3fa83d"]]},{"id":"3e8639976d3fa83d","type":"function","z":"9ae5928.011d07","name":"Prepare Items for Deletion","func":"if (Array.isArray(msg.payload)) {\n let itemsToDelete = msg.payload.map(item => {\n if (item.id) {\n return {\n listUUID: \"loremipsum-000c-45df-8736-loremipsum\",\n alexaItemId: item.id\n };\n } else {\n node.warn(\"Item is missing 'id' property:\", item);\n return null;\n }\n }).filter(item => item !== null);\n\n msg.payload = itemsToDelete;\n return msg;\n} else {\n node.error(\"msg.payload is not an array\");\n return null;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1060,"y":2820,"wires":[["c50add9252d7fb05"]]},{"id":"c50add9252d7fb05","type":"split","z":"9ae5928.011d07","name":"Split Items","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":1290,"y":2820,"wires":[["855ed602e8189bd9"]]},{"id":"855ed602e8189bd9","type":"alexa-remote-list","z":"9ae5928.011d07","name":"Remove Alexa Item","account":"","config":{"option":"removeItem","value":{"list":{"type":"str","value":"loremipsum"},"item":{"type":"msg","value":"payload.alexaItemId"}}},"x":1490,"y":2820,"wires":[[]]}]
Ich sollte vielleicht noch anmerken, dass ihr eure eigene listUUID verwenden müsst. Die in dem vorherigen Beispiel war meine eigene.
Die listUUID könnt ihr ganz einfach über die Entwicklertools von eurem Browser ermitteln.