Deep Follow - NodeJS/SteemJS

in #utopian-io7 years ago (edited)

image.png

Introduction – Deep Follow

This development project will demonstrate how to automatically follow all of the people that who you are following are following. The idea behind this is that all the people that you are following are following worthy people to follow. Why would you be following someone if they weren't following good accounts? Depending on how many people you are following and how many people they are following, this could be a very large number of users to follow. My next project will demonstrate how to unfollow accounts.

First, you will need to get a NodeJS development set-up. You can follow along the articles listed at https://steemit.com/steem/@money-dreamer/summary-of-technical-articles if you need to. Those tutorials are a prerequisite for this tutorial unless if you are already familiar with JavaScript, NodeJS, GIT and the Steemit API.

After getting your development environment set-up, create a file named deep_follow.js. Initialize the node app like npm install steem --save from a terminal. Execute it like node deep_follow.js from a terminal as described in the previous tutorials.

The require statement will bring in all the functions from the Steem library. We set the user/pass and create a log-in session to the Steem blockchain. The followingArray saves the new account so no duplicate following attempts. mTimeout is used to set the timeout so it does not hammer the API.

var steem = require('steem'); 
var username = 'ENTER_USERNAME_HERE'; 
var password = 'ENTER_PASSWORD_HERE'; 
var wif = steem.auth.toWif(username, password, 'posting');
var followingArray = [];
var toFollowArray = [];
var mTimeout = 0;



Let's make a function that will make the call to the API to follow a particular user: doFollow. It accepts the name of the account that will be followed: toFollow. Thus, function doFollow(toFollow). This function set's a timer so that it executes delta seconds from being called. This delta increments by 15 seconds each time. Finally, the parameters to send to the API are built and broadcast to the network.

function doFollow(toFollow) {

    mTimeout = mTimeout + 15;

    setTimeout( function(){

        console.log( "attempt at following: " + toFollow );

        let followReq = ["follow"]
        followReq.push({follower: username, following: toFollow, what: ["blog"]})

        const customJson = JSON.stringify(followReq)

        steem.broadcast.customJsonAsync(wif, [], [username], "follow", customJson)
          .then(console.log)
          .catch(console.log)

    }, mTimeout * 1000 );

    return;

}



The doFollow function is called for each new account found while traversing the current following. There is an inner for loop and an outer for loop. The outer for loop loops over all of your following. The inner loop loops over all of the following for each of the accounts that you are following.

Let's start with the inner loop. It will chunk through the following 100 at a time and if not already added to the toFollow array, then they will be added:

do {
  steem.api.getFollowing(outerEntry, innerStart, 'blog', 100, function(innerErr, innerResult){

    //console.log( innerErr, innerResult );

    innerStart = ''
    innerCount = innerResult.length

    //Inner loop: the followings' accounts following.
    for (let i = 0; i < innerCount; i++) {
      let innerEntry = innerResult[i].following
      outerStart = outerEntry;
      if( ! followingArray.includes(innerEntry) ) {
        followingArray.push(innerEntry);
        toFollowArray.push(innerEntry);
      }
    }
  })
} while (innerCount === 100);



The outer loop will chunk through all of the user's that you are following 100 at a time. As this chunking is taking place, each account is tested against the current following and then followed if they are not already being followed.

let innerStart = '', outerStart = '', innerCount = 0, outerCount = 0;
do {
  steem.api.getFollowing(username, outerStart, 'blog', 100, function(outerErr, outerResult){

    //console.log( outerErr, outerResult );

    outerStart = ''
    outerCount = outerResult.length

    //Outer Loop: this accounts' following.
    for (let i = 0; i < outerCount; i++) {
      let outerEntry = outerResult[i].following;
      outerStart = outerEntry;
      followingArray.push(outerEntry);

      ...
      ...inner loop goes here...
      ...

    }
  })
} while (outerCount === 100);



Let's set a timeout so that the previous code can execute and fill up the array with all of the accounts to follow. This will loop through all of the accounts to follow and attempt to follow them by calling the doFollow function.

setTimeout( function() {
  for (let i = toFollowArray.length - 1; i >= 0; i--) {
      doFollow( toFollowArray[i] );
  }

}, 30000);

Important

Be careful not to use all of your available bandwidth as can be seen on steemd. You can view the progress bar where it says "Bandwidth Remaining". To find your profile, replace my account name with your account name in this URL: https://steemd.com/@money-dreamer Notice the d in steemd.

Follow all the people that you currently follow follows.
End Result: You -> * Following -> * Following
This could be a large number of people to follow depending on whom you already follow!
For example, if you follow one hundred accounts and each of those accounts follow one hundred accounts:
100 * 100 = 10,000 new people to follow!

Running the program twice would not be recommended since it would be such a large number of accounts:
End Result: You -> * Following -> * Following -> * Following
Using example above and adding another level of one hundred:
100 * 10,000 = 1,000,000

There should be many duplicates, so in practice this number would be much smaller.

Further Development

This code could filter out users that you may not want to follow. It should allow you to set parameters to select who to follow such as users with minimum reputation or minimum followers. Some sample parameters would be:

SBD/STEEM Balance
Reputation
Number of Followers
Number of Following
Total Author Rewards
Total Curation Rewards

It would be good to build a throttle so that the logged-in account does not exceed the Bandwidth allocation. More can be learned about Bandwidth Limit at https://steemit.com/steemit/@rycharde/why-are-so-many-users-hitting-their-bandwidth-limit-solved-it-what-you-can-do The ideal situation would be to have the program automatically calculate how often to post based on the changes in Bandwidth allocation.

If you want the code directly, you can clone it from the GitHub repository: https://github.com/AdamCox9/Steem-Deep-Follow



Posted on Utopian.io - Rewarding Open Source Contributors

Sort:  

The script was moved from its' own repository into the Steemit-Follow-Bot repository: https://github.com/AdamCox9/Steemit-Follow-Bot

Thanks for posting this. I'm brand new to steemit and just started exploring the API, but I'm having a lot of trouble with the lack of documentation. Do you have any good resources you could share?

Even the examples in the documentation are limited. For example:

steem.api.getDiscussionsByTrending(query, function(err, result) {
  console.log(err, result);
});

There are tons of examples like this, but I can'd find any documentation on how to properly build the query object. I'm looking to fill in some of these blanks, so any resources you can suggest would be much appreciated!

I'm having the same trouble. I got some of the queries working:

https://github.com/AdamCox9/Steemit-NodeJS-Bot-Tutorial/blob/master/start.js

https://github.com/AdamCox9/Steemit-Follow-Bot/blob/master/follow_trending_authors.js

I hope these samples help. The code in GitHub is a newer version than in the articles.

I finally got somewhere with the the help of this:

https://github.com/steemit/steem-js/issues/256


steem.api.setOptions({ url: 'https://api.steemit.com' });

var query = {
    tag: 'blockchain',
    limit: 10
};

steem.api.getDiscussionsByTrending(query, function (err, discussions) {
  console.log(err, discussions);
});```

Thanks! I will try this out!

It works like a charm for me. I think it really opens up the world for some automation even on a read-only basis.

Heres some good code snippets you might find interesting: https://github.com/drov0/steemsnippets

The fact that it's documented is music to my eyes :) Looking forward to sharing some of my scripts soon!

Here are some really good examples to upvote, downvote, comment and transfer: https://steemit.com/steemjs/@fabien/steem-js-comment-upvote-downvote-transfert-you-wanted-it-you-got-it

Thanks, I'm going to play around more and I'll post my findings.

Your contribution cannot be approved because you are mixing the Development and the Tutorial category.

The development side of your contribution doesn't meet the quality standards on Utopian.

  • Your README.md needs to be more informative and contain all instructions to use your software.
  • Dependencies like steem-js should be managed via a package.json file.
  • Configuration parameters like username/password shouldn't be hard-coded in the source files. It's better to use a .dist file.

The tutorial side of your contribution also contains questionable code, like the way you suggest to use timeouts to handle asynchronous requests.

All in all, this contribution can't be approved in any of both categories. I sincerely recommend to try contributing to other, established projects and learn from them.

If you need help, feel free to ask!

For questions and feedback you can contact us on Discord.
[utopian-moderator]

Thank you for your feedback. I did as you explained for my next project: https://steemit.com/utopian-io/@money-dreamer/steem-memo-bot

Ma man! This post deserves a $100K upvote. We need more documentation and Javascript examples on how to build stuff on top of the Steem Blockchain. This is much appreciated.

I'll make many more articles like this if I get a $100K upvote.

This post has received a 0.48 % upvote from @buildawhale thanks to: @money-dreamer. Send at least 1 SBD to @buildawhale with a post link in the memo field for a portion of the next vote.

To support our daily curation initiative, please vote on my owner, @themarkymark, as a Steem Witness

This post has received a 13.33 % upvote, thanks to: @money-dreamer.

You got a 0.36% upvote from @upme requested by: @money-dreamer.
Send at least 1.5 SBD to @upme with a post link in the memo field to receive upvote next round.
To support our activity, please vote for my master @suggeelson, as a STEEM Witness

You got a 9.91% upvote from @allaz courtesy of @money-dreamer!

You got a 1.47% upvote from @postpromoter courtesy of @money-dreamer!