GET n8n for FREE! EASY Self-Hosting Tutorial + Cyber Monday Deal! 🚀

Hey Pickaxers :waving_hand:

Here’s the cheat sheet guide to follow along with!

:backhand_index_pointing_right: Click Here to GET up to 67% OFF! :backhand_index_pointing_left:

YouTube tutorial video:

Personal Assistant Agent system prompt “ROLE”:

identity:
  role: Pickaxe Assistant Agent
  model: Gemini 2.0 Flash
  personality: Friendly, professional, extremely fast and efficient. Get straight to the point. Confirm task completion.
  purpose: Demonstrate speed and capability by connecting Pickaxe UI to Google Calendar and Gmail via n8n backend

connected_actions:
  webhook_assistant: n8n workflow that retrieves calendar events and sends emails

webhook_trigger_conditions:
  - User asks about upcoming events: "What's on my calendar?", "Any meetings today?", "Show my appointments", "Check my schedule"
  - User asks about specific time periods: "What meetings do I have tomorrow?", "Any events this week?", "Calendar for next Monday"
  - User wants to see all events: "List all my events", "Show everything on my calendar"
  - When user query relates to checking, viewing, or listing calendar events, immediately call the webhook action

behavior_directives:
  - When user asks about calendar events, immediately trigger the webhook action - do not ask for event IDs or additional details
  - Pass the user's natural language query to the webhook
  - The webhook will retrieve events and return formatted results
  - Present the results clearly to the user
  - If the webhook returns an error, explain it and offer to try again
  - Keep responses concise and actionable

response_format:
  - Acknowledge the calendar check request briefly (e.g., "Checking your calendar...")
  - Trigger the webhook immediately
  - Display the returned event list in a clear, readable format
  - Offer follow-up actions if relevant

Suggested LLM Model(s):

For cost-effective, non-reasoning tasks:

  • Claude Haiku 4.5 or
  • Gemini 2.5/2.0 Flash

For complex/reasoning/math/code/data retrieval tasks:

  • Claude Sonnet 4.5 or
  • Gemini 3 Pro

Google OAuth Authentication in n8n - From Setup to Connection (Step-by-step guide)

n8n Workflow JSON Schema

Connected Actions:

Basic n8n Webhook
Trigger Prompt: Trigger this prompt whenever the user submits a query that requires n8n nodes for processing and pass it along to n8n.
Function Inputs x1
* Name user_query
* Description The user’s request for calendar or email operations
* Example value “Show me my upcoming calendar events”

Action Code:

import os
import requests
import json

def n8n_webhook_self_hosting_tut(user_query: str):
    """
    Sends a basic (POST) request to a n8n.io webhook

    Args:
        user_query (string): The user's request for calendar or email operations
    Envs:
        N8N_WEBHOOK_URL (string): Live webhook link from n8n.o
    """

    # Insert your code below. You can access environment variables using os.environ[].
    # Currently, only the requests library is supported, but more libraries will be available soon.
    # Use print statements or return values to display results to the user.
    # If you save a png, pdf, csv, jpg, webp, gif, or html file in the root directory, it will be automatically displayed to the user.
    # You do not have to call this function as the bot will automatically call and fill in the parameters.

    url = os.environ.get("N8N_WEBHOOK_URL")
    
    if not url:
        return json.dumps({
            "status": "error",
            "message": "Calendar service is not configured. Please contact support."
        })
    
    payload = {
        "query": user_query,
        "source": "pickaxe"
    }
    
    headers = {
        "Content-Type": "application/json"
    }
    
    try:
        resp = requests.post(url, headers=headers, json=payload, timeout=30)
        resp.raise_for_status()
        
        # n8n workflow returns calendar events or email confirmation
        try:
            data = resp.json()
            if isinstance(data, dict) and "response" in data:
                return data["response"]
            return json.dumps(data, indent=2)
        except Exception:
            return f"Calendar results:\n{resp.text}"
            
    except requests.Timeout:
        return json.dumps({
            "status": "error",
            "message": "Request timed out. Please try again."
        })
    except requests.RequestException as e:
        return json.dumps({
            "status": "error",
            "message": f"Could not reach calendar service: {str(e)}"
        })

**Note: Don’t forget to add “import JSON” under “import requests

LIMITED Black Friday Deal! :backhand_index_pointing_right: Click Here to GET up to 67% OFF! :backhand_index_pointing_left:

Congratulations! You’ve graduated beyond make. com and become a self-hosting expert in the process :clap:

3 Likes

This deal ends TONIGHT! Grab this wild discount when you still can!

Click Here to GET up to 67% OFF!