-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreblog.js
305 lines (222 loc) · 19.5 KB
/
reblog.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
// У вас должен быть установлен nodejs
// Установите зависимости для скрипта командой npm install golos-js
// Постинг ключ аккаунта, который будет делать реблоги
const postingkey = "5JUe9cDhdgpAweWAkFuD72Rs4uCR5ABE1Kыыыыыыыыыыы"
// Фильтр тэгов, "REBLOGGER" будет делать реблог, только если в посте будут указанные тэги
// Массив можно оставить пустым - [], тогда будут учтены любые тэги
const TAGS = ['ru--apvot50-50']
// Белый список авторов, постам которых мы будет делать реблог в блог "REBLOGGER"!
// К этому списку будут автоматически добавлены все, на кого будет подписан "accountfilter"!
let blogs = []
// Логин аккаунта который будет делать реблоги в свой блог
const REBLOGGER = "tester"
// Логин аккаунта который должен подписывать на пользователей, что бы их имена попали в белый список!
// Можно оставить пустым, тогда белый список будет браться из переменной выше - "blogs"
const accountfilter = "tester"
// Текст комментария под постом, которому вы сделали реблог
const COMMENT = `💡 **${REBLOGGER} сделал реблог :)**`
// Заголовок комментария - виден в уведомлениях и при приямой ссылке на комментарий
const TITLE = "Тест работы реблоггера"
// Вес голоса за пост которому вы сделали реблог. 100% = 10000 , 50% = 5000 и т.д.
const VOTEPOWER = 10000
// Если у вас не установлена локальная нода, адрес следует изменить на адрес публичной ноды.
// Например "wss://api.golos.cf" - нода @vik
const GOLOSNODE = "wss://ws.golos.io"
// =================== Ниже не редактируем! =========================
// Подключение JavaScript библиотеки для работы c API голоса
const golos = require('golos-js')
// Указываем ноду, к которой будет подключен скрипт
golos.config.set('websocket', GOLOSNODE)
// Глобальная переменная в которой будут хранится все ссылки на реблоги из блока Аккаунта, для дальнейшей сверки
// с постами. Это нужно для исключения из процесса реблогинга старых постов, которым аккаунт уже сделал реблог ранее
let urls = []
console.log(`\x1b[36m========================================= Reblogger =========================================\x1b[0m
✔ Избранные теги:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
${TAGS}
✔️ Загрузка белого списка пользователей:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`)
// Если задан аккаунт для формирования белого списка из подписок выполним следующее:
if (accountfilter) {
// Узнаем на какое количество пользователей подписан аккаунт-фильтр
golos.api.getFollowCount(accountfilter, (err, count) => {
// Если запрос не удался - прервем работу с ошибкой
if (err) return console.warn(err)
// Зададим пустую переменную вне цикла
let last = null
// Создадим функцию c передаваемым параметром lastname для цикла запросов всех на кого подписался аккаунт-фильтр
const getfollowings = (lastname) => {
// Запрашиваем список подписок
// Параметр blog - указывает на подписки. Если указать вместо этого параметр ignore - получим тех, кого аккаунт-фильтр добавил в игнор
// У запроса getFollowing в отличии от getFollowers лимит всего в 100 пользователей, а не 1000. Но если мы запомним последнее имя lastname мы сможем
// Вызыать getFollowing снова указав стартовое имя. Таким образом циклами по 100 имен мы можем получить список любого количества подписок без лимита
golos.api.getFollowing(accountfilter, lastname, "blog", 100, (errs, followings) => {
// Если ошибка - выведем лог в консоль и прервем работу
if (errs) return console.warn(errs)
// Если переменая last (есть выше, пока пустая) будет равна имени последнего пользователя из сотни запрошенных
// В очередном цикле, значит все подписки обработаны и запускаем следующую функцию checkReblogs
if (last === followings[followings.length - 1].following) {
console.log(`
${blogs}
\x1b[36m🔵 Проверяем последние 100 постов
Учтены выбранные вами теги и список пользователей на которых подписан аккаунт-фильтр ${accountfilter} (Если задан в настройках)\x1b[0m
Поиск 🔎 ...
`)
return checkReblogs("", "")
}
// IF условие выше сработает только если подписок больше нет
// Если подписки есть, то они будут сохраняться в массив blogs
// Для этого запустим петлю for of и запишем массив blogs каждого на кого подписался аккаунт-фильтр
for (let z of followings) blogs.push(z.following)
// Каждый раз вызавая новую сотню имен - будем записывать последнее имя в переменную last
last = followings[followings.length - 1].following
// Когда очередная сотня обработана , запросим следующую сделав отправным именем для запроса последнее имя из переменной last
getfollowings(last)
})
}
// Это первый запуск функции getfollowings, переменная last в нем еще пустая
getfollowings(last)
})
// Если аккаунт-фильтр не задан, то просто запустим функцию checkReblogs
} else {
checkReblogs("", "")
}
// Создаем функцию checkReblogs с возможностью передавать в нее при запуске две переменные lastauthor,lastpermlink
let checkReblogs = (lastauthor, lastpermlink) => {
// Создадим параметры для запроса к api в котором укажем переменные с аккаунтом реблогера, выбранными тегами, максимальным для этого запроса лимитом - 100
// А так же стартового автора и стартовую ссылку поста
let query = {
"select_authors": [REBLOGGER],
"select_tags": TAGS,
"limit": 100,
"start_author": lastauthor,
"start_permlink": lastpermlink
}
// Теперь отправляем запрос с указанными парамертами используя API вызов getDiscussionsByBlog
// Это позволит получить нам до 100 записей из блогов select_authors в которых есть select_tags начиная с start_author и start_permlink
// start_author и start_permlink пока что пустые и запрос нам выдаст последние 100 постов. Что бы получить 101 и так далее посты, мы будем шагать циклами по 100
// Каждый раз указывая start_author и start_permlink последнего автора и ссылку из прошлого запроса
golos.api.getDiscussionsByBlog(query, (e, blogposts) => {
if (e) return console.warn(e)
console.log(`
\x1b[1m\x1b[42m\x1b[37m-----------------------------------------------------------\x1b[0m
`)
// Если в блоге реблоггера нет постов и реблогов - сразу вызовем функция реблогинга
if (!blogposts[0]) return reblog(blogs)
// А иначе будет проверять и запоминать содержимое блога
// Зададим переменную "c" c нулем
let c = 0
// Создадим петлю при каждом цикле которой мы будем получать данные одного отдельного поста и сохранять их в переменную "u"
for (u of blogposts) {
// Мы возмем данные поста url и будем добавлять их в массив urls
urls.push(u.url)
// *Ниже за пределами функции есть переменная с плюсами "c++" - это увеличивает значение в ней на 1 при каждом витке
// Это помогает считать количество ссылок, которые мы сохранили в urls
// Ниже условие if помогает нам реагировать на то, когда наш "с" будет равна последней ссылке.
// Это будет значить, что мы обработали очередную порцию ссылок из нашего лимитированного запроса (лимит был 100)
if (c === blogposts.length - 1) {
// **Пропустите вглядом строки ниже до функции checkReblogs(u.author,u.permlink)
// С ее помощью мы рекурсивно запускаем снова функцию checkReblogs на этот раз передав в нее последнее имя и ссылку автора
// И следующий виток в 100 ссылок будет начинать уже с последнего автора и ссылки в прошлом витке
// Таким образом мы можем просмотреть все ссылки в блоге аккаунта реблоггера не смотря на лимит в 100 постов.
// Чтобы определить когда мы достигнем последнего поста и перестать прервать бесконечный цикл checkReblogs мы проверим,
// когда последние ссылка и автор последнего запроса будет такие же как и первые автор и ссылка следующего запроса
if (lastauthor + lastpermlink === u.author + u.permlink) {
// Если они равны - стало быть мы просмотрели весь блог и можно приступать к следующей функции. reblog(blogs)
// В переменной blogs мы передали список логинов из белого списка посты которых подлежат реблогам
reblog(blogs)
// Не забываем остановить отслужившую нам функцию checkReblogs с помощью return
return console.log(`\x1b[1m✔️ Список прошлых реблогов ${REBLOGGER} сохранен.
\x1b[34m🕑 🔎 Поиск новых постов для реблога\x1b[0m
\x1b[37m ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\x1b[0m
`)
}
// **Запуск checkReblogs описанный ранее
checkReblogs(u.author, u.permlink)
}
// Увеличение на +1 (*Было описано ранее)
c++
}
})
}
// Описание функции которую мы вызвали из функции выше.
// В переменную users мы записали содердимое переменной blogs --- reblog(blogs)
const reblog = users => {
// Делаем знакомый запрос на получение постов
// Но теперь select_authors у нас содержит всех users и мы получим 100 последних постов авторы которых есть в списке users и в которых есть тег из указанного тега TAGS
golos.api.getDiscussionsByBlog({
"select_authors": users,
"select_tags": TAGS,
"limit": 100
}, (err, blog) => {
if (err) return console.log(err)
// Создаем глобальную переменную с нулем, это пригодится нам в будущем для учета количества репостов и формирования отсрочки комментария
let count = 0
console.log(blog.length)
// Создаем цикл для обработки каждого поста из полученной сотни
for (post of blog) {
// console.log("Post \n", post.created)
const author = post.author
const permlink = post.permlink
const title = post.title
const link = post.url
const created = post.created
const timecreated = Date.parse(created)
const now = new Date().getTime();
const delta_sec = (now - timecreated) / 1000
const delta_hour = delta_sec / 60 / 60
// console.log(post.url, delta_hour)
// Проверяем есть ли ссылка текущего поста в блоге реблоггера.
if (urls.includes(link) || delta_hour > 32) {
// Если ссылка есть - стало быть мы уже делали реблог, в этом случае не будет ничего делать
console.log(`\x1b[33m⚠️ [Реблог либо уже есть, либо давний пост][${author}] ${title}\x1b[0m`)
// Если же ссылки нет, тогда будет делать реблог с помощью кода ниже
} else {
// Сначала запишем немного JSON который будет отправлять в ноду, что бы сделать реблог
// Мы расставим переменные так, что бы в json был аккаунт реблогера + логин и ссылка на пост которому нужно сделать реблог.
const json = JSON.stringify(
["reblog", {
account: REBLOGGER,
author: author,
permlink: permlink
}]
)
// Далее используем функцию бродкаста в Golos API и отправим операцию custom_json в блокчейн
golos.broadcast.customJson(postingkey, [], [REBLOGGER], "follow", json, (err, result) => {
if (err) return
// После того, как мы сделали репост, отправим комментарий пользователю и проголосуем за его пост
// Но здесь проблема, если делать реблоги мы можем сотням аккаунтов в секунду, то оставлять комментарии, не более раза в 20 секунд.
// Таким образом нам нужно задать острочку в 20 секунд для каждого комментария
console.log(`\x1b[32m🔗 [Сделан реблог] [${author}] ${title}\x1b[0m`)
setTimeout(() => {
// Подпишем в jsonmetada наш скрипт, это полезно для аналитики платформы
let jsonMetadata = {
"tags": ["vik"],
"app": "vik reblogger script ✉️ t.me/@chain_cf"
}
// Cохраним временной штамп в переменную, его будем делать "хвостом ссылки"
// Это необходимо, что бы сделать каждую ссылку уникальной
let timestamp = Date.now();
// Отправляем комментарий с зараннее подготовленными в настройках скрипта параметрами
golos.broadcast.comment(postingkey, author, permlink, REBLOGGER,
'comment-from-' + REBLOGGER + timestamp,
TITLE,
COMMENT,
jsonMetadata, (err, result) => {
if (err) return console.log(`\x1b[31m☹️ Невозможно отправить комменатарий к посту [${title}]\x1b[0m`)
// При каждом сработанном комментарии увеличиваем переменную на +1
// Голосуем за пост, которому сделали репост
console.log(`\x1b[96m💬 [Отправлен комментарий и upvote ${count}][${author}] ${title}\x1b[0m`)
golos.broadcast.vote(postingkey, REBLOGGER, author, permlink, VOTEPOWER, (error, result) => {
//console.log(error,result)
});
})
// Увеличиваем отсрочку каждого комментария, что бы публиковать его не чаще, чем 1 раз в 20 секунд
}, count * 3000)
count++
})
}
}
})
}