# World of Text

The World of Text: Automating Home Projects with Node-RED, MongoDB, Todoist, and More

As a homelab enthusiast, I constantly explore ways to streamline and automate daily tasks. My latest project, "World of Text," began with a simple yet powerful concept: capture everyday text inputs and transform them into enriched, actionable data. The idea was to create a system that could seamlessly integrate with various tools and services, adding value to basic text entries by enhancing them with context and storing them for future use.

### **The Concept**

The core idea behind "World of Text" is to take any textual input, whether it’s a note about a home improvement project, an idea for automation, or a simple to-do list item, and automatically enrich it with additional context. This enriched data is then stored in a database and converted into actionable tasks, making it easy to manage and track through various stages of completion.

### **Technologies Used**

To bring this concept to life, I leveraged several technologies, each serving a specific purpose within the system:

* **Proxmox**: The virtualization platform that hosts all the different components of the system. Proxmox enables the creation and management of virtual machines and containers, allowing for a flexible and scalable environment to run services like Node-RED, MongoDB, and Nginx.
* **Node-RED**: The flow-based development tool used to orchestrate the entire process. Node-RED handles everything from capturing user inputs to processing and enriching the data, and finally, integrating with other services.
* **MongoDB**: A NoSQL database used to store the enriched text entries. MongoDB’s flexibility in handling JSON-like documents makes it an ideal choice for storing the varied and dynamic data generated by the system.
* **Todoist**: The task management tool that transforms enriched text entries into actionable tasks. By integrating Todoist with Node-RED, I can automatically generate tasks that are prioritized and labeled according to the context provided by the enriched data.
* **Nginx**: A web server used as a reverse proxy to manage and secure access to the Node-RED instance. Nginx ensures that the system is both accessible and protected from unauthorized access.
* **Cloudflare**: A DNS and security service that provides SSL certificates and other security features, ensuring that the system remains secure and performant. Cloudflare also helps manage DNS settings, making the system accessible through a custom domain.
* **AI-Powered Intent Processing**: To enrich the text data, I used AI-driven intent processing within Node-RED. This component adds valuable context to the raw text inputs, making them more meaningful and actionable.
* **iOS Shortcuts**: This automation tool on iOS devices is used to seamlessly interact with the system, particularly for sending data to the Node-RED API endpoint. Through a custom shortcut, users can input text directly on their iOS device, which is then sent to the system for processing. The shortcut handles tasks like generating the appropriate POST request, adding authorization headers, and sending user input, making the interaction with the backend system smooth and efficient directly from a mobile device.

Each of these technologies plays a crucial role in the overall system, working together to turn simple text inputs into valuable, organized data that can be acted upon with minimal effort.

***

## Technology deployoment

### Proxmox

**Purpose:** Hosting the virtual machines (VMs) and containers that run the various components of the system.

**Requirements:**

1. **Installation of Proxmox:** Proxmox must be installed on a physical server or a dedicated machine. It needs to be accessible through your network, and a basic understanding of managing virtual environments is required.
2. **Network Configuration:** Ensure that Proxmox is configured with a static IP address, and has proper network settings to allow communication between VMs and containers.
3. **Virtual Machine/Container Creation:** Set up VMs or containers for each of the components like Node-RED, MongoDB, and Nginx. Allocate sufficient resources (CPU, RAM, and storage) based on the needs of each component.

**References:**

* [Proxmox VE Installation](https://www.proxmox.com/en/proxmox-ve/get-started)

***

### Node-RED

**Purpose:** Orchestrating the data flow, handling inputs, processing, and integration with other services.

**Requirements:**

1. **Installation on a VM/Container:** Install Node-RED on a dedicated VM or container within Proxmox.
2. **Node-RED Modules:** Install necessary Node-RED modules like `node-red-contrib-mongodb` for MongoDB integration, `node-red-contrib-ai-intent` for AI-based text enrichment, and `node-red-contrib-todoist-api` for Todoist integration.
3. **Environment Configuration:** Configure Node-RED to ensure it can communicate with MongoDB and Todoist. This includes setting up environment variables or configuration nodes within Node-RED to store API keys, database connection strings, and other credentials.

**References:**

* [Node-RED Getting Started](https://nodered.org/docs/getting-started/local)
* [Node-RED Modules](https://flows.nodered.org/)

***

### MongoDB

**Purpose:** Storing the enriched text entries and context data.

**Requirements:**

1. **Installation on a VM/Container:** Set up MongoDB on its own VM or container within Proxmox. Ensure that MongoDB is configured to allow connections from Node-RED.
2. **Database Configuration:** Create a database (`worldOfText` for instance) and necessary collections to store the enriched data.
3. **User and Access Control:** Set up a MongoDB user with appropriate permissions that Node-RED will use to interact with the database. Ensure network access is allowed for the Node-RED container/VM.

**References:**

* [MongoDB Installation Guide](https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/)
* [MongoDB Node-RED Integration](https://flows.nodered.org/node/node-red-node-mongodb)

***

### Todoist

**Purpose:** Converting enriched text entries into actionable tasks.

**Requirements:**

1. **API Access:** Register for a Todoist account and generate an API token. This token will be used within Node-RED to interact with Todoist.
2. **Project Setup:** Create a project in Todoist where the tasks will be added. Note the project ID as it will be needed in Node-RED.
3. **Node-RED Configuration:** Configure the `node-red-contrib-todoist-api` module with your Todoist API token and project ID to allow Node-RED to create tasks based on the enriched data.

**References:**

* [Todoist API Documentation](https://developer.todoist.com/rest/v2/#overview)
* [Node-RED Todoist Integration](https://flows.nodered.org/node/@foxleigh81/node-red-contrib-todoist-api)

***

### Nginx Reverse proxy Manager

**Purpose:** Acting as a reverse proxy to secure and manage access to the Node-RED instance.

**Requirements:**

1. **Installation on a VM/Container:** Install Nginx on a dedicated VM or container within Proxmox.
2. **Reverse Proxy Configuration:** Set up Nginx to reverse proxy the Node-RED instance, ensuring it can be accessed securely from outside your network.
3. **SSL Configuration:** Obtain and install SSL certificates (using Let's Encrypt or similar) to secure the connection to Node-RED. Configure Nginx to enforce HTTPS connections.
4. **Firewall Rules:** Ensure that the firewall is configured to allow traffic on the ports used by Nginx (typically 80 and 443).

**References:**

* [Nginx Setup Guide](https://nginxproxymanager.com/setup/)
* [SSL Configuration with Nginx](https://medium.com/@life-is-short-so-enjoy-it/homelab-nginx-proxy-manager-setup-ssl-certificate-with-domain-name-in-cloudflare-dns-732af64ddc0b)

***

### Cloudflare

**Purpose:** Providing DNS management, SSL certificates, and additional security for the system.

**Requirements:**

1. **Domain Setup:** Register a domain name and configure Cloudflare as your DNS provider.
2. **DNS Configuration:** Set up DNS records in Cloudflare to point to your Nginx server’s public IP address.
3. **SSL/TLS Configuration:** Use Cloudflare to generate and manage SSL certificates. Ensure SSL is configured to “Full (strict)” mode for end-to-end encryption between users and your Nginx server.
4. **Security Settings:** Configure additional security settings in Cloudflare such as DDoS protection, rate limiting, and firewall rules.

**References:**

* [Cloudflare SSL/TLS Configuration](https://developers.cloudflare.com/ssl/)

***

### AI-Powered Intent Processing in Node-RED

**Purpose:** Enriching raw text inputs with additional context to make them actionable.

**Requirements:**

1. **Node-RED Module Installation:** Install and configure the `node-red-contrib-ai-intent` module within Node-RED.
2. **API Integration:** Set up any required API keys or connections needed by the AI module to process text inputs.
3. **Flow Design:** Create Node-RED flows that utilize the AI intent processing to enrich data before storing it in MongoDB or sending it to Todoist.

**References:**

* [Node-RED AI Intent Processing Module](https://flows.nodered.org/node/@technithusiast/node-red-contrib-ai-intent)

***

### **iOS Shortcuts**

**Purpose:** Facilitating quick and seamless interaction with the Node-RED API directly from iOS devices, allowing users to send inputs and retrieve data without needing to access a computer.

**Requirements:**

* **Shortcut Creation:** Use the Shortcuts app on iOS to create a custom shortcut that sends a POST request to the Node-RED API. The shortcut should include input fields for the user’s message, resident identifier, and tags.
* **API Configuration:** Configure the shortcut with the appropriate API endpoint URL and include authorization headers.
* **Testing and Validation:** Test the shortcut to ensure it correctly sends data to Node-RED and handles responses appropriately.\
  **References:**
* [Apple Shortcuts Guide](https://support.apple.com/en-us/HT209055)

***

### **OpenAI**

**Purpose:** Enriching text inputs with context and generating intelligent responses through AI-powered processing.

**Requirements:**

* **API Access:** Register for OpenAI API access and obtain an API key.
* **Node-RED Integration:** Install and configure the necessary Node-RED nodes (e.g., `node-red-node-openai`) to communicate with the OpenAI API.
* **Flow Design:** Create Node-RED flows that leverage OpenAI to analyze and enrich input data before it is stored in MongoDB or converted into tasks in Todoist.
* **Rate Limits:** Be aware of and manage OpenAI API rate limits to ensure smooth operation without service interruptions.\
  **References:**
* [OpenAI API Documentation](https://platform.openai.com/docs/api-reference)

***

## Setup of outside access into Node-RED

Let's walk through the process of securing access to  Node-RED setup using Cloudflare with WAF rules, NGINX as a reverse proxy, and an HTTP In node with a switch node for authorization checks based on headers.

### **Setting Up Cloudflare with Web Application Firewall (WAF) Rules**

**Purpose:** Cloudflare provides an additional layer of security by managing DNS, SSL/TLS encryption, and acting as a firewall to block malicious traffic before it even reaches your server.

**Steps:**

1. **DNS Configuration:**
   * Point your domain name to the public IP address of your NGINX server via an A or CNAME record in Cloudflare's DNS settings.
   * Enable the Cloudflare proxy (orange cloud icon) to route all traffic through Cloudflare's network.
2. **SSL/TLS Configuration:**
   * Set the SSL/TLS encryption mode in Cloudflare to "Full (strict)" to ensure encrypted communication between Cloudflare and your NGINX server.
   * Optionally, use a Cloudflare Origin Certificate on your NGINX server for added security.
3. **WAF Rules Configuration:**
   * Navigate to Firewall > Firewall Rules in Cloudflare.
   * Create rules to block or challenge common threats, such as SQL injections or cross-site scripting (XSS).
   * You can also create a rule to allow traffic only from specific IP addresses (e.g., your home or office network) to further restrict access.

**References:**

* [Cloudflare Firewall Rules Documentation](https://developers.cloudflare.com/firewall/cf-firewall-rules/)

### **Configuring NGINX as a Reverse Proxy**

**Purpose:** NGINX acts as a secure reverse proxy, forwarding requests from the internet to your Node-RED instance running on an internal port.

**Steps:**

1.  **Setting Up NGINX Reverse Proxy:**

    * Install NGINX on a VM or container in Proxmox.
    * Edit the NGINX configuration file (typically found at `/etc/nginx/sites-available/default`) to include a server block for your domain:

    ```nginx
    server {
        listen 80;
        server_name yourdomain.com;

        location / {
            proxy_pass http://localhost:1880;  # Assuming Node-RED runs on port 1880
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    ```

    * Enable the configuration by creating a symbolic link to `sites-enabled` and reload NGINX:

    ```bash
    sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
    sudo systemctl reload nginx
    ```
2.  **Configuring SSL:**

    * Use Certbot to obtain an SSL certificate:

    ```bash
    sudo apt-get install certbot python3-certbot-nginx
    sudo certbot --nginx -d yourdomain.com
    ```

    * Update the NGINX configuration to redirect HTTP traffic to HTTPS:

    ```nginx
    server {
        listen 80;
        server_name yourdomain.com;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        server_name yourdomain.com;

        ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

        location / {
            proxy_pass http://localhost:1880;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    ```

**References:**

* [NGINX Reverse Proxy Guide](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/)
* [Certbot with NGINX](https://certbot.eff.org/lets-encrypt/ubuntufocal-nginx)

### **Securing Node-RED Access with HTTP In Node and Authorization Using a Switch Node**

**Purpose:** The Node-RED HTTP In node handles incoming requests, while a switch node checks the authorization headers to ensure that only authorized users can interact with your flows.

**Steps:**

1. **Setting Up the HTTP In Node:**
   * In Node-RED, create a new flow and add an HTTP In node. Configure the node with the desired method (e.g., POST) and path (e.g., `/webhook`).
2.  **Implementing Authorization with a Switch Node:**

    * After the HTTP In node, add a `function` node to extract the authorization header:

    ```javascript
    msg.authHeader = msg.req.headers.authorization;
    return msg;
    ```

    * Next, add a `switch` node to validate the extracted authorization token. Configure the switch node with rules to check if the `msg.authHeader` matches the expected token:
    * Example switch node setup:
      * `msg.authHeader == "Bearer your-secure-token"` (If this condition is true, the flow continues).
      * Otherwise, the request is rejected.
    * Following the switch node, add two outputs:
      * **Output 1:** Connect to the nodes that handle the authorized request (e.g., a processing function and then an HTTP Response node).
      * **Output 2:** Connect to a `change` node that sets a response message indicating unauthorized access and then to an HTTP Response node with a `401 Unauthorized` status.
3.  **Securing Node-RED Itself:**

    * Set up user-based authentication in Node-RED by editing the `settings.js` file (usually found in the `~/.node-red` directory):

    ```javascript
    adminAuth: {
        type: "credentials",
        users: [{
            username: "admin",
            password: "$2b$08$EwTgVoG2mthV4t0e4P5O.eFJ.vSJb4T/G9.oMiWxYkbab/qLb6b1W",  // Hashed password
            permissions: "*"
        }]
    },
    ```

    * Use `bcrypt` to hash your password before adding it to the configuration file.

**References:**

* [Node-RED HTTP In Node Documentation](https://nodered.org/docs/user-guide/http)
* [Node-RED Security Settings](https://nodered.org/docs/user-guide/runtime/securing-node-red)

#### **Summary**

By combining Cloudflare's WAF for filtering traffic, NGINX as a reverse proxy for handling incoming connections securely, and Node-RED with an HTTP In node secured via a switch node for authorization checks, you create a highly secure environment for your Node-RED setup. This ensures that only requests with the correct authorization headers are allowed to proceed, keeping your flows and data safe.

This structured approach not only secures the network and web layers but also ensures that any interaction with your Node-RED environment is tightly controlled and monitored.

***

## Node-RED data handling - preparing the data for OpenAI

Let’s dive into the “ API POST” group of the “WorldOfText” flow in Node-RED. This part of the flow is critical as it prepares the data for submission to OpenAI, ensuring the input is processed, checked, and formatted correctly before sending it out.

<figure><img src="https://561099036-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSO7C5hvc0iUrifgeRV5v%2Fuploads%2FTb1AtNCOQ60YV8Mr174A%2FScreenshot%202024-08-25%20at%2017.21.59.png?alt=media&#x26;token=121532b3-3d0b-4795-afc0-aa76d8086376" alt=""><figcaption></figcaption></figure>

#### **Step-by-Step Breakdown**

**1. HTTP In Node**

* **Name:** \[post] `/api/apiEndpoint`
* **Purpose:** Receives incoming HTTP POST requests directed to the `/api/apiEndpoint` endpoint.
* **Role:** This node acts as the entry point for the flow, where the raw data is received.

**2. Function Node: "Authz validation"**

* **Purpose:** Validates the authorization header to ensure that the request is from an authorized source.
*   **JavaScript Code:**

    ```javascript
    msg.authHeader = msg.req.headers.authorization;

    if (msg.authHeader === "Bearer your-secure-token") {
        return [msg, null]; // Proceed to the next step
    } else {
        return [null, msg]; // Redirect to Unauthorized flow
    }
    ```
* **Outputs:**
  * **Output 1:** If authorization is successful, the flow continues.
  * **Output 2:** If authorization fails, the flow routes to the "Unauthorized" node.
* **Role:** This node ensures that only requests with the correct authorization token can proceed further.

**3. Function Node: "Unauthorized"**

* **Purpose:** Handles cases where authorization fails.
*   **JavaScript Code:**

    ```javascript
    msg.payload = { error: "Unauthorized" };
    msg.statusCode = 401;
    return msg;
    ```
* **Role:** Sends a "401 Unauthorized" response back to the client if the authorization check fails.

**4. Function Node: "response cleaner"**

* **Purpose:** Prepares the data received from the OpenAI API for further processing.
*   **JavaScript Code:**

    ````javascript
    // Store the incoming request and response objects in the flow context
    global.set('httpReq', msg.req);
    global.set('httpResp', msg.res);

    // Structure the new message
    var newMsg = msg.payload.message;
    var newRes = msg.payload.resident;
    var newTag = msg.payload.tag;
    var originalMessage = newMsg + "\n\n" + "resident: " + newRes + "\n\n" + "tag: " + newTag;

    // Return an object with originalMessage as a key
    return { payload: { originalMessage: originalMessage } };
    ```
    ````
* **Role:** Extracts and cleans the AI-generated response for use in the system.

**5. Function Node: "systemPrompt"**

* **Purpose:** Adds the system prompt details to the payload for further processing.
*   **JavaScript Code:**

    ```javascript
    msg.payload = {
        systemPrompt: "Your System Prompt: Cognitive AI Assistant",
        originalMessage: msg.payload
    };
    return msg;
    ```
* **Role:** This node formats and prepares the system prompt and original message before combining it with other data.

**6. Join Node**

* **Purpose:** Combines the outputs of the "response cleaner" and "systemPrompt" nodes.
* **Configuration:** Joins messages into a single message object.
* **Role:** Merges the cleaned response and system prompt into one message payload.

**7. Function Node: "combined payload"**

* **Purpose:** Prepares the final payload combining all necessary information before storing it in MongoDB and returning a response.
*   **JavaScript Code:**

    ```javascript
    let textResponse = msg.payload.systemPrompt;
    msg.payload = {
        combinedPayload: textResponse,
        originalMessage: msg.payload.originalMessage
    };
    return msg;
    ```
* **Role:** This node structures the final payload for the MongoDB insertion.

### **Purpose of the SystemPrompt Node**

The "systemPrompt" node is designed to augment the incoming data with additional context, ensuring that the data has the necessary metadata and structure required for downstream processing, particularly when interacting with AI models or databases. This node essentially creates a structured prompt that provides the AI with the context it needs to generate accurate and relevant responses.

#### **Detailed Functionality**

1. **Input Data Handling:**
   * The node receives the processed message payload from the previous node in the flow. This payload typically contains the raw input data that was submitted to the `/api/apiEndpoint` endpoint.
   * This raw data might include user-provided text, tags, and any other metadata that was sent with the HTTP POST request.
2. **System Prompt Construction:**
   * The node constructs a system prompt that encapsulates the core task or directive for the AI model. This prompt provides the necessary context and instructions that guide the AI's response generation.
   * The prompt includes information such as:
     * **Assistant Role:** Specifies the role of the AI, in this case, as a "Cognitive AI Assistant".
     * **Task Description:** Clearly outlines the task the AI is expected to perform, such as generating context and metadata for the input data within the "World of Text" database.
     * **Core Responsibilities and Objectives:** Defines what the AI should focus on, including data integrity, security, and relevance, as well as dynamically connecting related concepts and tasks.
     * **Input Data:** The actual text or message that the AI needs to process, ensuring that the AI has all the necessary information to produce a relevant response.
3. **Formatting the Prompt:**
   * The node formats the prompt in a specific structure, making it easy to parse and use by downstream nodes or external APIs.
   *   The prompt is embedded into a JSON structure, which might look something like this:

       ```javascript
       msg.payload = {
           systemPrompt: "Your System Prompt: Cognitive AI Assistant  \n\n\nYour Task: Generate context and metadata for the following input within the \"World of Text\" database.\n\nYour Core Responsibilities:\n- Receive input data and create a input data JSON entry for mongoDB to store the input.\n- You research and add more context to the input to enhance the input for later retrieval, ensuring that it has more value.\n- You ensure the response is exactly as required, to ensure the entry to mongoDB is always correctly handled by other systems.\n\nYour Core Objectives:\n- Maintain data integrity, security, and relevance.\n- Dynamically connect related concepts, ideas, and tasks.\n- Provide precise responses that enhance user interaction with stored data.\n- Add necessary context and details as required.\n- Add url references to the output.\n\nThe Given Input: Will be a text that can be considered the core relevant trigger to act. \n\nYour restricted Output Requirement: JSON format with textResponse and mongoData.",
           originalMessage: msg.payload
       };
       ```
4. **Output for Further Processing:**
   * After constructing the system prompt, the node outputs this structured data to be combined with other pieces of information (such as AI responses) in the subsequent nodes.
   * The system prompt and the original message are passed downstream, often to a node that will send this data to an AI service like OpenAI for processing.

#### **Why is the SystemPrompt Node Important?**

* **Contextual Accuracy:** The system prompt provides essential context, ensuring that the AI model understands the task at hand and generates responses that are aligned with the specific needs of the "World of Text" system.
* **Consistency in Responses:** By standardizing the prompt structure, the node helps ensure that the AI's output is consistent, relevant, and formatted correctly for storage in the MongoDB database.
* **Enhanced AI Interaction:** The node facilitates better interaction with the AI model by clearly defining its role and the expectations for its output, which leads to more meaningful and actionable AI-generated content.

The current SystemPrompt used:

```javascript
// Define the system prompt text
let systemPrompt = `
Your System Prompt: Cognitive AI Assistant  

Your Task: Generate context and metadata for the following input within the "World of Text" database.

Your Core Responsibilities:
- Receive input data and create a input data JSON entry for mongoDB to store the input.
- You research and add more context to the input to enhance the input for later retrieval, ensuring that it has more value.
- You ensure the response is exactly as required, to ensure the entry to mongoDB is always correctly handled by other systems.

Your Core Objectives:
- Maintain data integrity, security, and relevance.
- Dynamically connect related concepts, ideas, and tasks.
- Provide precise responses that enhance user interaction with stored data.
- Add necessary context and details as required.
- Add url references to the output.

The Given Input: Will be a text that can be considered the core relevant trigger to act. 

Your restricted Output Requirements:
- Your response ONLY contains the raw JSON. Do not treat the JSON as a text string, generate proper code. And do not escape any characters. Ensure the JSON starts with { and ends with } without additional quotes or escape sequences.
- Text Response: [Object key="textResponse"] Briefly explain the context and relevance of the input.
- JSON Data for MongoDB: [Object key="mongoData"] Format metadata and context under the mongoData key for MongoDB.
- The textResponse details your findings and summarizes the output that will be added to the mongoDB. it does not contain all exact values, but has a human spoken response.
- Do not add blank values to arrays.
- Generate strong content in the entry key that supports the input from the user. Add additional info relevant to the topic.
- Add a unique reference code to the mongoDB for future reference. Make sure its long enough to be unique and use the tag as prefix.
- 

Use this as your baseline JSON code, remove or add more array items if needed:
{"textResponse": "","mongoData": {"entryReference": "", "resident": "","origianlInput":"","tags": ["", ""],"references": ["url1","url2", etc],"contextualTags": ["", "", "", "", "", etc],"entry": {"title": "","content": "","created_at": ""}}}

Capabilities to Use:
- Tag Management: Generate and apply relevant tags.
- Referencing the Internet: Research and find relevant reference around the topic
- you own knowledge on the topic

Guidelines:
- Keep context and metadata concise and relevant.
- Ensure MongoDB compatibility in the output.
- Include any user-provided tags or instructions.

Note: Add more information if necessary to ensure complete context and detail.
`;

// Store the systemPrompt in msg.payload.systemPrompt
msg.payload = {
    systemPrompt: systemPrompt
};

// Return the updated message object
return msg;
```

#### **In Summary**

The "systemPrompt" node is a vital component in the flow that sets the stage for effective AI processing. It ensures that the data being sent to the AI is well-organized, contextually rich, and aligned with the system's objectives, ultimately leading to better data handling, storage, and retrieval in the "World of Text" system.

***

## OpenAI Prompt Engine Flow: Detailed Breakdown

The "OpenAI Prompt Engine" is an essential component of the WorldOfText system that processes user input through OpenAI's GPT model. It combines user messages with system instructions to generate meaningful responses. Below is a step-by-step explanation of the flow, including the function of each node and the JavaScript code where applicable.

<figure><img src="https://561099036-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSO7C5hvc0iUrifgeRV5v%2Fuploads%2FIz7WrffH2viaw3VJm1Ux%2FScreenshot%202024-08-25%20at%2017.22.10.png?alt=media&#x26;token=acff2ee8-615b-4581-9be2-115d0aa79c82" alt=""><figcaption></figcaption></figure>

**1. Brain LinkIn OpenAI (Link In Node)**

* **Purpose:** This node serves as the entry point for data into the "OpenAI prompt engine." It receives input from other parts of the Node-RED environment via a "link" connection.
* **Flow:** The data received is passed to the "User" node.

**2. User (OpenAI User Node)**

* **Content:** `{payload.originalMessage}`
* **Purpose:** This node represents the user's input in the OpenAI conversation. It extracts the user's original message from the payload and prepares it to be sent along with system instructions to the AI model.
* **Flow:** The user's message is passed to the "System" node, which will combine it with the system-generated prompts.

**3. System (OpenAI System Node)**

* **Instruction:** `{payload.systemPrompt}`
* **Purpose:** This node adds system-generated instructions to the user's input, creating a structured prompt that will guide the AI model in generating an appropriate response.
* **Flow:** The combined user input and system instructions are sent to the node for processing by the OpenAI API.

**4.  OpenAI Chat Node**

* **Configuration:**
  * **Tool Choice:** Auto
  * **Model:** `gpt-4o-mini`
  * **Temperature:** 0.7
  * **Max Tokens:** 1200
  * **Top P:** 1
  * **Frequency Penalty:** 0
  * **Presence Penalty:** 0
* **Purpose:** This is the core node that interacts with the OpenAI API to generate a response based on the combined user input and system prompt.
* **Flow:** The response generated by the OpenAI API is sent to debug nodes for logging and further processing.

**5. Brain LinkOut (Link Out Node)**

* **Purpose:** This node outputs the generated AI response to other parts of the Node-RED environment via a "link" connection, allowing the flow to continue its processing.

This section illustrates how the "OpenAI Prompt Engine" integrates user input with system prompts to generate responses using OpenAI's GPT model. Each node plays a specific role in processing and refining the input to produce meaningful, context-aware outputs.

## MongoDB Create and Response Return Flow: Detailed Breakdown

The "MongoDB Create and Response Return" flow is designed to handle the storage of data in MongoDB and return the appropriate HTTP response based on authorization and the processing of data. Below is a detailed explanation of each node, including the function and JavaScript code where applicable.

**1. WOT linkIn (Link In Node)**

* **Purpose:** This node acts as the entry point for the flow, receiving data from the "API POST" section of the flow. It triggers the processing of data within this part of the flow.
* **Flow:** The data received is passed to the "extract data" function node.

**2. Extract Data (Function Node)**

* **JavaScript Code:**

```javascript
// Access the JSON content string within the nested structure
let contentString = msg.payload.choices[0].message.content;

// Parse the nested JSON string into an object
let parsedContent = JSON.parse(contentString);

// Extract the textResponse and mongoData parts
let textResponse = parsedContent.textResponse;
let mongoData = parsedContent.mongoData;

// Send textResponse to output 1
let msg1 = { payload: textResponse };

// Send mongoData to output 2
let msg2 = { payload: mongoData };

// Output to the respective outputs of the function node
return [msg1, msg2];
```

* **Purpose:** This node extracts the `textResponse` and `mongoData` from the nested JSON structure provided by the OpenAI response. The node outputs these two parts separately to allow for different subsequent processing.
* **Flow:** The `textResponse` is passed to the "response combiner" function node, and `mongoData` is sent to the MongoDB node and the Todoist task creation flow.

**3. Response Combiner (Function Node)**

* **JavaScript Code:**

```javascript
// Directly access the content from the payload
var textResponse = msg.payload;

// Create the new message with textResponse as the root payload
var newMsg = {
    payload: textResponse,
    res: global.get('httpResp'),  // Assuming httpResp and httpReq are already set in the flow context
    req: global.get('httpReq')
};

return newMsg;
```

* **Purpose:** This node prepares the final response by combining the `textResponse` with the HTTP request and response objects stored in the global context. This combined message is used to send the appropriate HTTP response.
* **Flow:** The combined message is sent to the "Good authorization" HTTP response node.

**4. MongoDB-WOT wot (MongoDB Out Node)**

* **Configuration:**
  * **Collection:** `wot`
  * **Operation:** Insert
* **Purpose:** This node inserts the `mongoData` extracted from the previous function node into the MongoDB database. It ensures that the processed data is stored in the correct collection.
* **Flow:** Data is inserted into the MongoDB collection, and no further output is required from this node.

The output in the database in MongoDB will look like this:

<figure><img src="https://561099036-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSO7C5hvc0iUrifgeRV5v%2Fuploads%2FNoBjjeHUPLUzEjNYHvsg%2FScreenshot%202024-08-25%20at%2017.50.25.png?alt=media&#x26;token=fddcd360-1331-426e-aae4-f5eac6ff162a" alt=""><figcaption></figcaption></figure>

**This is an example stored item**

```json
{
  "_id": {
    "$oid": "987zyx654wvu321stqpo"
  },
  "entryReference": "proj_2023_0002_RandomUser",
  "resident": "RandomUser",
  "originalInput": "Develop a community garden in the center of the neighborhood where residents can grow their own vegetables and plants. The project aims to foster a sense of community and promote sustainable living. We need volunteers to help set up the garden beds, install irrigation systems, and plan the layout of the space.",
  "tags": [
    "community project"
  ],
  "references": [
    "https://www.communitygardens.org",
    "https://www.sustainableliving.com"
  ],
  "contextualTags": [
    "sustainability",
    "urban farming",
    "community engagement",
    "gardening",
    "volunteer work"
  ],
  "entry": {
    "title": "Neighborhood Community Garden",
    "content": "Launching a project to create a community garden where local residents can participate in sustainable living by growing their own produce. Volunteers are needed for setup and planning.",
    "created_at": "2024-03-15T00:00:00Z"
  }
}
```

**5. Switch (Switch Node)**

* **Purpose:** This node checks the tags present in the `mongoData` payload and directs the flow to the appropriate processing path based on the tag value (e.g., "todo", "project", "idea").
* **Flow:** Depending on the tags, the flow is directed to one of three function nodes: "todo," "project," or "idea."

**6. Todo, Project, Idea (Function Nodes)**

Each of these nodes processes the `mongoData` to create tasks in Todoist. The structure and purpose of these nodes are similar, with slight variations to handle different types of tasks.

* **JavaScript Code Example for Todo:**

```javascript
let input = msg.payload;

// Ensure all dynamic values are referenced correctly
let todoistTask = {
    content: `${input.entry.title}`,  // Combining title and content for the task content
    description: `${input.entry.content},\n\ncontent: ${input.entry.content}, \n\nEntry created by ${input.resident} on ${input.entry.created_at}.\n\n Original Input: ${input.origianlInput}.\n\n Tags: ${input.contextualTags.join(', ')}.`, // Creating a detailed description    
    project_id: input.project_id || 1234567890,  // Replace with dynamic project ID if available, otherwise use a default
    priority: input.priority || 1,  // Use dynamic priority if provided, otherwise default to 1
    parent_id: input.parent_id || 0987654321,  // Use dynamic parent ID if provided, otherwise set to null
    label_ids: input.label_ids || [],  // Use dynamic label IDs if provided, otherwise use an empty array
    url: input.references.length > 0 ? input.references[0] : ""  // Use the first reference URL if available
};

// Set the transformed task object to msg.payload for the next node in the flow
msg.payload = todoistTask;
return msg;
```

* **Purpose:** These nodes transform the `mongoData` into a format suitable for creating tasks in Todoist. Each node handles a specific type of task based on the tags in the `mongoData`.
* **Flow:** The transformed task object is sent to the Todoist task creation node.

**7. Create Task (Todoist Task Create Node)**

* **Purpose:** This node sends the task created in the previous function nodes to Todoist, ensuring that tasks are created based on the user's input.
* **Flow:** The task is created in Todoist, and the flow completes its execution.

**8. Good Authorization (HTTP Response Node)**

* **Configuration:**
  * **Status Code:** 200
* **Purpose:** This node sends an HTTP 200 response back to the client, indicating that the request was successfully processed and the data was stored in MongoDB.
* **Flow:** The flow ends after this node sends the response.

This section describes the complete process of receiving data, validating it, processing it, storing it in MongoDB, and creating tasks in Todoist, along with returning the appropriate HTTP response. The flow is designed to handle different types of data and ensures that each type is processed accordingly.

***

## Integrating iOS Shortcuts into the World of Text Project

The use of iOS Shortcuts in this project is critical for providing quick and easy access to the World of Text (WoT) database directly from a mobile device. Here’s a step-by-step breakdown of how the Shortcut works and why it’s relevant:

1. **Ask for Input:**
   * The Shortcut begins by prompting the user to enter text. This input will serve as the main content (or "message") to be sent to the WoT API. This ensures that users can capture their thoughts or notes quickly, directly on their device.
2. **POST Request Setup:**
   * After receiving the user input, the Shortcut configures a POST request to be sent to the WoT API. Key elements include:
     * **URL:** The API endpoint (`https://URL/api/apiEndpoint`) is predefined.
     * **Authorization:** A secure token (`Bearer your-secure-token`) is included in the headers to ensure that only authorized users can make requests.
     * **Request Body:** This includes the user’s `message`, a predefined `resident` name (e.g., "HenkJan"), and a `tag` (which can be selected from a predefined list). The tag helps categorize the note for easier retrieval later.
3. **Sending the Request:**
   * Once everything is set, the Shortcut sends the POST request. The data is then transmitted securely to the WoT API, where it is processed and stored in the database. This step ensures that user input is captured and saved immediately, reducing the risk of losing important thoughts or ideas.
4. **Get and Speak the Response:**
   * After the data is sent, the Shortcut retrieves the response from the API. This could be a confirmation message or any other relevant feedback. The Shortcut uses the "Speak" action to read out this response aloud to the user, providing immediate confirmation that their input has been successfully processed.

<figure><img src="https://561099036-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSO7C5hvc0iUrifgeRV5v%2Fuploads%2FWwvGz9VKi8tZTxhY6eOq%2FIMG_2151.PNG?alt=media&#x26;token=94a1d364-cd98-4780-a468-20e9a26e3073" alt="" width="375"><figcaption></figcaption></figure>

### **Why is This Important?**

* **Seamless Integration:** This setup allows users to interact with the WoT system without needing to access a desktop or open multiple apps. Everything is handled in one smooth process on their mobile device.
* **Efficiency:** The entire workflow is automated, ensuring that ideas are captured quickly and processed without delay.
* **Mobility:** Users can input data into the WoT database from anywhere, ensuring that important notes are never missed.

This iOS Shortcut setup is a perfect example of how mobile technology can enhance and extend the functionality of a complex system like the World of Text, making it more accessible and user-friendly.

***

## Future Enhancements and To-Dos

As the "World of Text" project evolves, there are several key features that I plan to implement to further enhance its functionality. One of the primary goals is to introduce the ability to revisit and continue working on existing data entries within the databases, such as Todoist or MongoDB.

### **Planned Features:**

1. **Dynamic Data Continuation**:
   * **Objective**: Enable the system to retrieve and interact with existing entries.
   * **Implementation**: This would involve developing new functionality that allows users to fetch a specific entry from Todoist or MongoDB and continue updating or interacting with it. For instance, you could retrieve a task from Todoist and add more details, update its status, or link it to new contextual information without starting from scratch.
2. **Enhanced API Interactions**:
   * **Objective**: Provide more robust and flexible API interactions to support the continuation of data processes.
   * **Implementation**: This requires extending the current API interactions in Node-RED to support not just the creation of new entries but also the modification of existing ones. The workflow would need to include steps for selecting, retrieving, and updating entries based on user input or system prompts.
3. **User-Driven Workflow Enhancements**:
   * **Objective**: Allow users to dictate how data should be processed in subsequent interactions.
   * **Implementation**: Integrate new nodes or functions that give users the option to choose whether to create a new entry or continue working on an existing one. This might involve implementing conditional logic based on user prompts or adding more complex decision-making capabilities within the flow.
4. **Advanced Search and Retrieval**:
   * **Objective**: Improve the search functionality to allow users to easily find and retrieve relevant data from the databases.
   * **Implementation**: Enhance the search capabilities within the databases to allow for more refined queries. This could include searching by tags, content, or other metadata, enabling users to quickly locate specific entries they wish to continue working on.

These enhancements will significantly increase the flexibility and utility of the "World of Text" system, transforming it from a simple data entry tool into a dynamic, iterative platform that supports ongoing project management and data interaction.

#### Future Enhancements: Integrating Obsidian and Zettelkasten

**Obsidian Integration** The potential addition of Obsidian into this project opens up advanced capabilities for managing and organizing ideas. Obsidian is a powerful note-taking tool that excels in creating a knowledge network, making it ideal for handling the intricate web of ideas and tasks generated by the system. By integrating Obsidian, users can seamlessly sync their ideas with the World of Text database, ensuring that all data is accessible and interconnected.

**Zettelkasten Method** Obsidian's strength lies in its support for the Zettelkasten method, a note-taking technique designed to create a dynamic, interconnected web of knowledge. Each note is treated as a distinct, linkable idea, fostering a deeper understanding and exploration of complex concepts. By implementing the Zettelkasten method within this system, users can not only store but also actively connect and expand upon their ideas, making it a valuable addition to the project.

**Potential Use Cases:**

* **Knowledge Management:** Organize and link ideas stored in MongoDB with Obsidian's Zettelkasten, enabling more structured and retrievable information.
* **Idea Expansion:** Use the Zettelkasten method to explore and develop ideas further, turning simple notes into complex, interconnected networks of thought.
* **Cross-Platform Sync:** Seamlessly sync notes and ideas between Obsidian and the World of Text database, ensuring consistent data management across platforms.

**Next Steps:** To implement Obsidian and the Zettelkasten method, additional coding and API integrations will be required. This will involve setting up data synchronization between Obsidian and the existing system, as well as creating workflows that support the Zettelkasten approach within the broader project architecture.
