AutomationFlowsAI & RAG › Gist:dwedigital

Gist:dwedigital

Gist:Dwedigital. Uses httpRequest, googleGemini, openAi, microsoftOutlook. Webhook trigger; 15 nodes.

Webhook trigger★★★★☆ complexityAI-powered15 nodesHTTP RequestGoogle GeminiOpenAIMicrosoft OutlookGitHub
AI & RAG Trigger: Webhook Nodes: 15 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the GitHub → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "parameters": {
        "method": "PUT",
        "url": "=https://api.github.com/repos/dwedigital/curly-brackets-site/contents/public/images/posts/{{ $('Format data').item.json.data.slug }}.png",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "githubOAuth2Api",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "message",
              "value": "=Image creation for {{ $('Format data').item.json.data.title }}"
            },
            {
              "name": "content",
              "value": "={{ $json.data }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        3040,
        592
      ],
      "id": "40660657-34c5-42bf-91ac-01692e263b44",
      "name": "Github Image Creation",
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "image",
        "modelId": {
          "__rl": true,
          "value": "models/gemini-2.5-flash-image",
          "mode": "list",
          "cachedResultName": "models/gemini-2.5-flash-image (Nano Banana)"
        },
        "prompt": "=Create a photorealistic monochrome image with no text within the image. The image will be a hero image for a blog post title: {{ $json.data.title }}\n\nFull article for context:\n\n{{ $json.data.content }}",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "typeVersion": 1,
      "position": [
        2592,
        592
      ],
      "id": "409f4469-e65b-4d0b-b683-c31efd869671",
      "name": "Generate an image",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-5-nano",
          "mode": "list",
          "cachedResultName": "GPT-5-NANO"
        },
        "responses": {
          "values": [
            {
              "content": "=I am writing a blog about web technologies and processes. Everything from APIs, backend, frontend and databases. The audience is mostly junior developers looking to understand these technologies through guides and articles breaking down core technologies.\n\nI want you, as my assistant, to provide 5 article titles and short summaries of each that I can then use to write the full article.\n\nHere is a list of articles already created to give you an idea but please look for new ideas and not repeating topics:\n\n{{ $json.articles.join(\", \") }}"
            }
          ]
        },
        "builtInTools": {},
        "options": {
          "instructions": "You are a technical writer helping deliver compelling and interesting articles for a blog that focuses on web technologies as well as common scripting languages.\n\nYour aim is to come up with interesting topics to be explored as blog ideas and not to just copy existing themes all the time.\n\nTechnologies we cover include:\n* Web development\n* Server side development\n* Scripting (python, Go, Ruby primarily)\n\nTry not to repeat articles that have already been written.",
          "textFormat": {
            "textOptions": {
              "type": "json_schema",
              "schema": "{\n      \"type\": \"object\",\n      \"properties\": {\n        \"articles\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"title\": {\n                \"type\": \"string\",\n                \"description\": \"Title of the article\"\n              },\n              \"summary\": {\n                \"type\": \"string\",\n                \"description\": \"summary of the article\"\n              }\n            },\n            \"required\": [\n              \"title\",\n              \"summary\"\n            ],\n            \"additionalProperties\": false\n          },\n          \"description\": \"List of articles\"\n        }\n      },\n      \"required\": [\n        \"articles\"\n      ],\n      \"additionalProperties\": false\n    }"
            }
          }
        }
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2,
      "position": [
        768,
        496
      ],
      "id": "3d781b27-7465-4605-acd9-db4e1857208a",
      "name": "Get ideas",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "models/gemini-3-pro-preview",
          "mode": "list",
          "cachedResultName": "models/gemini-3-pro-preview"
        },
        "messages": {
          "values": [
            {
              "content": "=Write an educational blog post for a software developers with the title:{{$json.body.title || $json['0'].title}} and base it on the following summary as a guide:\n\n{{$json.body.summary || $json['0'].summary}}"
            }
          ]
        },
        "simplify": false,
        "jsonOutput": true,
        "options": {
          "systemMessage": "=You are a technical writer for a software engineering blog helping people to learn more about technologies. For the tags provide a maxiumum of 3 relevant tags but do not need to use 3 tags all the time if not relevant and 1 will do\n\nOutput Requirements: Return a JSON object (strictly valid JSON that another machine can understand with no additional parsing), not a string of text or code example of JSON with these fields:\n\n{ \"title\": \"A catchy title (no quotes).\",\"\n\"slug\": \"URL-friendly string (e.g., future-of-rsc).\",\n\"tags\":\" A JSON array of 1-3 tags (e.g., [\"React\", \"Web Dev\"]).\",\n\"content\": \"The body of the post in Markdown format. Use H2 (##) for headers. Do NOT include the frontmatter (---) in this field.\"}\n\nWithi the content of the article you can use code snippets and encouraged to where it helps illustrates points. Please ensure you use correct code snippet mardown syntax so python would look like:\n\n```python\n\ndef test()\n  pass\n```"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "typeVersion": 1,
      "position": [
        1568,
        592
      ],
      "id": "302c8319-1d10-4390-a75b-b0effc40aeee",
      "name": "Create article",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9d362bc6-634e-4245-86a8-07c7219453ce",
              "name": "data",
              "value": "={{ $('Create article').item.json.candidates[0].content.parts[0].text }}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2368,
        592
      ],
      "id": "500e4170-bccb-455a-8916-ee3a8867fc79",
      "name": "Format data"
    },
    {
      "parameters": {
        "operation": "sendAndWait",
        "toRecipients": "dave@dwedigital.com",
        "subject": "[Curly Brackets] - Article approval",
        "message": "=Title: {{ $json.candidates[0].content.parts[0].text.parseJson().title }}\n<br/><br/>\nTags: {{ $json.candidates[0].content.parts[0].text.parseJson().tags }}\n<br/><br/>\nContent: {{ $json.data }}",
        "approvalOptions": {
          "values": {
            "approvalType": "double"
          }
        },
        "options": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.microsoftOutlook",
      "typeVersion": 2,
      "position": [
        2144,
        592
      ],
      "id": "0ba10937-924e-4757-bcdf-81c779d3c1b5",
      "name": "Approval message",
      "credentials": {
        "microsoftOutlookOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "sendAndWait",
        "toRecipients": "dave@dwedigital.com",
        "subject": "[Curly Brackets] - Select Article ",
        "message": "={{ $json.output[0].content[0].text.articles.map(article =>`<h2>${article.title}</h2><p>${article.summary}</p>`).join(\"\") }}",
        "responseType": "customForm",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Article choice",
              "fieldType": "dropdown",
              "fieldOptions": {
                "values": [
                  {
                    "option": "={{ $json.output[0].content[0].text.articles[0].title }}"
                  },
                  {
                    "option": "={{ $json.output[0].content[0].text.articles[1].title }}"
                  },
                  {
                    "option": "={{ $json.output[0].content[0].text.articles[2].title }}"
                  },
                  {
                    "option": "={{ $json.output[0].content[0].text.articles[3].title }}"
                  },
                  {
                    "option": "={{ $json.output[0].content[0].text.articles[4].title }}"
                  }
                ]
              },
              "requiredField": true
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.microsoftOutlook",
      "typeVersion": 2,
      "position": [
        1120,
        496
      ],
      "id": "69aa2a1a-68d2-452b-86cb-edc446db1086",
      "name": "Select article message",
      "credentials": {
        "microsoftOutlookOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "binaryToPropery",
        "options": {}
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1.1,
      "position": [
        2816,
        592
      ],
      "id": "da6adb7d-adbd-4f84-b671-5f888b26072b",
      "name": "Convert to base64"
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "owner": {
          "__rl": true,
          "value": "dwedigital",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "curly-brackets-site",
          "mode": "name"
        },
        "filePath": "=posts/{{ $('Format data').item.json.data.slug }}.md",
        "fileContent": "=---\ntitle: \"{{ $('Format data').item.json.data.title }}\"\ndate: \"{{ $today.format('yyyy-MM-dd') }}\"\ntags: [{{ $('Format data').item.json.data.tags.map(item => \"'\"+item+\"'\")}}]\n\n---\n{{ $('Format data').item.json.data.content }}\n",
        "commitMessage": "=commit for  {{ $('Format data').item.json.data.title }} tes"
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        3264,
        592
      ],
      "id": "57245686-7df3-450d-b34f-f0636e1d400f",
      "name": "Create markdown file",
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "6e10d9db-f8ec-412b-921c-7bff72ec8862",
              "name": "articles",
              "value": "={{ $json.articles.map(article => article.title) }}",
              "type": "array"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        544,
        496
      ],
      "id": "b74e4eb0-5238-4163-ba65-04abd704ce62",
      "name": "Stringify existing titles"
    },
    {
      "parameters": {
        "url": "https://curlybrackets.tech/api/articles",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        320,
        496
      ],
      "id": "55bf8313-5978-4f9e-8143-f0c3006e519e",
      "name": "Get existing articles"
    },
    {
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\n// console.log($(\"Select article message\").all())\n\nlet article = $(\"Get ideas\").all()[0].json.output[0].content[0].text.articles.filter(article=>{\n  return article.title === $(\"Select article message\").all()[0].json.data[\"Article choice\"]\n})\n\nreturn {...article}"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1344,
        496
      ],
      "id": "be5e8566-04f6-478c-93b7-61087eecb2a2",
      "name": "Parse Article Data"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "03900f54-6352-4615-9a61-828e244314d8",
        "authentication": "headerAuth",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        1344,
        688
      ],
      "id": "27e37fc7-f891-4da3-8152-95547bf22b94",
      "name": "Manual trigger",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "markdownToHtml",
        "markdown": "={{ $json.candidates[0].content.parts[0].text.parseJson().content }}",
        "options": {}
      },
      "type": "n8n-nodes-base.markdown",
      "typeVersion": 1,
      "position": [
        1920,
        592
      ],
      "id": "89e524f8-978d-4643-b2b9-2a77e90c4fc6",
      "name": "Markdown"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        96,
        496
      ],
      "id": "acf5a85c-8fba-47d7-89a7-b33efd09c69a",
      "name": "Schedule Trigger"
    }
  ],
  "connections": {
    "Github Image Creation": {
      "main": [
        [
          {
            "node": "Create markdown file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate an image": {
      "main": [
        [
          {
            "node": "Convert to base64",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get ideas": {
      "main": [
        [
          {
            "node": "Select article message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create article": {
      "main": [
        [
          {
            "node": "Markdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format data": {
      "main": [
        [
          {
            "node": "Generate an image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Approval message": {
      "main": [
        [
          {
            "node": "Format data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select article message": {
      "main": [
        [
          {
            "node": "Parse Article Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to base64": {
      "main": [
        [
          {
            "node": "Github Image Creation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create markdown file": {
      "main": [
        []
      ]
    },
    "Stringify existing titles": {
      "main": [
        [
          {
            "node": "Get ideas",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get existing articles": {
      "main": [
        [
          {
            "node": "Stringify existing titles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Article Data": {
      "main": [
        [
          {
            "node": "Create article",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual trigger": {
      "main": [
        [
          {
            "node": "Create article",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Markdown": {
      "main": [
        [
          {
            "node": "Approval message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get existing articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Gist:Dwedigital. Uses httpRequest, googleGemini, openAi, microsoftOutlook. Webhook trigger; 15 nodes.

Source: https://gist.github.com/dwedigital/9b291c849ec63d58e2d5a70745c7c136 — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

How it works Runs on schedule (Monday-Friday at 9 AM) to automate lead generation Searches for companies on Google Maps by location and category Extracts owner information from company websites and im

HTTP Request, Anthropic, Google Gemini +3
AI & RAG

RSS Summary. Uses github, discord, openAi, httpRequest. Scheduled trigger; 26 nodes.

GitHub, Discord, OpenAI +3
AI & RAG

This workflow receives a blog generation request via webhook, uses Google Gemini to write a full SEO-optimized post, generates a featured image with DALL-E 3, and automatically publishes the completed

Google Gemini, OpenAI, HTTP Request +2
AI & RAG

Interviewgeneration. Uses openAi, googleGemini, @brightdata/n8n-nodes-brightdata, aiTransform. Webhook trigger; 15 nodes.

OpenAI, Google Gemini, @Brightdata/N8N Nodes Brightdata +2
AI & RAG

AI Institutional Stock Valuation Engine with Risk Scoring & Scenario Targets

Google Sheets, XML, HTTP Request +3