How Viscribe Works
This page walks through exactly what happens when you upload an image to the WordPress Media Library with Viscribe active.
Free version uses Groq only
The free version of Viscribe exclusively connects to Groq's API using Llama 4 Scout (Maverick is also available but deprecated by Groq). Only the Pro add-on adds support for OpenAI, Anthropic, Google Gemini, and custom providers. Everything described on this page assumes the Groq API pipeline.
1. Upload Interception
WordPress fires the wp_handle_upload_prefilter filter for every file uploaded through the Media Library. Viscribe hooks into this filter via the Image_Uploader class — before the file is saved to disk, the plugin gets a chance to inspect and rename it.
add_filter( 'wp_handle_upload_prefilter', [ $this, 'process_upload' ] );2. Enabled Check
The plugin first checks whether auto-rename is toggled on in the settings and whether a valid API key exists. If either is missing, the file passes through unchanged.
if ( ! $this->groq_service->is_enabled() ) {
return $file;
}3. File Type Validation
The uploaded file's MIME type is checked against the allowed types (JPEG, PNG, WebP, GIF by default). You can toggle these in the settings. The viscribe_allowed_file_types filter lets you add more.
4. File Size Check
Images larger than 10 MB are skipped to avoid timeout issues with the AI API. The viscribe_max_file_size filter can increase this limit.
5. Temporary File Handling
The uploaded file lives at a temporary path on the server. The plugin reads this file, encodes its contents as base64, and prepares it for the API request.
6. Building the Prompt
A prompt is constructed telling the AI what to do:
"Analyze this image and generate exactly N keywords that describe its content. Return only the keywords separated by commas, nothing else."
The keyword count (N) comes from the Max Keywords setting. The viscribe_prompt filter can customize this prompt entirely.
7. API Request
The plugin sends a POST request to the Groq API endpoint (https://api.groq.com/openai/v1/chat/completions) with:
- The chosen model (default:
llama-4-scout-17b-16e-instruct) - The base64-encoded image
- The text prompt
- Temperature and token limits
The viscribe_api_payload filter lets you modify the entire payload before it is sent. The viscribe_api_request_args filter lets you modify HTTP arguments (timeout, headers).
8. Response Parsing
The API returns a JSON response containing the AI-generated text. Viscribe extracts the content from choices[0].message.content. If no content is returned, the upload proceeds with the original filename.
9. Description to Filename
The raw AI text is passed through File_Sanitizer::sanitize(), which:
- Converts to lowercase
- Removes punctuation and special characters
- Strips common stop words (a, an, the, of, in, on, at, for, to, with, and, or, is, are, was, were)
- Collapses multiple hyphens into one
- Trims leading and trailing hyphens
The result is a clean slug like golden-retriever-playing-fetch-park.
10. Extension Mapping
The original file extension is extracted from the uploaded filename. If it is missing, the plugin maps the MIME type to an extension using the viscribe_mime_to_ext filter:
| MIME Type | Extension |
|---|---|
image/jpeg | jpg |
image/png | png |
image/webp | webp |
image/gif | gif |
11. Final Filename Assembly
The sanitized base name and extension are joined. The result is passed through the viscribe_new_filename filter, which allows developers to add prefixes, append timestamps, or rewrite the filename entirely.
$new_filename = apply_filters( 'viscribe_new_filename', $new_filename, $sanitized_name, $extension, $file, $description );12. File Renamed
The $file array's name key is updated with the new filename. WordPress saves the file with this new name. The viscribe_image_renamed action fires after the rename is done.
13. Alt Text (Optional)
If alt text generation is enabled, the plugin:
- Converts the sanitized slug back into readable text (
golden-retriever-playing-fetch-park→Golden retriever playing fetch park) - Passes it through the
viscribe_alt_textfilter - Stores it in a WordPress transient keyed to a UUID
- Hooks into
add_attachmentto retrieve the transient and callwp_update_post()to save the_wp_attachment_image_altmeta
Flow Diagram Overview
Upload → wp_handle_upload_prefilter
↓
Is enabled? → No → Return original file
↓ Yes
Allowed type? → No → Return original file
↓ Yes
File ≤ 10 MB? → No → Return original file
↓ Yes
Read file → base64 encode
↓
Build prompt (viscribe_prompt)
↓
Send to Groq API (viscribe_api_payload, viscribe_api_request_args)
↓
Parse response (viscribe_api_response action)
↓
Description returned? → No → Return original file
↓ Yes
Sanitize → File_Sanitizer::sanitize()
↓
Map extension (viscribe_mime_to_ext)
↓
Build filename (viscribe_new_filename)
↓
Update $file['name']
↓
viscribe_image_renamed action fires
↓
Alt text enabled? → Yes → Store in transient → Save on add_attachment
↓ No
File saved with new name