diff --git a/CONFIG_FIELDS.md b/CONFIG_FIELDS.md index 89b294a..a5e1db2 100644 --- a/CONFIG_FIELDS.md +++ b/CONFIG_FIELDS.md @@ -5,7 +5,7 @@ [Заполненный пример config.json](https://github.com/MrZillaGold/VK2Discord/blob/master/config_example.json) -**VK** +### VK | Поле | Пример заполнения | Описание | | ----------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -18,14 +18,35 @@ | `donut` | `false` | Публиковать записи доступные по подписке [VKDonut](https://vk.com/blog/vk-donut). | | `interval` | `30` | Интервал получения новых постов из ВКонтакте в секундах. Используется для ключа-доступа пользователя. | -**Discord** - -| Поле | Пример заполнения | Описание | -| -------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| `webhook_urls` | `["https://discordapp.com/api/webhooks/1", "https://discordapp.com/api/webhooks/2"]` | WebHook-ссылки, можно использовать несколько ссылок на разные каналы Discord. | -| `color` | `"#aabbcc"` | Цвет рамки сообщения Discord в формате [HEX](https://www.color-hex.com/). | -| `username` | `"VK2Discord"` | Имя для Webhook, показывается в качестве имени бота. (Строку можно оставить пустой, если не хотите менять Webhook имя) | -| `avatar_url` | `"https://sun9-29.userapi.com/rmoNl3t2KfRZlNpFbAwSEzeDwML-xczsHU6y1A/HApWIpxjkT4.jpg"` | Ссылка на аватар Webhook, показывается в качестве аватарки бота. (Строку можно оставить пустой, если не хотите менять Webhook аватар) | -| `content` | `"Новая запись! @everyone"` | Сообщение которое добавляется перед отправкой, можно использовать для упоминаний. | -| `author` | `false` | Указывать автора записи ВКонтакте (если имеется) в сообщении Discord. | -| `copyright` | `true` | Указывать источник записи ВКонтакте и подпись автора (если имеется) в сообщении Discord. | +### Discord + +| Поле | Пример заполнения | Описание | +| ----------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `webhook_urls` | `["https://discordapp.com/api/webhooks/1", "https://discordapp.com/api/webhooks/2"]` | WebHook-ссылки, можно использовать несколько ссылок на разные каналы Discord. | +| `color` | `"#aabbcc"` | Цвет рамки сообщения Discord в формате [HEX](https://www.color-hex.com/). | +| `username` | `"VK2Discord"` | Имя для Webhook, показывается в качестве имени бота. (Строку можно оставить пустой, если не хотите менять Webhook имя) | +| `avatar_url` | `"https://sun9-29.userapi.com/rmoNl3t2KfRZlNpFbAwSEzeDwML-xczsHU6y1A/HApWIpxjkT4.jpg"` | Ссылка на аватар Webhook, используется в качестве аватарки бота. (Строку можно оставить пустой, если не хотите менять Webhook аватар) | +| `content` | `"Новая запись! @everyone"` | Сообщение которое добавляется перед отправкой, можно использовать для упоминаний. | +| `author` | `false` | Указывать автора записи ВКонтакте (если имеется) в сообщении Discord. | +| `copyright` | `true` | Указывать источник записи ВКонтакте и подпись автора (если имеется) в сообщении Discord. | +| `date` | `true` | Добавлять дату публикации записи ВКонтакте в сообщении Discord. | +| `exclude_content` | `["photo", "text", "video"]` | Массив с типами контента для исключения из сообщения Discord. [Доступные значения](#доступный-контент-для-исключения). | + +#### Доступный контент для исключения + +| Тип | Описание | +| --------------------- | ------------------------ | +| `audio` | Аудиозапись | +| `doc` | Документ | +| `link` | Сниппет-ссылка | +| `photo` | Фотография | +| `poll` | Опрос | +| `video` | Видео | +| `album` | Альбом | +| `market` | Товар | +| `market_album` | Подборка товаров | +| `textlive` | Тестовая трансляция | +| `text` | Текст записи | +| `attachments` | Вложения записи | +| `repost_text` | Текст репоста | +| `repost_attachments` | Вложения репоста | diff --git a/README.md b/README.md index e388a04..c0ebc11 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Docker Pulls - Docker Pulls + wakatime Build Status diff --git a/config.json b/config.json index 751aebf..73976ee 100644 --- a/config.json +++ b/config.json @@ -20,9 +20,11 @@ "content": "", "color": "#aabbcc", "author": true, - "copyright": true + "copyright": true, + "date": true, + "exclude_content": [] } } ], - "version_dont_modify_me": 4 + "version_dont_modify_me": 5 } diff --git a/config_example.json b/config_example.json index b064040..8a6ac8b 100644 --- a/config_example.json +++ b/config_example.json @@ -20,7 +20,8 @@ "content": "@everyone", "color": "#aabbcc", "author": true, - "copyright": false + "copyright": false, + "date": false } }, { @@ -45,7 +46,8 @@ "content": "", "color": "#ffbbff", "author": true, - "copyright": true + "copyright": true, + "date": true } } ], diff --git a/package-lock.json b/package-lock.json index 768152c..6fed0e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vk2discord", - "version": "2.1.8", + "version": "3.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vk2discord", - "version": "2.1.8", + "version": "3.0.0", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "discord.js": "^13.2.0", diff --git a/package.json b/package.json index e7d1943..aba02c5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vk2discord", - "version": "2.1.8", - "LATEST_CONFIG_VERSION": 4, + "version": "3.0.0", + "LATEST_CONFIG_VERSION": 5, "description": "Автоматическая публикация записей из группы или профиля ВКонтакте в канал Discord.", "main": "./build/index.js", "type": "module", diff --git a/scripts/check.js b/scripts/check.js index 78a0673..30dd391 100644 --- a/scripts/check.js +++ b/scripts/check.js @@ -68,7 +68,9 @@ function createConfig() { content: '', color: '#aabbcc', author: true, - copyright: true + copyright: true, + date: true, + exclude_content: [] } } ], diff --git a/scripts/update.js b/scripts/update.js index 03bcd65..4a362d9 100644 --- a/scripts/update.js +++ b/scripts/update.js @@ -10,7 +10,8 @@ const { clusters, version_dont_modify_me } = config; const changes = new Map([ [2, [{}, { author: true, copyright: true }]], [3, [{}, { content: '', username: '', avatar_url: '' }]], - [4, [{ donut: false, ads: false, words_blacklist: [] }, {}]] + [4, [{ donut: false, ads: false, words_blacklist: [] }, {}]], + [5, [{}, { date: true, exclude_content: [] }]] ]); if (!clusters || !version_dont_modify_me) { diff --git a/src/index.ts b/src/index.ts index d823c2d..9c724e8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import { HexColorString } from 'discord.js'; -import { Handler, Storage, VK } from './modules'; +import { AttachmentTypeUnion, Handler, Storage, VK } from './modules'; // @ts-ignore import config from '../config.json'; @@ -22,6 +22,13 @@ export interface IVKParams { interval: number; } +export enum Exclude { + TEXT = 'text', + ATTACHMENTS = 'attachments', + REPOST_TEXT = 'repost_text', + REPOST_ATTACHMENTS = 'repost_attachments' +} + export interface IDiscordParams { webhook_urls: string[]; username: string; @@ -30,6 +37,8 @@ export interface IDiscordParams { color: HexColorString; author: boolean; copyright: boolean; + date: boolean; + exclude_content: (AttachmentTypeUnion | Exclude)[]; } export interface ICluster { diff --git a/src/modules/Attachments.ts b/src/modules/Attachments.ts index c07cabe..d900af9 100644 --- a/src/modules/Attachments.ts +++ b/src/modules/Attachments.ts @@ -1,11 +1,12 @@ import { MessageEmbed, MessageAttachment } from 'discord.js'; import { AttachmentType, ISharedAttachmentPayload, AttachmentTypeString } from 'vk-io'; -import { VK, Message } from './'; +import { Message } from './'; +import { ICluster } from '../'; import { generateRandomString, LINK_PREFIX } from '../utils'; -type AttachmentTypeUnion = AttachmentTypeString | 'textlive'; +export type AttachmentTypeUnion = AttachmentTypeString | 'textlive'; export type Attachment = { type: AttachmentTypeUnion; @@ -17,13 +18,14 @@ const { AUDIO, DOCUMENT, LINK, PHOTO, POLL, VIDEO, ALBUM, MARKET, MARKET_ALBUM } export class Attachments { - VK: VK; + private cluster: ICluster; - constructor(VK: VK) { - this.VK = VK; + constructor(cluster: Attachments['cluster']) { + this.cluster = cluster; } parse(attachments: Attachment[], embeds: Message['embeds'], files: Message['files']): string[] { + const { discord: { exclude_content } } = this.cluster; const [embed] = embeds; const attachmentFields: string[] = []; @@ -39,6 +41,10 @@ export class Attachments { .reduce((parsedAttachments, { type, photo, video, link, doc, audio, poll, album, textlive, market }) => { + if (exclude_content.includes(type)) { + return parsedAttachments; + } + switch (type) { case PHOTO: { const { sizes } = photo; diff --git a/src/modules/Handler.ts b/src/modules/Handler.ts index b896407..4e4a531 100644 --- a/src/modules/Handler.ts +++ b/src/modules/Handler.ts @@ -69,7 +69,7 @@ export class Handler { } private startInterval(): void { - const { index, vk: { interval, group_id, filter }, discord: { author, copyright } } = this.cluster; + const { index, vk: { interval, group_id, filter }, discord: { author, copyright, date } } = this.cluster; console.log(`[VK2Discord] Кластер #${index} будет проверять новые записи с интервалом в ${interval} секунд.`); @@ -112,7 +112,9 @@ export class Handler { const [embed] = sender.embeds; - embed.setTimestamp(payload.date as number * 1000); + if (date) { + embed.setTimestamp(payload.date as number * 1_000); + } if (author) { const postAuthor = getPostAuthor(payload as IWallPostContextPayload, profiles, groups); @@ -141,7 +143,7 @@ export class Handler { } private startPolling(): void { - const { index, discord: { author, copyright } } = this.cluster; + const { index, discord: { author, copyright, date } } = this.cluster; this.VK.updates.on('wall_post_new', async (context) => { const payload = context['payload']; @@ -151,7 +153,9 @@ export class Handler { const [embed] = sender.embeds; - embed.setTimestamp(payload.date as number * 1000); + if (date) { + embed.setTimestamp(payload.date as number * 1_000); + } if (author) { const postAuthor = await getById(this.VK.api, payload.from_id as number); diff --git a/src/modules/Message.ts b/src/modules/Message.ts index fe3b52e..a419612 100644 --- a/src/modules/Message.ts +++ b/src/modules/Message.ts @@ -1,9 +1,9 @@ import { MessageAttachment, MessageEmbed } from 'discord.js'; import { IWallPostContextPayload } from 'vk-io'; -import { Markdown, Attachments, Attachment } from './'; +import { Attachment, Attachments, Markdown } from './'; -import { ICluster } from '../'; +import { Exclude, ICluster } from '../'; export enum PostType { POST = 'post', @@ -36,48 +36,44 @@ export abstract class Message { } protected async parsePost(): Promise { - const { cluster: { VK }, payload: { text, attachments, copy_history } } = this; + const { cluster, payload: { text, attachments, copy_history } } = this; + const { VK, discord: { exclude_content } } = cluster; - if (text) { - this.post += `${ - await new Markdown(VK) - .fix(text) - }\n`; + const attachmentsParser = new Attachments(cluster); + const markdown = new Markdown(VK); + + if (text && !exclude_content.includes(Exclude.TEXT)) { + this.post += `${await markdown.fix(text)}\n`; } - if (attachments) { - const parsedAttachments = new Attachments(VK) - .parse(attachments as Attachment[], this.embeds, this.files); + if (attachments && !exclude_content.includes(Exclude.ATTACHMENTS)) { + const parsedAttachments = attachmentsParser.parse(attachments as Attachment[], this.embeds, this.files); - this.attachAttachments(parsedAttachments, PostType.POST); + this.attach(parsedAttachments, PostType.POST); } const repost = copy_history ? copy_history[0] : null; - if (repost) { + if (repost && !exclude_content.includes(Exclude.REPOST_TEXT) && !exclude_content.includes(Exclude.REPOST_ATTACHMENTS)) { const { text, from_id, id, attachments } = repost; this.repost += `\n>>> [**Репост записи**](https://vk.com/wall${from_id}_${id})`; - if (text) { - this.repost += `\n\n${ - await new Markdown(VK) - .fix(text) - }`; + if (text && !exclude_content.includes(Exclude.REPOST_TEXT)) { + this.repost += `\n\n${await markdown.fix(text)}`; } - if (attachments) { - const parsedAttachments = new Attachments(VK) - .parse(attachments as Attachment[], this.embeds, this.files); + if (attachments && !exclude_content.includes(Exclude.REPOST_ATTACHMENTS)) { + const parsedAttachments = attachmentsParser.parse(attachments as Attachment[], this.embeds, this.files); - this.attachAttachments(parsedAttachments, PostType.REPOST); + this.attach(parsedAttachments, PostType.REPOST); } } this.sliceMessage(); } - private attachAttachments(attachmentFields: string[], type: PostType): void { + private attach(attachmentFields: string[], type: PostType): void { const { embeds: [embed] } = this; switch (type) { diff --git a/src/modules/Sender.ts b/src/modules/Sender.ts index bffa4bf..846be18 100644 --- a/src/modules/Sender.ts +++ b/src/modules/Sender.ts @@ -66,6 +66,14 @@ export class Sender extends Message { await this.pushDate(); + if ( + !embed.description && + !embed.fields.length && + !embed.image + ) { + return; + } + const results = await Promise.allSettled( webhook_urls.map((url) => ( new WebhookClient({ diff --git a/test/test.js b/test/test.js index 1f63289..d760f23 100644 --- a/test/test.js +++ b/test/test.js @@ -23,7 +23,8 @@ const cluster = { content: '', color: '#ffbbff', author: true, - copyright: true + copyright: true, + exclude_content: [] } };