· 6 years ago · Feb 05, 2020, 09:16 PM
1const { VK } = require("vk-io");
2const vk = new VK();
3const { updates, snippets, api } = vk;
4const { Keyboard } = require("vk-io");
5const fs = require("fs");
6const VKCOINAPI = require("node-vkcoinapi");
7const users = require("./users.json");
8const course = require("./course.json");
9const txns = require("./txns.json");
10const stats = require("./stats.json");
11const vkcoin = new VKCOINAPI({token: "", key: "", userId: 461261437})
12const Qiwi = require('node-qiwi-api').Qiwi;
13const Wallet = new Qiwi('');
14
15vk.setOptions({
16token: "",
17apiMode: "parallel",
18pollingGroupId: 189613794
19});
20
21setInterval(() => {
22let users = require('./users.json');
23require('fs').writeFileSync('./users.json', JSON.stringify(users, null, '\t'));
24}, 1000);
25
26setInterval(() => {
27let txns = require('./txns.json');
28require('fs').writeFileSync('./txns.json', JSON.stringify(txns, null, '\t'));
29}, 500);
30
31setInterval(() => {
32let stats = require('./stats.json');
33require('fs').writeFileSync('./stats.json', JSON.stringify(stats, null, '\t'));
34}, 1000);
35
36async function saveUsers() {
37 require('fs').writeFileSync('./users.json', JSON.stringify(users, null, '\t'));
38 return true;
39}
40
41async function saveCourse() {
42 require('fs').writeFileSync('./course.json', JSON.stringify(course, null, '\t'));
43 return true;
44}
45
46setInterval(() => {
47 stats.sells = 0
48 stats.buys = 0
49 stats.trades = 0
50}, 86400000);
51
52setInterval(() => {
53 Wallet.getOperationHistory({rows: 10, operation: "IN"}, (err, operations) => {
54 if (!operations) {
55 console.log("operations не вернулась!")
56 return;
57 }
58 for(i in operations['data']){
59 users.map(user => {
60 if(user.wantBuy & operations['data'][i]['account'] == '+' + user.qiwi & !txns.find(x => x.txnId === operations['data'][i]['txnId'])){
61 if(operations['data'][i]['total']['amount'] < course.sell) return;
62 txns.push({
63 id: user.id,
64 tag: user.tag,
65 tag2: user.tag2,
66 amount: operations['data'][i]['total']['amount'],
67 txnId: operations['data'][i]['txnId']
68 })
69 user.wantBuy = false
70 stats.sells += operations['data'][i]['total']['amount'] / course.sell * 1000000
71 stats.sellv += operations['data'][i]['total']['amount'] / course.sell * 1000000
72 stats.trades += 1
73 stats.tradev += 1
74 vkcoin.sendPayment(user.id, Number(operations['data'][i]['total']['amount'] / course.sell * 1000000000));
75 vk.api.messages.send({user_id: user.id, message: `✅ Поступил платёж.
76Выполнен перевод ${vkcoin.formatCoins(operations['data'][i]['total']['amount'] / course.sell * 1000000000)} коинов.\n
77Проверьте свой баланс и оставьте отзыв со скриншотом (вкладка "история" в ВК коин) здесь, пожалуйста - https://vk.com/topic-190916951_40121919`,
78keyboard: JSON.stringify({"one_time": false, "buttons": [[{ "action": { "type": "text", "label": "Ок"}, "color": "positive" }]]})});
79 }
80 })
81 }
82 });
83}, 5000);
84
85updates.on('message', async (message, next) => {
86 if (Number(message.senderId) <= 0) return;
87 if (!users.find(x => x.id === message.senderId)) {
88 const [user_info] = await vk.api.users.get({user_id: message.senderId});
89
90 users.push({
91 id: message.senderId,
92 tag: user_info.first_name,
93 tag2: user_info.last_name,
94 qiwi: 0,
95 wantBuy: false,
96 wantSell: false
97 });
98 }
99 message.user = users.find(x => x.id === message.senderId);
100
101 console.log(`id${message.user.id}:${message.text}`)
102
103 try {
104
105 await next();
106 } catch (err){ throw err; }
107 require('fs').writeFileSync('./users.json', JSON.stringify(users, null, '\t'));
108});
109
110const utils = {
111 sp: (int) => {
112 int = int.toString();
113 return int.split('').reverse().join('').match(/[0-9]{1,3}/g).join(' ').split('').reverse().join('');
114 },
115 rn: (int, fixed) => {
116 if (int === null) return null;
117 if (int === 0) return '0';
118 fixed = (!fixed || fixed < 0) ? 0 : fixed;
119 let b = (int).toPrecision(2).split('e'),
120 k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3),
121 c = k < 1 ? int.toFixed(0 + fixed) : (int / Math.pow(10, k * 3)).toFixed(1 + fixed),
122 d = c < 0 ? c : Math.abs(c),
123 e = d + ['', 'тыс', 'млн', 'млрд', 'трлн'][k];
124 e = e.replace(/e/g, '');
125 e = e.replace(/\+/g, '');
126 e = e.replace(/Infinity/g, 'Бессконечно');
127 return e;
128 },
129 gi: (int) => {
130 int = int.toString();
131
132 let text = ``;
133 for (let i = 0; i < int.length; i++) {
134 text += `${int[i]}`;
135 }
136 return text;
137 },
138 decl: (n, titles) => {
139 return titles[(n % 10 === 1 && n % 100 !== 11) ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2]
140 },
141 random: (x, y) => {
142 return y ? Math.round(Math.random() * (y - x)) + x : Math.round(Math.random() * x);
143 },
144 pick: (array) => {
145 return array[utils.random(array.length - 1)];
146 }
147}
148
149updates.hear(/^(?:начать|ок)\s*$/i, async (message) => {
150 if (message.user.wantBuy && message.user.wantSell) return;
151 return message.send(`Привет! Это бот автоматической продажи и покупки коинов.
152\nПродаём - ${course.sellall} руб за 1 000 000 коинов.
153Покупаем - ${course.buy} руб за 1 000 000 коинов.
154\nОплата киви.
155\nОтзывы: https://vk.com/topic-190916951_40121919
156\nПо вопросам обращайся к @alex_kot228(Александру Котову).`, {
157 keyboard:
158 Keyboard.keyboard([
159 [
160 Keyboard.textButton({
161 label: 'Купить',
162 color: Keyboard.POSITIVE_COLOR
163 }),
164 Keyboard.textButton({
165 label: 'Продать',
166 color: Keyboard.NEGATIVE_COLOR
167 }),
168 ],
169 [
170 Keyboard.textButton({
171 label: 'Информация',
172 color: Keyboard.PRIMARY_COLOR
173 })
174 ]
175 ])
176 })
177});
178
179updates.hear(/^(?:купить)\s*$/i, async (message) => {
180 if (message.user.wantBuy && message.user.wantSell) return;
181 if (!message.user.qiwi) return message.send(`Укажи свой номер киви кошелька.\n(Пример: 79045313621)`);
182 message.user.wantBuy = true
183 const balances = await vkcoin.getBalance([344200877])
184 const balance = balances['response'][344200877]
185 const vbalance = vkcoin.formatCoins(balance);
186 return message.send(`Сейчас в продаже:\n9${vbalance} коинов.\nКурс ${course.sellall} руб за 1 000 000 коинов.\n\nМинимальный заказ 1 000 000.\n\nВведи количество коинов к покупке без пробелов (например, 1000000):`, {
187 keyboard:
188 Keyboard.keyboard([
189 [
190 Keyboard.textButton({
191 label: 'Отмена',
192 color: Keyboard.NEGATIVE_COLOR
193 })
194 ]
195 ])
196 })
197});
198
199updates.hear(/^(?:продать)\s*$/i, async (message) => {
200 if (message.user.wantBuy && message.user.wantSell) return;
201 if (!message.user.qiwi) return message.send(`Укажи свой номер киви кошелька.\n(Пример: 79045313621)`);
202 message.user.wantSell = true
203 return message.send(`Купим у тебя коины по курсу: ${course.buy} руб. за 1 000 000.\n\nМинимальное количество койнов: 1 000 000.\n\nВведи количество коинов, которое ты хочешь продать, без пробелов (например, 1000000):`, {
204 keyboard:
205 Keyboard.keyboard([
206 [
207 Keyboard.textButton({
208 label: 'Отмена',
209 color: Keyboard.NEGATIVE_COLOR
210 })
211 ]
212 ])
213 })
214});
215
216updates.hear(/^(?:отмена)\s*$/i, async (message) => {
217 message.user.wantBuy = false
218 message.user.wantSell = false
219 return message.send(`Сделка отменена`, {
220 keyboard:
221 Keyboard.keyboard([
222 [
223 Keyboard.textButton({
224 label: 'Купить',
225 color: Keyboard.POSITIVE_COLOR
226 }),
227 Keyboard.textButton({
228 label: 'Продать',
229 color: Keyboard.NEGATIVE_COLOR
230 }),
231 ],
232 [
233 Keyboard.textButton({
234 label: 'Информация',
235 color: Keyboard.PRIMARY_COLOR
236 })
237 ]
238 ])
239 })
240});
241
242updates.hear(/^(?:Oтмена)\s*$/i, async (message) => {
243 message.user.wantBuy = false
244 message.user.wantSell = false
245 return message.send(`Смена номера отменена`, {
246 keyboard:
247 Keyboard.keyboard([
248 [
249 Keyboard.textButton({
250 label: 'Купить',
251 color: Keyboard.POSITIVE_COLOR
252 }),
253 Keyboard.textButton({
254 label: 'Продать',
255 color: Keyboard.NEGATIVE_COLOR
256 }),
257 ],
258 [
259 Keyboard.textButton({
260 label: 'Информация',
261 color: Keyboard.PRIMARY_COLOR
262 })
263 ]
264 ])
265 })
266});
267
268updates.hear(/^(?:информация)\s*$/i, async (message) => {
269 return message.send(`Курс продажи: ${course.sellall}
270Курс скупки: ${course.buy}
271
272Продано сегодня: ${utils.sp(Math.floor(stats.sells))}
273Скуплено сегодня: ${utils.sp(Math.floor(stats.buys))}
274Сделок сегодня: ${utils.sp(Math.floor(stats.trades))}
275
276Продано всего: ${utils.sp(Math.floor(stats.sellv))}
277Скуплено всего: ${utils.sp(Math.floor(stats.buyv))}
278Всего сделок: ${utils.sp(Math.floor(stats.tradev))}`);
279});
280
281updates.hear(/^(?:сменить номер)\s*$/i, async (message) => {
282 message.user.qiwi = 0
283 return message.send(`Укажи свой номер киви кошелька.\n(Пример: 79045313621)`, {
284 keyboard:
285 Keyboard.keyboard([
286 [
287 Keyboard.textButton({
288 label: 'Oтмена',
289 color: Keyboard.NEGATIVE_COLOR
290 })
291 ]
292 ])
293 })
294});
295
296updates.hear(/^([0-9]+)\s*$/i, async (message) => {
297 if (!message.user.qiwi) {
298 let number = message.text
299 if (number[0] == '8') number = number.replaceAt(0, '7')
300 if (number.length != 11) return message.send(`Некорректный номер!`);
301 let unavailable = false
302 users.map(user => {
303 if (users.find(x => x.qiwi === number)) unavailable = true
304 });
305 if (unavailable) return message.send(`Указанный номер уже занят.`);
306 message.user.qiwi = number
307 return message.send(`Твой номер киви сохранён. (+${number})\nДля смены номера введи 'сменить номер'.`);
308 }
309 if (message.user.wantBuy) {
310 if (Number(message.text) < 1000000) return message.send(`Минимальный заказ 1 000 000 коинов.`);
311 let summa = course.sell * message.text / 1000000
312 if (!Number.isInteger(summa)) {
313 summa = Number(summa.toString().split('.')[0] + '.' + summa.toString().split('.')[1].slice(0, 2))
314 }
315 const balances = await vkcoin.getBalance([344200877])
316 const balance = balances['response'][344200877]
317 return message.send(`Заказ на ${utils.sp(message.text)} коинов.\nК оплате - ${summa} руб.\n\nДля оплаты переведи ${summa} руб на мой киви 7-904-531-36-21 с твоего киви. Коины будут зачислены тебе автоматически сразу после оплаты.\n\nТвой номер киви: ${message.user.qiwi}\nЕсли твой номер киви поменялся, нажми 'сменить номер'.`, {
318 keyboard:
319 Keyboard.keyboard([
320 [
321 Keyboard.textButton({
322 label: 'Отмена',
323 color: Keyboard.NEGATIVE_COLOR
324 }),
325 ],
326 [
327 Keyboard.textButton({
328 label: 'Сменить номер',
329 color: Keyboard.DEFAULT_COLOR
330 })
331 ]
332 ])
333 })
334 }
335 if (message.user.wantSell) {
336 if (Number(message.text) < 1000000) return message.send(`Минимальная продажа - 1 000 000 коинов.`);
337 let summa = course.buy * message.text / 1000000
338 if (!isInteger(summa)) {
339 summa = Number(summa.toString().split('.')[0] + '.' + summa.toString().split('.')[1].slice(0, 2))
340 }
341 const balances = await vkcoin.getBalance([message.senderId])
342 const balance = balances['response'][message.senderId]
343 if (Number(message.text) > Number(balance / 1000)) return message.send(`У тебя нет столько коинов. Твой баланс ${vkcoin.formatCoins(balance)} коинов.`);
344 return message.send(`Ты продаёшь ${utils.sp(message.text)} коинов.\nТы получишь: ${summa} руб\n\nПереведи коины по ссылке: ${vkcoin.getLink(Number(message.text * 1000), true)}\nБот переведёт тебе деньги на киви ${message.user.qiwi} сразу же после получения коинов.`, {
345 keyboard:
346 Keyboard.keyboard([
347 [
348 Keyboard.textButton({
349 label: 'Отмена',
350 color: Keyboard.NEGATIVE_COLOR
351 }),
352 ],
353 [
354 Keyboard.textButton({
355 label: 'Сменить номер',
356 color: Keyboard.DEFAULT_COLOR
357 })
358 ]
359 ])
360 })
361 }
362});
363
364async function run() {
365 await updates.startPolling();
366 await vkcoin.updates.startPolling();
367 vkcoin.updates.onTransfer(async(from, score) => {
368 let user = users.find(x => x.id === from);
369 if (!user) return;
370 if (!user.qiwi) return;
371 if (!user.wantSell) return;
372 if (score < 1000000000) return;
373 let pay = course.buy * score / 1000 / 1000000
374 if (!Number.isInteger(pay)) {
375 pay = Number(pay.toString().split('.')[0] + '.' + pay.toString().split('.')[1].slice(0, 2))
376 }
377 user.wantSell = false
378 stats.buys += score / 1000
379 stats.buyv += score / 1000
380 stats.trades += 1
381 stats.tradev += 1
382 Wallet.toWallet({ amount: pay, comment: `Продажа ${vkcoin.formatCoins(score)} коинов боту`, account: '+'+user.qiwi}, (err, data) => {
383 if(err) {
384 console.log(err);
385 }
386 })
387 vk.api.messages.send({ user_id: from, message: `✅ Ты успешно продал ${vkcoin.formatCoins(score)} коинов.\n
388Бот перевёл тебе ${pay} руб на киви ${user.qiwi}\n
389Проверь свой баланс и оставь отзыв здесь, пожалуйста - https://vk.com/topic-190916951_40121919` ,
390 keyboard:
391 Keyboard.keyboard([
392 [
393 Keyboard.textButton({
394 label: 'Купить',
395 color: Keyboard.POSITIVE_COLOR
396 }),
397 Keyboard.textButton({
398 label: 'Продать',
399 color: Keyboard.NEGATIVE_COLOR
400 }),
401 ],
402 [
403 Keyboard.textButton({
404 label: 'Информация',
405 color: Keyboard.PRIMARY_COLOR
406 })
407 ]
408 ])
409 })
410});
411 console.log("Бот запущен!");
412}
413
414run().catch(console.error);
415
416function isInteger(num) {
417 return (num ^ 0) === num;
418}
419
420String.prototype.replaceAt = function(index, replacement) {
421 return this.substr(0, index) + replacement + this.substr(index + replacement.length);
422}