새로운 실험 : 자동 보팅

in #test7 years ago (edited)

이게 잘 될지는 아직 미지수 지만 일단 테스트 ...

조건

  • 20분 마다 한번 씩 보팅을 수행
  • 해당 시점 기준 kr태그에서 조회
  • 100번째 이전 글 부터 탐색 후 아래 조건에 부합하는지 확인 ( 대략 1시간 정도 지났는데 인기가 조금 있는데 보상이 너무 없는 글? )
  • 제목에서 특정 단어 필터링
  • 1000자 이상 작성
  • 특정 사용자도 배제 ( krguidedog 에게 걸린 id를 수동으로 추가)
  • 보팅이 1이상 5이하
  • 수익이 0.5 달러 미만
  • 10% 파워로 보팅

이러면 하루 72번 큐레이팅 성공 !!

  • 나머지는 #kr-dev #kr-baby 에서 맘에 드는 글에 보팅 수동으로 보팅 !!
  • 해보고 결과물 봐서 좋게 나오면 지속적으로 할지 여부를 생각
  • 어떻게 해야 좋은 글을 찾을 수 있을까는 지속적으로 생각해 볼 예정...
  • 일단 뉴스 리뉴얼 작업이 완료 될 때까지 유지 할 예정 입니다.

@hr1 계정에 보팅 받은 것도 많아 유사하게 만들어 봤습니다.

혹시 위 글 관련하여 긍정/부정의 의견 주시면 확인 후 최대한 반영하겠습니다.
( 다운 보팅 한번 받고난 이후로 대중에 민감한지라... )

현재 나오는 결과물


launched at : 18/3/27 16:52
| title | 불꽃보다 화려한 눈꽃보다 단아한 곳 | url | https://steemit.com/kr/@kyju/pum9c | voting | 4 | reward | 0.12 | created | 18/3/27 16:14 | gap | 37 min |


launched at : 18/3/27 17:01
| title | 입장료 대신 라면 받는 콘서트 | url | https://steemit.com/kr/@paramil/7agfbv | voting | 5 | reward | 0.06 | created | 18/3/27 16:16 | gap | 44 min |


( 필요하실 분이 있을까나 ? 일단 그냥 참조하시라고 올려 봅니다. )

source : nodejs

const steem = require('steem');
const f = require('util').format;
const fs = require('fs');
const schedule = require('node-schedule');
const dateFormat = require('dateformat');

/*
    autovot

    자동 보팅 룰
        20분 단위로 수행
        kr 태그 사용자 중 최신글 기준 100번째 이전 글 부터 조회
        제목에서 한글이 포함된 단어만
        제목에서 특정 단어 필터링 ( 보팅, 이벤트, 가상화폐 등 )
        특정 사용자 제외 ( kr-guide 신고 당한 글 등 )
        보팅 회수가 1~5회 ( 0회는 너무 이상한 글이 많이 탐지됨에 제외, 5회 이상은 이미 유명글 )
        보상금액 약 0.5$ 이하 ( 보상금액 계산부분은 스달 시세와 연동 되 있어서 약간 차이날 수 있음 )
    
    참조
        기존에 보팅 목록에 있더라도 하단에 제가 정한 룰을 벗어나는 글은 임의로 보팅을 회수하는 점을 알려 드립니다.
        제가 정한 룰에 벗어나도 다운보팅은 없으며, 보팅을 회수 할 뿐 입니다. ^^
        룰은 임의로 추가되거나 삭제 될 수 있습니다.
    
    보팅 회수 대상
        저작권 침해 관련 글
        kr-guide 신고건
        이미지 딸랑에 복붙 글
*/

// 설정
const CREATOR = "내계정명";
const PRIVATE_KEY = "내 계정 개인키";

// API 접속 RPC 서버를 설정한다
steem.api.setOptions({ url: 'https://api.steemit.com' });

// 대략 이렇게 쿼리를 설정하면 30분 이전의 컨텐츠가 추출된다.
const FIND_LIMIT = 100;
var query = {
    limit: FIND_LIMIT,
    tag: 'kr'
};

// 가장 최근에 보팅한 아이디 - 동일한 경우 제외 다음 글로 ...
var lastvote = "";

// 제외 대상 제목
const BAN_TITLE = [
    "보팅", "이벤트", "코인", "ico", "ICO", "가상화폐", "암호화폐", "에어드랍", "무료토큰"
];

// 제외 대상 아이디
const BAN_ID = [
    { "id" : "ansony" , "cause" : "krguide", "date" : "180328" }
];

const BODY_MIN = 1000;
const VOTE_MIN = 1;
const VOTE_MAX = 5;
const VOTE_RATE = 100*10;   // 10%로 보팅
const VOTE_DOLLOR_DIV = 330125227228; // 가변적 임 : 수익을 vote_rshares로 나눠서 해당 값을 변경 해야 될듯 자주...
const VOTE_DOLLOR_LIMIT = 0.5; // 수익이 0.5달러 미만

Date.prototype.addHours = function(h) {
    this.setTime(this.getTime() + (h * 60 * 60 * 1000));
    return this;
}

function getLocalTime(created) {
    created = created.replace("T", " ")
    var t = new Date(created).addHours(9);
    return t;
}

function getFormadate(t) {
    return t.toLocaleDateString('ko-KR').substr(2).replace(/-/gi, "/") + " " + t.toLocaleTimeString('en-US', { hour12: false }).substr(0, 5);
}

function vote() {
    steem.api.getDiscussionsByCreated(query, function(err, result) {

        var findIdx = 1;

        if (err != undefined) {
            // 오류 내용을 기록한다
            fs.appendFile('votebot.err', err, function(e1) {
                // if (e) throw err;
            });
        }

        while (findIdx < FIND_LIMIT) {
            var item = result[result.length - findIdx];

            // console.log( item.active_votes.length );

            
            var isMatchBan = false;

            // 필터링 : 제목에 한글이 한글자도 포함이 안됨
            if(!wsm.isHangul(item.root_title)){
                isMatchBan = true;
            }

            // 필터링 : 타이틀 특정 문구 제거
            if(!isMatchBan){
                BAN_TITLE.forEach(ban => {
                    if (item.root_title.indexOf(ban) >= 0) {
                        isMatchBan = true;
                    }
                });    
            }

            // 필터링 : 아이디 기준으로 차단
            if(!isMatchBan){
                BAN_ID.forEach(ban => {
                    if (item.author == ban.id ) {
                        isMatchBan = true;
                    }
                });
            }

            // 필터링 : 최대 보팅 횟수 제한
            var vcnt = item.active_votes.length;

            // 필터링 : 최대 보팅 금액 제한
            var _vdol = isNaN(item.vote_rshares) ? 1 : Number(item.vote_rshares);
            var vdol = Math.round((_vdol / VOTE_DOLLOR_DIV) * 100) / 100;

            // [보팅, 이벤트]이라는 단어가 제목에 포함 안되어 있고
            // 최소 1회 보팅 및 5회 이하로 보팅이 되어야 됨
            // 또한 수익이 1달러 미만인 케이스
            // 특정 아이디 제한 
            // krguidedog이 포함되면 안됨 => 댓글에 포함되는 것은 확인 불가함
            if (!isMatchBan && vcnt >= VOTE_MIN && vcnt <= VOTE_MAX && vdol < VOTE_DOLLOR_LIMIT && item.body_length>=BODY_MIN && lastvote!=item.author) {
                const OUT_TEMPLATE = "| title | %s | url | https://steemit.com%s | voting | %d | reward | %d | created | %s | gap | %d min |\n";
                var created = getLocalTime(item.created);
                var created_fmt = getFormadate(created);
                var gap = Math.floor(((new Date() - created) / 1000) / 60); // min
                const OUT_RESULT = f(OUT_TEMPLATE, item.title, item.url, vcnt, vdol, created_fmt, gap);

                // 실제 보팅을 수행한다
                var wif = steem.auth.toWif(CREATOR, PRIVATE_KEY, 'posting');
                steem.broadcast.vote(wif,CREATOR,item.author, item.permlink, VOTE_RATE, function(e1, r) {
                    // 최근 투표한 아이디 정보 업데이트 
                    lastvote=item.author;

                    // 날짜별 파일에 보팅 정보 기록
                    fs.appendFile('votebot_'+dateFormat(new Date(), "yymmdd")+'.txt', OUT_RESULT, function(e2) {
                        // console.log(item);
                        console.log(OUT_RESULT);
                    });
                });
                break;
            }

            findIdx++;
        }
    });
}

// every 
var j = schedule.scheduleJob('1,20,40 * * * *', function(){
    console.log("launched at : " + getFormadate(new Date()) );
    vote();
});

// wsm
var wsm = {};
wsm.isHangul = (s)=> {
    const pattern = /[\u3131-\u314e|\u314f-\u3163|\uac00-\ud7a3]/g;
    return pattern.test(s);
};
Sort:  

어떻게 하면 사용 할 수 있습니까

nodejs 설치 이후 위 소스를 붙여넣기 한 이후 설정 부분을 약간 수정하여 동작시키면 됩니다 ^^

하지만 기초지식이 없는 상태에서 바로 적용은 어려울 수도 있으니... 책 또는 네이버나 구글링으로 기초 지식을 얻은 후 해보심을 추천 드립니다 ^^

와 멋지네요 언어는 파이썬 인가요?
혹 자동등록 소스 좀 어떻게 볼 수가 있을까용~~~^^
저도 뭐 만들어 보고 싶어서요 ㅎㅎㅎ ^^
글 가져갑니다~~~^^

자동으로 보팅하는 것입니다. 글쓰기는 아니고여 ^^;
nodejs로 만든 것 입니다.

와 멋지심

^^ 응원 감사요

와... 응원합니다!

응원 감사합니다

좋은 일 하십니다~~ 굿~~

아직은 초기인지라 ^^ 더욱 정진하겠습니다.

소스공개 감사합니다~

현재는 올려 놓은 소스에서 좀 더 많이 추가가 되긴 했는데 이 또한 나중에 포스팅해서 올리겠습니다.

필터링 부분이랑 파일 처리 부분이 변경 promise 적용을 통한 콜백 hell 최소화 등

Coin Marketplace

STEEM 0.21
TRX 0.20
JST 0.033
BTC 97309.89
ETH 3288.22
USDT 1.00
SBD 2.99