DTV News & Visa Updates
Migrify โ Header Thailand DTV Visa Specialists Home Audio Help Point Eligibility Checker Our Services Our DTV Visa Programmes Translation
<!-- Thailand DTV AI Chatbot Widget -->
<div id="dtv-chat-widget" style="position: fixed; bottom: 20px; right: 20px; z-index: 9999; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;">
<!-- Chat Button Trigger -->
<button id="dtv-chat-trigger" style="width: 60px; height: 60px; border-radius: 30px; background: linear-gradient(135deg, #f59e0b, #d97706); border: none; cursor: pointer; box-shadow: 0 4px 20px rgba(217, 119, 6, 0.3); display: flex; align-items: center; justify-content: center; transition: all 0.3s ease;">
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
</button>
<!-- Chat Window (Hidden by Default) -->
<div id="dtv-chat-window" style="display: none; width: 380px; height: 500px; border-radius: 16px; background: #0f172a; border: 1px solid #1e293b; box-shadow: 0 10px 30px rgba(0,0,0,0.5); flex-direction: column; position: absolute; bottom: 80px; right: 0; overflow: hidden; transition: all 0.3s ease;">
<!-- Header -->
<div style="background: #1e293b; padding: 16px; display: flex; align-items: center; justify-content: space-between; border-b: 1px solid #334155;">
<div style="display: flex; align-items: center; gap: 10px;">
<span style="font-size: 20px;">
</span>
<div>
<h4 style="margin: 0; color: #fff; font-size: 14px; font-weight: bold;">DTV AI Assistant</h4>
<span style="font-size: 10px; color: #10b981; display: flex; align-items: center; gap: 4px;">
<span style="width: 6px; height: 6px; background: #10b981; border-radius: 50%; display: inline-block;"></span> Online
</span>
</div>
</div>
<button id="dtv-chat-close" style="background: none; border: none; color: #94a3b8; cursor: pointer; font-size: 18px;">×</button>
</div>
<!-- Messages Container -->
<div id="dtv-chat-messages" style="flex: 1; padding: 16px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; background: #090d16;">
<div style="align-self: flex-start; background: #1e293b; color: #cbd5e1; padding: 10px 14px; border-radius: 12px 12px 12px 0; font-size: 13px; max-width: 80%; line-height: 1.4;">
Sawasdee khrap! Welcome to the Thailand DTV Visa Portal. I am your specialized AI Assistant. How can I assist you with your 5-year Destination Thailand Visa (DTV) today?
</div>
</div>
<!-- Input Area -->
<div style="padding: 12px; border-top: 1px solid #1e293b; display: flex; gap: 8px; background: #0f172a;">
<input id="dtv-chat-input" type="text" placeholder="Ask about costs, 500k THB proof, stay rules..." style="flex: 1; padding: 10px 14px; border-radius: 8px; border: 1px solid #334155; background: #020617; color: #fff; font-size: 13px; outline: none;" />
<button id="dtv-chat-send" style="background: #d97706; border: none; border-radius: 8px; padding: 0 14px; cursor: pointer; display: flex; align-items: center; justify-content: center;">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
</button>
</div>
</div>
</div>
<script>
(function() {
const trigger = document.getElementById('dtv-chat-trigger');
const windowEl = document.getElementById('dtv-chat-window');
const closeBtn = document.getElementById('dtv-chat-close');
const sendBtn = document.getElementById('dtv-chat-send');
const inputEl = document.getElementById('dtv-chat-input');
const messagesContainer = document.getElementById('dtv-chat-messages');
// Create a stable session ID for the browser session
let sessionId = sessionStorage.getItem('dtv_chat_session_id');
if (!sessionId) {
sessionId = 'web_' + Math.random().toString(36).substring(2, 11);
sessionStorage.setItem('dtv_chat_session_id', sessionId);
}
let chatHistory = [];
// Toggle Chat Window
trigger.addEventListener('click', () => {
const isHidden = windowEl.style.display === 'none';
windowEl.style.display = isHidden ? 'flex' : 'none';
if (isHidden) inputEl.focus();
});
closeBtn.addEventListener('click', () => {
windowEl.style.display = 'none';
});
// Send Message logic
async function sendMessage() {
const text = inputEl.value.trim();
if (!text) return;
inputEl.value = '';
// Render User Message
appendMessage(text, 'user');
// Render typing loader
const loaderId = appendTypingIndicator();
try {
const response = await fetch('https://ais-pre-ua5vfaf4oipf7xysfyk33p-867092543159.asia-southeast1.run.app/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sessionId: sessionId,
message: text,
history: chatHistory
})
});
const data = await response.json();
removeTypingIndicator(loaderId);
if (data.reply) {
appendMessage(data.reply, 'model');
chatHistory.push({ role: 'user', text: text });
chatHistory.push({ role: 'model', text: data.reply });
} else {
appendMessage("I am having trouble connecting to the service. Please try again.", 'model');
}
} catch (err) {
removeTypingIndicator(loaderId);
appendMessage("Connection error. Please try again.", 'model');
}
}
sendBtn.addEventListener('click', sendMessage);
inputEl.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
function appendMessage(text, sender) {
const div = document.createElement('div');
div.style.alignSelf = sender === 'user' ? 'flex-end' : 'flex-start';
div.style.background = sender === 'user' ? '#d97706' : '#1e293b';
div.style.color = sender === 'user' ? '#000' : '#cbd5e1';
div.style.fontWeight = sender === 'user' ? '600' : 'normal';
div.style.padding = '10px 14px';
div.style.borderRadius = sender === 'user' ? '12px 12px 0 12px' : '12px 12px 12px 0';
div.style.fontSize = '13px';
div.style.maxWidth = '80%';
div.style.lineHeight = '1.4';
div.style.wordBreak = 'break-word';
div.innerText = text;
messagesContainer.appendChild(div);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}
function appendTypingIndicator() {
const id = 'loader_' + Date.now();
const div = document.createElement('div');
div.id = id;
div.style.alignSelf = 'flex-start';
div.style.background = '#1e293b';
div.style.color = '#94a3b8';
div.style.padding = '10px 14px';
div.style.borderRadius = '12px 12px 12px 0';
div.style.fontSize = '12px';
div.innerText = "DTV Assistant is typing...";
messagesContainer.appendChild(div);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
return id;
}
function removeTypingIndicator(id) {
const el = document.getElementById(id);
if (el) el.remove();
}
})();
</script>
Please ensure that the information you upload here is correct as requested โ one small mistake can result in consular services rejecting your application.
Please note: Migrify can only validate the information we receive from you.