social-agent-cli 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ai/mapper.ts +38 -16
- package/ai/planner.ts +12 -3
- package/ai/runner.ts +4 -22
- package/maps/linkedin.json +70 -0
- package/maps/x.json +66 -67
- package/package.json +1 -1
- package/maps/linkedin_linkedin_post.json +0 -66
- package/maps/linkedin_linkedin_send_connection_request.json +0 -37
- package/maps/linkedin_post.json +0 -66
- package/maps/x_post.json +0 -64
- package/maps/x_tweet_be/304/237enmeyi_/303/266/304/237ren.json +0 -39
- package/maps/x_tweet_retweet_/303/266/304/237ren.json +0 -46
package/ai/mapper.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { readFileSync, writeFileSync, existsSync, mkdtempSync, rmSync } from "node:fs";
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, mkdtempSync, rmSync, readdirSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { PATHS } from "../core/config.js";
|
|
@@ -21,7 +21,7 @@ const SELECTOR_MAP_SCHEMA = JSON.stringify({
|
|
|
21
21
|
items: {
|
|
22
22
|
type: "object",
|
|
23
23
|
properties: {
|
|
24
|
-
action: { type: "string", enum: ["click", "type", "wait", "keypress", "goto"] },
|
|
24
|
+
action: { type: "string", enum: ["click", "type", "wait", "keypress", "goto", "upload"] },
|
|
25
25
|
description: { type: "string" },
|
|
26
26
|
selector: { type: "string" },
|
|
27
27
|
value: { type: "string" },
|
|
@@ -168,32 +168,52 @@ function claude(opts: ClaudeOptions): Promise<any> {
|
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
// ── Map CRUD
|
|
171
|
+
// ── Map CRUD (platform başına tek dosya) ─────────────────────
|
|
172
|
+
|
|
173
|
+
interface PlatformMaps {
|
|
174
|
+
[action: string]: SelectorMap;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function loadPlatformFile(platform: string): PlatformMaps {
|
|
178
|
+
const mapPath = join(PATHS.maps, `${platform}.json`);
|
|
179
|
+
if (!existsSync(mapPath)) return {};
|
|
180
|
+
try {
|
|
181
|
+
return JSON.parse(readFileSync(mapPath, "utf-8"));
|
|
182
|
+
} catch {
|
|
183
|
+
return {};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function savePlatformFile(platform: string, maps: PlatformMaps): void {
|
|
188
|
+
const mapPath = join(PATHS.maps, `${platform}.json`);
|
|
189
|
+
writeFileSync(mapPath, JSON.stringify(maps, null, 2));
|
|
190
|
+
}
|
|
172
191
|
|
|
173
192
|
export function loadMap(platform: string, action = "post"): SelectorMap | null {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
return JSON.parse(readFileSync(mapPath, "utf-8"));
|
|
193
|
+
const maps = loadPlatformFile(platform);
|
|
194
|
+
return maps[action] || null;
|
|
177
195
|
}
|
|
178
196
|
|
|
179
197
|
export function saveMap(map: SelectorMap): void {
|
|
180
198
|
const action = map.action || "post";
|
|
181
|
-
const
|
|
182
|
-
|
|
199
|
+
const maps = loadPlatformFile(map.platform);
|
|
200
|
+
maps[action] = map;
|
|
201
|
+
savePlatformFile(map.platform, maps);
|
|
183
202
|
}
|
|
184
203
|
|
|
185
204
|
export function listMaps(platform?: string): SelectorMap[] {
|
|
186
|
-
const
|
|
187
|
-
const maps: SelectorMap[] = [];
|
|
205
|
+
const results: SelectorMap[] = [];
|
|
188
206
|
try {
|
|
189
207
|
for (const file of readdirSync(PATHS.maps)) {
|
|
190
208
|
if (!file.endsWith(".json")) continue;
|
|
191
|
-
if (platform &&
|
|
192
|
-
const
|
|
193
|
-
|
|
209
|
+
if (platform && file !== `${platform}.json`) continue;
|
|
210
|
+
const maps = JSON.parse(readFileSync(join(PATHS.maps, file), "utf-8"));
|
|
211
|
+
for (const map of Object.values(maps) as SelectorMap[]) {
|
|
212
|
+
results.push(map);
|
|
213
|
+
}
|
|
194
214
|
}
|
|
195
215
|
} catch {}
|
|
196
|
-
return
|
|
216
|
+
return results;
|
|
197
217
|
}
|
|
198
218
|
|
|
199
219
|
// ── Map Oluştur ──────────────────────────────────────────────
|
|
@@ -215,6 +235,7 @@ ${domSnapshot}
|
|
|
215
235
|
Kurallar:
|
|
216
236
|
- ARIA snapshot'taki role ve name bilgilerini kullanarak selector oluştur
|
|
217
237
|
- aria-label, role, data-testid, id tercih et
|
|
238
|
+
- Dosya/görsel/video yükleme için "upload" action kullan (click DEĞİL). Upload action hidden input[type=file]'a dosyayı programatik olarak set eder, file picker açmaz. value alanına {{IMAGE}} yaz.
|
|
218
239
|
- Her adım için 2+ fallback selector
|
|
219
240
|
- Parametreler için placeholder kullan: {{CONTENT}} = metin, {{USERNAME}} = kullanıcı adı, {{URL}} = link, vs.
|
|
220
241
|
- Hangi parametreleri kullandığını "parameters" alanında listele
|
|
@@ -261,7 +282,7 @@ const REMAINING_STEPS_SCHEMA = JSON.stringify({
|
|
|
261
282
|
items: {
|
|
262
283
|
type: "object",
|
|
263
284
|
properties: {
|
|
264
|
-
action: { type: "string", enum: ["click", "type", "wait", "keypress", "goto"] },
|
|
285
|
+
action: { type: "string", enum: ["click", "type", "wait", "keypress", "goto", "upload"] },
|
|
265
286
|
description: { type: "string" },
|
|
266
287
|
selector: { type: "string" },
|
|
267
288
|
value: { type: "string" },
|
|
@@ -320,7 +341,8 @@ GÖREV: Ekranın mevcut durumunu analiz et. Amaca ulaşmak için kalan adımlar
|
|
|
320
341
|
- Belki ekstra bir adım gerekiyor (popup kapatma, scroll, vb.)
|
|
321
342
|
- Belki farklı bir yol izlenmeli
|
|
322
343
|
- {{CONTENT}} = post metni placeholder'ı
|
|
323
|
-
- data-testid, aria-label, role tercih et, her adıma 2+ fallback selector ver
|
|
344
|
+
- data-testid, aria-label, role tercih et, her adıma 2+ fallback selector ver
|
|
345
|
+
- Dosya yükleme için "upload" action kullan (click DEĞİL). value: {{IMAGE}}`;
|
|
324
346
|
|
|
325
347
|
console.log(`\n[heal] AI ekranı analiz ediyor (effort: ${effort})...\n`);
|
|
326
348
|
|
package/ai/planner.ts
CHANGED
|
@@ -59,9 +59,18 @@ export function listAllMaps(platform?: string): SelectorMap[] {
|
|
|
59
59
|
try {
|
|
60
60
|
for (const file of readdirSync(PATHS.maps)) {
|
|
61
61
|
if (!file.endsWith(".json")) continue;
|
|
62
|
-
if (platform &&
|
|
63
|
-
const
|
|
64
|
-
|
|
62
|
+
if (platform && file !== `${platform}.json`) continue;
|
|
63
|
+
const content = JSON.parse(readFileSync(join(PATHS.maps, file), "utf-8"));
|
|
64
|
+
// Yeni format: { "post": {...}, "post_with_image": {...} }
|
|
65
|
+
if (content.steps) {
|
|
66
|
+
// Eski format: direkt map objesi
|
|
67
|
+
maps.push(content);
|
|
68
|
+
} else {
|
|
69
|
+
// Yeni format: action bazlı obje
|
|
70
|
+
for (const map of Object.values(content) as SelectorMap[]) {
|
|
71
|
+
if (map.steps) maps.push(map);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
65
74
|
}
|
|
66
75
|
} catch {}
|
|
67
76
|
return maps;
|
package/ai/runner.ts
CHANGED
|
@@ -324,31 +324,13 @@ async function executeMapStep(
|
|
|
324
324
|
break;
|
|
325
325
|
|
|
326
326
|
case "upload": {
|
|
327
|
-
// Dosya yükleme - hidden file input'a dosya set et
|
|
328
327
|
const filePath = rp(step.value || "{{IMAGE}}");
|
|
329
328
|
if (!filePath || filePath.includes("{{")) break; // dosya yoksa atla
|
|
330
329
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
await input.setInputFiles(filePath);
|
|
336
|
-
uploaded = true;
|
|
337
|
-
break;
|
|
338
|
-
} catch {}
|
|
339
|
-
}
|
|
340
|
-
if (!uploaded) {
|
|
341
|
-
// Hidden input bulunamazsa, file chooser ile dene
|
|
342
|
-
try {
|
|
343
|
-
const [fileChooser] = await Promise.all([
|
|
344
|
-
page.waitForEvent("filechooser", { timeout: 5000 }),
|
|
345
|
-
page.click(selectors[0] || "[data-testid='fileInput']"),
|
|
346
|
-
]);
|
|
347
|
-
await fileChooser.setFiles(filePath);
|
|
348
|
-
uploaded = true;
|
|
349
|
-
} catch {}
|
|
350
|
-
}
|
|
351
|
-
if (!uploaded) throw new Error(`Upload failed: ${filePath}`);
|
|
330
|
+
// Hidden input[type=file]'a direkt setInputFiles - butona tıklamadan
|
|
331
|
+
const fileInput = page.locator('input[type="file"]').first();
|
|
332
|
+
await fileInput.setInputFiles(filePath);
|
|
333
|
+
|
|
352
334
|
if (step.waitMs) await page.waitForTimeout(step.waitMs);
|
|
353
335
|
break;
|
|
354
336
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"post": {
|
|
3
|
+
"platform": "linkedin",
|
|
4
|
+
"action": "post",
|
|
5
|
+
"description": "LinkedIn üzerinden yeni bir metin postu paylaşma",
|
|
6
|
+
"version": 1,
|
|
7
|
+
"lastUpdated": "2026-03-14T12:00:00.000Z",
|
|
8
|
+
"parameters": [
|
|
9
|
+
"{{CONTENT}}"
|
|
10
|
+
],
|
|
11
|
+
"steps": [
|
|
12
|
+
{
|
|
13
|
+
"action": "click",
|
|
14
|
+
"description": "Gönderi oluştur kutusuna tıkla",
|
|
15
|
+
"selector": "button.share-box-feed-entry__trigger",
|
|
16
|
+
"fallbackSelectors": [
|
|
17
|
+
"[aria-label*='Start a post']",
|
|
18
|
+
"[aria-label*='Gönderi başlat']",
|
|
19
|
+
"button[aria-label*='post']"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"action": "wait",
|
|
24
|
+
"description": "Post oluşturma modalının açılmasını bekle",
|
|
25
|
+
"waitMs": 1500
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"action": "click",
|
|
29
|
+
"description": "Metin alanına tıkla",
|
|
30
|
+
"selector": "[role='textbox'][aria-label*='Text editor']",
|
|
31
|
+
"fallbackSelectors": [
|
|
32
|
+
"[role='textbox'][contenteditable='true']",
|
|
33
|
+
".ql-editor[contenteditable='true']",
|
|
34
|
+
"[aria-label*='Metin düzenleyici']"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"action": "type",
|
|
39
|
+
"description": "Post metnini yaz",
|
|
40
|
+
"selector": "[role='textbox'][aria-label*='Text editor']",
|
|
41
|
+
"value": "{{CONTENT}}",
|
|
42
|
+
"fallbackSelectors": [
|
|
43
|
+
"[role='textbox'][contenteditable='true']",
|
|
44
|
+
".ql-editor[contenteditable='true']"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"action": "wait",
|
|
49
|
+
"description": "Metin girişi sonrası bekleme",
|
|
50
|
+
"waitMs": 1000
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"action": "click",
|
|
54
|
+
"description": "Gönder butonuna tıkla",
|
|
55
|
+
"selector": "button.share-actions__primary-action",
|
|
56
|
+
"fallbackSelectors": [
|
|
57
|
+
"[aria-label='Post']",
|
|
58
|
+
"[aria-label='Gönder']",
|
|
59
|
+
"button[aria-label*='Post']",
|
|
60
|
+
"button[aria-label*='Paylaş']"
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"action": "wait",
|
|
65
|
+
"description": "Post gönderimini bekle",
|
|
66
|
+
"waitMs": 2000
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
}
|
package/maps/x.json
CHANGED
|
@@ -1,69 +1,68 @@
|
|
|
1
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
|
-
]
|
|
2
|
+
"post": {
|
|
3
|
+
"platform": "x",
|
|
4
|
+
"action": "post",
|
|
5
|
+
"description": "X (Twitter) üzerinden yeni bir metin postu paylaşma",
|
|
6
|
+
"version": 1,
|
|
7
|
+
"lastUpdated": "2026-03-14T12:00:00.000Z",
|
|
8
|
+
"parameters": [
|
|
9
|
+
"{{CONTENT}}"
|
|
10
|
+
],
|
|
11
|
+
"steps": [
|
|
12
|
+
{
|
|
13
|
+
"action": "click",
|
|
14
|
+
"description": "Sidebar'daki post butonuna tıkla",
|
|
15
|
+
"selector": "[data-testid='SideNav_NewTweet_Button']",
|
|
16
|
+
"fallbackSelectors": [
|
|
17
|
+
"a[href='/compose/post']",
|
|
18
|
+
"[aria-label*='Post'][role='link']",
|
|
19
|
+
"[aria-label*='Gönder'][role='link']",
|
|
20
|
+
"[data-testid='FloatingActionButton']"
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"action": "wait",
|
|
25
|
+
"description": "Compose dialog açılmasını bekle",
|
|
26
|
+
"waitMs": 1500
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"action": "click",
|
|
30
|
+
"description": "Metin alanına tıkla",
|
|
31
|
+
"selector": "[data-testid='tweetTextarea_0']",
|
|
32
|
+
"fallbackSelectors": [
|
|
33
|
+
"[role='textbox'][contenteditable='true']",
|
|
34
|
+
".public-DraftEditor-content"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"action": "type",
|
|
39
|
+
"description": "Post metnini yaz",
|
|
40
|
+
"selector": "[data-testid='tweetTextarea_0']",
|
|
41
|
+
"value": "{{CONTENT}}",
|
|
42
|
+
"fallbackSelectors": [
|
|
43
|
+
"[role='textbox'][contenteditable='true']",
|
|
44
|
+
".public-DraftEditor-content"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"action": "wait",
|
|
49
|
+
"description": "Metin girişi sonrası bekleme",
|
|
50
|
+
"waitMs": 500
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"action": "click",
|
|
54
|
+
"description": "Gönder butonuna tıkla",
|
|
55
|
+
"selector": "[data-testid='tweetButton']",
|
|
56
|
+
"fallbackSelectors": [
|
|
57
|
+
"[data-testid='tweetButtonInline']",
|
|
58
|
+
"[role='button'][data-testid*='tweet']"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"action": "wait",
|
|
63
|
+
"description": "Post gönderimini bekle",
|
|
64
|
+
"waitMs": 2000
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|
|
69
68
|
}
|
package/package.json
CHANGED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"platform": "linkedin",
|
|
3
|
-
"version": 1,
|
|
4
|
-
"action": "linkedin_post",
|
|
5
|
-
"description": "LinkedIn platformunda metin içerikli post paylaşma",
|
|
6
|
-
"lastUpdated": "2026-03-14T11:33:00.454Z",
|
|
7
|
-
"parameters": [
|
|
8
|
-
"{{CONTENT}}"
|
|
9
|
-
],
|
|
10
|
-
"steps": [
|
|
11
|
-
{
|
|
12
|
-
"action": "goto",
|
|
13
|
-
"description": "LinkedIn ana sayfasına git",
|
|
14
|
-
"url": "https://www.linkedin.com/feed/"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"action": "wait",
|
|
18
|
-
"description": "Sayfanın yüklenmesini bekle",
|
|
19
|
-
"waitMs": 3000
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"action": "click",
|
|
23
|
-
"description": "Gönderi oluşturma kutusuna tıkla",
|
|
24
|
-
"selector": "button.rBknNMyPiauEsphJukuFITVzZCRzAenPRs",
|
|
25
|
-
"fallbackSelectors": [
|
|
26
|
-
".share-box-feed-entry__top-bar button.artdeco-button--tertiary",
|
|
27
|
-
"button[class*='share-box-feed-entry']"
|
|
28
|
-
]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"action": "wait",
|
|
32
|
-
"description": "Post oluşturma modalının açılmasını bekle",
|
|
33
|
-
"waitMs": 2000
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"action": "type",
|
|
37
|
-
"description": "Post içeriğini yaz",
|
|
38
|
-
"selector": "div.ql-editor[role='textbox']",
|
|
39
|
-
"fallbackSelectors": [
|
|
40
|
-
"div[aria-label='Metin Düzenleyici']",
|
|
41
|
-
"div.editor-content div[contenteditable='true']",
|
|
42
|
-
"div[data-placeholder='Ne hakkında konuşmak istiyorsunuz?']"
|
|
43
|
-
],
|
|
44
|
-
"value": "{{CONTENT}}"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"action": "wait",
|
|
48
|
-
"description": "İçeriğin yazılmasını bekle",
|
|
49
|
-
"waitMs": 1000
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"action": "click",
|
|
53
|
-
"description": "Gönder butonuna tıkla",
|
|
54
|
-
"selector": "button.share-actions__primary-action",
|
|
55
|
-
"fallbackSelectors": [
|
|
56
|
-
"button[aria-label='Gönderi paylaş']",
|
|
57
|
-
"button.artdeco-button--primary[class*='share-actions']"
|
|
58
|
-
]
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"action": "wait",
|
|
62
|
-
"description": "Gönderinin paylaşılmasını bekle",
|
|
63
|
-
"waitMs": 3000
|
|
64
|
-
}
|
|
65
|
-
]
|
|
66
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"platform": "linkedin",
|
|
3
|
-
"version": 1,
|
|
4
|
-
"action": "linkedin_send_connection_request",
|
|
5
|
-
"description": "LinkedIn mynetwork/grow sayfasından bir kişiye bağlantı isteği gönderme",
|
|
6
|
-
"lastUpdated": "2026-03-14T11:44:38.451Z",
|
|
7
|
-
"parameters": [
|
|
8
|
-
"{{USERNAME}}"
|
|
9
|
-
],
|
|
10
|
-
"steps": [
|
|
11
|
-
{
|
|
12
|
-
"action": "goto",
|
|
13
|
-
"description": "LinkedIn Ağım/Grow sayfasına git",
|
|
14
|
-
"url": "https://www.linkedin.com/mynetwork/grow/"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"action": "wait",
|
|
18
|
-
"description": "Sayfa ve öneri kartlarının yüklenmesini bekle",
|
|
19
|
-
"waitMs": 3000
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"action": "click",
|
|
23
|
-
"description": "{{USERNAME}} kişisinin bağlantı kurma (Connect) butonuna tıkla",
|
|
24
|
-
"selector": "button[aria-label*='{{USERNAME}}'][aria-label*='bağlantı' i]",
|
|
25
|
-
"fallbackSelectors": [
|
|
26
|
-
"button[aria-label*='{{USERNAME}}'][aria-label*='Connect' i]",
|
|
27
|
-
"button[aria-label*='{{USERNAME}}'][aria-label*='Invite' i]",
|
|
28
|
-
"//button[contains(@aria-label,'{{USERNAME}}') and (contains(@aria-label,'bağlantı') or contains(@aria-label,'Connect'))]"
|
|
29
|
-
]
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
"action": "wait",
|
|
33
|
-
"description": "Bağlantı isteği gönderilmesini veya modal açılmasını bekle",
|
|
34
|
-
"waitMs": 2000
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
}
|
package/maps/linkedin_post.json
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"platform": "linkedin",
|
|
3
|
-
"action": "post",
|
|
4
|
-
"description": "LinkedIn üzerinden yeni bir metin postu paylaşma",
|
|
5
|
-
"version": 1,
|
|
6
|
-
"lastUpdated": "2026-03-14T12:00:00.000Z",
|
|
7
|
-
"parameters": ["{{CONTENT}}"],
|
|
8
|
-
"steps": [
|
|
9
|
-
{
|
|
10
|
-
"action": "click",
|
|
11
|
-
"description": "Gönderi oluştur kutusuna tıkla",
|
|
12
|
-
"selector": "button.share-box-feed-entry__trigger",
|
|
13
|
-
"fallbackSelectors": [
|
|
14
|
-
"[aria-label*='Start a post']",
|
|
15
|
-
"[aria-label*='Gönderi başlat']",
|
|
16
|
-
"button[aria-label*='post']"
|
|
17
|
-
]
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"action": "wait",
|
|
21
|
-
"description": "Post oluşturma modalının açılmasını bekle",
|
|
22
|
-
"waitMs": 1500
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"action": "click",
|
|
26
|
-
"description": "Metin alanına tıkla",
|
|
27
|
-
"selector": "[role='textbox'][aria-label*='Text editor']",
|
|
28
|
-
"fallbackSelectors": [
|
|
29
|
-
"[role='textbox'][contenteditable='true']",
|
|
30
|
-
".ql-editor[contenteditable='true']",
|
|
31
|
-
"[aria-label*='Metin düzenleyici']"
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"action": "type",
|
|
36
|
-
"description": "Post metnini yaz",
|
|
37
|
-
"selector": "[role='textbox'][aria-label*='Text editor']",
|
|
38
|
-
"value": "{{CONTENT}}",
|
|
39
|
-
"fallbackSelectors": [
|
|
40
|
-
"[role='textbox'][contenteditable='true']",
|
|
41
|
-
".ql-editor[contenteditable='true']"
|
|
42
|
-
]
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"action": "wait",
|
|
46
|
-
"description": "Metin girişi sonrası bekleme",
|
|
47
|
-
"waitMs": 1000
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"action": "click",
|
|
51
|
-
"description": "Gönder butonuna tıkla",
|
|
52
|
-
"selector": "button.share-actions__primary-action",
|
|
53
|
-
"fallbackSelectors": [
|
|
54
|
-
"[aria-label='Post']",
|
|
55
|
-
"[aria-label='Gönder']",
|
|
56
|
-
"button[aria-label*='Post']",
|
|
57
|
-
"button[aria-label*='Paylaş']"
|
|
58
|
-
]
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"action": "wait",
|
|
62
|
-
"description": "Post gönderimini bekle",
|
|
63
|
-
"waitMs": 2000
|
|
64
|
-
}
|
|
65
|
-
]
|
|
66
|
-
}
|
package/maps/x_post.json
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"platform": "x",
|
|
3
|
-
"action": "post",
|
|
4
|
-
"description": "X (Twitter) üzerinden yeni bir metin postu paylaşma",
|
|
5
|
-
"version": 1,
|
|
6
|
-
"lastUpdated": "2026-03-14T12:00:00.000Z",
|
|
7
|
-
"parameters": ["{{CONTENT}}"],
|
|
8
|
-
"steps": [
|
|
9
|
-
{
|
|
10
|
-
"action": "click",
|
|
11
|
-
"description": "Sidebar'daki post butonuna tıkla",
|
|
12
|
-
"selector": "[data-testid='SideNav_NewTweet_Button']",
|
|
13
|
-
"fallbackSelectors": [
|
|
14
|
-
"a[href='/compose/post']",
|
|
15
|
-
"[aria-label*='Post'][role='link']",
|
|
16
|
-
"[aria-label*='Gönder'][role='link']",
|
|
17
|
-
"[data-testid='FloatingActionButton']"
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"action": "wait",
|
|
22
|
-
"description": "Compose dialog açılmasını bekle",
|
|
23
|
-
"waitMs": 1500
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"action": "click",
|
|
27
|
-
"description": "Metin alanına tıkla",
|
|
28
|
-
"selector": "[data-testid='tweetTextarea_0']",
|
|
29
|
-
"fallbackSelectors": [
|
|
30
|
-
"[role='textbox'][contenteditable='true']",
|
|
31
|
-
".public-DraftEditor-content"
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"action": "type",
|
|
36
|
-
"description": "Post metnini yaz",
|
|
37
|
-
"selector": "[data-testid='tweetTextarea_0']",
|
|
38
|
-
"value": "{{CONTENT}}",
|
|
39
|
-
"fallbackSelectors": [
|
|
40
|
-
"[role='textbox'][contenteditable='true']",
|
|
41
|
-
".public-DraftEditor-content"
|
|
42
|
-
]
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"action": "wait",
|
|
46
|
-
"description": "Metin girişi sonrası bekleme",
|
|
47
|
-
"waitMs": 500
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"action": "click",
|
|
51
|
-
"description": "Gönder butonuna tıkla",
|
|
52
|
-
"selector": "[data-testid='tweetButton']",
|
|
53
|
-
"fallbackSelectors": [
|
|
54
|
-
"[data-testid='tweetButtonInline']",
|
|
55
|
-
"[role='button'][data-testid*='tweet']"
|
|
56
|
-
]
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"action": "wait",
|
|
60
|
-
"description": "Post gönderimini bekle",
|
|
61
|
-
"waitMs": 2000
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"platform": "x",
|
|
3
|
-
"version": 1,
|
|
4
|
-
"lastUpdated": "2026-03-14T11:21:59.765Z",
|
|
5
|
-
"action": "tweet_beğenmeyi_öğren",
|
|
6
|
-
"description": "tweet beğenmeyi öğren",
|
|
7
|
-
"parameters": [
|
|
8
|
-
"{{TWEET_URL}}"
|
|
9
|
-
],
|
|
10
|
-
"steps": [
|
|
11
|
-
{
|
|
12
|
-
"action": "goto",
|
|
13
|
-
"description": "Beğenilecek tweet'in sayfasına git",
|
|
14
|
-
"url": "{{TWEET_URL}}",
|
|
15
|
-
"fallbackSelectors": []
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"action": "wait",
|
|
19
|
-
"description": "Tweet içeriğinin yüklenmesini bekle",
|
|
20
|
-
"waitMs": 2000,
|
|
21
|
-
"fallbackSelectors": []
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"action": "click",
|
|
25
|
-
"description": "Tweet'in altındaki beğen (kalp) butonuna tıkla",
|
|
26
|
-
"selector": "[data-testid=\"like\"]",
|
|
27
|
-
"fallbackSelectors": [
|
|
28
|
-
"[aria-label*=\"Beğen\"]",
|
|
29
|
-
"button[role=\"button\"] svg[viewBox=\"0 0 24 24\"]"
|
|
30
|
-
]
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"action": "wait",
|
|
34
|
-
"description": "Beğeni animasyonunun tamamlanmasını bekle",
|
|
35
|
-
"waitMs": 1000,
|
|
36
|
-
"fallbackSelectors": []
|
|
37
|
-
}
|
|
38
|
-
]
|
|
39
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"platform": "x",
|
|
3
|
-
"version": 1,
|
|
4
|
-
"lastUpdated": "2026-03-14T12:01:17.966Z",
|
|
5
|
-
"action": "tweet_retweet_öğren",
|
|
6
|
-
"description": "Belirtilen tweet sayfasına git, retweet butonuna tıkla ve onay ver",
|
|
7
|
-
"parameters": [
|
|
8
|
-
"{{TWEET_URL}}"
|
|
9
|
-
],
|
|
10
|
-
"steps": [
|
|
11
|
-
{
|
|
12
|
-
"action": "goto",
|
|
13
|
-
"description": "Belirtilen tweet sayfasına git",
|
|
14
|
-
"url": "{{TWEET_URL}}"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"action": "wait",
|
|
18
|
-
"description": "Tweet sayfasının yüklenmesini bekle",
|
|
19
|
-
"waitMs": 2000
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"action": "click",
|
|
23
|
-
"description": "Retweet butonuna tıkla",
|
|
24
|
-
"selector": "[data-testid='retweet']",
|
|
25
|
-
"fallbackSelectors": [
|
|
26
|
-
"button[aria-label*='Yeniden gönder']",
|
|
27
|
-
"button[aria-label*='Repost']",
|
|
28
|
-
"[data-testid='unretweet']"
|
|
29
|
-
]
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
"action": "wait",
|
|
33
|
-
"description": "Retweet menüsünün açılmasını bekle",
|
|
34
|
-
"waitMs": 1000
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"action": "click",
|
|
38
|
-
"description": "Yeniden gönder seçeneğine tıkla",
|
|
39
|
-
"selector": "[data-testid='retweetConfirm']",
|
|
40
|
-
"fallbackSelectors": [
|
|
41
|
-
"[role='menuitem'][data-testid='retweetConfirm']",
|
|
42
|
-
"[role='menu'] [role='menuitem']:first-child"
|
|
43
|
-
]
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
}
|