{"id":342804,"date":"2022-12-17T15:00:33","date_gmt":"2022-12-17T15:00:33","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=342804"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2022-12-17T15:00:33","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=342804","title":{"rendered":"<span>\u0422\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u0435\u043c\u044b \u0432 telegram, \u0438\u043b\u0438 \u043a\u0430\u043a \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430\u0436\u0438\u0442\u043e\u0435 \u043d\u0435\u043f\u043e\u0441\u0438\u043b\u044c\u043d\u044b\u043c \u0442\u0440\u0443\u0434\u043e\u043c<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u043e \u0440\u0430\u0437\u043d\u044b\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u044f \u0443\u0436\u0435 \u043a\u0430\u043a \u043f\u0430\u0440\u0443 \u043b\u0435\u0442 \u044f \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0412\u041a \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0441 \u0434\u0440\u0443\u0437\u044c\u044f\u043c\u0438\/\u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c\u0438 &#8212; \u0432\u0441\u0435 \u0443\u0448\u043b\u0438 \u0432 telegram. \u041d\u043e \u0432 \u0412\u041a \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u0445\u043e\u0434\u0438\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0430\u043c\u043e\u0435 \u0434\u043e\u0440\u043e\u0433\u043e\u0435 &#8212; \u0433\u0440\u0443\u043f\u043f\u044b \u0441 \u043c\u0435\u043c\u0430\u043c\u0438, \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u0447\u043a\u0430\u043c\u0438, \u0430\u043d\u0435\u043a\u0434\u043e\u0442\u0430\u043c\u0438 \u0438 \u0432\u0441\u044f\u043a\u043e\u0435 \u0442\u0430\u043a\u043e\u0435. \u0421\u0430\u043c\u043e\u043c\u0443 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e, \u0434\u0440\u0443\u0437\u044c\u044f\u043c &#8212; \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043a\u0430\u043a \u044f \u0440\u0435\u0448\u0438\u043b \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0437\u0430 \u043e\u0434\u0438\u043d \u0432\u0435\u0447\u0435\u0440 &#8212; \u0434\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043a\u0430\u0442 . <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/379\/caf\/75e\/379caf75e43f3d88403506745c82c283.png\" alt=\"\u041a\u0414\u041f\u0412\" title=\"\u041a\u0414\u041f\u0412\" width=\"751\" height=\"500\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/379\/caf\/75e\/379caf75e43f3d88403506745c82c283.png\"\/><figcaption>\u041a\u0414\u041f\u0412<\/figcaption><\/figure>\n<p>\u0418\u0442\u0430\u043a, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u043a\u0443\u0434\u0430-\u0442\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 (\u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c) &#8212; \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0434\u0432\u0435 \u0432\u0435\u0449\u0438 &#8212; \u044d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u043a\u0443\u0434\u0430-\u0442\u043e \u0432\u0437\u044f\u0442\u044c \u0438 \u043f\u043e\u0442\u043e\u043c \u044d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043a\u0443\u0434\u0430-\u0442\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c. <\/p>\n<p><strong>TL;DR<\/strong> \u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u044b \u0438\u0437 \u0412\u041a \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0438\u0445 \u0432 \u043a\u0430\u043d\u0430\u043b \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c\u0435. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a <a href=\"#readyToUse\" rel=\"noopener noreferrer nofollow\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435.<\/a><\/p>\n<h2>\u0427\u0430\u0441\u0442\u044c 1. \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0441\u0442\u043e\u0432 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a API: <\/p>\n<pre><code class=\"javascript\">  async callMethod(method, params){         const uri = new URLSearchParams(params).toString()         return await axios.get(`https:\/\/api.vk.com\/method\/${method}?v=5.131&amp;access_token=${this.token}&amp;${uri}`)     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e id \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c VK API \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0441\u0440\u0430\u0437\u0443 \u0441\u043f\u0438\u0441\u043a\u0430 \u0433\u0440\u0443\u043f\u043f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e id \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e:<\/p>\n<pre><code class=\"javascript\">  async getMemesGroupIds(){         const ids = await this.resolveIdByName(this.memesGroups.join(','))         return ids.map(val => val.id)     }   async resolveIdByName(name){         try {             const res = await this.callMethod('groups.getById', {                 group_ids: name             })             if(res.error !== undefined){                 console.error(res.error)                 throw new Error('Error on resolveIdsByName')             }             return res.data.response         }catch (e) {             console.error('Error on resolveIdsByName', `https:\/\/api.vk.com\/method\/groups.getById?v=5.131&amp;group_ids=${name}&amp;access_token=${token}`)         }     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430, \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u0432\u0441\u0435 \u043a\u0440\u0430\u0439\u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"javascript\">  async getPosts(ownerId, offset){         try {             const data = await this.callMethod('wall.get', {                 owner_id: ownerId,                 count: 100,                 offset: 0             })             if(data.error !== undefined){                 throw new Error('Error on getPosts')             }else{                 return data;             }         }catch (e) {             console.error('Error on getPosts')         }     }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e \u043d\u044e\u0430\u043d\u0441\u0430\u0445 \u0438 \u043b\u043e\u0433\u0438\u043a\u0435 \u0440\u0430\u0431\u043e\u0442\u044b. \u041c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/dev.vk.com\/method\/wall.get\" rel=\"noopener noreferrer nofollow\">wall.get<\/a> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u043f\u043e\u0441\u0442\u044b, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u044b\u0435, \u0440\u0435\u043f\u043e\u0441\u0442\u044b, \u043e\u043f\u0440\u043e\u0441\u044b \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0437\u0430\u043f\u0438\u0441\u0438, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445 &#8212; \u043d\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u0430. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0442\u0430\u043a: \u0437\u0430\u043f\u0438\u0441\u044c \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043d\u0435 \u0440\u0435\u043f\u043e\u0441\u0442\u043e\u043c, \u0443 \u043d\u0435\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430, \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043c\u0435\u0442\u043a\u0438 &#171;\u0440\u0435\u043a\u043b\u0430\u043c\u0430&#187;, \u043e\u043d\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043e\u043a \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 URL (https:\/\/site.ru), \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0439 \u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 Markdown ([Public|club123]). \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445 &#8212; \u043f\u043e \u0442\u0438\u043f\u0443 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u0435\u0431\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438, \u0432\u0438\u0434\u0435\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0435\u043a\u0441\u0442 \u0431\u0435\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043d\u043e \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 <a href=\"https:\/\/dev.vk.com\/reference\/objects\/video\" rel=\"noopener noreferrer nofollow\">API 5.0<\/a> \u0412\u041a \u043d\u0435 \u043e\u0442\u0434\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u043b\u0435\u0435\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f\u043c\u0438 \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u043c. \u0412-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u044b \u0434\u043d\u0435\u043c \u0440\u0430\u043d\u0435\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b \u043d\u043e\u0447\u044c\u044e, \u0430 \u0443\u0442\u0440\u043e\u043c \u044f \u043c\u043e\u0433 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043e \u0432\u0447\u0435\u0440\u0430 <em>(\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u0430\u043a, \u043f\u043e\u0447\u0435\u043c\u0443 &#8212; \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0434\u0430\u043b\u044c\u0448\u0435)<\/em>. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u043f\u0435\u0440\u0432\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0435\u043d\u044c \u0438\u0437 timestamp, \u0435\u0441\u043b\u0438 \u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u043d (\u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u044b \u0437\u0430\u043f\u0438\u0441\u0438), \u0435\u0441\u043b\u0438 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043d &#8212; \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u0430\u0442\u0443. \u0412\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043b\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0442\u0438\u043f\u044b &#8212; \u0432 \u0446\u0435\u043b\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 <em>allowedTypeAttachment <\/em>\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0422\u0440\u0435\u0442\u044c\u044f &#8212; <em>postRules <\/em>\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0432\u0441\u0435 \u043d\u0430 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u043c \u0442\u0440\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c, \u043d\u0443 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043f\u043e id \u0433\u0440\u0443\u043f\u043f\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u0442\u044b<\/p>\n<pre><code class=\"javascript\">  formattedDate(timestamp = 0){         if(timestamp === 0){             let a  = new Date()             a.setDate(a.getDate() - 1)             return a.getMonth() + '\/' + a.getDate()         }else{             let a = new Date(timestamp)             return a.getMonth() + '\/' + a.getDate()         }     }   isAllowedAttachmentType(attachment){         const allowedTypeAttachment = ['photo']         if(attachment === undefined)             return true         return attachment.find(val => allowedTypeAttachment.includes(val.type)) !== undefined     }   postRules(postObject){         const text = postObject['text']         const isContainUrl = \/((https?|ftp):\\\/\\\/?[^\\s\/$.?#].[^\\s]*$)|\\[.*?\\|.*?\\]\/gm.test(text)         return postObject['marked_as_ads'] === 0 &amp;&amp; \/\/ \u043d\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u0430             this.formattedDate() === this.formattedDate(postObject.date * 1000) &amp;&amp; \/\/ \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u043d\u0430 \u0432\u0447\u0435\u0440\u0430             this.isAllowedAttachmentType(postObject['attachments']) &amp;&amp; \/\/ \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f             postObject['is_pinned'] !== 1 &amp;&amp; \/\/ \u043d\u0435 \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c             postObject['copy_history'] === undefined &amp;&amp; \/\/ \u043d\u0435 \u0440\u0435\u043f\u043e\u0441\u0442             !isContainUrl \/\/ \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0441\u044b\u043b\u043e\u043a     }   async getPostGroup(ownerId){         let post =  await this.getPosts(ownerId)         return post.data.response.items             .filter(val => this.postRules(val))     }<\/code><\/pre>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043d\u044e\u0430\u043d\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0435\u043e\u0447\u0435\u0432\u0438\u0434\u0435\u043d &#8212; timestamp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 JS &#8212; \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e <strong>\u043c\u0441<\/strong>, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0441 1 \u044f\u043d\u0432\u0430\u0440\u044f 1970. Timestamp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0412\u041a (\u0438, \u043a\u0441\u0442\u0430\u0442\u0438, telegram) &#8212; \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e <strong>\u0441\u0435\u043a\u0443\u043d\u0434<\/strong>, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0441 \u0442\u043e\u0439 \u0436\u0435 \u0434\u0430\u0442\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u0447\u043a\u0430 &#8212; <em>postObject.date * 1000.<\/em><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0435\u0441\u0442\u044c \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u0442\u044b, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0430\u0433\u0438\u0438. \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u043f\u043e\u043b\u044f &#8212; views \u0438 likes, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u044b \u0438 \u043b\u0430\u0439\u043a\u0438 (\u0432\u0430\u0448 \u043a\u044d\u043f). \u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u0445 \u0434\u0440\u0443\u0433 \u043d\u0430 \u0434\u0440\u0443\u0433\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u0435\u0437\u0440\u0430\u0437\u043c\u0435\u0440\u043d\u0443\u044e \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443, <em> <\/em>\u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0435 views-like ratio &#8212; \u043f\u043e \u043d\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0431\u043e\u043b\u044c\u0448\u0435. \u0414\u0430\u043b\u044c\u0448\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e VL ratio \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0438 \u0431\u0435\u0440\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0442\u043e\u0432 (\u044f \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b 80%):<\/p>\n<pre><code class=\"javascript\">    async processSingleGroup(ownerId){         const countPostsPercent = 80 \/ 100;         const minPostsForCutting = Math.ceil(1\/countPostsPercent) \/\/ \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u0437\u044f\u0442\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430 \u0432\u0435\u0440\u043d\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0435\u0434\u0438\u043d\u0438\u0446\u044b         let items = []         const posts = await this.getPostGroup(ownerId)         posts.forEach(value => {             let res = {}             res.text = value.text             res.views = value.views.count             res.likes = value.likes.count             res.vlRatio = value.likes.count \/ value.views.count             res.date = new Date(value.date*1000)             res.owner = value.owner_id             const attObj = this.processAttachment(value['attachments'])             if(attObj !== undefined){                 res = {...res, ...attObj}              }             items.push(res)         })         const sortedItems = items.sort((a, b) => {             return b.vlRatio - a.vlRatio; \/\/ \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u043e VL Ration         })         if(minPostsForCutting >= sortedItems.length){             return sortedItems \/\/ \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u0442\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 - \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0441\u0435          }else{             return sortedItems.slice(0, sortedItems.length*countPostsPercent)         }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f\u043c\u0438 (<a href=\"https:\/\/dev.vk.com\/reference\/objects\/photo\" rel=\"noopener noreferrer nofollow\">VK API<\/a>). \u041e\u0431\u044a\u0435\u043a\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439 (<a href=\"https:\/\/dev.vk.com\/reference\/objects\/photo-sizes\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/a>), \u043e\u043d\u0438 \u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0435\u0437\u0430\u043d\u044b (\u043c\u0435\u0442\u043a\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 &#8212; o, p, q, r), \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 &#8212; s, m (\u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442, \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440), x, y, z, w &#8212; \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0445\u043e\u0434\u0438\u0442 z (\u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0438\u0439 \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440), \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e, \u043d\u043e \u043f\u043e\u0442\u043e\u043c \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435 \u0431\u044b\u0442\u044c (\u043f\u043e\u0447\u0435\u043c\u0443, \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e), \u0430 \u0445 <em>\u043f\u043e\u043a\u0430 <\/em>\u0431\u044b\u043b \u0432\u0441\u0435\u0433\u0434\u0430. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0439: <\/p>\n<pre><code class=\"javascript\">  processAttachment(attachment) {         const attachmentObj = {             photo: [],             \/\/video: [] \/\/ \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0438 \u0432\u0438\u0434\u0435\u043e         }         if(attachment === undefined)             return attachment         attachment.forEach(att => {             switch(att.type) {                 case 'photo':                     \/\/ \u0411\u0435\u0440\u0435\u043c \u0441\u0430\u043c\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435                     let photo = att.photo.sizes.filter(sizeObject => sizeObject['type'] === 'z' || sizeObject['type'] === 'x').at(-1)                     attachmentObj.photo.push(photo.url)                     break;                 case 'video':                     \/\/ TODO: \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0432\u0438\u0434\u0435\u043e                     break             }         })         return attachmentObj     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0434\u0435\u043b\u043e \u0437\u0430 \u043c\u0430\u043b\u044b\u043c &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u043e \u0432\u0441\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0445 \u043f\u043e\u0441\u0442\u044b \u0432 \u043e\u0434\u0438\u043d \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u043f\u043e\u0442\u043e\u043c \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0435 \u0448\u043b\u0438 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443 VL Ratio, \u0438 \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u0432\u0441\u0435, \u043d\u043e \u044f \u0438\u0445 \u0435\u0449\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e \u0432 JSON \u0444\u0430\u0439\u043b, \u0437\u0430\u0447\u0435\u043c &#8212; \u0447\u0443\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"javascript\">  async processAll(){         let posts = []         const ids = await this.getMemesGroupIds()         for (const id of ids) {             const p = await this.processSingleGroup(`-${id}`)             posts = [...posts, ...p]         }         \/* \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u043c *\/         return posts.map(value => ({ value, sort: Math.random() }))             .sort((a, b) => a.sort - b.sort)             .map(({ value }) => value)     }     storePosts(posts){         const len = posts.length         const resultObject = {             length: len,             posts         }         fs.writeFile('posts.txt', JSON.stringify(resultObject), err => {             if (err) {                 console.error(err);             }             console.log(`Stored ${len} posts`)             \/\/ file written successfully         });     }<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435, \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f  \u0442\u0430\u043a\u0438\u043c: <\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import axios from \"axios\"; import fs from 'fs' class Vk{     constructor(token, memesGroups) {         this.token = token         this.memesGroups = memesGroups     }      async callMethod(method, params){         const uri = new URLSearchParams(params).toString()         return await axios.get(`https:\/\/api.vk.com\/method\/${method}?v=5.131&amp;access_token=${this.token}&amp;${uri}`)     }     async getPosts(ownerId, offset = 0){         try {             const data = await this.callMethod('wall.get', {                 owner_id: ownerId,                 count: 100,                 offset: 0             })             if(data.error !== undefined){                 throw new Error('Error on getPosts')             }else{                 return data;             }         }catch (e) {             console.error('Error on getPosts')         }     }      async resolveIdByName(name){         try {             const res = await this.callMethod('groups.getById', {                 group_ids: name             })             if(res.error !== undefined){                 console.error(res.error)                 throw new Error('Error on resolveIdsByName')             }             return res.data.response         }catch (e) {             console.error('Error on resolveIdsByName', `https:\/\/api.vk.com\/method\/groups.getById?v=5.131&amp;group_ids=${name}&amp;access_token=${token}`)         }     }     async getMemesGroupIds(){         const ids = await this.resolveIdByName(this.memesGroups.join(','))         return ids.map(val => val.id)     }     formattedDate(timestamp = 0){         if(timestamp === 0){             let a  = new Date()             a.setDate(a.getDate() - 1)             return a.getMonth() + '\/' + a.getDate()         }else{             let a = new Date(timestamp)             return a.getMonth() + '\/' + a.getDate()         }     }     isAllowedAttachmentType(attachment){         const allowedTypeAttachment = ['photo']         if(attachment === undefined)             return true         return attachment.find(val => allowedTypeAttachment.includes(val.type)) !== undefined     }     postRules(postObject){         const text = postObject['text']         const isContainUrl = \/((https?|ftp):\\\/\\\/?[^\\s\/$.?#].[^\\s]*$)|\\[.*?\\|.*?\\]\/gm.test(text)         return postObject['marked_as_ads'] === 0 &amp;&amp;             this.formattedDate() === this.formattedDate(postObject.date * 1000) &amp;&amp;             this.isAllowedAttachmentType(postObject['attachments']) &amp;&amp;             postObject['is_pinned'] !== 1 &amp;&amp;             postObject['copy_history'] === undefined &amp;&amp;             !isContainUrl     }     async getPostGroup(ownerI){         \/\/let items = [];         let post =  await this.getPosts(ownerId)         return post.data.response.items             .filter(val => this.postRules(val))     }     async processSingleGroup(ownerId){         const countPostsPercent = 80 \/ 100;         const minPostsForCutting = 80         let items = []         const posts = await this.getPostGroup(ownerId)         posts.forEach(value => {             let res = {}             res.text = value.text             res.views = value.views.count             res.likes = value.likes.count             res.vlRatio = value.likes.count \/ value.views.count             res.date = new Date(value.date*1000)             res.owner = value.owner_id             const attObj = this.processAttachment(value['attachments'])             if(attObj !== undefined){                 res = {...res, ...attObj}             }             items.push(res)         })         const sortedItems = items.sort((a, b) => {             return b.vlRatio - a.vlRatio;         })         if(minPostsForCutting >= sortedItems.length){             return sortedItems         }else{             return sortedItems.slice(0, sortedItems.length*countPostsPercent)         }     }     processAttachment(attachment) {         const attachmentObj = {             photo: [],             \/\/video: []         }         if(attachment === undefined)             return attachment         attachment.forEach(att => {             switch(att.type) {                 case 'photo':                     \/\/ \u0411\u0435\u0440\u0435\u043c \u0441\u0430\u043c\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435                     \/\/console.log(att.photo.sizes.filter(sizeObject => sizeObject['type'] === 'z'))                     let photo = att.photo.sizes.filter(sizeObject => sizeObject['type'] === 'z' || sizeObject['type'] === 'x').at(-1)                     attachmentObj.photo.push(photo.url)                     break;                 case 'video':                     \/\/ TODO: \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0432\u0438\u0434\u0435\u043e                     break             }         })         return attachmentObj     }     async processAll(){         let posts = []         const ids = await this.getMemesGroupIds()         for (const id of ids) {             const p = await this.processSingleGroup(`-${id}`)             posts = [...posts, ...p]             await this.sleep(50)         }         \/* \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u043c *\/         return posts.map(value => ({ value, sort: Math.random() }))             .sort((a, b) => a.sort - b.sort)             .map(({ value }) => value)     }     storePosts(posts){         const len = posts.length         const resultObject = {             length: len,             posts         }         fs.writeFile('posts.txt', JSON.stringify(resultObject), err => {             if (err) {                 console.error(err);             }             console.log(`Stored ${len} posts`)             \/\/ file written successfully         });     }     sleep(ms){         return new Promise(r => setTimeout(r, ms));     }  } export default Vk<\/code><\/pre>\n<p>\u0412\u044b\u0437\u043e\u0432: <\/p>\n<pre><code class=\"javascript\">const vk = new Vk(token, memesGroups) const res = await vk.processAll() vk.storePosts(res)<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0427\u0430\u0441\u0442\u044c 2. \u041f\u043e\u0441\u0442\u0438\u043d\u0433 \u0432 telegram<\/h2>\n<p>\u042f \u0443\u0436\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f \u0430\u0432\u0442\u043e\u043f\u043e\u0441\u0442\u0438\u043d\u0433\u043e\u043c \u0432 telegram, \u043d\u043e \u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b Client API (\u044d\u0442\u043e \u0442\u043e \u0435\u0449\u0435 \u0440\u0430\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435, \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/habr.com\/ru\/post\/472970\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>), \u0432 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0439\u0442\u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043f\u0443\u0442\u0435\u043c, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Bot API, \u043e\u043d \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u0435\u0435 \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d, \u0438 \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0435 \u0444\u0438\u0447\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0431\u043e\u0442\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u043d\u0430 \u0444\u0430\u0439\u043b, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u0432 Client API \u043d\u0443\u0436\u043d\u043e \u0435\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c, \u0430 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a &#8212; \u043d\u0430\u0434\u043e \u0435\u0449\u0435 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u0442\u044c). \u0422\u0430\u043a \u0432\u043e\u0442, \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <a href=\"https:\/\/core.telegram.org\/tdlib\/docs\/classtd_1_1td__api_1_1message_send_options.html\" rel=\"noopener noreferrer nofollow\">sendMessage<\/a> \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c sheduleTime &#8212; \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0442\u043e\u0432, \u044d\u0442\u043e \u0438 \u0431\u044b\u043b \u043c\u043e\u0439 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u043b\u0430\u043d &#8212; \u0440\u0430\u0437\u043e\u0432\u043e \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0441 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0434\u043d\u044f, \u043d\u043e \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f Bot API \u0442\u0430\u043a \u043d\u0435 \u0443\u043c\u0435\u0435\u0442. \u0422\u043e\u0433\u0434\u0430 \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0432\u0441\u0435 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432 \u043a\u0430\u043d\u0430\u043b \u0440\u0430\u0437\u043e\u0432\u043e \u043d\u043e\u0447\u044c\u044e, \u0430 \u0434\u043d\u0435\u043c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0432\u0441\u0435. \u041d\u043e \u0442\u0443\u0442 \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u0438\u0448\u0435\u043b \u043d\u044e\u0430\u043d\u0441 &#8212; \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u043f\u043e\u0441\u0442\u043e\u0432 \u0431\u043e\u0442\u0430 \u0432 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 <em>\u043e\u043a\u0443\u0442\u0430\u043d\u043e \u0437\u0430\u0432\u0435\u0441\u043e\u0439 \u0442\u0430\u0439\u043d\u044b<\/em>. \u0422\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/stackoverflow.com\/questions\/45905266\/what-is-the-limit-of-sending-messages-from-a-telegram-bot\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a> \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043f\u0440\u043e 30 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443, \u0438 \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 20 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u0433\u0440\u0443\u043f\u043f\u0443 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043c\u0438\u043d\u0443\u0442\u044b. \u041d\u0430 \u0434\u0435\u043b\u0435 \u0436\u0435, 429 \u043e\u0448\u0438\u0431\u043a\u0430 (\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d \u043b\u0438\u043c\u0438\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432) &#8212; \u043f\u0430\u0434\u0430\u0435\u0442 \u0432\u0435\u0441\u044c\u043c\u0430 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e, \u0438\u043d\u043e\u0433\u0434\u0430 \u043e\u0442\u0432\u0430\u043b\u0438\u0432\u0430\u044f\u0441\u044c \u043d\u0430 20 \u043f\u043e\u0441\u0442\u0430\u0445, \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0430 15, \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0434\u043e 45-50. \u0427\u0442\u043e\u0436, \u043d\u0430\u0434\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c, \u0430 \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u0435\u0442\u043f\u0440\u043e\u0435\u043a\u0442, \u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f, \u0442\u043e \u0433\u043e\u0440\u043e\u0434\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0435 \u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0435 \u043c\u043d\u0435 \u0431\u044b\u043b\u043e \u043b\u0435\u043d\u044c, \u0438 \u044f \u0438\u0437\u043e\u0431\u0440\u0435\u043b \u043a\u043e\u0441\u0442\u044b\u043b\u044c \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0432 \u0444\u0430\u0439\u043b, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e \u0437\u0430\u0434\u0430\u0447\u0435 crontab-a \u0431\u0435\u0440\u0443 \u043e\u0442\u0442\u0443\u0434\u0430 \u0437\u0430\u043f\u0438\u0441\u0438, \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u044e, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0444\u0430\u0439\u043b, \u0443\u0434\u0430\u043b\u0438\u0432 \u0438\u0437 \u043d\u0438\u0445 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0435. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043b\u0430\u0434\u043d\u043e \ud83d\ude42<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043d\u043e\u0432\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a Bot API: <\/p>\n<pre><code class=\"javascript\">    async callMethod(method, params){         try{             return await axios.post(`https:\/\/api.telegram.org\/bot${this.token}\/${method}`, params)         }catch (e){             console.error('Error with callMethod', e.response.data)         }     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0442\u0440\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043e\u0431\u0435\u0440\u0442\u043e\u0447\u043a\u0438 \u0432\u043e\u043a\u0440\u0443\u0433 <em>callMethod<\/em>, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442, \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044e, \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439: <\/p>\n<pre><code class=\"javascript\">    async sendText(text){         return await this.callMethod('sendMessage', {             chat_id:this.destinationChat,             text:text         })     }     async sendPhoto(text, photo){         return await this.callMethod('sendPhoto', {             chat_id:this.destinationChat,             caption:text,             photo         })     }     async sendMediaGroup(text, arrayOfPhotos){         let mediaTypes = arrayOfPhotos.map((url, key) => {             let media =  {                 type: 'photo',                 media: url             }             return key === 0 ? {caption: text, ...media} : media \/\/ \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439         })         return await this.callMethod('sendMediaGroup', {             chat_id:this.destinationChat,             caption:text,             media: mediaTypes         })     }<\/code><\/pre>\n<p>\u0412 20 \u0441\u0442\u0440\u043e\u043a\u0435 \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u043c\u0435\u0440\u0430 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438. \u042d\u0442\u043e \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0430\u044f \u0432\u0435\u0449\u044c &#8212; \u0435\u0441\u0442\u044c \u0432 <em>sendPhoto<\/em> \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 caption, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u0432 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435, \u0442\u043e \u0432 <em>sendMediaGroup<\/em> \u0442\u0430\u043a\u043e\u0433\u043e \u043d\u0435\u0442 &#8212; \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0438 \u043a \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435. \u0420\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a &#8212; \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u0438 \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a, \u043d\u0430\u0434\u043e \u044d\u0442\u0443 \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u0437\u0430\u0434\u0430\u0442\u044c \u043a \u043f\u0435\u0440\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435, \u0430 \u0443 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u043f\u0443\u0441\u0442\u043e\u0439. <\/p>\n<p>\u041d\u0443 \u0438 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u0430\u043d\u0430\u043b, \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0442\u0430\u043a, \u0434\u0443\u043c\u0430\u044e, \u043f\u043e\u044f\u0441\u043d\u044f\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e, \u0441 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c\u0438 \u0442\u0443\u0442 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e: <\/p>\n<pre><code class=\"javascript\">    async processVkPosts(posts){ \/\/ \u043f\u043e\u0441\u0442\u0438\u043d\u0433 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043f\u043e\u0441\u0442\u043e\u0432          for (const post of posts) {             console.log('Process', request)             if('photo' in post){                 if(post['photo'].length > 1){                     await this.sendMediaGroup(post['text'], post['photo']) \/\/ \u0435\u0441\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439                 }else{                     await this.sendPhoto(post['text'], post['photo'][0]) \/\/ \u0435\u0441\u043b\u0438 \u043e\u0434\u043d\u0430 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f                 }             }else{                 await this.sendText(post['text']) \/\/ \u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043a\u0441\u0442             }         }     }     async postPartGroup({length, posts}){ \/\/ \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0437 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0447\u0430\u0441\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0438\u043d\u0433\u0430         const chunkSize = Math.floor((7 \/ 100) * length ) \/\/ \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043e \u0438\u0437 \u043e\u0431\u0449\u0435\u0433\u043e \u0447\u0438\u0441\u043b\u0430 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 7%)         const sliceEnd = chunkSize > length ? length : chunkSize         const processPosts = posts.slice(0, sliceEnd)         const otherPosts = posts.slice(sliceEnd, posts.length-1)         console.log('Proccess part, json len: ', length, 'real post: ', posts.length,' process post: ', processPosts.length, ' other posts: ', otherPosts.length, ' slice end: ', sliceEnd)         const resObject = {length, posts: otherPosts}         fs.writeFileSync('posts.txt', JSON.stringify(resObject));         await this.processVkPosts(processPosts)      } <\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f telegram \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a: <\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import axios from \"axios\"; import fs from 'fs' class Telegram{     constructor(token, destinationChat) {         this.token  = token         this.destinationChat  = destinationChat         this.token  = token     }      async callMethod(method, params){         try{             return await axios.post(`https:\/\/api.telegram.org\/bot${this.token}\/${method}`, params)         }catch (e){             console.error('Error with callMethod', e.response.data)         }     }      async sendText(text){         return await this.callMethod('sendMessage', {             \"chat_id\":this.destinationChat,             \"text\":text         })     }     async sendPhoto(text, photo){         return await this.callMethod('sendPhoto', {             \"chat_id\":this.destinationChat,             \"caption\":text,             photo         })     }     async sendMediaGroup(text, arrayOfPhotos){         let mediaTypes = arrayOfPhotos.map((url, key) => {             let media =  {                 type: 'photo',                 media: url             }             return key === 0 ? {caption: text, ...media} : media         })         return await this.callMethod('sendMediaGroup', {             \"chat_id\":this.destinationChat,             \"caption\":text,             'media': mediaTypes         })     }     async processVkPosts(posts){         let request = 0         for (const post of posts) {             if(request++ % 14 === 0){                 await this.sleep(1000)             }             console.log('Process', request)             if('photo' in post){                 if(post['photo'].length > 1){                     await this.sendMediaGroup(post['text'], post['photo'])                 }else{                     await this.sendPhoto(post['text'], post['photo'][0])                 }             }else{                 await this.sendText(post['text'])             }         }     }     async postPartGroup({length, posts}){         const chunkSize = Math.floor((7 \/ 100) * length )         const sliceEnd = chunkSize > length ? length : chunkSize         const processPosts = posts.slice(0, sliceEnd)         const otherPosts = posts.slice(sliceEnd, posts.length-1)         console.log('Proccess part, json len: ', length, 'real post: ', posts.length,' process post: ', processPosts.length, ' other posts: ', otherPosts.length, ' slice end: ', sliceEnd)         const resObject = {length, posts: otherPosts}         fs.writeFileSync('posts.txt', JSON.stringify(resObject));         await this.processVkPosts(processPosts)      }     sleep(ms){         return new Promise(r => setTimeout(r, ms));     } } export default Telegram<\/code><\/pre>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f: <\/p>\n<pre><code class=\"javascript\">const telegram = new Telegram(\u0442\u043e\u043a\u0435\u043d_\u0431\u043e\u0442\u0430, '@\u043a\u0430\u043d\u0430\u043b_\u0432_\u043a\u043e\u0442\u043e\u0440\u044b\u0439_\u043f\u043e\u0441\u0442\u0438\u0442\u044c') telegram.postPartGroup(JSON.parse(fs.readFileSync('posts.txt', 'utf8')))<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0435 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u0435. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0434\u043b\u044f crontab, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0434\u0435\u043d\u044c \u0432 3 \u0447\u0430\u0441\u0430 \u043d\u043e\u0447\u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u043f\u043e\u0441\u0442\u044b, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e\u0441\u0442\u0438\u043b. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043b\u0438\u0431\u043e \u0440\u0430\u0437\u043d\u0435\u0441\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0438 \u043f\u043e\u0441\u0442\u0438\u043d\u0433\u0430 \u0432 \u0440\u0430\u0437\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438. \u042f \u0432\u044b\u0431\u0440\u0430\u043b \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0430\u043a: <\/p>\n<pre><code class=\"javascript\">const args = process.argv if(args[2] === 'get'){     const res = await vk.processAll()     vk.storePosts(res) } if(args[2] === 'post'){     telegram.postPartGroup(JSON.parse(fs.readFileSync('posts.txt', 'utf8'))) }<\/code><\/pre>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 &#8212; <code>node index.js get<\/code>, \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0438\u043d\u0433\u0430 &#8212; <code>node index.js post<\/code><\/p>\n<h2>\u0427\u0430\u0441\u0442\u044c 3. \u041a\u0430\u043a \u0432\u0441\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u043b\u044f \u0441\u0435\u0431\u044f<\/h2>\n<p><a class=\"anchor\" name=\"readyToUse\" id=\"readyToUse\"><\/a><\/p>\n<p>\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0439 \u0433\u0430\u0439\u0434:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c access_token \u0434\u043b\u044f \u0412\u041a. \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0431\u0435\u0437 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0441\u044b\u043b\u043e\u043a: <\/p>\n<p>1.1 <a href=\"https:\/\/vk.com\/editapp?act=create\" rel=\"noopener noreferrer nofollow\">\u0421\u043e\u0437\u0434\u0430\u0435\u043c Standalone \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/a><\/p>\n<p>1.2 \u0417\u0430\u0445\u043e\u0434\u0438\u043c \u0432 <a href=\"https:\/\/vk.com\/apps?act=manage\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/a>, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c <code>ID \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/code>  \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u0441\u044b\u043b\u043a\u0443: <\/p>\n<p><code>https:\/\/oauth.vk.com\/authorize?client_id=\u0432\u0430\u0448 \u0430\u0439\u0434\u0438&amp;display=page&amp;redirect_uri=&amp;response_type=token&amp;revoke=1&amp;scope=<\/code><\/p>\n<p>1.3 \u0416\u043c\u0435\u043c &#171;\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c&#187;, \u0432\u0430\u0441 \u043f\u0435\u0440\u0435\u043a\u0438\u043d\u0435\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432 \u0430\u0434\u0440\u0435\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0431\u0443\u0434\u0435\u0442 access_token, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043e\u0442\u0430 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d. \u041f\u0438\u0448\u0435\u043c <a href=\"https:\/\/t.me\/BotFather\" rel=\"noopener noreferrer nofollow\">https:\/\/t.me\/BotFather<\/a>, \u0432\u0432\u043e\u0434\u0438\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d. \u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448\u0435\u043c\u0443 \u0431\u043e\u0442\u0443 \u0434\u043b\u044f \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438. \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0431\u043e\u0442\u0430 <\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u0430\u043d\u0430\u043b, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043e\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0431\u043e\u0442\u0430 &#8212; \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b <a href=\"https:\/\/github.com\/venanen\/StoleMemes\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>. \u0412 \u0444\u0430\u0439\u043b\u0435 index.js \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c: \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e token &#8212; \u0442\u043e\u043a\u0435\u043d \u0438\u0437 \u0412\u041a, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e memesGroups &#8212; \u043c\u0430\u0441\u0441\u0438\u0432 id \u0433\u0440\u0443\u043f\u043f \u0412\u041a, \u0432 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c id \u043a\u0430\u043d\u0430\u043b\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438. <\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0432\u0441\u0435 \u043b\u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e &#8212; <code>node index.js get<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0438\u0445 \u0432 \u0444\u0430\u0439\u043b post.txt, <code>node index.js post<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u0443\u044e \u043f\u043e\u0440\u0446\u0438\u044e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u0430\u043d\u0430\u043b<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c crontab \u043a\u0430\u043a \u0432\u0430\u043c \u0443\u0434\u043e\u0431\u043d\u043e. \u0423 \u043c\u0435\u043d\u044f \u0432 3 \u0447\u0430\u0441\u0430 \u043d\u043e\u0447\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u0438 c 7 \u0434\u043e 24 \u043f\u043e\u0441\u0442\u0438\u043d\u0433. \u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0435\u0433\u043e crontab: <\/p>\n<p><code>0 1 * * * cd \/home\/dir\/ &amp;&amp; \/root\/.nvm\/versions\/node\/v16.6.0\/bin\/node \/home\/dir\/index.js get >> \/home\/getTest.txt<br \/> 0 7-24 * * * cd \/home\/dir\/ &amp;&amp; \/root\/.nvm\/versions\/node\/v16.6.0\/bin\/node \/home\/dir\/index.js post >> \/home\/PostTest.txt<\/code><\/p>\n<\/li>\n<\/ol>\n<h2>P.S<\/h2>\n<p>\u041d\u0435 \u0437\u043d\u0430\u044e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 &#8212; \u043d\u043e \u043c\u043e\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0440\u0435\u0448\u0438\u043b\u043e, \u043c\u043e\u0436\u0435\u0442 \u0435\u0449\u0435 \u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f. <\/p>\n<p>\u0415\u0449\u0435 \u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0434\u0443\u043c\u0430\u043b \u043e\u0444\u043e\u0440\u043c\u0438\u0442\u044c \u044d\u0442\u043e \u0432\u0441\u0435 \u0432 \u0432\u0438\u0434\u0435 \u0431\u043e\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c, \u0438\u0437-\u0437\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u043f\u043e\u0441\u0442\u0438\u043d\u0433\u0443 &#8212; \u0434\u0443\u043c\u0430\u044e, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e. \u0428\u0442\u0443\u043a\u0443 \u0434\u0435\u043b\u0430\u043b \u0434\u043b\u044f \u0441\u0435\u0431\u044f, \u043e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u044e \u0438 \u0431\u043e\u0442\u0430 \u0438\u0437\u043e\u0431\u0440\u0435\u0441\u0442\u0438. <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043a\u0430\u043a \u043e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/t.me\/NeuralMemesv2\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a> \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c. \u0415\u0441\u043b\u0438 \u0437\u0430\u0439\u0434\u0435\u0442 &#8212; \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f, \u043d\u043e \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e, \u0442\u0430\u043c \u043c\u0435\u043c\u044b, \u0430 \u043c\u043e\u0438 \u0432\u043a\u0443\u0441\u044b \u0432\u0435\u0441\u044c\u043c\u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b, \u044f \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0434\u0438\u043b. <\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/706116\/\"> https:\/\/habr.com\/ru\/post\/706116\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u043e \u0440\u0430\u0437\u043d\u044b\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u044f \u0443\u0436\u0435 \u043a\u0430\u043a \u043f\u0430\u0440\u0443 \u043b\u0435\u0442 \u044f \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0412\u041a \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0441 \u0434\u0440\u0443\u0437\u044c\u044f\u043c\u0438\/\u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c\u0438 &#8212; \u0432\u0441\u0435 \u0443\u0448\u043b\u0438 \u0432 telegram. \u041d\u043e \u0432 \u0412\u041a \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u0445\u043e\u0434\u0438\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0430\u043c\u043e\u0435 \u0434\u043e\u0440\u043e\u0433\u043e\u0435 &#8212; \u0433\u0440\u0443\u043f\u043f\u044b \u0441 \u043c\u0435\u043c\u0430\u043c\u0438, \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u0447\u043a\u0430\u043c\u0438, \u0430\u043d\u0435\u043a\u0434\u043e\u0442\u0430\u043c\u0438 \u0438 \u0432\u0441\u044f\u043a\u043e\u0435 \u0442\u0430\u043a\u043e\u0435. \u0421\u0430\u043c\u043e\u043c\u0443 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e, \u0434\u0440\u0443\u0437\u044c\u044f\u043c &#8212; \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043a\u0430\u043a \u044f \u0440\u0435\u0448\u0438\u043b \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0437\u0430 \u043e\u0434\u0438\u043d \u0432\u0435\u0447\u0435\u0440 &#8212; \u0434\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043a\u0430\u0442 . <\/p>\n<figure class=\"full-width\"><figcaption>\u041a\u0414\u041f\u0412<\/figcaption><\/figure>\n<p>\u0418\u0442\u0430\u043a, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u043a\u0443\u0434\u0430-\u0442\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 (\u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c) &#8212; \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0434\u0432\u0435 \u0432\u0435\u0449\u0438 &#8212; \u044d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u043a\u0443\u0434\u0430-\u0442\u043e \u0432\u0437\u044f\u0442\u044c \u0438 \u043f\u043e\u0442\u043e\u043c \u044d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043a\u0443\u0434\u0430-\u0442\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c. <\/p>\n<p><strong>TL;DR<\/strong> \u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u044b \u0438\u0437 \u0412\u041a \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0438\u0445 \u0432 \u043a\u0430\u043d\u0430\u043b \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c\u0435. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a <a href=\"#readyToUse\" rel=\"noopener noreferrer nofollow\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435.<\/a><\/p>\n<h2>\u0427\u0430\u0441\u0442\u044c 1. \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0441\u0442\u043e\u0432 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a API: <\/p>\n<pre><code class=\"javascript\">  async callMethod(method, params){         const uri = new URLSearchParams(params).toString()         return await axios.get(`https:\/\/api.vk.com\/method\/${method}?v=5.131&amp;access_token=${this.token}&amp;${uri}`)     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e id \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c VK API \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0441\u0440\u0430\u0437\u0443 \u0441\u043f\u0438\u0441\u043a\u0430 \u0433\u0440\u0443\u043f\u043f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e id \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e:<\/p>\n<pre><code class=\"javascript\">  async getMemesGroupIds(){         const ids = await this.resolveIdByName(this.memesGroups.join(','))         return ids.map(val => val.id)     }   async resolveIdByName(name){         try {             const res = await this.callMethod('groups.getById', {                 group_ids: name             })             if(res.error !== undefined){                 console.error(res.error)                 throw new Error('Error on resolveIdsByName')             }             return res.data.response         }catch (e) {             console.error('Error on resolveIdsByName', `https:\/\/api.vk.com\/method\/groups.getById?v=5.131&amp;group_ids=${name}&amp;access_token=${token}`)         }     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430, \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u0432\u0441\u0435 \u043a\u0440\u0430\u0439\u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"javascript\">  async getPosts(ownerId, offset){         try {             const data = await this.callMethod('wall.get', {                 owner_id: ownerId,                 count: 100,                 offset: 0             })             if(data.error !== undefined){                 throw new Error('Error on getPosts')             }else{                 return data;             }         }catch (e) {             console.error('Error on getPosts')         }     }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e \u043d\u044e\u0430\u043d\u0441\u0430\u0445 \u0438 \u043b\u043e\u0433\u0438\u043a\u0435 \u0440\u0430\u0431\u043e\u0442\u044b. \u041c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/dev.vk.com\/method\/wall.get\" rel=\"noopener noreferrer nofollow\">wall.get<\/a> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u043f\u043e\u0441\u0442\u044b, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u044b\u0435, \u0440\u0435\u043f\u043e\u0441\u0442\u044b, \u043e\u043f\u0440\u043e\u0441\u044b \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0437\u0430\u043f\u0438\u0441\u0438, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445 &#8212; \u043d\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u0430. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0442\u0430\u043a: \u0437\u0430\u043f\u0438\u0441\u044c \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043d\u0435 \u0440\u0435\u043f\u043e\u0441\u0442\u043e\u043c, \u0443 \u043d\u0435\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430, \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043c\u0435\u0442\u043a\u0438 &#171;\u0440\u0435\u043a\u043b\u0430\u043c\u0430&#187;, \u043e\u043d\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043e\u043a \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 URL (https:\/\/site.ru), \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u0439 \u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 Markdown ([Public|club123]). \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445 &#8212; \u043f\u043e \u0442\u0438\u043f\u0443 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u0435\u0431\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438, \u0432\u0438\u0434\u0435\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0435\u043a\u0441\u0442 \u0431\u0435\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043d\u043e \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 <a href=\"https:\/\/dev.vk.com\/reference\/objects\/video\" rel=\"noopener noreferrer nofollow\">API 5.0<\/a> \u0412\u041a \u043d\u0435 \u043e\u0442\u0434\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u043b\u0435\u0435\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f\u043c\u0438 \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u043c. \u0412-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u044b \u0434\u043d\u0435\u043c \u0440\u0430\u043d\u0435\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b \u043d\u043e\u0447\u044c\u044e, \u0430 \u0443\u0442\u0440\u043e\u043c \u044f \u043c\u043e\u0433 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043e \u0432\u0447\u0435\u0440\u0430 <em>(\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u0430\u043a, \u043f\u043e\u0447\u0435\u043c\u0443 &#8212; \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0434\u0430\u043b\u044c\u0448\u0435)<\/em>. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u043f\u0435\u0440\u0432\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0435\u043d\u044c \u0438\u0437 timestamp, \u0435\u0441\u043b\u0438 \u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u043d (\u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u044b \u0437\u0430\u043f\u0438\u0441\u0438), \u0435\u0441\u043b\u0438 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043d &#8212; \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u0430\u0442\u0443. \u0412\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043b\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0442\u0438\u043f\u044b &#8212; \u0432 \u0446\u0435\u043b\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 <em>allowedTypeAttachment <\/em>\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0422\u0440\u0435\u0442\u044c\u044f &#8212; <em>postRules <\/em>\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0432\u0441\u0435 \u043d\u0430 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u043c \u0442\u0440\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c, \u043d\u0443 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043f\u043e id \u0433\u0440\u0443\u043f\u043f\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u0442\u044b<\/p>\n<pre><code class=\"javascript\">  formattedDate(timestamp = 0){         if(timestamp === 0){             let a  = new Date()             a.setDate(a.getDate() - 1)             return a.getMonth() + '\/' + a.getDate()         }else{             let a = new Date(timestamp)             return a.getMonth() + '\/' + a.getDate()         }     }   isAllowedAttachmentType(attachment){         const allowedTypeAttachment = ['photo']         if(attachment === undefined)             return true         return attachment.find(val => allowedTypeAttachment.includes(val.type)) !== undefined     }   postRules(postObject){         const text = postObject['text']         const isContainUrl = \/((https?|ftp):\\\/\\\/?[^\\s\/$.?#].[^\\s]*$)|\\[.*?\\|.*?\\]\/gm.test(text)         return postObject['marked_as_ads'] === 0 &amp;&amp; \/\/ \u043d\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u0430             this.formattedDate() === this.formattedDate(postObject.date * 1000) &amp;&amp; \/\/ \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u043d\u0430 \u0432\u0447\u0435\u0440\u0430             this.isAllowedAttachmentType(postObject['attachments']) &amp;&amp; \/\/ \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f             postObject['is_pinned'] !== 1 &amp;&amp; \/\/ \u043d\u0435 \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c             postObject['copy_history'] === undefined &amp;&amp; \/\/ \u043d\u0435 \u0440\u0435\u043f\u043e\u0441\u0442             !isContainUrl \/\/ \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0441\u044b\u043b\u043e\u043a     }   async getPostGroup(ownerId){         let post =  await this.getPosts(ownerId)         return post.data.response.items             .filter(val => this.postRules(val))     }<\/code><\/pre>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043d\u044e\u0430\u043d\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0435\u043e\u0447\u0435\u0432\u0438\u0434\u0435\u043d &#8212; timestamp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 JS &#8212; \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e <strong>\u043c\u0441<\/strong>, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0441 1 \u044f\u043d\u0432\u0430\u0440\u044f 1970. Timestamp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0412\u041a (\u0438, \u043a\u0441\u0442\u0430\u0442\u0438, telegram) &#8212; \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e <strong>\u0441\u0435\u043a\u0443\u043d\u0434<\/strong>, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0441 \u0442\u043e\u0439 \u0436\u0435 \u0434\u0430\u0442\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u0447\u043a\u0430 &#8212; <em>postObject.date * 1000.<\/em><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0435\u0441\u0442\u044c \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u0442\u044b, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0430\u0433\u0438\u0438. \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u043f\u043e\u043b\u044f &#8212; views \u0438 likes, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u044b \u0438 \u043b\u0430\u0439\u043a\u0438 (\u0432\u0430\u0448 \u043a\u044d\u043f). \u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u0445 \u0434\u0440\u0443\u0433 \u043d\u0430 \u0434\u0440\u0443\u0433\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u0435\u0437\u0440\u0430\u0437\u043c\u0435\u0440\u043d\u0443\u044e \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443, <em> <\/em>\u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0435 views-like ratio &#8212; \u043f\u043e \u043d\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0431\u043e\u043b\u044c\u0448\u0435. \u0414\u0430\u043b\u044c\u0448\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e VL ratio \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0438 \u0431\u0435\u0440\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0442\u043e\u0432 (\u044f \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b 80%):<\/p>\n<pre><code class=\"javascript\">    async processSingleGroup(ownerId){         const countPostsPercent = 80 \/ 100;         const minPostsForCutting = Math.ceil(1\/countPostsPercent) \/\/ \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u0437\u044f\u0442\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430 \u0432\u0435\u0440\u043d\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0435\u0434\u0438\u043d\u0438\u0446\u044b         let items = []         const posts = await this.getPostGroup(ownerId)         posts.forEach(value => {             let res = {}             res.text = value.text             res.views = value.views.count             res.likes = value.likes.count             res.vlRatio = value.likes.count \/ value.views.count             res.date = new Date(value.date*1000)             res.owner = value.owner_id             const attObj = this.processAttachment(value['attachments'])             if(attObj !== undefined){                 res = {...res, ...attObj}              }             items.push(res)         })         const sortedItems = items.sort((a, b) => {             return b.vlRatio - a.vlRatio; \/\/ \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u043e VL Ration         })         if(minPostsForCutting >= sortedItems.length){             return sortedItems \/\/ \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u0442\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 - \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0441\u0435          }else{             return sortedItems.slice(0, sortedItems.length*countPostsPercent)         }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f\u043c\u0438 (<a href=\"https:\/\/dev.vk.com\/reference\/objects\/photo\" rel=\"noopener noreferrer nofollow\">VK API<\/a>). \u041e\u0431\u044a\u0435\u043a\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439 (<a href=\"https:\/\/dev.vk.com\/reference\/objects\/photo-sizes\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/a>), \u043e\u043d\u0438 \u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0435\u0437\u0430\u043d\u044b (\u043c\u0435\u0442\u043a\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 &#8212; o, p, q, r), \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 &#8212; s, m (\u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442, \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440), x, y, z, w &#8212; \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0445\u043e\u0434\u0438\u0442 z (\u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0438\u0439 \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440), \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e, \u043d\u043e \u043f\u043e\u0442\u043e\u043c \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435 \u0431\u044b\u0442\u044c (\u043f\u043e\u0447\u0435\u043c\u0443, \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e), \u0430 \u0445 <em>\u043f\u043e\u043a\u0430 <\/em>\u0431\u044b\u043b \u0432\u0441\u0435\u0433\u0434\u0430. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u0439: <\/p>\n<pre><code class=\"javascript\">  processAttachment(attachment) {         const attachmentObj = {             photo: [],             \/\/video: [] \/\/ \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0438 \u0432\u0438\u0434\u0435\u043e         }         if(attachment === undefined)             return attachment         attachment.forEach(att => {             switch(att.type) {                 case 'photo':                     \/\/ \u0411\u0435\u0440\u0435\u043c \u0441\u0430\u043c\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435                     let photo = att.photo.sizes.filter(sizeObject => sizeObject['type'] === 'z' || sizeObject['type'] === 'x').at(-1)                     attachmentObj.photo.push(photo.url)                     break;                 case 'video':                     \/\/ TODO: \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0432\u0438\u0434\u0435\u043e                     break             }         })         return attachmentObj     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0434\u0435\u043b\u043e \u0437\u0430 \u043c\u0430\u043b\u044b\u043c &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u043e \u0432\u0441\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0445 \u043f\u043e\u0441\u0442\u044b \u0432 \u043e\u0434\u0438\u043d \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u043f\u043e\u0442\u043e\u043c \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0435 \u0448\u043b\u0438 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443 VL Ratio, \u0438 \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u0432\u0441\u0435, \u043d\u043e \u044f \u0438\u0445 \u0435\u0449\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e \u0432 JSON \u0444\u0430\u0439\u043b, \u0437\u0430\u0447\u0435\u043c &#8212; \u0447\u0443\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"javascript\">  async processAll(){         let posts = []         const ids = await this.getMemesGroupIds()         for (const id of ids) {             const p = await this.processSingleGroup(`-${id}`)             posts = [...posts, ...p]         }         \/* \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u043c *\/         return posts.map(value => ({ value, sort: Math.random() }))             .sort((a, b) => a.sort - b.sort)             .map(({ value }) => value)     }     storePosts(posts){         const len = posts.length         const resultObject = {             length: len,             posts         }         fs.writeFile('posts.txt', JSON.stringify(resultObject), err => {             if (err) {                 console.error(err);             }             console.log(`Stored ${len} posts`)             \/\/ file written successfully         });     }<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435, \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f  \u0442\u0430\u043a\u0438\u043c: <\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import axios from \"axios\"; import fs from 'fs' class Vk{     constructor(token, memesGroups) {         this.token = token         this.memesGroups = memesGroups     }      async callMethod(method, params){         const uri = new URLSearchParams(params).toString()         return await axios.get(`https:\/\/api.vk.com\/method\/${method}?v=5.131&amp;access_token=${this.token}&amp;${uri}`)    <\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-342804","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/342804","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=342804"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/342804\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=342804"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=342804"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=342804"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}