XActions Actions Library - Complete X/Twitter Actions
How to Use
- Navigate to x.com and log in
- Open DevTools Console (F12 or Cmd+Option+I)
- Paste
src/automation/core.jsfirst - Paste the script below and press Enter
Note: This script requires pasting src/automation/core.js first for shared utilities.
Full Script
Copy and paste this entire script into your browser DevTools console on x.com.
// XActions Actions Library - Complete X/Twitter Actions
// https://github.com/nirholas/XActions
//
// This module contains ALL available X/Twitter actions - visible, hidden, and undocumented.
// Paste core.js FIRST, then this file. Other scripts can use window.XActions.
//
// Usage: XActions.tweet.post("Hello world!")
// XActions.user.follow("username")
// XActions.dm.send("username", "Hi there!")
window.XActions = window.XActions || {};
window.XActions = (() => {
const Core = window.XActions?.Core;
if (!Core) {
console.error('❌ Core module not loaded! Paste core.js first.');
return null;
}
const { sleep, randomDelay, log, storage, waitForElement, waitForElements, clickElement, typeText } = Core;
// ============================================
// EXTENDED SELECTORS (All X UI Elements)
// ============================================
const SEL = {
// === Tweet/Post Elements ===
tweet: '[data-testid="tweet"]',
tweetText: '[data-testid="tweetText"]',
tweetLink: 'a[href*="/status/"]',
quoteTweet: '[data-testid="tweet"] [data-testid="tweet"]',
// === Compose/Input ===
tweetTextarea: '[data-testid="tweetTextarea_0"]',
tweetButton: '[data-testid="tweetButton"]',
tweetButtonInline: '[data-testid="tweetButtonInline"]',
replyTextarea: '[data-testid="tweetTextarea_0"]',
dmTextarea: '[data-testid="dmComposerTextInput"]',
dmSendButton: '[data-testid="dmComposerSendButton"]',
searchInput: '[data-testid="SearchBox_Search_Input"]',
// === Action Buttons ===
likeButton: '[data-testid="like"]',
unlikeButton: '[data-testid="unlike"]',
retweetButton: '[data-testid="retweet"]',
unretweetButton: '[data-testid="unretweet"]',
replyButton: '[data-testid="reply"]',
shareButton: '[data-testid="share"]',
bookmarkButton: '[data-testid="bookmark"]',
removeBookmark: '[data-testid="removeBookmark"]',
// === Follow/Unfollow ===
followButton: '[data-testid$="-follow"]',
unfollowButton: '[data-testid$="-unfollow"]',
followingButton: '[data-testid="placementTracking"] [role="button"]',
// === Dropdown/Menu Actions ===
caret: '[data-testid="caret"]',
menuItem: '[role="menuitem"]',
confirmButton: '[data-testid="confirmationSheetConfirm"]',
cancelButton: '[data-testid="confirmationSheetCancel"]',
// === User Elements ===
userCell: '[data-testid="UserCell"]',
userAvatar: '[data-testid="UserAvatar-Container"]',
userName: '[data-testid="User-Name"]',
userDescription: '[data-testid="UserDescription"]',
userFollowIndicator: '[data-testid="userFollowIndicator"]',
// === Profile Elements ===
profileHeader: '[data-testid="UserProfileHeader_Items"]',
editProfileButton: '[data-testid="editProfileButton"]',
userProfileSchema: '[data-testid="UserProfileSchema"]',
// === Navigation ===
primaryColumn: '[data-testid="primaryColumn"]',
sidebarColumn: '[data-testid="sidebarColumn"]',
timeline: 'section[role="region"]',
tabList: '[role="tablist"]',
backButton: '[data-testid="app-bar-back"]',
// === Modals/Dialogs ===
modal: '[data-testid="modal"]',
sheetDialog: '[data-testid="sheetDialog"]',
toast: '[data-testid="toast"]',
// === Media ===
mediaUpload: 'input[data-testid="fileInput"]',
gifButton: '[data-testid="gifyButton"]',
emojiButton: '[data-testid="emojiButton"]',
pollButton: '[data-testid="pollButton"]',
scheduleButton: '[data-testid="scheduledButton"]',
locationButton: '[data-testid="geoButton"]',
// === Lists ===
listContainer: '[data-testid="list"]',
listItem: '[data-testid="listItem"]',
// === DM Elements ===
dmConversation: '[data-testid="conversation"]',
dmMessage: '[data-testid="messageEntry"]',
dmInbox: '[data-testid="DMDrawer"]',
// === Notifications ===
notification: '[data-testid="notification"]',
notificationCell: '[data-testid="cellInnerDiv"]',
// === Communities ===
communityCard: '[data-testid="CommunityCard"]',
communityHeader: '[data-testid="communityHeader"]',
// === Spaces ===
spaceBar: '[data-testid="SpaceBar"]',
spaceCard: '[data-testid="SpaceCard"]',
};
// ============================================
// SECTION 1: TWEET/POST ACTIONS
// ============================================
const tweet = {
// Post a new tweet
post: async (text, options = {}) => {
log(`Posting tweet: "${text.substring(0, 30)}..."`, 'action');
// Navigate to compose if needed
const composeButton = document.querySelector('[data-testid="SideNav_NewTweet_Button"]');
if (composeButton && !document.querySelector(SEL.tweetTextarea)) {
await clickElement(composeButton);
await sleep(1000);
}
const textarea = await waitForElement(SEL.tweetTextarea);
if (!textarea) {
log('Could not find tweet textarea', 'error');
return false;
}
await typeText(textarea, text);
await sleep(500);
// Handle media if provided
if (options.mediaUrl) {
// Note: Browser can't upload files directly, but can trigger input
log('Media upload requires manual file selection', 'warning');
}
if (!options.draft) {
const postButton = document.querySelector(SEL.tweetButton) ||
document.querySelector(SEL.tweetButtonInline);
if (postButton && !postButton.disabled) {
await clickElement(postButton);
log('Tweet posted!', 'success');
return true;
}
}
return false;
},
// Reply to a tweet
reply: async (tweetElement, text) => {
log(`Replying: "${text.substring(0, 30)}..."`, 'action');
const replyBtn = tweetElement.querySelector(SEL.replyButton);
if (!replyBtn) return false;
await clickElement(replyBtn);
await sleep(800);
const textarea = await waitForElement(SEL.replyTextarea);
if (!textarea) return false;
await typeText(textarea, text);
await sleep(500);
const postButton = document.querySelector('[data-testid="tweetButton"]');
if (postButton && !postButton.disabled) {
await clickElement(postButton);
log('Reply posted!', 'success');
return true;
}
return false;
},
// Quote tweet
quote: async (tweetElement, text) => {
log(`Quote tweeting: "${text.substring(0, 30)}..."`, 'action');
const retweetBtn = tweetElement.querySelector(SEL.retweetButton);
if (!retweetBtn) return false;
await clickElement(retweetBtn);
await sleep(500);
// Click "Quote" option
const quoteOption = await waitForElement('[data-testid="Dropdown"] [role="menuitem"]:nth-child(2)');
if (!quoteOption) return false;
await clickElement(quoteOption);
await sleep(800);
const textarea = await waitForElement(SEL.tweetTextarea);
if (!textarea) return false;
await typeText(textarea, text);
await sleep(500);
const postButton = document.querySelector(SEL.tweetButton);
if (postButton && !postButton.disabled) {
await clickElement(postButton);
log('Quote tweet posted!', 'success');
return true;
}
return false;
},
// Delete a tweet (must be on your own tweet)
delete: async (tweetElement) => {
log('Deleting tweet...', 'action');
const caret = tweetElement.querySelector(SEL.caret);
if (!caret) return false;
await clickElement(caret);
await sleep(500);
// Find delete option
const menuItems = document.querySelectorAll(SEL.menuItem);
let deleteItem = null;
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('delete')) {
deleteItem = item;
break;
}
}
if (!deleteItem) return false;
await clickElement(deleteItem);
await sleep(500);
const confirmBtn = await waitForElement(SEL.confirmButton);
if (confirmBtn) {
await clickElement(confirmBtn);
log('Tweet deleted!', 'success');
return true;
}
return false;
},
// Pin a tweet to profile
pin: async (tweetElement) => {
log('Pinning tweet...', 'action');
const caret = tweetElement.querySelector(SEL.caret);
if (!caret) return false;
await clickElement(caret);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
let pinItem = null;
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('pin')) {
pinItem = item;
break;
}
}
if (pinItem) {
await clickElement(pinItem);
await sleep(500);
const confirmBtn = await waitForElement(SEL.confirmButton);
if (confirmBtn) await clickElement(confirmBtn);
log('Tweet pinned!', 'success');
return true;
}
return false;
},
// Get tweet ID from element
getId: (tweetElement) => {
const link = tweetElement.querySelector(SEL.tweetLink);
if (link) {
const match = link.href.match(/status\/(\d+)/);
if (match) return match[1];
}
return null;
},
// Get all visible tweets
getAll: () => {
return Array.from(document.querySelectorAll(SEL.tweet));
},
// Thread: Post multiple tweets as a thread
thread: async (tweets) => {
log(`Posting thread of ${tweets.length} tweets...`, 'action');
for (let i = 0; i < tweets.length; i++) {
await tweet.post(tweets[i], { addToThread: i > 0 });
await randomDelay(2000, 4000);
}
log('Thread posted!', 'success');
return true;
},
};
// ============================================
// SECTION 2: ENGAGEMENT ACTIONS
// ============================================
const engage = {
// Like a tweet
like: async (tweetElement) => {
const likeBtn = tweetElement.querySelector(SEL.likeButton);
if (!likeBtn) {
log('Already liked or button not found', 'warning');
return false;
}
await clickElement(likeBtn);
log('Liked!', 'success');
return true;
},
// Unlike a tweet
unlike: async (tweetElement) => {
const unlikeBtn = tweetElement.querySelector(SEL.unlikeButton);
if (!unlikeBtn) return false;
await clickElement(unlikeBtn);
log('Unliked!', 'success');
return true;
},
// Retweet
retweet: async (tweetElement) => {
const rtBtn = tweetElement.querySelector(SEL.retweetButton);
if (!rtBtn) return false;
await clickElement(rtBtn);
await sleep(500);
// Click first option (Repost)
const repostOption = await waitForElement('[data-testid="retweetConfirm"]');
if (repostOption) {
await clickElement(repostOption);
log('Retweeted!', 'success');
return true;
}
return false;
},
// Undo retweet
unretweet: async (tweetElement) => {
const unrtBtn = tweetElement.querySelector(SEL.unretweetButton);
if (!unrtBtn) return false;
await clickElement(unrtBtn);
await sleep(500);
const confirmOption = await waitForElement('[data-testid="unretweetConfirm"]');
if (confirmOption) {
await clickElement(confirmOption);
log('Unretweeted!', 'success');
return true;
}
return false;
},
// Bookmark a tweet
bookmark: async (tweetElement) => {
const shareBtn = tweetElement.querySelector(SEL.shareButton);
if (!shareBtn) return false;
await clickElement(shareBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('bookmark')) {
await clickElement(item);
log('Bookmarked!', 'success');
return true;
}
}
return false;
},
// Remove bookmark
unbookmark: async (tweetElement) => {
const removeBtn = tweetElement.querySelector(SEL.removeBookmark);
if (removeBtn) {
await clickElement(removeBtn);
log('Bookmark removed!', 'success');
return true;
}
// Try via share menu
return await engage.bookmark(tweetElement); // Toggle
},
// Add to list via tweet menu
addToList: async (tweetElement, listName) => {
const caret = tweetElement.querySelector(SEL.caret);
if (!caret) return false;
await clickElement(caret);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('add') &&
item.textContent.toLowerCase().includes('list')) {
await clickElement(item);
await sleep(800);
// Find and click the specific list
if (listName) {
const lists = document.querySelectorAll('[data-testid="listItem"]');
for (const list of lists) {
if (list.textContent.includes(listName)) {
await clickElement(list);
log(`Added to list: ${listName}`, 'success');
return true;
}
}
}
return true;
}
}
return false;
},
// Report a tweet
report: async (tweetElement, reason) => {
log('Opening report dialog...', 'action');
const caret = tweetElement.querySelector(SEL.caret);
if (!caret) return false;
await clickElement(caret);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('report')) {
await clickElement(item);
log('Report dialog opened - complete manually', 'warning');
return true;
}
}
return false;
},
// Copy link to tweet
copyLink: async (tweetElement) => {
const shareBtn = tweetElement.querySelector(SEL.shareButton);
if (!shareBtn) return false;
await clickElement(shareBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('copy link')) {
await clickElement(item);
log('Link copied!', 'success');
return true;
}
}
return false;
},
// Share via DM
shareViaDM: async (tweetElement, username) => {
const shareBtn = tweetElement.querySelector(SEL.shareButton);
if (!shareBtn) return false;
await clickElement(shareBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('send via direct message')) {
await clickElement(item);
await sleep(800);
// Type username to search
if (username) {
const searchInput = await waitForElement('input[placeholder*="Search"]');
if (searchInput) {
searchInput.value = username;
searchInput.dispatchEvent(new Event('input', { bubbles: true }));
await sleep(1000);
// Click first result
const result = await waitForElement('[data-testid="TypeaheadUser"]');
if (result) await clickElement(result);
}
}
return true;
}
}
return false;
},
// Embed tweet (get embed code)
embed: async (tweetElement) => {
const shareBtn = tweetElement.querySelector(SEL.shareButton);
if (!shareBtn) return false;
await clickElement(shareBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('embed')) {
await clickElement(item);
log('Embed dialog opened', 'success');
return true;
}
}
return false;
},
// View tweet analytics (if available)
viewAnalytics: async (tweetElement) => {
const caret = tweetElement.querySelector(SEL.caret);
if (!caret) return false;
await clickElement(caret);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('analytics') ||
item.textContent.toLowerCase().includes('view post engagements')) {
await clickElement(item);
log('Analytics opened', 'success');
return true;
}
}
return false;
},
// Request Community Note
requestNote: async (tweetElement) => {
const caret = tweetElement.querySelector(SEL.caret);
if (!caret) return false;
await clickElement(caret);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('note') ||
item.textContent.toLowerCase().includes('community note')) {
await clickElement(item);
log('Community note dialog opened', 'success');
return true;
}
}
return false;
},
// Highlight tweet (X Premium)
highlight: async (tweetElement) => {
const caret = tweetElement.querySelector(SEL.caret);
if (!caret) return false;
await clickElement(caret);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('highlight')) {
await clickElement(item);
log('Tweet highlighted!', 'success');
return true;
}
}
return false;
},
};
// ============================================
// SECTION 3: USER ACTIONS
// ============================================
const user = {
// Follow a user
follow: async (target) => {
let button;
if (typeof target === 'string') {
window.location.href = `https://x.com/${target}`;
await sleep(2000);
button = await waitForElement(SEL.followButton);
} else {
button = target.querySelector(SEL.followButton);
}
if (!button) {
log('Follow button not found (already following?)', 'warning');
return false;
}
await clickElement(button);
log(`Followed!`, 'success');
return true;
},
// Unfollow a user
unfollow: async (target) => {
let button;
if (typeof target === 'string') {
window.location.href = `https://x.com/${target}`;
await sleep(2000);
button = await waitForElement(SEL.unfollowButton);
} else {
button = target.querySelector(SEL.unfollowButton);
}
if (!button) {
log('Unfollow button not found', 'warning');
return false;
}
await clickElement(button);
await sleep(500);
const confirmBtn = await waitForElement(SEL.confirmButton);
if (confirmBtn) {
await clickElement(confirmBtn);
log(`Unfollowed!`, 'success');
return true;
}
return false;
},
// Block a user
block: async (username) => {
log(`Blocking @${username}...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const moreButton = await waitForElement('[data-testid="userActions"]');
if (!moreButton) return false;
await clickElement(moreButton);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('block')) {
await clickElement(item);
await sleep(500);
const confirmBtn = await waitForElement(SEL.confirmButton);
if (confirmBtn) {
await clickElement(confirmBtn);
log(`Blocked @${username}!`, 'success');
return true;
}
}
}
return false;
},
// Unblock a user
unblock: async (username) => {
log(`Unblocking @${username}...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const unblockBtn = await waitForElement('[data-testid="placementTracking"] [role="button"]');
if (unblockBtn && unblockBtn.textContent.toLowerCase().includes('blocked')) {
await clickElement(unblockBtn);
await sleep(500);
const confirmBtn = await waitForElement(SEL.confirmButton);
if (confirmBtn) await clickElement(confirmBtn);
log(`Unblocked @${username}!`, 'success');
return true;
}
return false;
},
// Mute a user
mute: async (username) => {
log(`Muting @${username}...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const moreButton = await waitForElement('[data-testid="userActions"]');
if (!moreButton) return false;
await clickElement(moreButton);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('mute')) {
await clickElement(item);
log(`Muted @${username}!`, 'success');
return true;
}
}
return false;
},
// Unmute a user
unmute: async (username) => {
log(`Unmuting @${username}...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const moreButton = await waitForElement('[data-testid="userActions"]');
if (!moreButton) return false;
await clickElement(moreButton);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('unmute')) {
await clickElement(item);
log(`Unmuted @${username}!`, 'success');
return true;
}
}
return false;
},
// Report a user
report: async (username) => {
log(`Reporting @${username}...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const moreButton = await waitForElement('[data-testid="userActions"]');
if (!moreButton) return false;
await clickElement(moreButton);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('report')) {
await clickElement(item);
log('Report dialog opened - complete manually', 'warning');
return true;
}
}
return false;
},
// Add user to a list
addToList: async (username, listName) => {
log(`Adding @${username} to list...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const moreButton = await waitForElement('[data-testid="userActions"]');
if (!moreButton) return false;
await clickElement(moreButton);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('add') &&
item.textContent.toLowerCase().includes('list')) {
await clickElement(item);
await sleep(800);
if (listName) {
const lists = document.querySelectorAll('[role="checkbox"]');
for (const list of lists) {
if (list.closest('[data-testid]')?.textContent.includes(listName)) {
await clickElement(list);
log(`Added to ${listName}!`, 'success');
break;
}
}
}
const doneBtn = document.querySelector('[data-testid="addToListsButton"]');
if (doneBtn) await clickElement(doneBtn);
return true;
}
}
return false;
},
// Turn on notifications for user
notifyOn: async (username) => {
log(`Turning on notifications for @${username}...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const moreButton = await waitForElement('[data-testid="userActions"]');
if (!moreButton) return false;
await clickElement(moreButton);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('turn on notifications') ||
item.textContent.toLowerCase().includes('notify')) {
await clickElement(item);
log(`Notifications on for @${username}!`, 'success');
return true;
}
}
return false;
},
// Turn off notifications for user
notifyOff: async (username) => {
log(`Turning off notifications for @${username}...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const moreButton = await waitForElement('[data-testid="userActions"]');
if (!moreButton) return false;
await clickElement(moreButton);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('turn off notifications')) {
await clickElement(item);
log(`Notifications off for @${username}!`, 'success');
return true;
}
}
return false;
},
// Navigation helpers
viewTopics: async (username) => { window.location.href = `https://x.com/${username}/topics`; await sleep(2000); return true; },
viewLists: async (username) => { window.location.href = `https://x.com/${username}/lists`; await sleep(2000); return true; },
viewFollowers: async (username) => { window.location.href = `https://x.com/${username}/followers`; await sleep(2000); return true; },
viewFollowing: async (username) => { window.location.href = `https://x.com/${username}/following`; await sleep(2000); return true; },
viewLikes: async (username) => { window.location.href = `https://x.com/${username}/likes`; await sleep(2000); return true; },
viewMedia: async (username) => { window.location.href = `https://x.com/${username}/media`; await sleep(2000); return true; },
viewReplies: async (username) => { window.location.href = `https://x.com/${username}/with_replies`; await sleep(2000); return true; },
viewHighlights: async (username) => { window.location.href = `https://x.com/${username}/highlights`; await sleep(2000); return true; },
viewArticles: async (username) => { window.location.href = `https://x.com/${username}/articles`; await sleep(2000); return true; },
// Check if user follows you
followsYou: async (username) => {
window.location.href = `https://x.com/${username}`;
await sleep(2000);
return document.querySelector(SEL.userFollowIndicator) !== null;
},
// Get user info
getInfo: async (username) => {
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const info = {
username,
displayName: document.querySelector('[data-testid="UserName"]')?.textContent || '',
bio: document.querySelector(SEL.userDescription)?.textContent || '',
followsYou: document.querySelector(SEL.userFollowIndicator) !== null,
verified: document.querySelector('[data-testid="icon-verified"]') !== null,
protected: document.querySelector('[data-testid="icon-lock"]') !== null,
};
const links = document.querySelectorAll('a[href*="/followers"], a[href*="/following"]');
links.forEach(link => {
const text = link.textContent;
if (link.href.includes('/followers')) info.followers = text;
else if (link.href.includes('/following')) info.following = text;
});
return info;
},
// Restrict user
restrict: async (username) => {
log(`Restricting @${username}...`, 'action');
window.location.href = `https://x.com/${username}`;
await sleep(2000);
const moreButton = await waitForElement('[data-testid="userActions"]');
if (!moreButton) return false;
await clickElement(moreButton);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('restrict')) {
await clickElement(item);
log(`Restricted @${username}!`, 'success');
return true;
}
}
return false;
},
};
// ============================================
// SECTION 4: DIRECT MESSAGES
// ============================================
const dm = {
// Send a DM to user
send: async (username, message) => {
log(`Sending DM to @${username}...`, 'action');
window.location.href = `https://x.com/messages`;
await sleep(2000);
// Click new message button
const newMsgBtn = await waitForElement('[data-testid="NewDM_Button"]');
if (newMsgBtn) {
await clickElement(newMsgBtn);
await sleep(800);
}
// Search for user
const searchInput = await waitForElement('input[placeholder*="Search"]');
if (searchInput) {
searchInput.value = username;
searchInput.dispatchEvent(new Event('input', { bubbles: true }));
await sleep(1000);
// Click first result
const userResult = await waitForElement('[data-testid="TypeaheadUser"]');
if (userResult) {
await clickElement(userResult);
await sleep(500);
// Click next
const nextBtn = await waitForElement('[data-testid="nextButton"]');
if (nextBtn) await clickElement(nextBtn);
await sleep(800);
}
}
// Type message
const msgInput = await waitForElement(SEL.dmTextarea);
if (msgInput) {
await typeText(msgInput, message);
await sleep(300);
const sendBtn = document.querySelector(SEL.dmSendButton);
if (sendBtn) {
await clickElement(sendBtn);
log(`DM sent to @${username}!`, 'success');
return true;
}
}
return false;
},
// Open DM conversation with user
open: async (username) => {
log(`Opening DM with @${username}...`, 'action');
window.location.href = `https://x.com/messages`;
await sleep(2000);
// Search in conversations
const conversations = document.querySelectorAll('[data-testid="conversation"]');
for (const conv of conversations) {
if (conv.textContent.toLowerCase().includes(username.toLowerCase())) {
await clickElement(conv);
log(`Opened DM with @${username}`, 'success');
return true;
}
}
// If not found, start new conversation
return await dm.send(username, '');
},
// Get all conversations
getConversations: async () => {
window.location.href = `https://x.com/messages`;
await sleep(2000);
const conversations = [];
const convElements = document.querySelectorAll('[data-testid="conversation"]');
for (const conv of convElements) {
conversations.push({
element: conv,
text: conv.textContent,
});
}
return conversations;
},
// Delete a conversation
deleteConversation: async (conversationElement) => {
log('Deleting conversation...', 'action');
// Long press or find menu
const moreBtn = conversationElement.querySelector('[data-testid="caret"]');
if (moreBtn) {
await clickElement(moreBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('delete')) {
await clickElement(item);
await sleep(500);
const confirmBtn = await waitForElement(SEL.confirmButton);
if (confirmBtn) {
await clickElement(confirmBtn);
log('Conversation deleted!', 'success');
return true;
}
}
}
}
return false;
},
// Leave a group DM
leaveGroup: async () => {
log('Leaving group...', 'action');
const infoBtn = await waitForElement('[data-testid="DMConversationInfoButton"]');
if (infoBtn) {
await clickElement(infoBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('leave')) {
await clickElement(item);
await sleep(500);
const confirmBtn = await waitForElement(SEL.confirmButton);
if (confirmBtn) {
await clickElement(confirmBtn);
log('Left group!', 'success');
return true;
}
}
}
}
return false;
},
// Create group DM
createGroup: async (usernames, groupName = null) => {
log(`Creating group DM with ${usernames.length} users...`, 'action');
window.location.href = `https://x.com/messages`;
await sleep(2000);
const newMsgBtn = await waitForElement('[data-testid="NewDM_Button"]');
if (newMsgBtn) await clickElement(newMsgBtn);
await sleep(800);
const searchInput = await waitForElement('input[placeholder*="Search"]');
if (!searchInput) return false;
for (const username of usernames) {
searchInput.value = username;
searchInput.dispatchEvent(new Event('input', { bubbles: true }));
await sleep(1000);
const userResult = await waitForElement('[data-testid="TypeaheadUser"]');
if (userResult) {
await clickElement(userResult);
await sleep(500);
}
searchInput.value = '';
}
const nextBtn = await waitForElement('[data-testid="nextButton"]');
if (nextBtn) {
await clickElement(nextBtn);
log('Group created!', 'success');
return true;
}
return false;
},
// Send image in DM
sendImage: async () => {
log('Opening image picker...', 'action');
const mediaBtn = document.querySelector('[data-testid="DMImageButton"]');
if (mediaBtn) {
await clickElement(mediaBtn);
log('Image picker opened - select file manually', 'warning');
return true;
}
return false;
},
// Send GIF in DM
sendGif: async (searchTerm) => {
log('Opening GIF picker...', 'action');
const gifBtn = document.querySelector('[data-testid="DMGifButton"]');
if (gifBtn) {
await clickElement(gifBtn);
await sleep(500);
if (searchTerm) {
const gifSearch = await waitForElement('input[placeholder*="Search"]');
if (gifSearch) {
gifSearch.value = searchTerm;
gifSearch.dispatchEvent(new Event('input', { bubbles: true }));
await sleep(1000);
// Click first result
const gifResult = await waitForElement('[data-testid="gif"]');
if (gifResult) {
await clickElement(gifResult);
log('GIF selected!', 'success');
return true;
}
}
}
}
return false;
},
// React to a message
react: async (messageElement, emoji) => {
// Double-click to react
messageElement.dispatchEvent(new MouseEvent('dblclick', { bubbles: true }));
await sleep(500);
// Select reaction
const reactions = document.querySelectorAll('[data-testid="reactionEmoji"]');
for (const reaction of reactions) {
if (reaction.textContent.includes(emoji)) {
await clickElement(reaction);
log('Reacted!', 'success');
return true;
}
}
return false;
},
};
// ============================================
// SECTION 5: SEARCH & NAVIGATION
// ============================================
const search = {
// Search for a query
query: async (query, filter = 'top') => {
log(`Searching: "${query}"...`, 'action');
const encoded = encodeURIComponent(query);
const filterParam = filter !== 'top' ? `&f=${filter}` : '';
window.location.href = `https://x.com/search?q=${encoded}${filterParam}`;
await sleep(2000);
return true;
},
// Search filters
top: async (query) => await search.query(query, 'top'),
latest: async (query) => await search.query(query, 'live'),
people: async (query) => await search.query(query, 'user'),
photos: async (query) => await search.query(query, 'image'),
videos: async (query) => await search.query(query, 'video'),
// Advanced search operators
from: async (username) => await search.query(`from:${username}`),
to: async (username) => await search.query(`to:${username}`),
mentions: async (username) => await search.query(`@${username}`),
hashtag: async (tag) => await search.query(`#${tag.replace('#', '')}`),
// Complex search
advanced: async (options) => {
const parts = [];
if (options.words) parts.push(options.words);
if (options.exactPhrase) parts.push(`"${options.exactPhrase}"`);
if (options.anyWords) parts.push(`(${options.anyWords.split(' ').join(' OR ')})`);
if (options.excludeWords) parts.push(options.excludeWords.split(' ').map(w => `-${w}`).join(' '));
if (options.hashtags) parts.push(options.hashtags.map(t => `#${t.replace('#', '')}`).join(' '));
if (options.from) parts.push(`from:${options.from}`);
if (options.to) parts.push(`to:${options.to}`);
if (options.mentioning) parts.push(`@${options.mentioning}`);
if (options.minReplies) parts.push(`min_replies:${options.minReplies}`);
if (options.minFaves) parts.push(`min_faves:${options.minFaves}`);
if (options.minRetweets) parts.push(`min_retweets:${options.minRetweets}`);
if (options.since) parts.push(`since:${options.since}`);
if (options.until) parts.push(`until:${options.until}`);
if (options.lang) parts.push(`lang:${options.lang}`);
if (options.verified) parts.push('filter:verified');
if (options.hasMedia) parts.push('filter:media');
if (options.hasImages) parts.push('filter:images');
if (options.hasVideos) parts.push('filter:videos');
if (options.hasLinks) parts.push('filter:links');
if (options.isReply) parts.push('filter:replies');
if (options.isRetweet) parts.push('filter:nativeretweets');
if (options.excludeRetweets) parts.push('-filter:retweets');
if (options.near) parts.push(`near:${options.near}`);
if (options.within) parts.push(`within:${options.within}`);
return await search.query(parts.join(' '), options.filter || 'top');
},
// Get current search results
getResults: () => {
return Array.from(document.querySelectorAll(SEL.tweet));
},
};
const nav = {
// Main navigation
home: async () => { window.location.href = 'https://x.com/home'; await sleep(2000); },
explore: async () => { window.location.href = 'https://x.com/explore'; await sleep(2000); },
notifications: async () => { window.location.href = 'https://x.com/notifications'; await sleep(2000); },
messages: async () => { window.location.href = 'https://x.com/messages'; await sleep(2000); },
bookmarks: async () => { window.location.href = 'https://x.com/i/bookmarks'; await sleep(2000); },
lists: async () => { window.location.href = 'https://x.com/i/lists'; await sleep(2000); },
communities: async () => { window.location.href = 'https://x.com/i/communities'; await sleep(2000); },
premium: async () => { window.location.href = 'https://x.com/i/premium_sign_up'; await sleep(2000); },
profile: async (username) => { window.location.href = `https://x.com/${username || 'me'}`; await sleep(2000); },
settings: async () => { window.location.href = 'https://x.com/settings'; await sleep(2000); },
// Notification tabs
notifyAll: async () => { window.location.href = 'https://x.com/notifications'; await sleep(2000); },
notifyVerified: async () => { window.location.href = 'https://x.com/notifications/verified'; await sleep(2000); },
notifyMentions: async () => { window.location.href = 'https://x.com/notifications/mentions'; await sleep(2000); },
// Timeline tabs
forYou: async () => {
await nav.home();
const tabs = document.querySelectorAll('[role="tab"]');
for (const tab of tabs) {
if (tab.textContent.toLowerCase().includes('for you')) {
await clickElement(tab);
return true;
}
}
},
following: async () => {
await nav.home();
const tabs = document.querySelectorAll('[role="tab"]');
for (const tab of tabs) {
if (tab.textContent.toLowerCase().includes('following')) {
await clickElement(tab);
return true;
}
}
},
// Quick access
trending: async () => { window.location.href = 'https://x.com/explore/tabs/trending'; await sleep(2000); },
forYouExplore: async () => { window.location.href = 'https://x.com/explore/tabs/for_you'; await sleep(2000); },
news: async () => { window.location.href = 'https://x.com/explore/tabs/news'; await sleep(2000); },
sports: async () => { window.location.href = 'https://x.com/explore/tabs/sports'; await sleep(2000); },
entertainment: async () => { window.location.href = 'https://x.com/explore/tabs/entertainment'; await sleep(2000); },
// Spaces
spaces: async () => { window.location.href = 'https://x.com/i/spaces'; await sleep(2000); },
// Scroll
scrollToTop: () => window.scrollTo({ top: 0, behavior: 'smooth' }),
scrollToBottom: () => window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }),
scrollBy: (px) => window.scrollBy({ top: px, behavior: 'smooth' }),
// Back
back: () => window.history.back(),
forward: () => window.history.forward(),
refresh: () => window.location.reload(),
};
// ============================================
// SECTION 6: LISTS MANAGEMENT
// ============================================
const lists = {
// Create a new list
create: async (name, description = '', isPrivate = false) => {
log(`Creating list: ${name}...`, 'action');
window.location.href = 'https://x.com/i/lists';
await sleep(2000);
const createBtn = await waitForElement('[data-testid="createList"]');
if (createBtn) {
await clickElement(createBtn);
await sleep(800);
const nameInput = await waitForElement('input[name="name"]');
if (nameInput) {
nameInput.value = name;
nameInput.dispatchEvent(new Event('input', { bubbles: true }));
}
const descInput = await waitForElement('textarea[name="description"]');
if (descInput && description) {
descInput.value = description;
descInput.dispatchEvent(new Event('input', { bubbles: true }));
}
if (isPrivate) {
const privateToggle = document.querySelector('[data-testid="makePrivate"]');
if (privateToggle) await clickElement(privateToggle);
}
await sleep(300);
const nextBtn = document.querySelector('[data-testid="listCreationNextButton"]');
if (nextBtn) {
await clickElement(nextBtn);
log(`List "${name}" created!`, 'success');
return true;
}
}
return false;
},
// Delete a list
delete: async (listId) => {
log('Deleting list...', 'action');
window.location.href = `https://x.com/i/lists/${listId}`;
await sleep(2000);
const moreBtn = await waitForElement('[data-testid="listsMoreButton"]');
if (moreBtn) {
await clickElement(moreBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('delete')) {
await clickElement(item);
await sleep(500);
const confirmBtn = await waitForElement(SEL.confirmButton);
if (confirmBtn) {
await clickElement(confirmBtn);
log('List deleted!', 'success');
return true;
}
}
}
}
return false;
},
// Edit list
edit: async (listId, newName, newDescription) => {
log('Editing list...', 'action');
window.location.href = `https://x.com/i/lists/${listId}`;
await sleep(2000);
const editBtn = await waitForElement('[data-testid="editList"]');
if (editBtn) {
await clickElement(editBtn);
await sleep(800);
if (newName) {
const nameInput = await waitForElement('input[name="name"]');
if (nameInput) {
nameInput.value = newName;
nameInput.dispatchEvent(new Event('input', { bubbles: true }));
}
}
if (newDescription !== undefined) {
const descInput = await waitForElement('textarea[name="description"]');
if (descInput) {
descInput.value = newDescription;
descInput.dispatchEvent(new Event('input', { bubbles: true }));
}
}
const saveBtn = document.querySelector('[data-testid="listEditSaveButton"]');
if (saveBtn) {
await clickElement(saveBtn);
log('List updated!', 'success');
return true;
}
}
return false;
},
// Follow a list
follow: async (listId) => {
window.location.href = `https://x.com/i/lists/${listId}`;
await sleep(2000);
const followBtn = await waitForElement('[data-testid="listFollow"]');
if (followBtn) {
await clickElement(followBtn);
log('List followed!', 'success');
return true;
}
return false;
},
// Unfollow a list
unfollow: async (listId) => {
window.location.href = `https://x.com/i/lists/${listId}`;
await sleep(2000);
const unfollowBtn = await waitForElement('[data-testid="listUnfollow"]');
if (unfollowBtn) {
await clickElement(unfollowBtn);
log('List unfollowed!', 'success');
return true;
}
return false;
},
// Pin/unpin list
pin: async (listId) => {
window.location.href = `https://x.com/i/lists/${listId}`;
await sleep(2000);
const moreBtn = await waitForElement('[data-testid="listsMoreButton"]');
if (moreBtn) {
await clickElement(moreBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('pin')) {
await clickElement(item);
log('List pin toggled!', 'success');
return true;
}
}
}
return false;
},
// Get all lists
getAll: async () => {
window.location.href = 'https://x.com/i/lists';
await sleep(2000);
const listItems = document.querySelectorAll('[data-testid="listItem"]');
return Array.from(listItems).map(item => ({
element: item,
text: item.textContent,
}));
},
// View list members
viewMembers: async (listId) => {
window.location.href = `https://x.com/i/lists/${listId}/members`;
await sleep(2000);
return true;
},
// View list followers
viewFollowers: async (listId) => {
window.location.href = `https://x.com/i/lists/${listId}/followers`;
await sleep(2000);
return true;
},
};
// ============================================
// SECTION 7: SETTINGS & PROFILE
// ============================================
const settings = {
// Navigation to settings pages
account: async () => { window.location.href = 'https://x.com/settings/account'; await sleep(2000); },
security: async () => { window.location.href = 'https://x.com/settings/security'; await sleep(2000); },
privacy: async () => { window.location.href = 'https://x.com/settings/privacy_and_safety'; await sleep(2000); },
notifications: async () => { window.location.href = 'https://x.com/settings/notifications'; await sleep(2000); },
accessibility: async () => { window.location.href = 'https://x.com/settings/accessibility'; await sleep(2000); },
monetization: async () => { window.location.href = 'https://x.com/settings/monetization'; await sleep(2000); },
creatorSubs: async () => { window.location.href = 'https://x.com/settings/manage_subscriptions'; await sleep(2000); },
premium: async () => { window.location.href = 'https://x.com/settings/premium'; await sleep(2000); },
// Muted/blocked lists
mutedAccounts: async () => { window.location.href = 'https://x.com/settings/muted/all'; await sleep(2000); },
mutedWords: async () => { window.location.href = 'https://x.com/settings/muted_keywords'; await sleep(2000); },
blockedAccounts: async () => { window.location.href = 'https://x.com/settings/blocked/all'; await sleep(2000); },
// Add muted word
addMutedWord: async (word, options = {}) => {
log(`Muting word: "${word}"...`, 'action');
window.location.href = 'https://x.com/settings/add_muted_keyword';
await sleep(2000);
const input = await waitForElement('input[name="keyword"]');
if (input) {
input.value = word;
input.dispatchEvent(new Event('input', { bubbles: true }));
await sleep(300);
const saveBtn = document.querySelector('[data-testid="addButton"]');
if (saveBtn) {
await clickElement(saveBtn);
log(`Word "${word}" muted!`, 'success');
return true;
}
}
return false;
},
// Download your data
downloadData: async () => {
window.location.href = 'https://x.com/settings/download_your_data';
await sleep(2000);
log('Download data page opened', 'success');
return true;
},
// Deactivate account page
deactivate: async () => {
window.location.href = 'https://x.com/settings/deactivate';
await sleep(2000);
log('Deactivate page opened - proceed with caution', 'warning');
return true;
},
};
const profile = {
// Edit profile
edit: async () => {
const editBtn = await waitForElement(SEL.editProfileButton);
if (editBtn) {
await clickElement(editBtn);
log('Edit profile opened', 'success');
return true;
}
// Navigate to profile first
window.location.href = 'https://x.com/settings/profile';
await sleep(2000);
return true;
},
// Update display name
updateName: async (newName) => {
window.location.href = 'https://x.com/settings/profile';
await sleep(2000);
const nameInput = await waitForElement('input[name="displayName"]');
if (nameInput) {
nameInput.value = newName;
nameInput.dispatchEvent(new Event('input', { bubbles: true }));
const saveBtn = document.querySelector('[data-testid="ProfileSaveButton"]');
if (saveBtn) {
await clickElement(saveBtn);
log(`Name updated to "${newName}"!`, 'success');
return true;
}
}
return false;
},
// Update bio
updateBio: async (newBio) => {
window.location.href = 'https://x.com/settings/profile';
await sleep(2000);
const bioInput = await waitForElement('textarea[name="description"]');
if (bioInput) {
bioInput.value = newBio;
bioInput.dispatchEvent(new Event('input', { bubbles: true }));
const saveBtn = document.querySelector('[data-testid="ProfileSaveButton"]');
if (saveBtn) {
await clickElement(saveBtn);
log('Bio updated!', 'success');
return true;
}
}
return false;
},
// Update location
updateLocation: async (location) => {
window.location.href = 'https://x.com/settings/profile';
await sleep(2000);
const locInput = await waitForElement('input[name="location"]');
if (locInput) {
locInput.value = location;
locInput.dispatchEvent(new Event('input', { bubbles: true }));
const saveBtn = document.querySelector('[data-testid="ProfileSaveButton"]');
if (saveBtn) {
await clickElement(saveBtn);
log(`Location updated to "${location}"!`, 'success');
return true;
}
}
return false;
},
// Update website
updateWebsite: async (url) => {
window.location.href = 'https://x.com/settings/profile';
await sleep(2000);
const urlInput = await waitForElement('input[name="url"]');
if (urlInput) {
urlInput.value = url;
urlInput.dispatchEvent(new Event('input', { bubbles: true }));
const saveBtn = document.querySelector('[data-testid="ProfileSaveButton"]');
if (saveBtn) {
await clickElement(saveBtn);
log(`Website updated to "${url}"!`, 'success');
return true;
}
}
return false;
},
// Open avatar picker
updateAvatar: async () => {
window.location.href = 'https://x.com/settings/profile';
await sleep(2000);
const avatarBtn = document.querySelector('[data-testid="ProfileAvatarInput"]');
if (avatarBtn) {
await clickElement(avatarBtn);
log('Avatar picker opened - select file manually', 'warning');
return true;
}
return false;
},
// Open header picker
updateHeader: async () => {
window.location.href = 'https://x.com/settings/profile';
await sleep(2000);
const headerBtn = document.querySelector('[data-testid="ProfileHeaderInput"]');
if (headerBtn) {
await clickElement(headerBtn);
log('Header picker opened - select file manually', 'warning');
return true;
}
return false;
},
// Switch to professional account
switchToProfessional: async () => {
window.location.href = 'https://x.com/i/flow/convert_to_professional';
await sleep(2000);
log('Professional account flow opened', 'success');
return true;
},
};
// ============================================
// SECTION 8: UTILITIES & HIDDEN FEATURES
// ============================================
const utils = {
// Get current user info
getCurrentUser: () => {
const accountSwitcher = document.querySelector('[data-testid="SideNav_AccountSwitcher_Button"]');
if (accountSwitcher) {
const text = accountSwitcher.textContent;
const match = text.match(/@(\w+)/);
if (match) return match[1];
}
return null;
},
// Check if logged in
isLoggedIn: () => {
return document.querySelector('[data-testid="SideNav_AccountSwitcher_Button"]') !== null;
},
// Get authentication tokens (for API use - be careful!)
getTokens: () => {
const cookies = document.cookie.split(';').reduce((acc, cookie) => {
const [key, value] = cookie.trim().split('=');
acc[key] = value;
return acc;
}, {});
return {
ct0: cookies.ct0, // CSRF token
authToken: cookies.auth_token,
};
},
// Extract tweet ID from URL
getTweetIdFromUrl: (url) => {
const match = url?.match(/status\/(\d+)/);
return match ? match[1] : null;
},
// Extract username from URL
getUsernameFromUrl: (url) => {
const match = url?.match(/x\.com\/(\w+)/);
return match ? match[1] : null;
},
// Wait for page load
waitForPageLoad: async () => {
await waitForElement(SEL.primaryColumn);
await sleep(500);
return true;
},
// Scroll and load more content
loadMore: async (times = 3) => {
for (let i = 0; i < times; i++) {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
await sleep(2000);
}
return true;
},
// Clear all X data from localStorage
clearXData: () => {
Object.keys(localStorage)
.filter(k => k.includes('twitter') || k.includes('x.com') || k.startsWith('xactions_'))
.forEach(k => localStorage.removeItem(k));
log('X data cleared from localStorage', 'success');
},
// Export bookmarks (scroll through and collect)
exportBookmarks: async (maxItems = 100) => {
log('Exporting bookmarks...', 'action');
window.location.href = 'https://x.com/i/bookmarks';
await sleep(2000);
const bookmarks = [];
let lastHeight = 0;
while (bookmarks.length < maxItems) {
const tweets = document.querySelectorAll(SEL.tweet);
tweets.forEach(tweet => {
const link = tweet.querySelector(SEL.tweetLink)?.href;
const text = tweet.querySelector(SEL.tweetText)?.textContent;
if (link && !bookmarks.find(b => b.link === link)) {
bookmarks.push({ link, text: text?.substring(0, 100) });
}
});
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
await sleep(2000);
if (document.body.scrollHeight === lastHeight) break;
lastHeight = document.body.scrollHeight;
}
log(`Exported ${bookmarks.length} bookmarks!`, 'success');
return bookmarks;
},
// Export likes
exportLikes: async (username, maxItems = 100) => {
log(`Exporting likes from @${username}...`, 'action');
window.location.href = `https://x.com/${username}/likes`;
await sleep(2000);
const likes = [];
let lastHeight = 0;
while (likes.length < maxItems) {
const tweets = document.querySelectorAll(SEL.tweet);
tweets.forEach(tweet => {
const link = tweet.querySelector(SEL.tweetLink)?.href;
if (link && !likes.includes(link)) {
likes.push(link);
}
});
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
await sleep(2000);
if (document.body.scrollHeight === lastHeight) break;
lastHeight = document.body.scrollHeight;
}
log(`Exported ${likes.length} likes!`, 'success');
return likes;
},
// Copy to clipboard
copyToClipboard: async (text) => {
try {
await navigator.clipboard.writeText(text);
log('Copied to clipboard!', 'success');
return true;
} catch (e) {
log('Clipboard access denied', 'error');
return false;
}
},
// Screenshot tweet (opens in new tab for saving)
screenshotTweet: async (tweetUrl) => {
// Use a screenshot service
const id = utils.getTweetIdFromUrl(tweetUrl);
if (id) {
window.open(`https://tweetpik.com/${id}`, '_blank');
log('Screenshot service opened', 'success');
return true;
}
return false;
},
// Enable keyboard shortcuts display
showKeyboardShortcuts: async () => {
// Press ? to show shortcuts
document.dispatchEvent(new KeyboardEvent('keydown', { key: '?' }));
log('Keyboard shortcuts triggered', 'success');
return true;
},
// Developer mode - show hidden elements
devMode: () => {
// Show all data-testid attributes
document.querySelectorAll('[data-testid]').forEach(el => {
el.style.outline = '1px solid red';
el.title = el.getAttribute('data-testid');
});
log('Dev mode enabled - elements outlined', 'success');
},
// Get all data-testid selectors on page
getAllSelectors: () => {
const selectors = new Set();
document.querySelectorAll('[data-testid]').forEach(el => {
selectors.add(el.getAttribute('data-testid'));
});
return Array.from(selectors).sort();
},
};
// ============================================
// SECTION 9: SPACES & COMMUNITIES
// ============================================
const spaces = {
// View live spaces
browse: async () => {
window.location.href = 'https://x.com/i/spaces';
await sleep(2000);
return true;
},
// Join a space
join: async (spaceId) => {
window.location.href = `https://x.com/i/spaces/${spaceId}`;
await sleep(2000);
const joinBtn = await waitForElement('[data-testid="SpaceJoinButton"]');
if (joinBtn) {
await clickElement(joinBtn);
log('Joined space!', 'success');
return true;
}
return false;
},
// Leave current space
leave: async () => {
const leaveBtn = await waitForElement('[data-testid="SpaceLeaveButton"]');
if (leaveBtn) {
await clickElement(leaveBtn);
log('Left space!', 'success');
return true;
}
return false;
},
// Request to speak
requestToSpeak: async () => {
const requestBtn = await waitForElement('[data-testid="SpaceRequestSpeaker"]');
if (requestBtn) {
await clickElement(requestBtn);
log('Requested to speak!', 'success');
return true;
}
return false;
},
// Set reminder for scheduled space
setReminder: async (spaceId) => {
window.location.href = `https://x.com/i/spaces/${spaceId}`;
await sleep(2000);
const reminderBtn = await waitForElement('[data-testid="SpaceReminder"]');
if (reminderBtn) {
await clickElement(reminderBtn);
log('Reminder set!', 'success');
return true;
}
return false;
},
// Share space
share: async () => {
const shareBtn = await waitForElement('[data-testid="SpaceShareButton"]');
if (shareBtn) {
await clickElement(shareBtn);
await sleep(500);
const copyBtn = await waitForElement('[data-testid="SpaceCopyLink"]');
if (copyBtn) {
await clickElement(copyBtn);
log('Space link copied!', 'success');
return true;
}
}
return false;
},
};
const communities = {
// Browse communities
browse: async () => {
window.location.href = 'https://x.com/i/communities';
await sleep(2000);
return true;
},
// View a community
view: async (communityId) => {
window.location.href = `https://x.com/i/communities/${communityId}`;
await sleep(2000);
return true;
},
// Join a community
join: async (communityId) => {
await communities.view(communityId);
const joinBtn = await waitForElement('[data-testid="CommunityJoin"]');
if (joinBtn) {
await clickElement(joinBtn);
log('Joined community!', 'success');
return true;
}
return false;
},
// Leave a community
leave: async (communityId) => {
await communities.view(communityId);
const moreBtn = await waitForElement('[data-testid="CommunityActions"]');
if (moreBtn) {
await clickElement(moreBtn);
await sleep(500);
const menuItems = document.querySelectorAll(SEL.menuItem);
for (const item of menuItems) {
if (item.textContent.toLowerCase().includes('leave')) {
await clickElement(item);
log('Left community!', 'success');
return true;
}
}
}
return false;
},
// Post in community
post: async (communityId, text) => {
window.location.href = `https://x.com/i/communities/${communityId}`;
await sleep(2000);
// Click tweet button which will post to community
const composeBtn = document.querySelector('[data-testid="SideNav_NewTweet_Button"]');
if (composeBtn) {
await clickElement(composeBtn);
await sleep(800);
const textarea = await waitForElement(SEL.tweetTextarea);
if (textarea) {
await typeText(textarea, text);
await sleep(500);
const postBtn = document.querySelector(SEL.tweetButton);
if (postBtn && !postBtn.disabled) {
await clickElement(postBtn);
log('Posted to community!', 'success');
return true;
}
}
}
return false;
},
};
// Expose ALL sections
log('XActions FULL library loaded!', 'success');
return {
SEL,
tweet,
engage,
user,
dm,
search,
nav,
lists,
settings,
profile,
utils,
spaces,
communities,
};
})();
console.log(`
╔══════════════════════════════════════════════════════════════════════╗
║ 📦 XActions Library - COMPLETE (All 9 Sections) ║
╠══════════════════════════════════════════════════════════════════════╣
║ ✅ XActions.tweet - Post, reply, quote, delete, pin, thread ║
║ ✅ XActions.engage - Like, RT, bookmark, share, highlight ║
║ ✅ XActions.user - Follow, block, mute, lists, restrict ║
║ ✅ XActions.dm - Send, group, react, GIFs, delete ║
║ ✅ XActions.search - Query, filters, advanced operators ║
║ ✅ XActions.nav - Navigation, tabs, scroll, timeline ║
║ ✅ XActions.lists - Create, edit, delete, follow, pin ║
║ ✅ XActions.settings - Account, privacy, muted words ║
║ ✅ XActions.profile - Edit name, bio, location, avatar ║
║ ✅ XActions.utils - Tokens, export, dev mode, clipboard ║
║ ✅ XActions.spaces - Join, leave, request speaker, share ║
║ ✅ XActions.communities - Browse, join, leave, post ║
╠══════════════════════════════════════════════════════════════════════╣
║ 💡 Example: XActions.tweet.post("Hello!") ║
║ 💡 Example: XActions.user.follow("elonmusk") ║
║ 💡 Example: XActions.search.advanced({from:"user", minFaves:100}) ║
╚══════════════════════════════════════════════════════════════════════╝
`);
⚡ More XActions Scripts
Browse 300+ free browser scripts for X/Twitter automation. No API keys, no fees.
Browse All Scripts