Size
8.6 KB
Version
1.2.1
Created
Jan 11, 2026
Updated
24 days ago
1// ==UserScript==
2// @name Bing Search Automation
3// @description Automate Bing searches with customizable search terms and intervals
4// @version 1.2.1
5// @match https://*.bing.com/*
6// @icon https://www.bing.com/sa/simg/favicon-trans-bg-blue-mg-png.png
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 // Default search terms
12 const DEFAULT_SEARCH_TERMS = [
13 'weather today',
14 'news headlines',
15 'technology updates',
16 'sports scores',
17 'movie reviews',
18 'recipe ideas',
19 'travel destinations',
20 'health tips',
21 'science news',
22 'book recommendations'
23 ];
24
25 // Configuration
26 let isRunning = false;
27 let currentSearchIndex = 0;
28 let searchInterval = null;
29
30 // Initialize the extension
31 async function init() {
32 console.log('Bing Search Automation initialized');
33
34 // Load saved state
35 const savedState = await GM.getValue('automationState', {
36 isRunning: false,
37 searchTerms: DEFAULT_SEARCH_TERMS,
38 intervalSeconds: 10,
39 currentIndex: 0
40 });
41
42 // Create control panel
43 createControlPanel(savedState);
44 }
45
46 // Create the control panel UI
47 function createControlPanel(state) {
48 const panel = document.createElement('div');
49 panel.id = 'search-automation-panel';
50 panel.style.cssText = `
51 position: fixed;
52 top: 20px;
53 right: 20px;
54 background: white;
55 border: 2px solid #0078d4;
56 border-radius: 8px;
57 padding: 15px;
58 box-shadow: 0 4px 12px rgba(0,0,0,0.15);
59 z-index: 10000;
60 min-width: 300px;
61 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
62 `;
63
64 panel.innerHTML = `
65 <div style="margin-bottom: 15px;">
66 <h3 style="margin: 0 0 10px 0; color: #0078d4; font-size: 16px;">🔍 Search Automation</h3>
67 <div style="margin-bottom: 10px;">
68 <label style="display: block; margin-bottom: 5px; font-size: 12px; color: #333;">Interval (seconds):</label>
69 <input type="number" id="interval-input" value="${state.intervalSeconds}" min="5" max="300"
70 style="width: 100%; padding: 5px; border: 1px solid #ccc; border-radius: 4px;">
71 </div>
72 <div style="margin-bottom: 10px;">
73 <label style="display: block; margin-bottom: 5px; font-size: 12px; color: #333;">Search Terms (one per line):</label>
74 <textarea id="search-terms-input" rows="6"
75 style="width: 100%; padding: 5px; border: 1px solid #ccc; border-radius: 4px; font-size: 12px; resize: vertical;">${state.searchTerms.join('\n')}</textarea>
76 </div>
77 <div style="display: flex; gap: 10px; margin-bottom: 10px;">
78 <button id="start-btn" style="flex: 1; padding: 8px; background: #0078d4; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold;">
79 ▶ Start
80 </button>
81 <button id="stop-btn" style="flex: 1; padding: 8px; background: #d13438; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold;" disabled>
82 ⏸ Stop
83 </button>
84 </div>
85 <div style="font-size: 11px; color: #666; padding: 8px; background: #f5f5f5; border-radius: 4px;">
86 <div>Status: <span id="status-text" style="font-weight: bold; color: #666;">Stopped</span></div>
87 <div>Searches: <span id="search-count" style="font-weight: bold;">0</span> / <span id="total-searches">0</span></div>
88 <div>Next: <span id="next-search" style="font-style: italic;">-</span></div>
89 </div>
90 </div>
91 `;
92
93 document.body.appendChild(panel);
94
95 // Add event listeners
96 const startBtn = document.getElementById('start-btn');
97 const stopBtn = document.getElementById('stop-btn');
98 const intervalInput = document.getElementById('interval-input');
99 const searchTermsInput = document.getElementById('search-terms-input');
100
101 startBtn.addEventListener('click', async () => {
102 const interval = parseInt(intervalInput.value);
103 const terms = searchTermsInput.value.split('\n').filter(t => t.trim());
104
105 if (terms.length === 0) {
106 alert('Please enter at least one search term');
107 return;
108 }
109
110 await startAutomation(terms, interval);
111 startBtn.disabled = true;
112 stopBtn.disabled = false;
113 intervalInput.disabled = true;
114 searchTermsInput.disabled = true;
115 });
116
117 stopBtn.addEventListener('click', async () => {
118 await stopAutomation();
119 startBtn.disabled = false;
120 stopBtn.disabled = true;
121 intervalInput.disabled = false;
122 searchTermsInput.disabled = false;
123 });
124
125 // Update total searches count
126 updateTotalSearches();
127 }
128
129 // Start the automation
130 async function startAutomation(searchTerms, intervalSeconds) {
131 console.log('Starting search automation with', searchTerms.length, 'terms');
132
133 isRunning = true;
134 currentSearchIndex = 0;
135
136 // Save state
137 await GM.setValue('automationState', {
138 isRunning: true,
139 searchTerms: searchTerms,
140 intervalSeconds: intervalSeconds,
141 currentIndex: 0
142 });
143
144 updateStatus('Running', '#0078d4');
145 updateTotalSearches();
146
147 // Perform first search immediately
148 await performSearch(searchTerms[currentSearchIndex]);
149 currentSearchIndex++;
150
151 // Set up interval for subsequent searches
152 searchInterval = setInterval(async () => {
153 if (currentSearchIndex >= searchTerms.length) {
154 console.log('All searches completed');
155 await stopAutomation();
156 return;
157 }
158
159 await performSearch(searchTerms[currentSearchIndex]);
160 currentSearchIndex++;
161 }, intervalSeconds * 1000);
162 }
163
164 // Stop the automation
165 async function stopAutomation() {
166 console.log('Stopping search automation');
167
168 isRunning = false;
169 if (searchInterval) {
170 clearInterval(searchInterval);
171 searchInterval = null;
172 }
173
174 await GM.setValue('automationState', {
175 isRunning: false,
176 searchTerms: DEFAULT_SEARCH_TERMS,
177 intervalSeconds: 10,
178 currentIndex: 0
179 });
180
181 updateStatus('Stopped', '#666');
182 document.getElementById('next-search').textContent = '-';
183 }
184
185 // Perform a single search
186 async function performSearch(searchTerm) {
187 console.log('Performing search:', searchTerm);
188
189 // Navigate to search URL
190 const searchUrl = `https://www.bing.com/search?q=${encodeURIComponent(searchTerm)}`;
191 window.location.href = searchUrl;
192
193 // Update UI
194 const searchCount = document.getElementById('search-count');
195 if (searchCount) {
196 searchCount.textContent = currentSearchIndex + 1;
197 }
198
199 // Update next search preview
200 const state = await GM.getValue('automationState');
201 if (state && currentSearchIndex + 1 < state.searchTerms.length) {
202 document.getElementById('next-search').textContent = state.searchTerms[currentSearchIndex + 1];
203 } else {
204 document.getElementById('next-search').textContent = 'Complete';
205 }
206 }
207
208 // Update status display
209 function updateStatus(text, color) {
210 const statusText = document.getElementById('status-text');
211 if (statusText) {
212 statusText.textContent = text;
213 statusText.style.color = color;
214 }
215 }
216
217 // Update total searches count
218 function updateTotalSearches() {
219 const searchTermsInput = document.getElementById('search-terms-input');
220 const totalSearches = document.getElementById('total-searches');
221 if (searchTermsInput && totalSearches) {
222 const terms = searchTermsInput.value.split('\n').filter(t => t.trim());
223 totalSearches.textContent = terms.length;
224 }
225 }
226
227 // Wait for page to load
228 if (document.readyState === 'loading') {
229 document.addEventListener('DOMContentLoaded', init);
230 } else {
231 init();
232 }
233})();