-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
157 lines (129 loc) · 5.01 KB
/
Copy pathserver.js
File metadata and controls
157 lines (129 loc) · 5.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
const express = require("express");
const { exec } = require("child_process");
const { chromium } = require("playwright-extra");
const stealthPlugin = require("puppeteer-extra-plugin-stealth")();
const cors = require("cors");
chromium.use(stealthPlugin);
const app = express();
app.use(cors());
const port = 3000;
// Middleware to parse JSON body
app.use(express.json());
let clients = [];
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
app.get("/events", (req, res) => {
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
// 将当前客户端添加到列表
clients.push(res);
// 客户端关闭连接时,从列表中移除
req.on("close", () => {
clients = clients.filter((client) => client !== res);
});
});
// 发送消息给所有连接的客户端
function sendEvent(message) {
clients.forEach((client) => {
client.write(`data: ${JSON.stringify(message)}\n\n`);
});
}
// The command to launch Chrome with a remote debugging port and a dedicated user data directory
const launchChromeCommand = `'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' --remote-debugging-port=9222 --user-data-dir='./chrome-dev-session'`;
app.post("/launch", async (req, res) => {
const usersString = req.body.users; // Assume users sent as { "users": "@jjj @kkk ..." }
const message = req.body.message;
sendEvent({ message: "开始执行" });
// Split the incoming string by spaces and filter out the @ symbols
const users = usersString
.split(" ")
.map((user) => user.replace("@", "").trim())
.filter((user) => user);
console.log("Users to process:", users);
const chunks = [];
for (let i = 0; i < users.length; i += 3) {
chunks.push(users.slice(i, i + 3));
}
try {
// Ensure Chrome is running
console.log("Starting Chrome with remote debugging...");
const chromeProcess = exec(launchChromeCommand);
try {
console.log("Attempting to connect with Playwright...");
const browser = await chromium.connectOverCDP("http://localhost:9222", {
_automation: false,
});
const context = browser.contexts()[0];
const page = await context.newPage();
for (const group of chunks) {
for (const user of group) {
console.log("正在执行用户:", user);
await page.goto("https://x.com/messages/compose");
await delay(Math.floor(Math.random() * 2000) + 1000);
try {
let searchBox;
try {
searchBox = page.getByTestId("searchPeople");
await searchBox.waitFor({ state: "visible", timeout: 1000 });
} catch (e) {
throw "搜索框获取失败";
}
await searchBox.click();
await delay(Math.floor(Math.random() * 2000) + 1000);
await searchBox.fill(user);
await delay(Math.floor(Math.random() * 2000) + 1000);
try {
const button = page.getByTestId("TypeaheadUser").first();
const ariaDisabled = await button.getAttribute("aria-disabled");
console.log("ariaDisabled", ariaDisabled);
if (ariaDisabled === "true") {
throw "";
}
await page.getByTestId("TypeaheadUser").first().click();
await delay(Math.floor(Math.random() * 2000) + 1000);
} catch (error) {
throw "点击第一个搜索结果失败";
}
await page.getByTestId("nextButton").click();
await delay(Math.floor(Math.random() * 2000) + 1000);
await page
.getByTestId("dmComposerTextInput")
.locator("div")
.nth(2)
.click();
await delay(Math.floor(Math.random() * 2000) + 1000);
await page.getByTestId("dmComposerTextInput").fill(message);
await delay(Math.floor(Math.random() * 2000) + 1000);
await page.getByTestId("dmComposerSendButton").click();
console.log(`Message sent to ${user}`);
sendEvent({ user: user, message: "操作成功" });
await delay(Math.floor(Math.random() * 2000) + 1000);
} catch (error) {
console.log("error", error);
sendEvent({ user: user, message: "操作失败" });
await delay(Math.floor(Math.random() * 2000) + 1000);
}
}
}
res.status(200).json({
success: true,
message: "Messages sent successfully.",
});
} catch (e) {
console.error("Failed to connect or navigate with Playwright:", e);
res.status(500).json({
success: false,
message: "Failed to connect to browser.",
error: e.message,
});
}
} catch (error) {
console.error("Error:", error);
res.status(500).json({ success: false, error: error.message });
}
});
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});