πŸ“ŠAI Twitter Thread Maker

Create viral Twitter threads instantly with AI! Generate engaging, SEO-optimized threads with viral hooks, emoji integration, and real-time character counting. No login required - start creating viral content now!

πŸ€” What Is a Twitter Thread Generator?

Think of a Twitter thread like a digital storytelling staircase - each tweet leads perfectly to the next! This AI tool transforms your ideas into engaging, viral-ready Twitter threads complete with hooks, emojis, and perfect character counts. No more struggling to break up your thoughts or losing followers mid-story!

πŸ”₯ Viral Thread Templates

⚑ Productivity Tips
10 habits that changed my life in 90 days
πŸ’Ό Business Lessons
5 mistakes I made building my startup
πŸ’» Tech Insights
Why AI will change everything in 2025
🌟 Personal Growth
How I overcame fear and built confidence
πŸ“ˆ Marketing Strategy
7 growth hacks that got me 10K followers
πŸ’° Finance Tips
How to save $10K in 12 months
${formatTweetContent(tweet)}
πŸ’¬ ${Math.floor(Math.random() * 50)} πŸ” ${Math.floor(Math.random() * 100)} ❀️ ${Math.floor(Math.random() * 200)} πŸ“Š ${Math.floor(Math.random() * 1000)}
`; previewContainer.appendChild(tweetDiv); }); } function formatTweetContent(content) { return content .replace(/(#\w+)/g, '$1') .replace(/(@\w+)/g, '$1') .replace(/(https?:\/\/[^\s]+)/g, '$1'); } function updateTweetPreview(index) { const input = document.getElementById(`tweet-${index}`); if (input) { currentThread[index] = input.value; updateCharCounter(index); updateThreadPreview(); updateAnalytics(); } } function updateCharCounter(index) { const input = document.getElementById(`tweet-${index}`); const counter = document.getElementById(`counter-${index}`); if (input && counter) { const length = input.value.length; counter.textContent = `${length}/280`; if (length > 280) { counter.className = 'char-counter error'; } else if (length > 250) { counter.className = 'char-counter warning'; } else { counter.className = 'char-counter'; } } } function updateAnalytics() { const totalChars = currentThread.reduce((sum, tweet) => sum + tweet.length, 0); const avgChars = Math.round(totalChars / currentThread.length); const emojiCount = currentThread.join('').match(/[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu)?.length || 0; const hashtagCount = currentThread.join('').match(/#\w+/g)?.length || 0; // Calculate viral score based on various factors const viralScore = calculateViralScore(); document.getElementById('totalChars').textContent = totalChars; document.getElementById('avgChars').textContent = avgChars; document.getElementById('emojiCount').textContent = emojiCount; document.getElementById('hashtagCount').textContent = hashtagCount; document.getElementById('engagementScore').textContent = viralScore; } function calculateViralScore() { let score = 0; // Thread length optimization (5-7 tweets ideal) const length = currentThread.length; if (length >= 5 && length <= 7) score += 25; else if (length >= 3 && length <= 10) score += 15; else score += 5; // Hook quality (first tweet) const firstTweet = currentThread[0] || ''; if (firstTweet.includes('?')) score += 10; if (firstTweet.length < 240) score += 10; if (/^\d+/.test(firstTweet) || firstTweet.includes('thread')) score += 15; // Engagement elements const allText = currentThread.join(' '); if (allText.includes('?')) score += 10; if (allText.includes('!')) score += 5; if (allText.match(/#\w+/g)?.length > 0) score += 10; if (allText.match(/[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]/gu)?.length > 3) score += 15; // Structure bonus if (currentThread.some(tweet => /^\d+\//.test(tweet))) score += 15; return Math.min(score, 100); } function addTweet() { currentThread.push('New tweet content...'); displayThreadEditor(); updateThreadPreview(); updateAnalytics(); } // ========== EXPORT FUNCTIONS ========== function copyThread() { const threadText = currentThread.map((tweet, index) => `${index + 1}/${currentThread.length}\n${tweet}`).join('\n\n'); navigator.clipboard.writeText(threadText).then(() => { document.getElementById('exportStatus').textContent = 'Thread copied to clipboard!'; showNotification('Thread copied successfully!', 'success'); }).catch(() => { // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = threadText; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); document.getElementById('exportStatus').textContent = 'Thread copied to clipboard!'; showNotification('Thread copied successfully!', 'success'); }); } function exportToJSON() { const threadData = { topic: document.getElementById('threadTopic').value, createdAt: new Date().toISOString(), tweets: currentThread, analytics: { totalChars: currentThread.reduce((sum, tweet) => sum + tweet.length, 0), avgChars: Math.round(currentThread.reduce((sum, tweet) => sum + tweet.length, 0) / currentThread.length), emojiCount: currentThread.join('').match(/[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]/gu)?.length || 0, hashtagCount: currentThread.join('').match(/#\w+/g)?.length || 0, viralScore: calculateViralScore() } }; const blob = new Blob([JSON.stringify(threadData, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `twitter-thread-${Date.now()}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); document.getElementById('exportStatus').textContent = 'Thread exported as JSON!'; showNotification('Thread exported successfully!', 'success'); } // ========== SAMPLE FUNCTIONS ========== function useSample(sampleType) { const template = THREAD_TEMPLATES[sampleType]; if (!template) return; document.getElementById('threadTopic').value = template.topic; // Set appropriate thread length document.getElementById('threadLength').value = template.content.length + 2; // +2 for hook and CTA // Auto-generate with template setTimeout(() => generateThread(), 100); // Smooth scroll to generator document.getElementById('generateBtn').scrollIntoView({ behavior: 'smooth', block: 'center' }); } // ========== UTILITY FUNCTIONS ========== // Show notification toast function showNotification(message, type = 'success') { const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.remove(); }, 3000); } // Show OTA section function showOTA() { const otaContainer = document.getElementById('otaContainer'); if (otaContainer && (otaContainer.style.display === 'none' || !otaContainer.style.display)) { otaContainer.style.display = 'block'; // Update message for content creators const otaHeader = document.querySelector('.ota-header h3'); const otaText = document.querySelector('.ota-header p'); if (otaHeader && otaText) { otaHeader.textContent = '🌟 Ready to Share Your Viral Content?'; otaText.textContent = 'Planning to travel for content creation or business meetings? Find the best deals worldwide!'; } } } // Analytics tracking function trackEvent(eventName, data = {}) { if (typeof gtag !== 'undefined') { gtag('event', eventName, { 'event_category': TOOL_CONFIG.category, 'event_label': TOOL_CONFIG.name, ...data }); } } // ========== AI ASSISTANT FUNCTIONS ========== // AI λͺ¨λ‹¬ μ—΄κΈ° function openAIModal() { const modal = document.getElementById('aiModal'); if(modal) modal.classList.add('show'); if (aiModalState.apiKey && aiModalState.currentView === 'gemini') { showGeminiChat(); } else { showAISelector(); } updateAPIKeyStatus(); } // AI λͺ¨λ‹¬ λ‹«κΈ° function closeAIModal() { const modal = document.getElementById('aiModal'); if(modal) modal.classList.remove('show'); setTimeout(() => { aiModalState.currentView = 'selector'; showAISelector(); }, 300); } // AI 선택 ν™”λ©΄ ν‘œμ‹œ function showAISelector() { document.getElementById('aiModalTitle').textContent = 'Choose Your AI Assistant'; document.getElementById('aiSelector').style.display = 'flex'; document.getElementById('geminiChat').style.display = 'none'; document.getElementById('apiKeySetup').style.display = 'none'; aiModalState.currentView = 'selector'; } // Gemini μ±„νŒ… ν™”λ©΄ ν‘œμ‹œ function showGeminiChat() { document.getElementById('aiModalTitle').innerHTML = '✨ Gemini AI Assistant'; document.getElementById('aiSelector').style.display = 'none'; document.getElementById('geminiChat').style.display = 'flex'; document.getElementById('apiKeySetup').style.display = 'none'; aiModalState.currentView = 'gemini'; const chatMessages = document.getElementById('chatMessages'); if (!chatMessages.innerHTML.trim()) { addMessage('assistant', `Hello! I can help you with: β€’ Creating viral Twitter thread ideas β€’ Improving your thread engagement β€’ Optimizing content for different audiences β€’ Finding trending topics in your niche β€’ Writing compelling hooks and CTAs What would you like help with for your Twitter threads?`); } } // API ν‚€ μ„€μ • ν™”λ©΄ ν‘œμ‹œ function showAPIKeySetup() { document.getElementById('aiModalTitle').textContent = 'Setup Gemini API'; document.getElementById('aiSelector').style.display = 'none'; document.getElementById('geminiChat').style.display = 'none'; document.getElementById('apiKeySetup').style.display = 'block'; aiModalState.currentView = 'setup'; } // AI 선택 처리 function selectAI(aiType) { switch(aiType) { case 'chatgpt': const toolContext = `I need help creating viral Twitter threads. I'm using a Twitter Thread Maker tool and want to improve my content strategy and engagement.`; const chatUrl = `https://chat.openai.com/?q=${encodeURIComponent(toolContext)}`; window.open(chatUrl, '_blank'); closeAIModal(); trackEvent('ai_selection', { ai_type: 'chatgpt' }); break; case 'claude': const claudeContext = `I need help creating viral Twitter threads. I'm using a Twitter Thread Maker tool and want to improve my content strategy and engagement.`; const claudeUrl = `https://claude.ai/chat?q=${encodeURIComponent(claudeContext)}`; window.open(claudeUrl, '_blank'); closeAIModal(); trackEvent('ai_selection', { ai_type: 'claude' }); break; case 'gemini': if (!aiModalState.apiKey) { showAPIKeySetup(); } else { showGeminiChat(); } trackEvent('ai_selection', { ai_type: 'gemini' }); break; } } // API ν‚€ μ €μž₯ function saveGeminiApiKey() { const apiKey = document.getElementById('geminiApiKeyInput').value.trim(); if (apiKey) { localStorage.setItem('geminiApiKey', apiKey); aiModalState.apiKey = apiKey; showGeminiChat(); updateAPIKeyStatus(); } else { alert('Please enter a valid API key'); } } // API ν‚€ μƒνƒœ μ—…λ°μ΄νŠΈ function updateAPIKeyStatus() { const statusEl = document.getElementById('apiKeyStatus'); if (aiModalState.apiKey) { statusEl.innerHTML = 'Change API Key'; } else { statusEl.textContent = 'No API key set'; } } // μ±„νŒ… λ©”μ‹œμ§€ μΆ”κ°€ function addMessage(type, content) { const chatMessages = document.getElementById('chatMessages'); const messageDiv = document.createElement('div'); messageDiv.className = `message ${type}`; if (type === 'user') { messageDiv.innerHTML = `You: ${content}`; } else { messageDiv.innerHTML = `✨ Gemini:
${content.replace(/\n/g, '
')}`; } chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } // Gemini에 λ©”μ‹œμ§€ 전솑 async function sendToGemini() { const input = document.getElementById('geminiInput'); const message = input.value.trim(); if (!message) return; addMessage('user', message); input.value = ''; const loadingMsg = document.createElement('div'); loadingMsg.className = 'message assistant'; loadingMsg.innerHTML = '✨ Gemini:
Thinking...'; loadingMsg.id = 'loading-message'; document.getElementById('chatMessages').appendChild(loadingMsg); try { const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${aiModalState.apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ contents: [{ parts: [{ text: `Context: User is using a Twitter Thread Maker tool to create viral content. Help them with: - Thread ideas and viral hooks - Content optimization for engagement - Twitter best practices and strategy - Trending topics and hashtag suggestions - Writing compelling openings and CTAs Current thread topic: "${document.getElementById('threadTopic').value || 'Not set'}" User question: ${message}` }] }], generationConfig: { temperature: 0.7, maxOutputTokens: 1000 } }) }); const data = await response.json(); document.getElementById('loading-message').remove(); if (data.candidates && data.candidates[0] && data.candidates[0].content) { const reply = data.candidates[0].content.parts[0].text; addMessage('assistant', reply); } else { addMessage('assistant', 'Sorry, I could not generate a response. Please try again.'); } } catch (error) { document.getElementById('loading-message')?.remove(); if (error.message.includes('API key')) { addMessage('error', 'Invalid API key. Please check your API key and try again.'); showAPIKeySetup(); } else { addMessage('error', 'Failed to connect to Gemini. Please check your internet connection and try again.'); } } } // ========== EVENT LISTENERS ========== document.addEventListener('DOMContentLoaded', function() { // Thread topic enter key const topicInput = document.getElementById('threadTopic'); if (topicInput) { topicInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { generateThread(); } }); } // AI λ²„νŠΌ 이벀트 document.getElementById('aiBtn').addEventListener('click', openAIModal); // λͺ¨λ‹¬ μ™ΈλΆ€ ν΄λ¦­μ‹œ λ‹«κΈ° document.getElementById('aiModal').addEventListener('click', function(e) { if (e.target === this) { closeAIModal(); } }); // μ—”ν„° ν‚€ 지원 및 ESC ν‚€λ‘œ λͺ¨λ‹¬ λ‹«κΈ° document.addEventListener('keydown', function(e) { if (e.key === 'Enter') { const geminiInput = document.getElementById('geminiInput'); if (document.activeElement === geminiInput) { sendToGemini(); } } if (e.key === 'Escape') { closeAIModal(); } }); updateAPIKeyStatus(); updateCurrentYear(); updateToolCount(); }); // ========== DYNAMIC TOOL COUNT ========== async function updateToolCount() { try { const response = await fetch('/api/tool-count.php'); const data = await response.json(); document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${data.count}+ free online tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${data.count}+ ${suffix}`; }); } catch (error) { const fallbackCount = 333; document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${fallbackCount}+ free online tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${fallbackCount}+ ${suffix}`; }); } } function updateCurrentYear() { const currentYear = new Date().getFullYear(); document.querySelectorAll('.current-year').forEach(el => { el.textContent = currentYear; }); } // ========== ANALYTICS ========== window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXX'); trackEvent('page_view', { tool: TOOL_CONFIG.name, category: TOOL_CONFIG.category });