# Node-Red example flows for beginners

**URL:** <https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294>\
**Category:** Using farmOS\
**Created:** [July 26, 2022, 4:45pm UTC](https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294 "2022-07-26T16:45:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![pat](https://yyz2.discourse-cdn.com/free1/user_avatar/farmos.discourse.group/pat/32/1050_2.png) [@pat](https://farmos.discourse.group/u/pat)\
**Post date:** [July 26, 2022, 4:45pm UTC](https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294/1 "2022-07-26T16:45:06Z")

</div>

It would be nice to have a thread of simple examples of Node-Red flows interacting with FarmOS. I’ve tried this a few times myself, but I never get it to the finish.  
So I ask for help here, and also try to make it easier for others to start using Node-Red.

@Farmer-Ed has documented a lot of his Node-Red project here in the forum, but it’s quite complex to start with.

I think a **screenshot** of the Flow, and a **JSON export of the flow** could work.  
The flows shold not be farm specific.

---

<div class="post-metadata">

**Author:** ![pat](https://yyz2.discourse-cdn.com/free1/user_avatar/farmos.discourse.group/pat/32/1050_2.png) [@pat](https://farmos.discourse.group/u/pat)\
**Post date:** [July 26, 2022, 5:07pm UTC](https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294/2 "2022-07-26T17:07:22Z")

</div>

> Authenticate with FarmOS:

 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/ca99915bb73197d97094ed8f47ab8d2af2420cd1.png)  
This flow should provide a login to FarmOS. It also keeps you logged in for some time.  
It would need the installation of **node-red-dashboard** and maybe **node-red-contrib-oauth2**  
Edit: **node-red-contrib-credentials** is also needed.

![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/77b843e29cc544c34d569b2874d1a928e03e921b.png)

The ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/2c74528bd44a52d37ce662d80efa77320b02920d.png) node must be setup with the FarmOS URL of your instance.

Then you should be able to log in from the dashboard in Node Red.  
If success you will get a notice of “Access Granted”  
 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/8374a05a3cf7a8e668258f5a22f2fbff60ef27bf.png)

```auto
[
    {
        "id": "cb009280587b2d34",
        "type": "tab",
        "label": "FarmOS authenticate",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "54e5e55c099a85e8",
        "type": "function",
        "z": "cb009280587b2d34",
        "name": "Save OAuth Token",
        "func": "if (msg.payload.access_token) {\n var token = msg.payload.access_token;\n var refresh = msg.payload.refresh_token;\n global.set('token', token);\n flow.set('refresh', refresh);\n Time = new Date()\n msg.payload = \"Access Granted \" + Time;\n \n} else {\n msg.payload = \"Authorization error.\";\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 850,
        "y": 80,
        "wires": [
            [
                "553b16d833bcfc85"
            ]
        ]
    },
    {
        "id": "8439cae9548df4ae",
        "type": "function",
        "z": "cb009280587b2d34",
        "name": "Refresh Token",
        "func": "var refresh = flow.get('refresh');\n\nmsg.oauth2Request = {\n \"access_token_url\": global.get('farmOSurl').concat('/oauth/token'), \n \"credentials\": {\n \"grant_type\": \"refresh_token\",\n \"client_id\": \"farm\",\n \"client_secret\": \"client_secret\",\n \"refresh_token\": refresh,\n \"scope\": \"farm_manager\"\n }\n};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 500,
        "y": 20,
        "wires": [
            [
                "7aa71dad7ad382af"
            ]
        ]
    },
    {
        "id": "814dda54a6d2dfcb",
        "type": "function",
        "z": "cb009280587b2d34",
        "name": "Creat OAuth2Request",
        "func": "var farmOSurl = msg.payload.url\nglobal.set('farmOSurl', farmOSurl);\n\nmsg.oauth2Request = { \n \"access_token_url\": msg.payload.url.concat(\"/oauth/token\"), \n \"credentials\": {\n \"grant_type\": \"password\",\n \"username\": msg.payload.username,\n \"password\": msg.payload.password,\n \"client_id\": \"farm\",\n \"client_secret\": \"client_secret\",\n \"scope\": \"farm_manager\"\n }\n };\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 480,
        "y": 80,
        "wires": [
            [
                "7aa71dad7ad382af"
            ]
        ]
    },
    {
        "id": "7aa71dad7ad382af",
        "type": "oauth2",
        "z": "cb009280587b2d34",
        "name": "",
        "container": "payload",
        "access_token_url": "http://localhost/oauth2/token",
        "grant_type": "set_by_credentials",
        "username": "",
        "password": "",
        "client_id": "",
        "client_secret": "",
        "scope": "farmos_restws_access",
        "rejectUnauthorized": true,
        "headers": {},
        "x": 670,
        "y": 80,
        "wires": [
            [
                "54e5e55c099a85e8"
            ]
        ]
    },
    {
        "id": "01598c1320769cdd",
        "type": "credentials",
        "z": "cb009280587b2d34",
        "name": "farmOS URL ",
        "props": [
            {
                "value": "payload.url",
                "type": "msg"
            }
        ],
        "credentials": {},
        "x": 270,
        "y": 80,
        "wires": [
            [
                "814dda54a6d2dfcb"
            ]
        ]
    },
    {
        "id": "beb68fa523b60517",
        "type": "ui_button",
        "z": "cb009280587b2d34",
        "name": "",
        "group": "16448850.68666",
        "order": 2,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Refresh Token",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 90,
        "y": 20,
        "wires": [
            [
                "8439cae9548df4ae"
            ]
        ]
    },
    {
        "id": "269fc9d8c70219ea",
        "type": "ui_form",
        "z": "cb009280587b2d34",
        "name": "",
        "label": "FarmOS Login",
        "group": "16448850.68666",
        "order": 1,
        "width": 0,
        "height": 0,
        "options": [
            {
                "label": "Username",
                "value": "username",
                "type": "text",
                "required": true,
                "rows": null
            },
            {
                "label": "Password",
                "value": "password",
                "type": "password",
                "required": true,
                "rows": null
            }
        ],
        "formValue": {
            "username": "",
            "password": ""
        },
        "payload": "",
        "submit": "Logg inn",
        "cancel": "Avbryt",
        "topic": "",
        "topicType": "str",
        "splitLayout": false,
        "className": "",
        "x": 90,
        "y": 80,
        "wires": [
            [
                "01598c1320769cdd"
            ]
        ]
    },
    {
        "id": "553b16d833bcfc85",
        "type": "ui_text",
        "z": "cb009280587b2d34",
        "group": "16448850.68666",
        "order": 2,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Auth Token",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "className": "",
        "x": 1050,
        "y": 80,
        "wires": []
    },
    {
        "id": "16448850.68666",
        "type": "ui_group",
        "name": "",
        "tab": "e4996a8c673daf28",
        "order": 2,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "e4996a8c673daf28",
        "type": "ui_tab",
        "name": "farmOS OAuth2",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

```

---

<div class="post-metadata">

**Author:** ![Farmer-Ed](https://yyz2.discourse-cdn.com/free1/user_avatar/farmos.discourse.group/farmer-ed/32/662_2.png) [@Farmer-Ed](https://farmos.discourse.group/u/Farmer-Ed)\
**Post date:** [July 26, 2022, 6:12pm UTC](https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294/3 "2022-07-26T18:12:34Z")

</div>

Most of my flows use custom nodes which are not available to install via Manage Palette in Node-Red, but can be installed by running the following inside the Node-Red folder.

```auto
npm i @farmer-ed/node-red-4-farmos

```

**Authentication**

 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/bfc66f12a66343e1cb05b0dc2e9ea69d0f2b6eec.png)

```auto
[
    {
        "id": "1cc68abbf2c0569c",
        "type": "inject",
        "z": "01518f98870b2ad5",
        "name": "",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "10",
        "topic": "",
        "x": 170,
        "y": 120,
        "wires": [
            [
                "aa45d743bb90f4ab"
            ]
        ]
    },
    {
        "id": "ac596d264a467b63",
        "type": "debug",
        "z": "01518f98870b2ad5",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 750,
        "y": 120,
        "wires": []
    },
    {
        "id": "4f3a447ade862043",
        "type": "comment",
        "z": "01518f98870b2ad5",
        "name": "Oauth2 example",
        "info": "",
        "x": 180,
        "y": 60,
        "wires": []
    },
    {
        "id": "aa45d743bb90f4ab",
        "type": "credentials",
        "z": "01518f98870b2ad5",
        "name": "farmOS Credentials",
        "props": [
            {
                "value": "payload.url",
                "type": "msg"
            },
            {
                "value": "payload.username",
                "type": "msg"
            },
            {
                "value": "payload.password",
                "type": "msg"
            },
            {
                "value": "payload.client_id",
                "type": "msg"
            },
            {
                "value": "client_secret",
                "type": "msg"
            },
            {
                "value": "payload.scope",
                "type": "msg"
            }
        ],
        "credentials": {},
        "x": 350,
        "y": 120,
        "wires": [
            [
                "5fc86eeb94e10cb0"
            ]
        ]
    },
    {
        "id": "5fc86eeb94e10cb0",
        "type": "sf:895a366cbeeeb85e",
        "z": "01518f98870b2ad5",
        "name": "",
        "credentials": {},
        "x": 560,
        "y": 120,
        "wires": [
            [
                "ac596d264a467b63"
            ]
        ]
    }
]

```

**Simple GET**  
 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/9357e992115edf36909b4d1a206119bb8b5f9e9c.png)  
 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/5d515e92a6d88e0b6055e9558016169498c9edac.png)

```auto
[
    {
        "id": "d1bdb8fba4d14229",
        "type": "comment",
        "z": "01518f98870b2ad5",
        "name": "Get Examples",
        "info": "",
        "x": 170,
        "y": 200,
        "wires": []
    },
    {
        "id": "f7be6a3510df7551",
        "type": "inject",
        "z": "01518f98870b2ad5",
        "name": "",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 170,
        "y": 260,
        "wires": [
            [
                "69ef18606737bae9"
            ]
        ]
    },
    {
        "id": "69ef18606737bae9",
        "type": "sf:949541c9b70110d5",
        "z": "01518f98870b2ad5",
        "name": "",
        "API": "log/transplanting",
        "Method": "GET",
        "x": 330,
        "y": 260,
        "wires": [
            [
                "f18dbdfa68fe209f"
            ]
        ]
    },
    {
        "id": "f18dbdfa68fe209f",
        "type": "debug",
        "z": "01518f98870b2ad5",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 510,
        "y": 260,
        "wires": []
    }
]

```

---

<div class="post-metadata">

**Author:** ![Farmer-Ed](https://yyz2.discourse-cdn.com/free1/user_avatar/farmos.discourse.group/farmer-ed/32/662_2.png) [@Farmer-Ed](https://farmos.discourse.group/u/Farmer-Ed)\
**Post date:** [July 26, 2022, 6:23pm UTC](https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294/4 "2022-07-26T18:23:28Z")

</div>

**GET taxonomy terms and save to a flow variable array**  
If paginated all results are combined into a single array in Node-Red. Array is destroyed and recreated on each run.

 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/2c190cc5a79365547b6b12c7fa16013f324cfc2e.png)

```auto
[
    {
        "id": "96151bcfe0fc47aa",
        "type": "inject",
        "z": "01518f98870b2ad5",
        "name": "",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 170,
        "y": 320,
        "wires": [
            [
                "7b059f30417e29b4"
            ]
        ]
    },
    {
        "id": "753807fcc66731e5",
        "type": "sf:949541c9b70110d5",
        "z": "01518f98870b2ad5",
        "name": "",
        "API": "taxonomy_term/animal_type",
        "Method": "GET",
        "x": 510,
        "y": 320,
        "wires": [
            [
                "b3d2697f4efe2d5f"
            ]
        ]
    },
    {
        "id": "b3d2697f4efe2d5f",
        "type": "function",
        "z": "01518f98870b2ad5",
        "name": "GET Animal Term ID's",
        "func": "var array = flow.get('breeds') || [];\nvar breed;\nvar id;\n\nmsg.payload.data.forEach(data => {\nbreed = data.attributes.name;\nid = data.id;\narray.push({id:id,breed:breed});\n})\n\nflow.set(\"breeds\", array);\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 720,
        "y": 320,
        "wires": [
            [
                "d1ca3b9a04ba568a"
            ]
        ]
    },
    {
        "id": "d1ca3b9a04ba568a",
        "type": "debug",
        "z": "01518f98870b2ad5",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 930,
        "y": 320,
        "wires": []
    },
    {
        "id": "7b059f30417e29b4",
        "type": "change",
        "z": "01518f98870b2ad5",
        "name": "Clear array",
        "rules": [
            {
                "t": "delete",
                "p": "breeds",
                "pt": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 330,
        "y": 320,
        "wires": [
            [
                "753807fcc66731e5"
            ]
        ]
    }
]

```

**CSV Export**

 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/d0ec79e50cf63646a8f7f7dff7bb2d3741d45a3c.png)

```auto
[
    {
        "id": "b5f0fab209322c18",
        "type": "function",
        "z": "01518f98870b2ad5",
        "name": "CSV Headings",
        "func": "//Headings for Creation of Blank CSV File\nmsg.payload = \"Tag Number,Gender,Date of Birth,Breed\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 340,
        "y": 540,
        "wires": [
            [
                "af52c3f7785bbd99"
            ]
        ]
    },
    {
        "id": "af52c3f7785bbd99",
        "type": "file",
        "z": "01518f98870b2ad5",
        "name": "Blank File with Headings",
        "filename": "/Node Red/Herd Export.csv",
        "appendNewline": true,
        "createDir": false,
        "overwriteFile": "true",
        "encoding": "none",
        "x": 570,
        "y": 540,
        "wires": [
            [
                "11faaec3fb80cce5"
            ]
        ]
    },
    {
        "id": "f14d58aa9952ef30",
        "type": "function",
        "z": "01518f98870b2ad5",
        "name": "Parse Asset",
        "func": "//Declare Variables\nvar array = flow.get('breeds')\nlet outputMsgs = [];\nvar tag,dob,breed,gender,csv,code;\n\n//extract data from each asset\nmsg.payload.data.forEach(data => {\n if (data.attributes.archived == null) {\n tag = data.attributes.id_tag[0].id;\n gender = data.attributes.sex;\n dob = data.attributes.birthdate;\n \n //Start DOB Date formatting\n const date = new Date(dob);\n const newDateString = date.getDate() + \"/\" + (date.getMonth()+1) + \"/\" + date.getFullYear();\n //End DOB Date formatting\n \n //Get Breed from taxanomy UUID\n breed = data.relationships.animal_type.data.id;\n array.forEach(dat => {\n if (dat.id == breed) {\n code = dat.breed;\n }\n })\n \n //output Data to CSV one asset at a time\n csv = tag +\",\"+gender+ \",\" + newDateString + \",\" + code ; \n outputMsgs.push({payload:csv});\n \n }\n })\n\nreturn [outputMsgs];",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 970,
        "y": 540,
        "wires": [
            [
                "79f6c5a353cb3aef"
            ]
        ]
    },
    {
        "id": "79f6c5a353cb3aef",
        "type": "file",
        "z": "01518f98870b2ad5",
        "name": "Export CSV file",
        "filename": "/Node Red/Herd Export.csv",
        "appendNewline": true,
        "createDir": false,
        "overwriteFile": "false",
        "encoding": "none",
        "x": 1160,
        "y": 540,
        "wires": [
            [
                "d851e8a3f77105ee"
            ]
        ]
    },
    {
        "id": "11faaec3fb80cce5",
        "type": "sf:949541c9b70110d5",
        "z": "01518f98870b2ad5",
        "name": "GET Asset",
        "API": "asset/animal",
        "Method": "GET",
        "x": 790,
        "y": 540,
        "wires": [
            [
                "f14d58aa9952ef30"
            ]
        ]
    },
    {
        "id": "32788bf611c63b3c",
        "type": "inject",
        "z": "01518f98870b2ad5",
        "name": "",
        "props": [],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 170,
        "y": 540,
        "wires": [
            [
                "b5f0fab209322c18"
            ]
        ]
    },
    {
        "id": "d851e8a3f77105ee",
        "type": "debug",
        "z": "01518f98870b2ad5",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1350,
        "y": 540,
        "wires": []
    }
]

```

---

<div class="post-metadata">

**Author:** ![pat](https://yyz2.discourse-cdn.com/free1/user_avatar/farmos.discourse.group/pat/32/1050_2.png) [@pat](https://farmos.discourse.group/u/pat)\
**Post date:** [August 12, 2022, 11:33am UTC](https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294/5 "2022-08-12T11:33:40Z")

</div>

Basic example of POSTing data to FarmoOS:  
Provided youre already authorized, this flow will post a plain and simple activity log tied to an equipment asset.

 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/70c80800f1a436970142b4b3043348e03ac2ed05.png)

If you set the debug node to view the complete message object, you will get some status message.  
 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/cfba6628f9a51aff06d3c49486542f8bd2558e72.png)

If success, you will get statuscode 201  
 ![image](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/f637395325d203c2666eb735c24bca55713c61b8.png)

```auto
[
    {
        "id": "2d39822504e03b5b",
        "type": "tab",
        "label": "forum",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "9cdf92a9f8583ac2",
        "type": "change",
        "z": "2d39822504e03b5b",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"data\":{\"type\":\"log--activity\",\"attributes\":{\"name\":\"This is an activity log\",\"status\":\"done\",\"notes\":\"Fra nodered\"},\"relationships\":{\"asset\":{\"data\":{\"type\":\"asset--equipment\",\"id\":\"14c07f0e-84d0-4ac1-8bc5-e9bd5b7cbd4d\"}}}}}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 340,
        "y": 120,
        "wires": [
            [
                "01661044537a78d6"
            ]
        ]
    },
    {
        "id": "01661044537a78d6",
        "type": "sf:949541c9b70110d5",
        "z": "2d39822504e03b5b",
        "name": "",
        "API": "log/activity",
        "Method": "POST",
        "x": 530,
        "y": 120,
        "wires": [
            [
                "3d7be814bfa50091"
            ]
        ]
    },
    {
        "id": "ff32f244a2986306",
        "type": "inject",
        "z": "2d39822504e03b5b",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 160,
        "y": 120,
        "wires": [
            [
                "9cdf92a9f8583ac2"
            ]
        ]
    },
    {
        "id": "3d7be814bfa50091",
        "type": "debug",
        "z": "2d39822504e03b5b",
        "name": "debug 36",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 700,
        "y": 120,
        "wires": []
    }
]

```

---

<div class="post-metadata">

**Author:** ![pat](https://yyz2.discourse-cdn.com/free1/user_avatar/farmos.discourse.group/pat/32/1050_2.png) [@pat](https://farmos.discourse.group/u/pat)\
**Post date:** [August 26, 2022, 5:27pm UTC](https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294/6 "2022-08-26T17:27:33Z")

</div>

A basic log creation in Node-Red.  
I just push a button on the dashboard, and an activity log of adding salt to an asset is created.

It’s a bit confusing not having a status message in the end, telling me if it was really saved.  
So I came up with this solution:

 ![bilde](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/8bfcadf0cf54cfd7ce7993ff5a7c1aa3b2f7503b.png)

It adds a notification node. It recieves a html string.  
It could also be placed after the button node to let the user proceed or abort before saving anything.

![bilde](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/aa350d18f22e2c89a67d2699b1d75d1558758182.png)  
Translation :  
“Saved in FarmOS”  
The URL takes me to the logs of this asset.

Ideally the URL should point direcly to the logs edit page. But that’s next level.

The switch node checks if msg.statuscode is 201 (success) or not 201.

---

<div class="post-metadata">

**Author:** ![pat](https://yyz2.discourse-cdn.com/free1/user_avatar/farmos.discourse.group/pat/32/1050_2.png) [@pat](https://farmos.discourse.group/u/pat)\
**Post date:** [November 14, 2022, 4:31pm UTC](https://farmos.discourse.group/t/node-red-example-flows-for-beginners/1294/7 "2022-11-14T16:31:09Z")

</div>

Create observation log by sending email.

![bilde](https://global.discourse-cdn.com/free1/uploads/farm_os/original/1X/195ac1dea4325be9b182ad66b894798793d5d53a.png)

The flow checks for unread mails in a inbox folder. If so, it creates a log with the mail topic as the log’s name, and the mail body as the log’s note.  
I also put an “Email” category to it, so it’s easy to verify them later.

I set up a mail alias and when I forward a mail to the alias, the mail is placed in the FarmOS folder.  
When the flow is executed, the email node changes the mail read status.

```auto
[
    {
        "id": "9d8a923241677a34",
        "type": "e-mail in",
        "z": "1ca30f9571004237",
        "name": "",
        "protocol": "IMAP",
        "server": "imap.fastmail.com",
        "useSSL": true,
        "autotls": "never",
        "port": "993",
        "box": "FarmOS",
        "disposition": "Read",
        "criteria": "UNSEEN",
        "repeat": "3600",
        "fetch": "auto",
        "inputs": 0,
        "x": 190,
        "y": 1080,
        "wires": [
            [
                "e0938f721fea4f15"
            ]
        ]
    },
    {
        "id": "e0938f721fea4f15",
        "type": "function",
        "z": "1ca30f9571004237",
        "name": "function 28",
        "func": "var mail=\n{\n \"data\": {\n \"type\": 'log--observation',\n \"attributes\": {\n \"name\": \"Epost - \" + msg.topic,\n \"status\": \"done\",\n \"notes\": \"\" + msg.payload\n },\n \"relationships\": {\n \"category\": {\n \"data\": [\n {\n \"type\": \"taxonomy_term--log_category\",\n \"id\": \"dbb44cda-addb-4c5e-b41d-237691a3a71e\" //Epost-katoegori\n }\n]\n }\n }\n }\n}\nmsg.payload = mail;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 330,
        "y": 1080,
        "wires": [
            [
                "2894caf76e2466f5"
            ]
        ]
    },
    {
        "id": "2894caf76e2466f5",
        "type": "sf:949541c9b70110d5",
        "z": "1ca30f9571004237",
        "name": "",
        "API": "log/observation",
        "Method": "POST",
        "x": 490,
        "y": 1080,
        "wires": [
            [
                "f8f6784bbb8f464c"
            ]
        ]
    },
    {
        "id": "f8f6784bbb8f464c",
        "type": "debug",
        "z": "1ca30f9571004237",
        "name": "debug 96",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 640,
        "y": 1080,
        "wires": []
    }
]

```
