Product photo → Arabic and English captions
Drop a product photo in a Drive folder; AI writes Instagram captions in Arabic and English with hashtags.
How it works
- Detect a new photo in your Drive folder.
- Download it and let AI look at the product.
- AI writes an Arabic caption, an English caption and hashtags in your brand voice.
- Save them to your Content sheet with the photo link, ready to review and post.
Diagram
Code
JavaScript used in the Code step — already included in the template below.
// Mode: Run Once for Each Item
// The AI was asked for JSON like:
// {"product": "Black abaya", "ar": "...", "en": "...", "hashtags": "#abaya #..."}
const match = $json.text.match(/\{[\s\S]*\}/);
const c = match ? JSON.parse(match[0]) : {};
const file = $("New product photo").item.json;
return {
json: {
date: new Date().toISOString().slice(0, 10),
file: file.name,
photo: file.webViewLink,
product: c.product || "",
caption_ar: c.ar || "",
caption_en: c.en || "",
hashtags: c.hashtags || "",
status: "Needs review",
},
};Build it
Pick your tool — same automation, step by step.
Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder. AI steps use a Claude model node — swap it for OpenAI, Gemini or Ollama if you prefer.
Show code (206 lines)
{
"name": "Product photo → Arabic and English captions (Flowngn)",
"nodes": [
{
"parameters": {
"content": "## Product photo → Arabic and English captions\nDrop a product photo in a Drive folder; AI writes Instagram captions in Arabic and English with hashtags.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
"height": 260,
"width": 340
},
"id": "43ef6e94-927f-4bc8-a7a3-d4912df10d1f",
"name": "Setup notes",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-420,
-60
]
},
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"value": "YOUR_PRODUCTS_FOLDER_ID",
"mode": "id"
},
"event": "fileCreated",
"options": {}
},
"id": "43ef6e94-927f-4bc8-a7a3-d4912df10d1f",
"name": "New product photo",
"type": "n8n-nodes-base.googleDriveTrigger",
"typeVersion": 1,
"position": [
0,
0
]
},
{
"parameters": {
"operation": "download",
"fileId": {
"__rl": true,
"value": "={{ $json.id }}",
"mode": "id"
},
"options": {}
},
"id": "43ef6e94-927f-4bc8-a7a3-d4912df10d1f",
"name": "Download photo",
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
300,
0
]
},
{
"parameters": {
"promptType": "define",
"text": "=You write Instagram captions for YOUR_BRAND. Brand voice: YOUR_BRAND_VOICE. Audience: YOUR_AUDIENCE.\nLook at this product photo. File name (may include product name and price): {{ $('New product photo').item.json.name }}\n\nReply ONLY with JSON: {\"product\": \"<short product name>\", \"ar\": \"<Arabic caption, 2-3 short lines, natural Gulf/Egyptian-friendly Arabic>\", \"en\": \"<English caption, 2-3 short lines>\", \"hashtags\": \"<8-10 relevant hashtags, Arabic and English>\"}. Never invent prices, materials or offers that aren't in the file name.",
"passthroughBinaryImages": true
},
"id": "43ef6e94-927f-4bc8-a7a3-d4912df10d1f",
"name": "Write captions",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.5,
"position": [
600,
0
]
},
{
"parameters": {
"model": {
"__rl": true,
"value": "claude-sonnet-5",
"mode": "list"
},
"options": {}
},
"id": "43ef6e94-927f-4bc8-a7a3-d4912df10d1f",
"name": "Claude model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"typeVersion": 1.3,
"position": [
600,
220
]
},
{
"parameters": {
"jsCode": "// Mode: Run Once for Each Item\n// The AI was asked for JSON like:\n// {\"product\": \"Black abaya\", \"ar\": \"...\", \"en\": \"...\", \"hashtags\": \"#abaya #...\"}\nconst match = $json.text.match(/\\{[\\s\\S]*\\}/);\nconst c = match ? JSON.parse(match[0]) : {};\nconst file = $(\"New product photo\").item.json;\n\nreturn {\n json: {\n date: new Date().toISOString().slice(0, 10),\n file: file.name,\n photo: file.webViewLink,\n product: c.product || \"\",\n caption_ar: c.ar || \"\",\n caption_en: c.en || \"\",\n hashtags: c.hashtags || \"\",\n status: \"Needs review\",\n },\n};",
"mode": "runOnceForEachItem"
},
"id": "43ef6e94-927f-4bc8-a7a3-d4912df10d1f",
"name": "Read captions",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
0
]
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "YOUR_SPREADSHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "Content",
"mode": "name"
},
"columns": {
"mappingMode": "autoMapInputData",
"value": {}
},
"options": {}
},
"id": "43ef6e94-927f-4bc8-a7a3-d4912df10d1f",
"name": "Save to Content sheet",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1200,
0
]
}
],
"connections": {
"New product photo": {
"main": [
[
{
"node": "Download photo",
"type": "main",
"index": 0
}
]
]
},
"Download photo": {
"main": [
[
{
"node": "Write captions",
"type": "main",
"index": 0
}
]
]
},
"Write captions": {
"main": [
[
{
"node": "Read captions",
"type": "main",
"index": 0
}
]
]
},
"Read captions": {
"main": [
[
{
"node": "Save to Content sheet",
"type": "main",
"index": 0
}
]
]
},
"Claude model": {
"ai_languageModel": [
[
{
"node": "Write captions",
"type": "ai_languageModel",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"meta": {
"templateCredsSetupCompleted": false
},
"tags": []
}In Make, create a new scenario and add these modules in order:
- Google Drive › Watch Files in a Folder
- Google Drive › Upload a File
- Anthropic Claude › Create a Prompt (or OpenAI › Create a Completion)
- Tools › Set variable / Iterator + Array aggregator (same logic as the Code step)
- Google Sheets › Add a Row
- Every module run uses Make operations — the free plan includes a monthly quota.
- Make's built-in functions (map, sum, formatDate…) can replace most Code steps; for complex logic use a code module.
- Module and step names can differ slightly as Make and Zapier update their apps.
In Zapier, create a new Zap and add these steps in order:
- Google Drive — New File in Folder
- Google Drive — Upload File
- Anthropic (Claude) — Send Message (or ChatGPT — Conversation)
- Code by Zapier — Run JavaScript (paste the code from the Code section)
- Google Sheets — Create Spreadsheet Row
- Zaps with more than two steps need a paid Zapier plan.
- Webhooks, Filters/Paths and Code by Zapier are premium features on some Zapier plans.
- Code by Zapier runs JavaScript: reuse the code shown above, reading inputs from inputData instead of $json.
- Module and step names can differ slightly as Make and Zapier update their apps.
Tips
- Name files with the product name and price ("black-abaya-450.jpg"), since AI uses the file name too.
- Use an AI model that can read images.
Related flows
Blog post → social media drafts
When you publish a blog post, AI drafts LinkedIn and X posts for you to approve.
YouTube video → blog post + social posts
Every new video becomes a blog draft, a LinkedIn post and an X post — saved to Notion for review.
A week of content ideas from your industry's news
Every Sunday, AI reads the week's industry news and posts 7 content ideas to your Slack channel.