{
  "id": "zBUd6Sdh1oAUmTYd",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "GithubDeployer",
  "tags": [],
  "nodes": [
    {
      "id": "e9793e41-708a-4b4f-99c7-8968822a0715",
      "name": "Tavily",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "position": [
        864,
        1072
      ],
      "parameters": {
        "url": "https://api.tavily.com/search",
        "method": "POST",
        "jsonBody": "{\n    \"api_key\": \"<API-KEY>\",\n    \"query\": \"{searchTerm}\",\n    \"search_depth\": \"basic\",\n    \"include_answer\": true,\n    \"topic\": \"news\",\n    \"include_raw_content\": true,\n    \"max_results\": 3\n} ",
        "sendBody": true,
        "specifyBody": "json",
        "toolDescription": "Use this tool to search the internet",
        "placeholderDefinitions": {
          "values": [
            {
              "name": "searchTerm",
              "type": "string",
              "description": "What the user has requested to write a blog about"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "c00d85b9-2bc9-462d-8248-e3b7bcf8dc3b",
      "name": "Anthropic Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        656,
        944
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "cf2da38c-8871-4750-8980-bfae6ef41881",
      "name": "Try Again",
      "type": "n8n-nodes-base.set",
      "position": [
        1264,
        800
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f2a8ff2d-6b59-4ad6-a2e7-8705354f4105",
              "name": "response",
              "type": "string",
              "value": "Error occurred. Please try again."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a540fab8-74ff-495b-80dc-687239850e23",
      "name": "Deployer Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueErrorOutput",
      "position": [
        816,
        704
      ],
      "parameters": {
        "text": "={{ $json.text }}{{ $json.data }}",
        "options": {
          "systemMessage": "=This agent automates the deployment process by committing code or files directly to a GitHub repository. If the Slack message specifies a target folder, store the files there. If no folder is mentioned, use the default root directory of the repository."
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "fb283574-5f5b-4077-afaf-247d3ae9150e",
      "name": "Create a file in GitHub",
      "type": "n8n-nodes-base.githubTool",
      "position": [
        1024,
        944
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "list",
          "value": "humbleturtleai",
          "cachedResultUrl": "https://github.com/humbleturtleai",
          "cachedResultName": "humbleturtleai"
        },
        "filePath": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('File_Path', ``, 'string') }}",
        "resource": "file",
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "n8ntest",
          "cachedResultUrl": "https://github.com/humbleturtleai/n8ntest",
          "cachedResultName": "n8ntest"
        },
        "fileContent": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('File_Content', ``, 'string') }}",
        "commitMessage": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Commit_Message', ``, 'string') }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "94fcc313-137d-4d19-9c94-a6c0b4ca24ab",
      "name": "Send a message",
      "type": "n8n-nodes-base.slack",
      "position": [
        1264,
        640
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C094L9A4B4J",
          "cachedResultName": "ai-agent"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.3
    },
    {
      "id": "cfa06161-22df-4944-8698-7635b2cd2f02",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        720
      ],
      "parameters": {
        "color": 6,
        "width": 280,
        "height": 140,
        "content": "## Message in Slack Channel\nThe node listens for new messages in a Slack Channel."
      },
      "typeVersion": 1
    },
    {
      "id": "7b68ecea-a52d-4546-88c0-108e56b766d9",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        1072
      ],
      "parameters": {
        "color": 6,
        "height": 260,
        "content": "## Push code to Github repository \nThe code is automatically pushed to the default GitHub repository. To ensure better organization, it is recommended to include a desired folder structure in your prompt. This helps the system determine the appropriate location for storing the file within the repository."
      },
      "typeVersion": 1
    },
    {
      "id": "9cebaafa-39b0-4aab-8be8-e32b64796a18",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        -1504
      ],
      "parameters": {
        "color": 5,
        "width": 2424,
        "height": 720,
        "content": "## Deploy Code to GitHub with Natural Language via Slack & Claude 3.5\n### Overview\nThe Deployer Agent is an intelligent automation tool that integrates with Slack to streamline code deployment workflows. Powered by Anthropic's Claude 3.5 and Tavily for web search, it enables seamless, context-aware file pushes to a GitHub repository with minimal user input.\n\n### Capabilities\n- Accepts natural language via Slack\n- Automatically pushes code to a default GitHub repository\n- Uses Claude 3.5 for code generation and decision-making\n- Leverages Tavily for real-time web search to enhance context\n- Supports folder structure hints to ensure clean and organized repositories\n\n### Required Connections\nTo operate correctly, the following integrations must be in place:\n- Slack API Token with permission to read messages and post responses\n- GitHub Personal Access Token with repo write permissions\n- Tavily API Key for external search functionality\n- Claude 3.5 API Access via Anthropic\n\n### Example Input\nFrom Slack, you can send messages like:\n\"Generate a basic `README.md` for my Python project and store it in the root directory.\"\n\n### Customising This Workflow\nYou can tailor the workflow by:\n- Modifying default folder paths or repository settings\n- Integrate Jira node to use issue keys as default folder naming\n- Add slack file upload option "
      },
      "typeVersion": 1
    },
    {
      "id": "f838d781-091d-4427-b5e2-bf0ea6d47e26",
      "name": "Natural text",
      "type": "n8n-nodes-base.slackTrigger",
      "position": [
        528,
        704
      ],
      "parameters": {
        "options": {},
        "trigger": [
          "message"
        ],
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "C094L9A4B4J"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c26e074f-ddb8-48a9-9e33-669d355d5e16",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        -784
      ],
      "parameters": {
        "color": 3,
        "width": 608,
        "height": 1280,
        "content": "## Configuring the Slack API Acces\n### Step 1: Create a Slack App\n1. Go to https://api.slack.com/apps\n2. Click Create New App\n3. Select From scratch\n4. Give your app a name (e.g., n8n Slack Integration)\n5. Choose your workspace and click Create App\n\n### Step 2: Enable Event Subscriptions\n1. In your Slack app\u2019s settings, go to Event Subscriptions\n2. Toggle Enable Events to On\n3. In the Request URL field, enter the webhook URL for your Slack Trigger node:\n4. In n8n, open your Slack Trigger node \u2192 copy the Webhook URL\n5. Slack will verify this URL \u2014 your n8n workflow must be active for verification to succeed\n6. Under Subscribe to Bot Events, click Add Bot User Event and add:\n    - message.channels (for public channel messages)\n    - message.groups (for private channels, if needed)\n7. Click Save Changes\n\n### Step 3: Set Bot Token Scopes\n1. Go to OAuth & Permissions in your Slack app settings\n2. Under Bot Token Scopes, add:\n    - channels:history\n    - channels:read\n    - groups:history (if you need private channels)\n    - groups:read\n    - chat:write (if you want to send messages back)\n3. Click Save Changes\n\n### Step 4: Install the App to Your Workspace\n1. In the Slack app settings, go to Install App\n2. Click Install to Workspace\n3. Approve the requested permissions\n4. Copy the Bot User OAuth Token (starts with xoxb-) \u2014 you\u2019ll use this in n8n\n\n### Step 5: Configure Slack Credentials in n8n\n1. Open your n8n instance\n2. Go to Settings \u2192 Credentials\n3. Create new Slack API credentials:\n    - Name: e.g., Slack Bot Access\n    - Access Token: Paste the Bot User OAuth Token from Step 4\n4. Save the credentials\n\n### Step 6: Connect the Credentials to the Slack Trigger Node\n1. Open your existing Slack Trigger node\n2. Under Credentials, select the Slack credentials you just created\n3. Make sure Event Type matches what you subscribed to (message events)\n4. Save the node configuration\n\n### Step 7: Activate and Test\n1. Activate your n8n workflow\n2. In Slack, post a message in the configured channel\n3. Check n8n\u2019s execution logs \u2014 you should see the workflow triggered"
      },
      "typeVersion": 1
    },
    {
      "id": "6fa027a8-9aba-4584-99a7-08e8e4524d5d",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        -784
      ],
      "parameters": {
        "color": 3,
        "width": 608,
        "height": 1280,
        "content": "## Configuring the Anthropic Claude 3.5 API Access\n### Step 1: Get Your Anthropic API Key\n1. Go to the Anthropic console: https://console.anthropic.com/\n2. Sign in or create an account\n3. In the dashboard, go to API Keys\n4. Click Create Key\n5. Give the key a name (e.g., n8n Claude Access)\n6. Copy the generated API key \u2014 it will look like: sk-YOUR_OPENAI_KEY_HERE-xxxxxxxxxxxxxxxxxxxxxxxx\n7. Store it securely \u2014 you will need it in n8n\n\n### Step 2: Open Your Existing Anthropic Node in n8n\n1. In n8n, open the workflow that contains the Anthropic node\n2. Click the Anthropic node to view its settings\n\n### Step 3: Assign Anthropic Credentials\n1. In the node settings, locate the Credentials field\n2. If no credentials are assigned:\n    - Click Select Credential \u2192 Create New\n    - Name: e.g., Claude 3.5 Access\n    - API Key: Paste the key from Step 1\n3. Save the credentials\n\n### Step 4: Verify Node Configuration\n1. Make sure the Model is set to claude-3-5-sonnet (or whichever Claude 3.5 variant you want)\n2. Ensure the Prompt or Messages field contains valid input:\n    - Static test text for verification\n    - Or dynamic expressions from previous nodes\n\n### Step 5: Test the Node\n1. If this node depends on prior nodes (e.g., Slack Trigger, Telegram Trigger), run those first\n2. Click Execute Node on the Anthropic node\n3. Check the output panel for a text completion or chat response"
      },
      "typeVersion": 1
    },
    {
      "id": "ac90d0fe-5858-4e8c-8825-c2a9c91295b0",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -784
      ],
      "parameters": {
        "color": 3,
        "width": 608,
        "height": 1280,
        "content": "## Configuring the Tavily API Access\n### Step 1: Get Your Tavily API Key\n1. Go to the Tavily website: https://tavily.com/\n*(or directly to the developer portal if you have the link from Tavily\u2019s docs)*\n2. Sign in or create a free account\n3. Navigate to the API Keys or Developer Settings section\n4. Click Create API Key\n5. Copy the generated key \u2014 it will look something like: tavily-xxxxxxxxxxxxxxxxxxxxxxxx\n6. Store this key securely \u2014 you will use it in n8n\n\n### Step 2: Open the Existing Tavily Node in n8n\n1. In n8n, open the workflow containing the Tavily node\n2. Click on the Tavily node to view its settings\n\n### Step 3: Assign Tavily Credentials\n1. In the node settings, locate the Credentials section\n2. If no credentials are selected:\n    - Click Select Credential \u2192 Create New\n    - Name: Give the credentials a label (e.g., Tavily Search Access)\n    - API Key: Paste the key from Step 1\n3. Click Save\n\n### Step 4: Configure the Tavily Node\n1. In the Operation field, select what you want Tavily to do (e.g., Search)\n2. In the Query field:\n    - Enter a static test search term (for testing)\n    - Or use an expression to pass dynamic input from previous nodes\n3. Adjust optional parameters (e.g., search depth, filters) based on your needs\n\n### Step 5: Test the Node\n1. If your node depends on prior input, run those first\n2. Click Execute Node in n8n\n3. Review the output to confirm Tavily returned relevant search results\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3ec33ca4-4dc2-4788-8a0d-89433eb03fb7",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1488,
        -784
      ],
      "parameters": {
        "color": 3,
        "width": 608,
        "height": 1280,
        "content": "## Configuring the GitHub API Access\n### Step 1: Generate a GitHub Personal Access Token\n1. Sign in to GitHub: https://github.com/login\n2. Go to Settings (click your profile picture \u2192 Settings)\n3. Scroll down to Developer settings \u2192 Personal Access Tokens \u2192 Tokens (classic)\n*(or Fine-grained tokens if you want more control)*\n4. Click Generate new token\n5. Give the token a descriptive name (e.g., n8n GitHub Access)\n6. Set an expiration date (choose \"No expiration\" for long-term use \u2014 but keep it secure)\n7. Under Scopes, enable at least:\n    - repo (full control of private repositories)\n    - public_repo (if only working with public repositories)\n8. Click Generate token\n9. Copy the token \u2014 it will look like: ghp_YOUR_GITHUB_TOKEN_HERE\n\n### Step 2: Open the Existing GitHub Node in n8n\n1. In n8n, open the workflow containing the GitHub node\n2. Click on the node to open its configuration panel\n\n### Step 3: Assign GitHub Credentials\n1. In the node settings, find the Credentials field\n2. If no credentials are selected:\n    - Click Select Credential \u2192 Create New\n    -Name: Give a descriptive name (e.g., GitHub Repo Access)\n    - Access Token: Paste the token from Step 1\n3. Save the credentials\n\n### Step 4: Configure the Node for Creating a File\n1. In the node configuration:\n    - Resource: File\n    - Operation: Create\n2. Fill in the required fields:\n    - Owner: GitHub username or organization name\n    - Repository: Name of the repo\n    - File Path: Path where the file will be created (e.g., docs/readme.md)\n    - File Content: Static text or dynamic content from previous nodes\n    - Commit Message: Short description of the change\n3. (Optional) Enable \"Branch\" selection if you want to create the file in a branch other than main\n\n### Step 5: Test the Node\n1. If the node depends on earlier steps for content, run those first\n2. Click Execute Node in n8n\n3. Check the repository in GitHub to confirm the file was created with the correct content\n"
      },
      "typeVersion": 1
    },
    {
      "id": "2c418d17-508f-4d84-b428-b90d368018e9",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        1072
      ],
      "parameters": {
        "color": 6,
        "width": 304,
        "height": 152,
        "content": "## Claude 3.5 LLM model\nInteracts with Anthropic\u2019s Claude 3.5 language models.\n\nMonetary Credits are needed for Claude 3.5. \n\n\u00e5"
      },
      "typeVersion": 1
    },
    {
      "id": "a785217c-0be0-4bec-a965-d9cd129a7737",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        816,
        1232
      ],
      "parameters": {
        "color": 6,
        "height": 216,
        "content": "## Internet searches using Tavily\nEnables automated, real-time web searches to find best practices, patterns, and emerging trends in software architectures.\nRequires a valid Tavily API key for access."
      },
      "typeVersion": 1
    },
    {
      "id": "839713a0-8617-4fbf-912c-653eaa542202",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        496
      ],
      "parameters": {
        "color": 4,
        "width": 2432,
        "height": 1168,
        "content": "## Workflow\n\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "4e9e26b7-5565-4125-a49e-3ff95f4ebefd",
  "connections": {
    "Tavily": {
      "ai_tool": [
        [
          {
            "node": "Deployer Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Natural text": {
      "main": [
        [
          {
            "node": "Deployer Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Deployer Agent": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Try Again",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Deployer Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Create a file in GitHub": {
      "ai_tool": [
        [
          {
            "node": "Deployer Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}