Skip to content

Commit

Permalink
Initial commit of version 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
3urobeat committed Jan 15, 2020
1 parent e3f9423 commit c103965
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 1 deletion.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ You can either provide multiple quotes for a random one every time or only one f
The start script will start as many bots as you provide login-informations for. If you are planning to build your bot imperium this could be a great place to start from.
Continue reading for a detailed setup guide.

**Disclaimer!** > I am not responsible and cannot be held liable for any action the operator/user of this bot uses it for.
**Disclaimer!** > I am not responsible and cannot be held liable for any action the operator/user of this bot uses it for.
If you, the user, download or use this application, you agree that only you are responsible for any action.

## Requirements

Expand Down Expand Up @@ -39,12 +40,17 @@ Open `config.json` with a text editor. You can customize the values below `versi
| ------------- | ---------------- | ----- |
| mode | 1 or 2 | Mode 1: All bots you have logininformations provided for will start up and work for themselves. Mode 2: The first logininfo will start a bot and when a comment is requested all accounts you have provided logininfos for will comment under that one profile. |
| status | [Status Codes](https://github.com/DoctorMcKay/node-steam-user/blob/master/enums/EPersonaState.js) | Sets your status. (Online, Busy etc.) |
| commentdelay | Delay in ms | Adds a delay between each comment to prevent a cooldown from steam. Default: 5000
| logindelay | Delay in ms | Adds a delay between each login when the bot is started to prevent a cooldown from steam. Default: 2500
| game | "my game name" | This custom text will be shown on your profile as the name of a game you are playing. |
| yourgroup | "link to my group" | Advertise your group with the !group command. Leave it empty (like this: "") to disable the command. |
| yourgroup64id | "my group64id" | [How do I get this ID?](https://steamcommunity.com/sharedfiles/filedetails/?id=1344514370) The bot will send a group invite instead of the link to your group from above. If no ID is provided, the bot will send the link from above but no invite. |
| owner | "link to my profile" | Advertise your own profile with the !owner command. Leave it empty (like this: "") to disable the command. |


Open `quotes.txt` with a text editor. You can add as many quotes as you want, line by line. **Don't leave an empty line anywhere in this file!**
The bot will choose a random quote for **every** comment. If you only provide one quote, the bot will only use that quote.

The bot(s) is/are now setup.

## Starting the bot
Expand Down
154 changes: 154 additions & 0 deletions bot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
//Code by: https://github.com/HerrEurobeat/

module.exports.run = async (logOnOptions, loginindex) => {
const SteamUser = require('steam-user');
const SteamCommunity = require('steamcommunity');
const SteamID = require('steamid');
var start = require("./start.js")
const config = require('./config.json');
const logininfo = require('./logininfo.json');
var logger = start.logger

const bot = new SteamUser();
const community = new SteamCommunity();

if (config.mode === 1) var thisbot = `Bot ${loginindex}`
else var thisbot = "Main"

var loggedininterval = setInterval(() => { //set an interval to check if previous acc is logged on
if(start.accisloggedin === true) {
bot.logOn(logOnOptions)
start.accisloggedin = false; //set to false again
clearInterval(loggedininterval) //stop interval
}
}, 250);

bot.on('steamGuard', function(domain, callback) {
process.stdout.write(`[${logOnOptions.accountName}] Steam Guard Code: `)
var stdin = process.openStdin();

stdin.addListener('data', text => {
var code = text.toString().trim()
callback(code);

stdin.pause() //stop reading
})
});

//Log in:
bot.on('loggedOn', () => {
start.accisloggedin = true; //set to true to log next account in
bot.setPersona(config.status);
if (config.mode === 1) { //individual mode
bot.gamesPlayed([config.game,730]); //set game for all bots
} else if (config.mode === 2) { //connected mode
if (loginindex === 0) bot.gamesPlayed([config.game,730]); //set game only for the "leader" bot
}

start.communityobject[loginindex] = community //export this community instance to the communityobject
start.botobject[loginindex] = bot //export this bot instance to the botobject
});

bot.on("webSession", (sessionID, cookies) => {
community.setCookies(cookies);
//Accept offline group & friend invites
for (let i = 0; i < Object.keys(bot.myFriends).length; i++) { //Credit: https://dev.doctormckay.com/topic/1694-accept-friend-request-sent-in-offline/
if (bot.myFriends[Object.keys(bot.myFriends)[i]] == 2) {
bot.addFriend(Object.keys(bot.myFriends)[i]);
logger(`[${thisbot}] Added user while I was offline! User: ` + Object.keys(bot.myFriends)[i])
bot.chatMessage(Object.keys(bot.myFriends)[i], 'Hello there! Thanks for adding me!\nRequest a free comment with !comment\nType !help for more info!')
bot.inviteToGroup(Object.keys(bot.myFriends)[i], new SteamID(config.yourgroup64id));
}}
for (let i = 0; i < Object.keys(bot.myGroups).length; i++) {
if (bot.myGroups[Object.keys(bot.myGroups)[i]] == 2) {
bot.respondToGroupInvite(Object.keys(bot.myGroups)[i], true)
logger(`[${thisbot}] Accepted group invite while I was offline: ` + Object.keys(bot.myGroups)[i])
}}
});

//Message interactions
bot.on('friendMessage', function(steamID, message) {
if (loginindex > 0) {
switch(message.toLowerCase()) {
case '!help':
if (config.owner.length > 1) var ownertext = "\nType !owner to check out my owner's profile!"; else var ownertext = "";
if (config.yourgroup.length > 1) var yourgrouptext = "\n\nJoin my !group"; else var yourgrouptext = "";
bot.chatMessage(steamID, `Type !comment to get a free comment!\nType !ping for a pong!\nType !about for credit.${ownertext}${yourgrouptext}`)
break;
case '!comment':
community.getSteamUser(bot.steamID, (err, user) => { //check if acc is limited and if yes if requester is on friendlist
if(user.isLimitedAccount && !Object.keys(bot.myFriends).includes(new SteamID(steamID.getSteam3RenderedID()).getSteamID64())) return bot.chatMessage(steamID, "You have to send me a friend request before I can comment on your profile!")})
community.getSteamUser(steamID, (err, user) => { //check if profile is private
if(user.privacyState !== "public") return bot.chatMessage(steamID, "Your profile seems to be private. Please edit your privacy settings on your profile and try again!") });

var randomstring = arr => arr[Math.floor(Math.random() * arr.length)];
var comment = randomstring(start.quotes);
community.postUserComment(steamID, comment, (error) => {
if(error !== null) { logger(`[${thisbot}] postUserComment error: ${error}`); return; }
logger(`[${thisbot}] Comment: ${comment}`)
if (config.mode === 1) bot.chatMessage(steamID, 'Okay I commented on your profile! If you are a nice person then leave a +rep on my profile!')
else {
var waittime = (Object.keys(logininfo).length * config.commentdelay) / 1000
var waittimeunit = "seconds"
if (waittime > 120) { var waittime = waittime / 60; var waittimeunit = "minutes" }
if (waittime > 120) { var waittime = waittime / 60; var waittimeunit = "hours" }
bot.chatMessage(steamID, `Estimated wait time for ${Object.keys(logininfo).length} comments: ${Number(Math.round(waittime+'e'+3)+'e-'+3)} ${waittimeunit}.`) }
})

if (config.mode === 2) {
start.commenteverywhere(steamID) //Let all other accounts comment if the mode is activated
bot.chatMessage(steamID, `The other ${Object.keys(logininfo).length} comments should follow with a delay of ${config.commentdelay}ms.`)
}
break;
case '!ping':
bot.chatMessage(steamID, 'Pong!')
break;
case '!owner':
if (config.owner.length < 1) return bot.chatMessage(steamID, "I don't know that command. Type !help for more info.")
bot.chatMessage(steamID, "Check my owner's profile: '" + config.owner + "'")
break;
case '!group':
if (config.yourgroup.length < 1 && config.yourgroup64id.length < 1) return bot.chatMessage(steamID, "I don't know that command. Type !help for more info.") //no group info at all? stop.
if (config.yourgroup64id.length > 1) { bot.inviteToGroup(steamID, new SteamID(config.yourgroup64id)); bot.chatMessage(steamID, "I send you an invite! Thanks for joining!"); return; } //id? send invite and stop
bot.chatMessage(steamID, "Join my group here: " + config.yourgroup) //seems like no id has been saved but an url. Send the user the url
break;
case '!about':
if (config.owner.length > 1) var ownertext = config.owner; else var ownertext = "anonymous (no owner link provided)";
bot.chatMessage(steamID, `This bot was created by 3urobeat.\nGitHub: https://github.com/HerrEurobeat/steam-comment-service-bot \nSteam: https://steamcommunity.com/id/3urobeat \nDisclaimer: I (the developer) am not responsible and cannot be held liable for any action the operator/user of this bot uses it for.\n\nThis instance of the bot is used and operated by: ${ownertext}`)
break;
default:
bot.chatMessage(steamID, "I don't know that command. Type !help for more info.") }
} else {
if (config.mode === 2) {
switch(message.toLowerCase()) {
case '!about':
if (config.owner.length > 1) var ownertext = config.owner; else var ownertext = "anonymous (no owner link provided)";
bot.chatMessage(steamID, `This bot was created by 3urobeat.\nGitHub: https://github.com/HerrEurobeat/steam-comment-service-bot \nSteam: https://steamcommunity.com/id/3urobeat \nDisclaimer: I (the developer) am not responsible and cannot be held liable for any action the operator/user of this bot uses it for.\n\nThis instance of the bot is used and operated by: ${ownertext}`)
break;
default:
bot.chatMessage(steamID, "This is one account running in a bot cluster.\nPlease add the main bot and send him a !help message.\nIf you want to check out what this is about, type: !about")
}}
}
logger(`[${thisbot}] Friend message from ${steamID.getSteam3RenderedID()}: ${message}`);
});

//Friend requests
bot.on('friendRelationship', (steamid, relationship) => {
if (relationship === 2) {
bot.addFriend(steamid);
logger(`[${thisbot}] Added User: ` + steamid)
bot.chatMessage(steamid, 'Hello there! Thanks for adding me!\nRequest a free comment with !comment\nType !help for more info!');
}
});

bot.on('groupRelationship', (steamid, relationship) => {
if (relationship === 2) {
bot.respondToGroupInvite(steamid, true)
logger(`[${thisbot}] Accepted group invite: ` + steamid)
}
});

module.exports={
bot
}
}
12 changes: 12 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "2.0",

"mode": 2,
"status": 1,
"commentdelay": 5000,
"logindelay": 2500,
"game": "!help | 3urobeat",
"yourgroup": "https://steamcommunity.com/groups/3urobeatGroup",
"yourgroup64id": "103582791464712227",
"owner": "https://steamcommunity.com/id/3urobeat/"
}
3 changes: 3 additions & 0 deletions quotes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
comment1
comment2
comment3
98 changes: 98 additions & 0 deletions start.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//Code by: https://github.com/HerrEurobeat/

var b = require('./bot.js');
const logininfo = require('./logininfo.json');
const config = require('./config.json');
const SteamID = require('steamid');
var fs = require("fs");

var communityobject = new Object();
var botobject = new Object();
const d = function d() { return new Date(); }
var bootstart = 0;
var bootstart = d();


//Functions:
var logger = function logger(string) { //Custom logger
console.log(string)
fs.appendFileSync('./output.txt', string.replace(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/g, '') + '\n', err => { //Credit: https://github.com/Filirom1/stripcolorcodes
if(err) logger(LOGERR + 'Error: ' + err) }) }

process.on('unhandledRejection', (reason, p) => {
logger(`Unhandled Rejection! Reason: ${reason.stack}`) });

var quotes = new Array();
var quotes = fs.readFileSync('quotes.txt', 'utf8').split("\n"); //get all quotes from the quotes.txt file into an array

var commenteverywhere = function commenteverywhere(steamID) { //function to let all bots comment
var failedcomments = new Array();
Object.keys(communityobject).forEach((k, i) => {
if (i < 1) return; //first account already commented

communityobject[k].getSteamUser(botobject[k].steamID, (err, user) => { //check if acc is limited and if yes if requester is on friendlist
if(user.isLimitedAccount && !Object.keys(botobject[k].myFriends).includes(new SteamID(steamID.getSteam3RenderedID()).getSteamID64())) return failedcomments.push(botobject[k].steamID.getSteam3RenderedID())})
communityobject[k].getSteamUser(steamID, (err, user) => { //check if profile is private
if(user.privacyState !== "public") return failedcomments.push(botobject[k].steamID.getSteam3RenderedID())});

var randomstring = arr => arr[Math.floor(Math.random() * arr.length)];
var comment = randomstring(quotes);
setTimeout(() => {
communityobject[k].postUserComment(steamID, comment, (error) => {
if(error !== null) { logger(`[Bot ${k}] postUserComment error: ${error}`); failedcomments.push(botobject[k].steamID.getSteam3RenderedID()); return; }
logger(`[Bot ${k}] Comment: ${comment}`) })

if (Object.keys(communityobject).length === i+1) { botobject[0].chatMessage(steamID, `All comments have been sent. Failed: ${failedcomments.length}/${i+1}`) }
}, config.commentdelay * i); //delay every comment
})}

accisloggedin = true; //var to check if previous acc is logged on (in case steamGuard event gets fired) -> set to true for first account

module.exports={
logger,
communityobject,
botobject,
commenteverywhere,
quotes,
accisloggedin }

//Size of accounts - 1 (first acc logs in instantly) * logindelay -> wait time / 100 -> ms to seconds + 1 tolerance second
logger(`\x1b[34m[${bootstart}]\x1b[0m Logging in... Estimated wait time: ${((config.logindelay * (Object.keys(logininfo).length - 1)) / 1000) + 1} seconds.`)

//Logging in:
Object.keys(logininfo).forEach((k, i) => {
setTimeout(() => {
var logOnOptions = {
accountName: logininfo[k][0],
password: logininfo[k][1],
promptSteamGuardCode: false,
machineName: "3urobeat's Commment Bot"
};
b.run(logOnOptions, i);
}, config.logindelay * i);
})

if (config.mode !== 1 && config.mode !== 2) {
logger("\x1b[31mThe mode you provided is invalid! Please choose between 1 or 2. Aborting...\x1b[0m")
process.exit(0); }


var readyinterval = setInterval(() => { //log startup to console
if (Object.keys(communityobject).length === Object.keys(logininfo).length) {
logger(' ')
logger('*------------------------------------------*')
if (config.mode === 2) logger(`\x1b[34m${logininfo.bot1[0]}\x1b[0m version ${config.version} with ${Object.keys(communityobject).length - 1} accounts logged in.`);
else logger(`Started ${Object.keys(logininfo).length} accounts version ${config.version}.`);

communityobject[0].getSteamUser(botobject[0].steamID, (err, user) => { //display warning if account is limited
if(user.isLimitedAccount) var limitedacc = "Leader Bot has a \x1b[31mlimited account\x1b[0m!";
else var limitedacc = ""
logger(`Using Mode ${config.mode}. ${limitedacc}`)
const bootend = d() - bootstart
logger('Ready after ' + bootend + 'ms!')
logger('*------------------------------------------*')
logger(' ')
})
clearInterval(readyinterval)
}
}, 100);

1 comment on commit c103965

@3urobeat
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good old times...

Please sign in to comment.