6.0 KiB
6.0 KiB
Directus Flow Setup Guide - YouTube Thumbnail Automation
Overview
This guide sets up a Directus Flow to automatically extract YouTube thumbnails when media_items are created or updated with type = youtube_video or youtube.
Prerequisites
- Access to your Directus admin at
https://enias.zeabur.app/admin - Admin permissions to create flows and modify collections
Step 1: Add youtube_thumbnail Field to media_items Collection
- Go to Settings → Data Model → media_items
- Click Create Field
- Configure the field:
- Field Name:
youtube_thumbnail - Type: File
- Interface: File (Image)
- Display Template: Show thumbnail preview in layouts
- Required: No
- Default: null
- Field Name:
Step 2: Create the YouTube Automation Flow
2.1 Create New Flow
- Go to Settings → Flows
- Click Create Flow
- Configure basic settings:
- Name: "YouTube Thumbnail Auto-Population"
- Status: Active
- Icon: smart_display (or video icon)
- Color: #FF0000 (YouTube red)
- Description: "Automatically extract and populate YouTube thumbnails"
2.2 Configure Trigger
- Click Add Trigger
- Select Event Hook trigger
- Configure trigger:
- Scope: Items
- Actions: Update, Create
- Collections: media_items
2.3 Add Filter Condition
In the trigger configuration, add a filter condition:
{
"$and": [
{
"$or": [
{ "type": { "_eq": "youtube_video" } },
{ "type": { "_eq": "youtube" } }
]
},
{
"url": { "_nnull": true }
}
]
}
2.4 Create Operations
Operation 1: Extract Video ID (Run Script)
- Add Run Script operation
- Name: "Extract YouTube Video ID"
- Code:
// Extract YouTube video ID from URL
function extractYouTubeId(url) {
if (!url) return null;
// Handle different YouTube URL formats
const patterns = [
/(?:youtube\.com\/watch\?v=)([a-zA-Z0-9_-]{11})/,
/(?:youtu\.be\/)([a-zA-Z0-9_-]{11})/,
/(?:youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/,
/(?:youtube\.com\/v\/)([a-zA-Z0-9_-]{11})/
];
for (const pattern of patterns) {
const match = url.match(pattern);
if (match) return match[1];
}
return null;
}
const videoId = extractYouTubeId($trigger.payload.url);
if (!videoId) {
throw new Error('Could not extract YouTube video ID from URL: ' + $trigger.payload.url);
}
// Generate thumbnail URLs with quality fallback
const thumbnailUrls = [
`https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`,
`https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,
`https://img.youtube.com/vi/${videoId}/mqdefault.jpg`,
`https://img.youtube.com/vi/${videoId}/default.jpg`
];
module.exports = {
video_id: videoId,
thumbnail_urls: thumbnailUrls
};
Operation 2: Download & Upload Thumbnail (Run Script)
- Add Run Script operation
- Name: "Download and Upload Thumbnail"
- Code:
const axios = require('axios');
// Download thumbnail and upload to Directus
async function downloadAndUploadThumbnail(thumbnailUrls, videoId) {
// Try each thumbnail URL until we find one that works
for (const url of thumbnailUrls) {
try {
// Download thumbnail
const response = await axios.get(url, {
responseType: 'arraybuffer',
timeout: 10000,
headers: {
'User-Agent': 'Mozilla/5.0 (compatible; DirectusBot/1.0)'
}
});
if (response.status === 200 && response.data.length > 1000) { // Ensure it's a valid image
// Upload to Directus files collection
const fileData = {
title: `YouTube Thumbnail - ${videoId}`,
filename_download: `youtube_${videoId}.jpg`,
type: 'image/jpeg',
storage: 'local',
data: Buffer.from(response.data).toString('base64')
};
const uploadResult = await $directus.files.createOne(fileData);
return uploadResult.id;
}
} catch (error) {
console.log(`Failed to download from ${url}:`, error.message);
continue; // Try next URL
}
}
throw new Error('Failed to download thumbnail from any source');
}
const fileId = await downloadAndUploadThumbnail(
$last.thumbnail_urls,
$last.video_id
);
module.exports = { thumbnail_file_id: fileId };
Operation 3: Update Media Item (Update Data)
- Add Update Data operation
- Configure:
- Collection: media_items
- Key:
{{$trigger.key}} - Payload:
{ "youtube_thumbnail": "{{$last.thumbnail_file_id}}" }
Step 3: Test the Flow
Test Data
Create or update a media_items record with:
type: "youtube_video"url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
Expected Result
The Flow should automatically:
- Extract video ID:
dQw4w9WgXcQ - Download the best available thumbnail
- Upload it to Directus files
- Update the
youtube_thumbnailfield with the file reference
Step 4: Verify Integration
- Check Activity tab for flow execution logs
- Verify
youtube_thumbnailfield is populated - Confirm thumbnail displays in collection layouts
- Test with different YouTube URL formats
Troubleshooting
Common Issues
- Flow not triggering: Check filter conditions and collection name
- Thumbnail download fails: YouTube may block requests - add retry logic
- File upload fails: Check Directus storage configuration
- Permission errors: Ensure flow has file creation permissions
Debug Tips
- Enable flow logging in Settings
- Check Activity logs for error details
- Test operations individually
- Verify field permissions and data types
Alternative Approach: HTTP Request Operation
If the Run Script approach doesn't work, you can use HTTP Request operations:
- HTTP Request to download thumbnail
- HTTP Request to upload to Directus files API
- Update Data to link the file
This approach uses the REST API instead of the JavaScript SDK.