132 lines
6.0 KiB
HTML
132 lines
6.0 KiB
HTML
{% extends 'base.html' %}
|
|
|
|
{% block title %}Bot Settings - WhatsApp AI Bot{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-8">
|
|
|
|
<!-- Pairing Mode Section -->
|
|
<div class="card p-4 mb-4 border-primary shadow-sm">
|
|
<h5 class="fw-bold text-primary mb-3"><i class="bi bi-phone me-2"></i>Link Personal WhatsApp</h5>
|
|
<p class="small text-muted mb-3">
|
|
Connect your existing WhatsApp account using the <b>Link Device</b> feature.
|
|
Enter your number below to generate a pairing code.
|
|
</p>
|
|
|
|
<div class="input-group mb-3">
|
|
<input type="text" id="pairingPhone" class="form-control" placeholder="Phone Number (e.g. 15551234567)">
|
|
<button class="btn btn-dark" type="button" onclick="getPairingCode()">Get Pairing Code</button>
|
|
</div>
|
|
|
|
<div id="pairingCodeDisplay" class="alert alert-success d-none text-center">
|
|
<span class="text-muted small d-block mb-1">Enter this code on your phone (WhatsApp > Linked Devices > Link with phone number):</span>
|
|
<h2 class="fw-bold font-monospace letter-spacing-2" id="codeValue" style="letter-spacing: 5px;">----</h2>
|
|
</div>
|
|
<div id="pairingError" class="alert alert-danger d-none small"></div>
|
|
</div>
|
|
|
|
<div class="card p-4 shadow-sm">
|
|
<h2 class="fw-bold mb-4">AI Bot Configuration</h2>
|
|
<form method="POST">
|
|
{% csrf_token %}
|
|
|
|
<h5 class="mb-3 text-secondary">🤖 Personality</h5>
|
|
<div class="mb-4">
|
|
<label class="form-label fw-600">System Instruction (Prompt)</label>
|
|
<textarea name="system_prompt" class="form-control" rows="5" placeholder="Define how the AI should behave...">{{ settings.system_prompt }}</textarea>
|
|
<div class="form-text mt-2">
|
|
This instruction defines the bot's tone, personality, and knowledge limits.
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<h5 class="mb-3 text-secondary">🔌 Meta Connection (Official API)</h5>
|
|
<p class="small text-muted">Use these settings only if you are <b>not</b> using the pairing mode above.</p>
|
|
<div class="mb-3">
|
|
<label class="form-label fw-600">Verification Token</label>
|
|
<input type="text" name="verify_token" class="form-control" value="{{ settings.verify_token }}">
|
|
<div class="form-text">
|
|
Use this arbitrary string when verifying the webhook in the Meta Portal.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-600">Phone Number ID</label>
|
|
<input type="text" name="whatsapp_phone_number_id" class="form-control" value="{{ settings.whatsapp_phone_number_id|default:'' }}" placeholder="e.g. 100609346...">
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-600">Access Token</label>
|
|
<input type="password" name="whatsapp_access_token" class="form-control" value="{{ settings.whatsapp_access_token|default:'' }}" placeholder="Meta Graph API Token">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-check form-switch mb-4 mt-3">
|
|
<input class="form-check-input" type="checkbox" name="is_active" id="activeSwitch" {% if settings.is_active %}checked{% endif %}>
|
|
<label class="form-check-label fw-600" for="activeSwitch">Enable Auto-Reply</label>
|
|
</div>
|
|
|
|
<hr>
|
|
|
|
<div class="d-flex justify-content-between">
|
|
<a href="{% url 'index' %}" class="btn btn-light">Back to Dashboard</a>
|
|
<button type="submit" class="btn btn-primary px-4">Save Changes</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="card mt-4 p-4 border-info bg-info bg-opacity-10">
|
|
<h5><i class="bi bi-info-circle me-2"></i>Setup Tip</h5>
|
|
<p class="mb-0 small text-dark">
|
|
Your Webhook URL: <code>https://{{ request.get_host }}/webhook/whatsapp/</code><br>
|
|
Verification Token: <code>{{ settings.verify_token }}</code>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
async function getPairingCode() {
|
|
const btn = document.querySelector('button[onclick="getPairingCode()"]');
|
|
const input = document.getElementById('pairingPhone');
|
|
const display = document.getElementById('pairingCodeDisplay');
|
|
const codeVal = document.getElementById('codeValue');
|
|
const errorBox = document.getElementById('pairingError');
|
|
|
|
btn.disabled = true;
|
|
btn.innerText = "Requesting...";
|
|
errorBox.classList.add('d-none');
|
|
display.classList.add('d-none');
|
|
|
|
const formData = new FormData();
|
|
formData.append('phone_number', input.value);
|
|
|
|
try {
|
|
const res = await fetch("{% url 'get_pairing_code' %}", {
|
|
method: 'POST',
|
|
body: formData
|
|
});
|
|
const data = await res.json();
|
|
|
|
if (res.ok) {
|
|
codeVal.innerText = data.code;
|
|
display.classList.remove('d-none');
|
|
// Reload page or update UI to show "Bridge Connected"?
|
|
// For now just show the code.
|
|
} else {
|
|
errorBox.innerText = data.error || "Failed to get code";
|
|
errorBox.classList.remove('d-none');
|
|
}
|
|
} catch (e) {
|
|
errorBox.innerText = "Connection error. Ensure the internal Bridge Service is running.";
|
|
errorBox.classList.remove('d-none');
|
|
} finally {
|
|
btn.disabled = false;
|
|
btn.innerText = "Get Pairing Code";
|
|
}
|
|
}
|
|
</script>
|
|
{% endblock %}
|