Beyond ChatGPT: Secret and Surprisingly Powerful Things You Can Build With the OpenAI API
When most people think about the OpenAI API, they imagine a text box where somebody types a question and artificial intelligence sends back an answer. That is technically correct, but it barely scratches the surface of what the API can actually do.
I use OpenAI differently on AlexanderMirvis.com and BrooklynNotaryNinjas.com. Instead of treating artificial intelligence as a separate chatbot sitting in the corner of a website, I can make it part of the actual software. OpenAI can examine webpages before publication, generate metadata, analyze uploaded documents, assist with medical and legal research, power customer-service conversations, automate repetitive work, monitor servers, analyze cybersecurity logs, transcribe telephone calls, generate spoken responses, search private document collections and communicate with other parts of my applications through controlled functions.
The real trick is understanding that the OpenAI API does not have to be the application. It can be the intelligence inside the application.
A traditional PHP application might contain logic such as:
if ($documentType === 'affidavit') {
// Do something
}
An AI-enabled application can go much further. I can give OpenAI an uploaded document and ask it to identify the document type, extract important dates, recognize the people involved, summarize what happened, identify missing information and return everything as structured data that PHP can process.
This changes OpenAI from a text generator into something much closer to an intelligent software component.
Building One Central OpenAI Function
For PHP applications, I prefer having one central server-side function that communicates with the OpenAI API. The rest of the website can then call that function whenever artificial intelligence is needed.
The API key should always remain on the server. It should never be placed inside JavaScript that is sent to a visitor's browser.
<?php
function openaiResponse(array $payload): array
{
$apiKey = getenv('OPENAI_API_KEY');
if (!$apiKey) {
throw new RuntimeException('OPENAI_API_KEY is not configured.');
}
$ch = curl_init('https://api.openai.com/v1/responses');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_TIMEOUT => 120
]);
$raw = curl_exec($ch);
if ($raw === false) {
throw new RuntimeException(curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($raw, true);
if ($status >= 400) {
throw new RuntimeException(
$data['error']['message'] ?? 'OpenAI request failed.'
);
}
return $data;
}
A basic request can then look like this:
$response = openaiResponse([
'model' => 'gpt-5',
'input' => 'Explain what a New York notarial acknowledgment is.'
]);
echo $response['output'][0]['content'][0]['text'] ?? '';
The exact model can be changed depending on the task, desired speed, reasoning requirements and cost. The important architectural decision is that everything goes through my server. The browser talks to my PHP application, my application decides what is allowed, and only then does the server communicate with OpenAI.
This gives me control over authentication, rate limits, security, logging, permissions, billing and exactly what information the model is allowed to access.
Using OpenAI to Generate Titles, Metadata and Analyze Every Page
One of the most useful OpenAI integrations on AlexanderMirvis.com is automatic content and SEO analysis. Instead of manually writing a title tag, meta description, keyword list and search description every time I publish something, OpenAI can examine the actual article and propose them automatically.
The important trick is that I do not necessarily want OpenAI to answer me conversationally. I want my CMS to receive data that it can store directly in the database.
For example, I may want a response that looks like this:
{
"title": "Suggested Page Title",
"meta_description": "Suggested description",
"keywords": [
"keyword one",
"keyword two"
],
"seo_score": 84,
"problems": [
"Meta description is too vague"
],
"recommendations": [
"Add a stronger introductory paragraph"
]
}
I can ask the API for structured output instead of arbitrary prose.
$pageText = strip_tags($pageHtml);
$response = openaiResponse([
'model' => 'gpt-5',
'instructions' => '
You are the SEO analysis engine for AlexanderMirvis.com.
Analyze the supplied webpage.
Do not use clickbait.
Do not invent facts.
The title must accurately describe the article.
Examine:
headings,
topic clarity,
search intent,
keyword usage,
article structure,
internal linking opportunities,
readability,
metadata quality
and duplicate-looking sections.
',
'input' => $pageText,
'text' => [
'format' => [
'type' => 'json_schema',
'name' => 'seo_analysis',
'strict' => true,
'schema' => [
'type' => 'object',
'properties' => [
'title' => [
'type' => 'string'
],
'meta_description' => [
'type' => 'string'
],
'keywords' => [
'type' => 'array',
'items' => [
'type' => 'string'
]
],
'seo_score' => [
'type' => 'integer',
'minimum' => 0,
'maximum' => 100
],
'problems' => [
'type' => 'array',
'items' => [
'type' => 'string'
]
],
'recommendations' => [
'type' => 'array',
'items' => [
'type' => 'string'
]
]
],
'required' => [
'title',
'meta_description',
'keywords',
'seo_score',
'problems',
'recommendations'
],
'additionalProperties' => false
]
]
]
]);
Now the CMS can automatically save the results instead of requiring me to copy and paste them manually.
$analysisJson =
$response['output'][0]['content'][0]['text'];
$seo = json_decode($analysisJson, true);
$stmt = $pdo->prepare("
UPDATE posts
SET
meta_title = ?,
meta_description = ?,
seo_score = ?
WHERE id = ?
");
$stmt->execute([
$seo['title'],
$seo['meta_description'],
$seo['seo_score'],
$postId
]);
I can take this much further than simply generating a title. OpenAI can examine the title, headings, body text, image descriptions, URL slug, categories, keywords, internal links and even whether the article actually delivers what its title promises.
My CMS can display something like:
SEO SCORE: 82 / 100
Strong Points:
The article clearly explains the main subject.
The primary topic appears early.
The heading structure is logical.
Problems:
The meta description is too generic.
There is no internal link to a related article.
Two headings discuss nearly identical material.
Suggested Title:
How Remote Online Notarization Actually Works in New York
Analyze Articles Automatically Before Publishing
Another useful trick is connecting OpenAI directly to the publishing workflow. Instead of remembering to click an AI button, the CMS can automatically analyze a page when its status changes from draft to published.
if ($oldStatus === 'draft' && $newStatus === 'published') {
$seo = analyzePageWithOpenAI($post);
saveSeoAnalysis(
$post['id'],
$seo
);
if ($seo['seo_score'] < 60) {
createAdminWarning(
'This article has significant SEO problems.'
);
}
}
At that point, OpenAI becomes part of the publishing pipeline instead of something separate from the CMS.
Using OpenAI to Generate Content
Content generation is probably the most obvious use of OpenAI, but it is also one of the easiest features to implement badly. Asking artificial intelligence to simply "write an article about cybersecurity" usually produces generic content because the model was given almost no editorial direction.
A better approach is to provide an editorial specification that explains the website, audience, tone, formatting requirements and factual restrictions.
For AlexanderMirvis.com, I can use something like:
$prompt = <<<PROMPT
Write a detailed article for AlexanderMirvis.com.
Topic:
{$topic}
Audience:
Technically curious readers who may not be software engineers.
Requirements:
Use normal paragraphs.
Explain technical concepts in plain English.
Include practical examples.
Avoid fake quotes.
Do not invent statistics.
Use headings where useful.
Include code only when it genuinely helps.
Do not make the article sound like marketing copy.
Return HTML suitable for insertion into a CMS article body.
Do not include html, head or body tags.
PROMPT;
$response = openaiResponse([
'model' => 'gpt-5',
'input' => $prompt
]);
For BrooklynNotaryNinjas.com, the instructions can be completely different.
$prompt = <<<PROMPT
Create a consumer information article for BrooklynNotaryNinjas.com.
Topic:
{$topic}
Explain the subject in simple language.
Do not give legal advice.
Distinguish a notary's role from an attorney's role.
Do not state that notarization proves the truth of a document.
Do not invent legal requirements.
When a requirement is uncertain, explicitly state that it
should be independently verified.
Use complete paragraphs.
PROMPT;
The model might be the same, but the instructions transform it into a completely different application.
I can also give my CMS individual AI functions such as Rewrite, Expand, Shorten, Simplify, Make Technical, Generate FAQ, Generate Summary, Generate SEO, Translate, Analyze Arguments and Identify Claims That Need Verification.
This effectively turns OpenAI into an intelligent editorial toolbar.
Uploading Documents for AI Analysis
Document analysis is where the OpenAI API becomes particularly useful. A website can allow someone to upload a PDF, Word document or other supported file and then ask OpenAI to analyze what is actually inside it.
This can be useful for medical records, legal documents, contracts, pleadings, accident reports, research papers, affidavits, transcripts, invoices, business records, insurance documents, policies and many other types of files.
The first step is uploading the file to OpenAI.
<?php
function uploadToOpenAI(string $path): array
{
$apiKey = getenv('OPENAI_API_KEY');
$ch = curl_init(
'https://api.openai.com/v1/files'
);
$post = [
'purpose' => 'user_data',
'file' => new CURLFile(
$path,
mime_content_type($path),
basename($path)
)
];
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey
],
CURLOPT_POSTFIELDS => $post
]);
$raw = curl_exec($ch);
if ($raw === false) {
throw new RuntimeException(
curl_error($ch)
);
}
curl_close($ch);
return json_decode($raw, true);
}
After the upload:
$file = uploadToOpenAI(
$_FILES['document']['tmp_name']
);
$fileId = $file['id'];
The uploaded file can then be supplied to the model.
$response = openaiResponse([
'model' => 'gpt-5',
'input' => [
[
'role' => 'user',
'content' => [
[
'type' => 'input_file',
'file_id' => $fileId
],
[
'type' => 'input_text',
'text' => '
Analyze this document.
Identify:
1. Document type.
2. Important dates.
3. Important people or entities.
4. Major factual findings.
5. Internal inconsistencies.
6. Important missing information.
7. Questions that deserve additional investigation.
Separate facts contained in the
document from your interpretation.
'
]
]
]
]
]);
This goes far beyond ordinary text extraction. The application is not simply reading the words from the PDF. It is asking OpenAI to understand what those words mean in context.
Medical Record Analysis
One obvious application is medical record review. A large medical file might contain emergency room records, diagnostic imaging, surgical reports, physical therapy notes, physician examinations, medication records and follow-up recommendations scattered across hundreds or even thousands of pages.
I can instruct OpenAI to turn those records into a chronological medical timeline.
Create a chronological medical timeline.
For every encounter identify:
Date
Provider
Complaint
Diagnosis
Objective findings
Imaging
Procedure
Medication
Restrictions
Follow-up recommendations
Separately identify:
Prior conditions
New conditions
Changes in diagnosis
Gaps in treatment
Conflicting statements
Unresolved recommendations
Do not diagnose the patient.
Clearly distinguish documented facts
from analytical observations.
This can transform a massive collection of medical records into something that is considerably easier to review.
Artificial intelligence should not replace a physician, attorney or qualified expert, but it can be extremely useful for organization, chronology creation, document comparison and identifying issues that deserve human review.
Legal Research and Case Analysis
The same architecture can be used for legal documents. Instead of simply asking OpenAI to summarize a pleading, I can ask it to organize the case into specific categories.
Review these materials as a legal research assistant.
Create:
Factual Background
Procedural History
Issues Presented
Potentially Relevant Law
Evidence Supporting Each Position
Evidence Against Each Position
Unresolved Factual Questions
Potential Research Topics
Do not invent cases or citations.
Clearly identify any issue that requires
independent legal research.
This gives me a starting point for actual research while reducing the amount of time required to manually organize documents.
Creating Word Documents and PDF Reports
I generally prefer having OpenAI create the analysis while my own application controls the final document. That lets me control branding, headers, page numbering, disclaimers, typography and layout.
The architecture looks like this:
Uploaded Document
|
v
OpenAI Analysis
|
v
Structured JSON
|
v
PHP
|
v
Word Document or PDF
For example, OpenAI can return:
{
"title": "Medical Record Review",
"summary": "Summary goes here",
"timeline": [],
"findings": [],
"questions": []
}
PHP can then create a Word document using PHPWord.
composer require phpoffice/phpword
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\IOFactory;
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$section->addTitle(
'Medical Record Analysis',
1
);
$section->addText(
$analysis['summary']
);
$section->addTitle(
'Chronology',
2
);
foreach ($analysis['timeline'] as $entry) {
$section->addText(
$entry['date'] . ' - ' .
$entry['provider'],
['bold' => true]
);
$section->addText(
$entry['summary']
);
}
$section->addTitle(
'Important Findings',
2
);
foreach ($analysis['findings'] as $finding) {
$section->addListItem($finding);
}
$writer = IOFactory::createWriter(
$phpWord,
'Word2007'
);
$writer->save(
__DIR__ . '/reports/analysis.docx'
);
A PDF can be created with a library such as Dompdf.
composer require dompdf/dompdf
use Dompdf\Dompdf;
$html = '
<h1>Document Analysis</h1>
<p>' .
htmlspecialchars($analysis['summary']) .
'</p>
';
foreach ($analysis['findings'] as $finding) {
$html .=
'<p>' .
htmlspecialchars($finding) .
'</p>';
}
$pdf = new Dompdf();
$pdf->loadHtml($html);
$pdf->render();
file_put_contents(
__DIR__ . '/reports/analysis.pdf',
$pdf->output()
);
This separates intelligence from presentation. OpenAI creates the analysis, while my own software decides exactly how the finished product looks.
Turning Private Documents Into an AI Knowledge Base
If I have hundreds or thousands of documents, repeatedly attaching every file to every question would be inefficient. Instead, documents can be stored inside a searchable knowledge system and retrieved based on their meaning.
This is generally called retrieval-augmented generation, or RAG.
For BrooklynNotaryNinjas.com, a private knowledge collection could contain service descriptions, company procedures, notary reference material, apostille information, internal instructions, customer FAQs and website documentation.
The chatbot can then search those records when answering a customer.
$response = openaiResponse([
'model' => 'gpt-5',
'tools' => [
[
'type' => 'file_search',
'vector_store_ids' => [
getenv(
'NOTARY_VECTOR_STORE_ID'
)
]
]
],
'input' =>
'What documents do I need for this service?'
]);
The result is fundamentally different from a generic chatbot. A generic chatbot knows general information. A properly constructed business chatbot can search information specifically belonging to the business.
The OpenAI Chatbot on BrooklynNotaryNinjas.com
A chatbot becomes substantially more useful when it can communicate with the actual website instead of simply generating answers.
I can expose carefully controlled server-side functions such as:
- get_service_price
- get_business_hours
- lookup_session_status
- check_document_requirements
- create_support_ticket
- find_available_notary
The AI can determine when one of those functions is needed, while PHP performs the actual operation.
$tools = [
[
'type' => 'function',
'name' => 'get_service_price',
'description' =>
'Retrieve current pricing from the website database.',
'strict' => true,
'parameters' => [
'type' => 'object',
'properties' => [
'service' => [
'type' => 'string'
]
],
'required' => [
'service'
],
'additionalProperties' => false
]
]
];
If somebody asks:
How much does an apostille cost?
the model does not need to guess or rely on old training information. It can request the actual price from my application.
$stmt = $pdo->prepare(
'SELECT price
FROM services
WHERE slug = ?'
);
$stmt->execute([
'apostille'
]);
$price = $stmt->fetchColumn();
The database remains the authority. OpenAI handles the conversation.
Remembering a Conversation
A useful chatbot also needs context. If someone starts by saying that they need an apostille and then says that the document is going to Spain, they should not have to explain everything again.
$response = openaiResponse([
'model' => 'gpt-5',
'previous_response_id' =>
$_SESSION['openai_response_id'] ?? null,
'input' => $userMessage
]);
$_SESSION['openai_response_id'] =
$response['id'];
The conversation can then work naturally:
USER:
I need an apostille.
ASSISTANT:
What country will receive the document?
USER:
Spain.
The model understands that Spain refers to the apostille request from the previous message.
Automation: Making OpenAI Work Without Clicking a Button
The OpenAI API becomes especially valuable when it is connected to automation. Instead of manually asking the model to perform the same task repeatedly, the server can run the task automatically.
For example, a Linux cron job can analyze newly published articles every night.
0 3 * * * /usr/bin/php /home/site/scripts/ai-audit.php
The PHP script can locate anything that has not already been reviewed.
$posts = $pdo->query("
SELECT *
FROM posts
WHERE ai_reviewed = 0
AND status = 'published'
")->fetchAll();
foreach ($posts as $post) {
$analysis =
analyzePageWithOpenAI($post);
saveAnalysis(
$post['id'],
$analysis
);
markReviewed(
$post['id']
);
}
That gives AlexanderMirvis.com an automated editorial auditor.
The same idea can be used on BrooklynNotaryNinjas.com to analyze unanswered questions, classify support requests, summarize documents, detect repeated FAQs, suggest knowledge-base improvements, translate approved content and summarize customer conversations.
AI Decides What Is Needed, PHP Executes It
One of the most powerful application patterns is allowing OpenAI to interpret what a person wants while normal software performs the actual operation.
USER
|
v
OPENAI
|
v
FUNCTION REQUEST
|
v
MY PHP CODE
|
v
DATABASE OR BUSINESS LOGIC
|
v
OPENAI
|
v
USER
Imagine somebody tells Brooklyn Notary Ninjas:
I have a document that needs to go to Spain and I need somebody tomorrow.
OpenAI may determine that the application needs to identify the service, check availability, retrieve pricing and explain the requirements.
The AI can request those functions, but it should not receive unrestricted database access.
I might permit:
check_availability
but I would never give a model a function such as:
execute_arbitrary_sql
This is the AI version of the security principle known as least privilege.
Using OpenAI for Cybersecurity
One of the most practical ways I use OpenAI is for cybersecurity and server monitoring. Both AlexanderMirvis.com and BrooklynNotaryNinjas.com are public-facing websites, which means the servers are constantly exposed to scanners, automated vulnerability probes, fake WordPress requests, credential attacks, malicious bots and attempts to locate configuration files.
Anyone who operates a public web server quickly discovers how noisy the Internet really is.
A server log might contain:
185.234.219.32 "GET /wp-login.php" 404
185.234.219.32 "GET /wp-admin/" 404
185.234.219.32 "GET /.env" 403
185.234.219.32 "GET /.git/config" 403
185.234.219.32 "GET /phpmyadmin/" 404
A human administrator immediately recognizes that this probably is not someone casually browsing the website. Something is systematically searching for common administration interfaces and secret configuration files.
I still use traditional security tools such as firewalls, Fail2Ban, rate limiting and application security rules. OpenAI does not replace those systems. Instead, I can place OpenAI above them as an analysis layer.
Traditional security tools answer a question such as:
Did this request match a known security rule?
OpenAI can help answer:
What does this entire pattern of activity appear to represent?
Turning Raw Server Logs Into Security Intelligence
Instead of manually reading thousands of Apache, Nginx, PHP, SSH or application log entries, I can send suspicious portions of those logs to OpenAI for defensive analysis.
from pathlib import Path
logfile = Path(
"/var/log/nginx/access.log"
)
with logfile.open(
"r",
encoding="utf-8",
errors="ignore"
) as f:
lines = f.readlines()
recent = lines[-1000:]
log_text = "".join(recent)
I can then ask OpenAI to examine the activity.
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5",
instructions="""
You are assisting with defensive
cybersecurity monitoring.
Analyze the supplied HTTP access log.
Identify activity that may indicate:
credential attacks,
vulnerability scanning,
WordPress probing,
environment-file probing,
Git repository probing,
SQL injection attempts,
path traversal,
command injection,
suspicious user agents,
excessive enumeration,
scraping,
or unusual request patterns.
Do not assume that an IP is malicious
based on one failed request.
Distinguish normal traffic from activity
that deserves investigation.
Provide defensive recommendations only.
""",
input=log_text
)
print(response.output_text)
Instead of reading a thousand log entries myself, I can receive an incident summary explaining that one address requested WordPress administration pages, an environment file, a Git configuration file and phpMyAdmin within a few seconds.
More importantly, the model can tell me whether the supplied logs show merely attempted access or evidence of successful access.
Correlating Different Logs
A server rarely has only one useful security log. I may be examining web server logs, PHP errors, application logs, SSH authentication logs, Fail2Ban events, firewall activity, database errors and CMS login attempts.
An attack can appear differently in each system.
WEB LOG:
Repeated requests to /admin/login
APPLICATION LOG:
Twenty failed administrator logins
FAIL2BAN:
IP added to jail
AUTH LOG:
SSH authentication failures
from the same address
Looking at each source separately can hide the larger pattern. OpenAI can help correlate them.
security_event = f"""
WEB SERVER LOG
---------------
{web_log}
APPLICATION LOG
---------------
{application_log}
SSH LOG
---------------
{ssh_log}
FAIL2BAN LOG
---------------
{fail2ban_log}
"""
The combined event can then be analyzed.
response = client.responses.create(
model="gpt-5",
instructions="""
Act as a defensive security analyst.
Correlate events across these server logs.
Determine whether events appear related.
Produce:
Executive Summary
Timeline
Source IP Addresses
Targeted Services
Suspicious Requests
Successful Requests
Failed Requests
Possible Attack Technique
Evidence Supporting the Assessment
Evidence Against the Assessment
Recommended Defensive Actions
Never claim compromise occurred unless
the supplied logs provide evidence.
""",
input=security_event
)
This distinction is extremely important. Someone requesting /.env does not mean they obtained the file. If the server returned HTTP 403, the security control likely prevented access.
Detecting WordPress Probes on a Website That Does Not Use WordPress
AlexanderMirvis.com uses a custom CMS, but automated scanners do not know that. Bots will still request WordPress paths such as /wp-login.php, /wp-admin/, /xmlrpc.php and /wp-config.php.
That creates a useful security signal. If the website does not use WordPress, legitimate users have essentially no reason to request those administration paths.
$suspiciousPaths = [
'/wp-login.php',
'/wp-admin',
'/wp-config.php',
'/xmlrpc.php',
'/.env',
'/.git',
'/phpmyadmin'
];
$requestUri =
$_SERVER['REQUEST_URI'];
foreach ($suspiciousPaths as $path) {
if (
stripos(
$requestUri,
$path
) !== false
) {
logSecurityEvent([
'ip' =>
$_SERVER['REMOTE_ADDR'],
'path' =>
$requestUri,
'user_agent' =>
$_SERVER[
'HTTP_USER_AGENT'
] ?? '',
'timestamp' =>
time()
]);
break;
}
}
Creating a Security Event Database
Instead of immediately banning every visitor that requests something suspicious, I can record the event and examine the behavior over time.
CREATE TABLE security_events (
id BIGINT UNSIGNED
AUTO_INCREMENT
PRIMARY KEY,
ip_address VARCHAR(45)
NOT NULL,
event_type VARCHAR(100)
NOT NULL,
request_uri TEXT,
user_agent TEXT,
risk_score INT
DEFAULT 0,
ai_summary TEXT,
created_at DATETIME
NOT NULL
);
OpenAI can then examine multiple events associated with the same address and determine whether the activity appears accidental, unusual or consistent with automated reconnaissance.
Giving Security Events a Risk Score
Instead of returning a paragraph, the cybersecurity analyzer can return structured information.
{
"risk_score": 82,
"classification": "automated_reconnaissance",
"confidence": 0.91,
"indicators": [
"WordPress probing",
"Environment file probing",
"Git configuration probing"
],
"recommended_action": "temporary_block"
}
The model can be specifically instructed to remain conservative.
response = client.responses.create(
model="gpt-5",
instructions="""
Analyze this server activity for
defensive cybersecurity purposes.
Score risk from 0 through 100.
Be conservative.
A single 404 request should normally
receive a low score.
Repeated requests for known secret files,
administrative interfaces or exploit
paths should increase the score.
Successful responses from sensitive
resources should receive special
attention.
""",
input=events,
text={
"format": {
"type": "json_schema",
"name": "security_analysis",
"strict": True,
"schema": {
"type": "object",
"properties": {
"risk_score": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"classification": {
"type": "string"
},
"confidence": {
"type": "number"
},
"indicators": {
"type": "array",
"items": {
"type": "string"
}
},
"recommended_action": {
"type": "string"
}
},
"required": [
"risk_score",
"classification",
"confidence",
"indicators",
"recommended_action"
],
"additionalProperties": False
}
}
}
)
This allows OpenAI to feed an actual security dashboard instead of simply producing an answer that a human must manually interpret.
OpenAI and Fail2Ban
Fail2Ban is still an excellent tool for automatically reacting to repeated malicious activity. OpenAI can complement it by performing a different job.
LOG EVENT
|
v
DETERMINISTIC RULES
|
v
OPENAI ANALYSIS
|
v
RISK SCORE
|
v
POLICY ENGINE
|
v
FAIL2BAN OR FIREWALL
The policy engine is extremely important. OpenAI may recommend a temporary block, but my application determines whether that recommendation satisfies the actual enforcement rules.
if (
analysis["risk_score"] >= 90
and event_count >= 10
):
action = "temporary_block"
elif analysis["risk_score"] >= 60:
action = "watch"
else:
action = "log"
The model provides interpretation. My software provides enforcement.
Safe Automated Firewall Actions
If I automate temporary firewall actions, I do not allow the model to create arbitrary shell commands. Instead, the application calls a predefined security function.
import subprocess
import ipaddress
def block_ip(ip):
address =
ipaddress.ip_address(ip)
subprocess.run(
[
"/usr/local/sbin/security-block",
str(address)
],
check=True
)
I would never do something such as:
os.system(ai_generated_command)
Allowing model-generated text to execute directly as root would create an obvious security problem.
The safe design is:
OpenAI recommends:
temporary_block
Application translates that into:
a predefined and validated
firewall operation
Detecting SSH Credential Attacks
SSH authentication logs are another useful source of information.
Failed password for root from 203.0.113.91
Failed password for admin from 203.0.113.91
Invalid user oracle from 203.0.113.91
Invalid user postgres from 203.0.113.91
Invalid user ubuntu from 203.0.113.91
A traditional security tool can count the attempts. OpenAI can help explain the pattern.
For example, it may identify that the source is attempting several common administrative usernames and that the sequence is consistent with automated SSH username enumeration or credential guessing.
It should also clearly say when no successful authentication appears in the supplied evidence.
Analyzing PHP Errors for Security Problems
Not every security problem originates with an attacker. Sometimes the application itself reveals information that should not be exposed.
PHP Warning:
file_get_contents(
/home/user/private/config.php
):
Permission denied
PHP Fatal error:
Uncaught PDOException:
SQLSTATE[HY000] [1045]
Access denied for user...
An OpenAI log-analysis system can identify security-relevant issues such as filesystem paths being exposed, database details appearing in logs, credentials accidentally being logged, stack traces appearing in production, unsafe upload handling, repeated authentication failures and permission problems.
response = client.responses.create(
model="gpt-5",
instructions="""
Review these PHP production logs.
Look for security-relevant problems.
Identify:
filesystem path disclosure,
database information disclosure,
credentials accidentally logged,
stack traces,
unsafe upload handling,
authentication problems,
SQL errors,
permission failures,
and repeated application errors.
Prioritize findings by severity.
""",
input=php_log
)
Detecting SQL Injection Probes
HTTP logs sometimes contain suspicious URLs attempting to manipulate database queries.
/products.php?id=4%27%20OR%201=1--
or:
/search?q=%27%20UNION%20SELECT
The important part is not simply recognizing that the request resembles SQL injection. I want my system to investigate what happened around that request.
Useful questions include whether the request was blocked, whether PHP produced a database error, whether the response size changed unexpectedly, whether the request received a successful response, whether the same source attempted multiple payloads and whether related database errors occurred at approximately the same time.
This creates useful security analysis instead of a simplistic alert saying that SQL injection was detected.
Detecting Secret File and Path Traversal Probes
Scanners frequently search for files that should never be public.
../../../../etc/passwd
/.env
/.git/config
/config.php
/backup.zip
/database.sql
/.aws/credentials
Instead of creating fifty individual warnings, my security system can group related requests into a single incident.
INCIDENT #2841
Source:
185.234.219.32
Duration:
47 seconds
Requests:
63
Categories:
Secret-file discovery
Repository probing
Configuration discovery
Backup-file enumeration
Successful sensitive responses:
None
Risk:
High
Automatic action:
IP temporarily blocked
Automatically Generating Cybersecurity Incident Reports
OpenAI is also very useful for turning raw technical evidence into a readable incident report.
The final report can include the incident summary, detection time, affected host, source addresses, timeline, observed techniques, security controls triggered, evidence of successful or failed activity, containment actions and recommended follow-up.
prompt = f"""
Prepare a technical cybersecurity incident report
based only on the evidence below.
Do not invent events.
Explicitly distinguish:
attempted access,
blocked access,
successful access,
and unknown outcomes.
LOG DATA:
{incident_logs}
"""
report = client.responses.create(
model="gpt-5",
input=prompt
)
The resulting analysis can then be converted into a Word document or PDF using the same reporting system used for medical or legal document analysis.
SECURITY EVENT
|
v
LOG COLLECTION
|
v
OPENAI ANALYSIS
|
v
INCIDENT TIMELINE
|
v
WORD OR PDF REPORT
Watching My Custom CMS
Because AlexanderMirvis.com uses a custom CMS, I can log application-specific security events that would never appear clearly in an ordinary web server access log.
securityLog(
'ADMIN_LOGIN_FAILURE',
[
'username' => $username,
'ip' =>
$_SERVER['REMOTE_ADDR']
]
);
Other security events might include:
- ADMIN_LOGIN_SUCCESS
- ADMIN_LOGIN_FAILURE
- PASSWORD_CHANGED
- USER_CREATED
- USER_DELETED
- FILE_UPLOADED
- EXECUTABLE_UPLOAD_BLOCKED
- PAGE_DELETED
- DATABASE_EXPORT
- API_KEY_SETTING_CHANGED
- PERMISSION_CHANGED
- HONEYPOT_TRIGGERED
This gives OpenAI considerably better information about what is happening inside the application.
For example, imagine the system sees:
03:02 ADMIN LOGIN SUCCESS
03:03 API KEY CHANGED
03:04 NEW ADMIN CREATED
03:05 87 POSTS DELETED
03:06 DATABASE EXPORT
Every individual operation may technically have been authorized by the account, but the sequence is highly unusual. A contextual analyzer can recognize that pattern and raise the risk level.
Behavioral Baselines and Anomaly Detection
Another interesting use is comparing current behavior to normal activity.
For example, my system might know that normal administrator activity usually involves occasional page edits and article publishing during ordinary hours.
Then it sees:
4:16 AM
Administrator authenticated
Previously unseen IP address
312 pages modified
14 PHP files uploaded
Database export initiated
Even if no traditional signature was triggered, this combination deserves immediate attention.
OpenAI can explain why the behavior differs from the expected baseline and provide an incident summary for review.
Watching File Integrity
File integrity monitoring can also become part of the system.
inotifywait \
-m \
-r \
/home/site/public_html \
-e modify,create,delete,move
If the server suddenly reports:
CREATE shell.php
CREATE wp-admin.php
MODIFY index.php
CREATE .htaccess
DELETE security.php
the combination is obviously more concerning than an ordinary content update.
The security analyzer can immediately generate a warning explaining that unexpected PHP files appeared in the public directory while important application files were simultaneously modified.
Natural Language Security Searches
Once the security events are stored, I can use OpenAI to provide natural-language reporting.
Instead of manually constructing SQL queries, I can ask:
Show me scanners from the last month that tried both WordPress paths and .env files.
Or:
Were there any successful requests from IP addresses that were later banned?
Or:
What were the most common attack patterns this week?
The AI should not receive unrestricted SQL access. Instead, it can call a controlled reporting function such as:
search_security_events
with structured arguments:
{
"start_date": "2026-08-29",
"end_date": "2026-08-30",
"minimum_risk": 70,
"event_types": [
"reconnaissance",
"credential_attack"
]
}
My application constructs and executes the SQL query. OpenAI never receives permission to execute arbitrary SQL.
Automatic Daily Security Briefings
I can also automate a daily cybersecurity summary.
0 7 * * * /usr/bin/python3 /opt/security/daily-report.py
The script can collect the previous day's security activity and ask OpenAI to identify the events that actually deserve attention.
DAILY SERVER SECURITY REPORT
Requests analyzed:
184,293
High-risk sources:
17
Automatically blocked:
12
Most common activity:
WordPress vulnerability scanning
Second most common:
Environment-file probing
Credential attacks:
3
Evidence of successful compromise:
None detected in supplied telemetry
Important event:
One address probed numerous administrative
paths and later attempted SSH authentication.
This is much more useful than manually reading thousands of individual security events.
Reducing Security Alert Fatigue
One of the biggest problems with security monitoring is alert fatigue. If every failed request generates an urgent warning, eventually the administrator stops paying attention.
AI-assisted triage can help separate events into categories such as informational, low, medium, high and critical.
if analysis["risk_score"] >= 90:
send_critical_alert()
elif analysis["risk_score"] >= 70:
add_to_security_dashboard()
else:
archive_event()
This allows email, SMS or push notifications to be reserved for events that genuinely deserve immediate attention.
Never Give the AI Root Access
One of the most important cybersecurity rules in this entire architecture is that the model should be allowed to analyze much more than it is allowed to control.
I would never tell an AI system:
Here are my server logs. Figure out what happened and execute whatever Linux commands you think are necessary.
Instead, I expose narrow functions such as:
- block_ip
- unblock_ip
- query_ip_history
- read_recent_logs
- disable_user_session
- invalidate_web_session
- quarantine_uploaded_file
- create_security_alert
The model might request:
{
"ip": "185.234.219.32",
"duration": 3600
}
My application validates it.
import ipaddress
def request_block(ip, duration):
address =
ipaddress.ip_address(ip)
if duration > 86400:
raise ValueError(
"Maximum automatic block is 24 hours."
)
create_firewall_block(
str(address),
duration
)
The AI never receives an unrestricted root shell.
Voice-to-Text With OpenAI
OpenAI can also process speech, which creates another major category of automation.
For example, a recorded voicemail can be automatically transcribed.
from openai import OpenAI
client = OpenAI()
with open("caller.wav", "rb") as audio:
transcription =
client.audio.transcriptions.create(
model="gpt-4o-transcribe",
file=audio
)
print(transcription.text)
That transcript can then be analyzed.
response = client.responses.create(
model="gpt-5",
input=f"""
Analyze this telephone message.
Extract:
caller intent,
requested service,
urgency,
unanswered questions,
and recommended follow-up.
Transcript:
{transcription.text}
"""
)
print(response.output_text)
A voicemail has now become structured business information instead of simply an audio recording sitting in a mailbox.
Text-to-Speech
The process can also work in reverse. OpenAI can turn text into spoken audio.
from openai import OpenAI
client = OpenAI()
with client.audio.speech.with_streaming_response.create(
model="gpt-4o-mini-tts",
voice="cedar",
input="""
Thank you for calling.
Tell me what kind of document
you need notarized.
"""
) as response:
response.stream_to_file(
"response.mp3"
)
That creates the basic architecture of an AI telephone assistant:
CALLER SPEAKS
|
v
SPEECH TO TEXT
|
v
OPENAI REASONING
|
v
TEXT RESPONSE
|
v
TEXT TO SPEECH
|
v
CALLER HEARS RESPONSE
Integrating OpenAI With FreePBX
This becomes particularly interesting when OpenAI is connected to Asterisk or FreePBX. I can use the same infrastructure for a customer-service assistant, an after-hours telephone system, an internal support line or an inbound anti-scam honeypot that I jokingly call a Troll Bot.
The general architecture looks like this:
INCOMING CALL
|
v
FREEPBX / ASTERISK
|
v
CUSTOM DESTINATION
|
v
RECORD CALLER
|
v
OPENAI TRANSCRIPTION
|
v
OPENAI RESPONSE
|
v
OPENAI SPEECH
|
v
ASTERISK PLAYS RESPONSE
A simplified Asterisk context might look like this:
[ai-trollbot]
exten => s,1,Answer()
same => n,Playback(custom/hello-ai)
same => n,Record(
/tmp/caller.wav,
3,
10
)
same => n,System(
/usr/bin/python3
/opt/trollbot/respond.py
/tmp/caller.wav
)
same => n,Playback(
/tmp/ai-response
)
same => n,Hangup()
The Python program can transcribe the caller.
import sys
from openai import OpenAI
client = OpenAI()
audio_file = sys.argv[1]
with open(audio_file, "rb") as f:
transcript =
client.audio.transcriptions.create(
model="gpt-4o-transcribe",
file=f
)
caller_text = transcript.text
Then OpenAI can generate a response.
reply = client.responses.create(
model="gpt-5",
instructions="""
You are an automated anti-scam
honeypot answering an inbound
telephone line.
Never request passwords,
banking information,
Social Security numbers,
authentication codes,
or other sensitive information.
Never threaten the caller.
Keep the conversation harmless.
Be slightly confused and mildly humorous.
Keep responses short.
""",
input=caller_text
)
answer = reply.output_text
The response can then be converted into speech.
with client.audio.speech.with_streaming_response.create(
model="gpt-4o-mini-tts",
voice="cedar",
input=answer
) as speech:
speech.stream_to_file(
"/tmp/ai-response.mp3"
)
The audio can then be converted into a telephony-friendly WAV file.
ffmpeg \
-y \
-i /tmp/ai-response.mp3 \
-ar 8000 \
-ac 1 \
/tmp/ai-response.wav
The Troll Bot
The Troll Bot is really an experiment in connecting telephony infrastructure to an artificial intelligence reasoning system. I use this concept only for inbound calls, anti-scam honeypots, internal testing and other lawful purposes, rather than unsolicited or harassing outbound calls.
A scam call could theoretically result in a conversation like this:
CALLER:
Hello sir, this is Microsoft Technical Support.
BOT:
Wonderful. Which Microsoft?
I have several windows in the house
and one sticks when it rains.
CALLER:
No sir, your computer Windows.
BOT:
Oh.
That makes considerably more sense.
The kitchen window does not have
a keyboard.
The joke is entertaining, but the engineering behind it is much more interesting. Asterisk has effectively become a telephone interface to an AI reasoning system.
Realtime Voice and SIP
The previous approach works by recording, transcribing, generating an answer and playing a new audio file. That can introduce noticeable latency.
A more sophisticated design uses realtime audio communication.
SIP CALL
|
v
FREEPBX
|
v
REALTIME VOICE SESSION
|
v
OPENAI
|
v
LIVE SPOKEN RESPONSE
A realtime system can detect when someone starts and stops speaking, respond with considerably lower latency and potentially allow interruption while the AI is speaking.
This produces a much more natural telephone experience than repeatedly recording complete audio clips.
Different AI Personalities for Different Extensions
Another entertaining and useful feature is giving different telephone extensions different AI instructions.
Extension 700
Professional receptionist
Extension 701
After-hours assistant
Extension 702
Spam-call honeypot
Extension 703
Internal technical support
Extension 704
Notary FAQ assistant
All of these extensions can use the same OpenAI infrastructure. Only their instructions and permitted functions need to change.
The receptionist might be allowed to check business hours and appointment availability, while the anti-scam honeypot receives no access to business functions at all.
AI personalities are easy to create. Permissions require much more careful thought.
Using OpenAI as a Classifier Before Using It as a Writer
One overlooked use of artificial intelligence is classification.
Suppose a customer writes:
I have my birth certificate and I am moving overseas and they told me it needs authentication.
Before generating any response, OpenAI can classify the request.
{
"intent": "apostille",
"confidence": 0.94,
"urgency": "normal",
"requires_human": false
}
The application now knows which workflow should handle the request.
This means customers do not need to understand the internal structure of my website. They can simply explain what they need in ordinary language.
Building AI Pipelines Instead of Giant Prompts
Another useful technique is breaking complicated work into multiple AI stages instead of using one enormous prompt.
A document-analysis pipeline might look like this:
CLASSIFY DOCUMENT
|
v
EXTRACT PEOPLE AND DATES
|
v
BUILD CHRONOLOGY
|
v
IDENTIFY INCONSISTENCIES
|
v
CREATE RESEARCH QUESTIONS
|
v
GENERATE FINAL REPORT
A publishing workflow can operate similarly:
DRAFT ARTICLE
|
v
GRAMMAR ANALYSIS
|
v
SEO ANALYSIS
|
v
FACT CLAIM IDENTIFICATION
|
v
METADATA GENERATION
|
v
INTERNAL LINK SUGGESTIONS
|
v
HUMAN REVIEW
|
v
PUBLISH
Breaking work into separate stages makes the system easier to test, debug and improve.
Separate AI Judgment From Database Truth
This is one of the most important lessons in building reliable OpenAI applications.
Artificial intelligence is excellent for questions such as:
- What does this person probably mean?
- What category does this belong to?
- What information appears to be missing?
- How should this be explained?
- Which part of these records appears relevant?
- What should I investigate next?
- How can this information be summarized?
Artificial intelligence should not be treated as the authoritative source for transactional information such as:
- What did this customer pay?
- When is the appointment?
- What is the current service price?
- Was an invoice actually paid?
- What permissions does this user currently have?
Those answers belong in the database.
The model interprets the question. My application retrieves the truth.
Privacy and Security Are Part of the Architecture
Any system that analyzes medical records, legal documents, business records or security logs needs to be designed with privacy in mind from the beginning.
I do not need to send an entire user profile when only one document is relevant. Temporary uploads should be deleted when they are no longer required. Sensitive documents should not appear in ordinary debug logs. API keys should remain on the server. Public and private knowledge collections should remain separated.
The same principle applies to cybersecurity. OpenAI may be able to analyze server logs, but that does not mean the model should automatically receive every credential, session token, secret key or configuration value contained in those logs.
Before logs are submitted for analysis, sensitive data can be redacted or normalized where practical.
What OpenAI Really Turns My Websites Into
Once these systems are combined, OpenAI stops being a novelty.
AlexanderMirvis.com can become an AI-assisted publishing, research and cybersecurity platform. Articles can be generated, reviewed, summarized, translated, scored and given metadata. Uploaded documents can become timelines and reports. The custom CMS can monitor its own security events. Server logs can be analyzed automatically and suspicious activity can be summarized into security incidents.
BrooklynNotaryNinjas.com can become an AI-assisted business platform. The chatbot can answer questions using controlled company knowledge, retrieve live information from databases, classify customer requests, explain procedures, assist with uploaded documents and route people toward the correct service.
The same OpenAI infrastructure can extend into FreePBX. Telephone speech becomes text, the model determines what the caller means, approved functions can retrieve information, and the resulting answer can be spoken back to the caller.
Meanwhile, the cybersecurity system can continually examine what is happening behind the scenes. Web server logs, CMS events, SSH activity, firewall actions, application errors and file changes can all contribute to a larger picture of server security.
The most important lesson is that OpenAI should not control everything.
OpenAI interprets. My application decides.
OpenAI reasons. My database remains authoritative.
OpenAI proposes actions. My server decides whether those actions are permitted.
OpenAI analyzes security events. My security policy decides whether something is blocked.
OpenAI generates content. My CMS decides what gets published.
That is where the OpenAI API becomes genuinely powerful.
It is not simply ChatGPT placed inside a website.
It becomes a reasoning layer sitting between human language, documents, databases, websites, telephone systems, cybersecurity tools and ordinary software.
Once I started treating OpenAI that way, the possibilities became much larger than simply asking an AI to write something. It became a tool that can help operate, analyze, automate and protect the systems themselves.