The redditPost
function automates posting on Reddit using Selenium WebDriver, taking parameters such as content, start page, and driver instance to create and submit a post. It handles errors and uses Markdown formatting for the title and body, with optional title generation using a Large Language Model.
npm run import -- "reddit post"
const loginReddit = importer.import("reddit login")
const getClient = importer.import("selenium client")
const getAllQuery = importer.import("selenium query")
const { By } = require('selenium-webdriver')
async function redditPost(driver, content, startPage) {
let {llmPrompt} = await importer.import("create llm session")
if(!startPage.includes('://')) {
startPage = 'https://www.reddit.com/r/' + startPage
}
if(!startPage.includes('/submit')) {
startPage += '/submit?type=TEXT'
}
if(!driver) {
driver = await getClient()
}
await driver.get(startPage)
await loginReddit(driver)
await new Promise(resolve => setTimeout(resolve, 1500))
let titleStr = (/\*\*(.*?)\*\*\n*/gi).exec(content)
if(titleStr) {
content = content.replace(titleStr[0], '')
titleStr = titleStr[1].replaceAll(/[#*"']/gi, '')
} else {
titleStr = await llmPrompt(
'Generate a short title for this summary:\n' +
content)
titleStr = titleStr.replaceAll(/[#*"']/gi, '')
}
try {
let title = await driver.findElement(By.css('faceplate-textarea-input[name*="title"]'))
await title.click()
//await driver.executeScript('arguments[0].click();', title)
await driver.actions().sendKeys(titleStr).perform()
let switchButton = await getAllQuery(driver, [
'shreddit-composer',
'button[aria-label*="Switch to Markdown"]'
])
await driver.executeScript('arguments[0].click();', switchButton[0])
await new Promise(resolve => setTimeout(resolve, 500))
let body = await getAllQuery(driver, [
'shreddit-composer',
'shreddit-markdown-composer',
'textarea[placeholder*="Body"]'
])
await driver.executeScript('arguments[0].click();', body[0])
await driver.actions().sendKeys(content).perform()
let submit = await driver.findElement(By.css('#submit-post-button'))
submit.click()
await new Promise(resolve => setTimeout(resolve, 1500))
} catch (e) {
//driver.quit()
throw e
}
}
module.exports = redditPost
const { By } = require('selenium-webdriver');
const { Client } = require('selenium-webdriver/chrome');
const { Builder } = require('selenium-webdriver');
const loginReddit = require('./reddit login');
const getAllQuery = require('./selenium query');
const importLLM = require('./create llm session');
const puppeteer = require('puppeteer');
/**
* Posts to a subreddit using Reddit's submit page.
*
* @param {string} startPage The name of the subreddit to post to (e.g. 'r/test').
* @param {string} content The content of the post.
* @param {string|object|undefined} driver The Selenium WebDriver instance to use.
* @throws {Error} If an error occurs during the posting process.
*/
async function redditPost(startPage, content, driver) {
// Get the start page URL if the startPage parameter does not include '://'
if (!startPage.includes('://')) {
startPage = `https://www.reddit.com/r/${startPage}`;
}
// Append the post submission URL to the start page if not already present
if (!startPage.includes('/submit')) {
startPage += '/submit?type=TEXT';
}
// Initialize the Selenium driver if none is provided
driver = driver || (await getClient());
// Navigate to the post submission page
await driver.get(startPage);
// Log in to Reddit
await loginReddit(driver);
// Wait for a short period to allow the page to load
await new Promise(resolve => setTimeout(resolve, 1500));
// Extract the title from the content if it is marked up with Markdown headers
let titleStr;
const titleMatch = (/\*\*(.*?)\*\*\n*/gi).exec(content);
if (titleMatch) {
content = content.replace(titleMatch[0], '');
titleStr = titleMatch[1].replaceAll(/[#*"']/gi, '');
} else {
// Otherwise, generate a title using the LLM
const { llmPrompt } = await importLLM();
titleStr = await llmPrompt('Generate a short title for this summary:\n' + content);
titleStr = titleStr.replaceAll(/[#*"']/gi, '');
}
// Try to submit the post
try {
// Click into the title field
const titleField = await driver.findElement(By.css('faceplate-textarea-input[name*="title"]'));
await titleField.click();
// Send the title to the title field
await driver.actions().sendKeys(titleStr).perform();
// Switch to Markdown mode
const switchButton = await getAllQuery(driver, [
'shreddit-composer',
'button[aria-label*="Switch to Markdown"]',
]);
await driver.executeScript('arguments[0].click();', switchButton[0]);
await new Promise(resolve => setTimeout(resolve, 500));
// Click into the body field
const bodyField = await getAllQuery(driver, [
'shreddit-composer',
'shreddit-markdown-composer',
'textarea[placeholder*="Body"]',
]);
await driver.executeScript('arguments[0].click();', bodyField[0]);
// Send the content to the body field
await driver.actions().sendKeys(content).perform();
// Submit the post
const submitButton = await driver.findElement(By.css('#submit-post-button'));
submitButton.click();
// Wait for a short period to allow the post to be submitted
await new Promise(resolve => setTimeout(resolve, 1500));
} catch (error) {
// TODO: Consider logging the error and quitting the driver if desired
throw error;
}
}
// Export the redditPost function
module.exports = redditPost;
// TODO: Consider implementing a retry mechanism for failed post submissions
// TODO: Consider adding a test suite for the redditPost function
// TODO: Consider refactoring the code to use a more robust error handling mechanism
This is a JavaScript function named redditPost
that automates posting on Reddit using Selenium WebDriver. It takes three parameters: driver
, content
, and startPage
.
driver
: The Selenium WebDriver instance. If not provided, it will be created using the getClient
function.content
: The content of the post, which can include a Markdown-formatted title and body.startPage
: The URL of the Reddit subreddit page where the post will be submitted. It will be prepended with https://www.reddit.com/r/
if it doesn't contain a protocol.startPage
is a valid URL and adds https://www.reddit.com/r/
if necessary.startPage
ends with /submit
and appends it if necessary.loginReddit
function.setTimeout
.content
string using a regular expression. If the title is not found, it uses the LLM (Large Language Model) to generate a title.content
string.The function catches any errors that occur during execution and re-throws them.
The function is exported as a module using module.exports = redditPost
.