וואלהתאונת דרכים בין 2 כלי רכב סמוך לבית אורן - בת 18 נפצעה בינוניPunchSubsidy: Your reforms worsening hardship, Atiku lashes at TinubuESPN DeportesTigres se salvó de un papelón ante Atlante y resolvió en la recta final del dueloESPNBroncos' Nix throws for TD in return from injurySözcüErdoğan'dan ayaküstü transfer teklifiCNN TürkEBRAR KARAKURT MİLLİ TAKIMDA NEDEN YOK? 2026 CEV Şampiyonası Filenin Sultanları Ebrar Karakurt sakat mı, neden oynamıyor?InquirerLTFRB summons jeepney operator in viral Quezon City counterflow videoRTL BoulevardKleinzoon Jantje verandert veel voor de Bauers, maar deze realityregel blijft heiligالشرقهجمات روسية أوكرانية متبادلة.. واستهداف مكثف لمنشآت الطاقة والبنة التحتيةBBC عربيالضغط الاقتصادي على إيران يتصاعد... وكلفة الحرب تلاحق ترامب في الداخل20 MinutenNach Hitzesommer: Grünen-Kritik an Rösti – SVP kontert scharfCumhuriyetPark halindeki 3 araca çarptıktan sonra devrildi: 'Sese uyandık'
The Daily Newsstand · Free, Always
Saturday, August 22, 2026

Бэкапим чат «Избранное» из VK

Translate

Я, как и многие, пользуюсь величайшим облачным хранилищем — перепиской с самим собой. Туда улетают интересные посты, статьи, лайфхаки, мемы и фильмы, которые «посмотрю потом». Увидел я как-то этот мем и задумался, что нужно бы забэкапить это дело.

Привет! Меня зовут Игорь. В статье рассказываю про инструмент для бэкапа сообщений из VK с сохранением вложений.

Введение

За долгое время в переписке с самим собой накопилась большая коллекция полезной информации. Половину из которой я уже забыл. Доступ к ней не очень удобный, приходится проскроллить не одну сотню сообщений. А бывает и сообщества удаляют свои посты или ограничивают доступ, и вместе с этим пропадает то, что ты сохранил :(

Изначально решил поискать уже что-то готовое, но полезного и работающего не попалось. Из всего что попалось, более менее была полезна информация про возможность запросить у VK “что VK о тебе знает и хранит”. Посмотреть можно тут: «Как получить архив со своими данными?». Через архив можно получить переписку, лайки, группы, список друзей, чёрные списки, денежные переводы, но к сожалению вложения не скачиваются.

Решил написать скриптик самостоятельно, который будет конвертировать сообщения в md файлы со всеми вложениями. Да и давно хотелось попробовать AI-агентскую разработку.

Требования и получившийся инструмент

Требования сформировал достаточно быстро:

  • сохранить переписку со всеми вложениями: посты, фотографии, видео, гифки, файлы, ну и конечно же мемы :).

    Причём сохранять в читаемом виде, решил использовать markdown файлы;

  • иметь удобный доступ для чтения этой библиотеки (я заметки храню на GitHub). В результате на GitHub у меня это выглядит так:

    Как моя структура бэкапа выглядит на GitHub

    Как моя структура бэкапа выглядит на GitHub

  • позднее добавилась идея добавить web-редактор, в котором можно будет избавляться от мусорных сообщений, переименовывать статьи и раскладывать сообщения по разделам;

  • работать полностью локально, без SaaS и любой передачи сообщений на сторонние серверы.

В итоге получился вот такой вот веб-редактор:

Веб-редактор сообщений

Веб-редактор сообщений

Ссылка исходников на GitHub: Тык.

Всё полностью локально - данные не покидают компьютер. Для тех, кто не хочет ставить Python, есть портативный exe, прикреплённый к релизу: скачал, запустил, браузер открылся сам.

Дальнейшая часть статьи посвящена тому как шла работа, какие были идеи и какие появились наблюдения из работы с ИИ-агентом. Если подробности не интересуют, то эту часть можно пропустить.

P.S. В конце статьи есть ссылки на другие мои статьи, если вам это интересно.

Часть 1. Какие были идеи и что получилось

Сначала думал решить задачу мини-приложением внутри VK, работая непосредственно с API VK. С агентом за пару часов накидали весь код по выгрузке сырых сообщений, но упёрся в ограничение, что теперь API VK не предоставляет доступ к сообщениям (Документация).

Ограничение на доступ к сообщениям

Ограничение на доступ к сообщениям

Доступ формально можно получить через личную переписку с техподдержкой, но у меня не получилось :(

Переписка с техподдержкой:

Запрос на подключение пермишена messages

Здравствуйте.

Я хотел бы получить доступ по REST API к сообщениям своего профиля. Нужен режим readonly (возможности отправлять, изменять, удалять и т.д. не нужны. Нужно только чтение).

Я хотел бы иметь возможность читать свою переписку из диалогов с помощью самописных скриптов. Важно, чтобы были доступны возможности читать вложения, пересланные сообщения от других людей и самого себя, пересланные посты из сообществ. P.S. Вариант “создание архива профиля” мне не подходит, уже пробовал.

По сути мне нужен функционал messages.getHistory и другие функции связанные с чтением сообщений. https://dev.vk.com/ru/method/messages.getHistory

AppId: XXXXXXXX В открытый доступ приложение публиковать не собираюсь, нужно только для личного использования. Скрипты собираюсь использовать без серверной логики. Вся логика будет на клиенте, взаимодействие через vk-bridge.

Ответ техподдержки на подключение пермишена messages

Здравствуйте, Игорь!

Спасибо за ожидание.

С 15 января 2019 года мы частично ограничили доступ к методам секции messages: vk.cc/cog0ot. Сделали это мы в целях безопасности наших пользователей. Если ключ доступа с такими правами окажется у злоумышленника, в его руки могут попасть личные данные пользователя. Уверен, вы понимаете, насколько это может быть опасно.

По умолчанию методы этой секции доступны для вызова только с ключом доступа сообщества и от его имени.

Пошёл искать обходные пути. Порыскав в интернете нашёл, что доступ к пермишенам messages не закрыт у чатов сообществ. Решил попробовать вариант с пересылкой сообщений в чат сообщества, после чего можно с помощью REST API достать сырые json данные через API VK. В итоге сделал такую реализацию(код в истории гита где-то болтается), но такое решение требует ручной пересылки сообщений в чат сообщества. Решил попробовать написать код, который через консоль браузера сможет переслать сообщения юзера в чат сообщества. Идея с сообществом не нравилось, но решил попробовать.

Если кому нужно, вот код для пересылки сообщений из диалога в чат сообщества.

Код

Код можно упростить. Это был эксперимент. Для работы зайти в диалог и запустить в консоли браузера. Пересылает текущие загруженные сообщения на клиенте. Ограничение пересылки 100 за одно сообщение.

let commynityChatPeerId = -239911892 // перейти в чат сообщества и скопировать из url
let fromChatPeerId = 123456789 // перейти в диалог откуда хотите переслать сообщения и скопировать из url

let article = document.querySelector('article[class*="ConvoHistory__messageBlock"]');
let key = Object.keys(article).find(k => k.startsWith('__reactFiber$'));
let fiber = article[key];

function findStoreProvider(fiber) {
  while (fiber) {
    if (fiber.type?.$$typeof === Symbol.for('react.provider')) {
      const val = fiber.memoizedState?.value || fiber.pendingProps?.value;
      if (val?.getState)
        return val;  // store {getState, subscribe, dispatch}
    }
    fiber = fiber.return; // или fiber._debugOwner
  }
  return null;
}

storeProvider = findStoreProvider(fiber)

let messagesToForward = storeProvider.getState().convos.get(fromChatPeerId).history.confirmed
    .filter(n => n.kind === "Node")
    .map(n => n.item);


storeProvider.dispatch({
  type: "UserHitSend",
  entrypoint: "forward_messages_target",
  text: "auto sent",
  attaches: {},
  timestamp: Date.now(),
  peerId: commynityChatPeerId,
  extra: {},
  forwarded: messagesToForward.filter(m => m.kind === "Normal")
});

В итоге получилось добиться желаемого, но вариант с сообществом меня не очень устраивал. Как-то сложно и не удобно… Раз всё равно пришлось возиться с ручным выполнение скриптов в консоли, то решил попробовать просто сохранить сообщения в сырой json, без пересылки в чат сообщества. Были опасения, что загруженные сообщения на клиенте могут содержать не все поля, но к счастью данные оказались те же самые и в полном объёме.

В итоге написал небольшой скриптик, который выкачивает сообщения из диалога в обычный json-файл. Как им пользоваться подробно описано в веб-редакторе.

Инструкция экспорта сообщений из веб-редактора

Инструкция экспорта сообщений из веб-редактора

Код вставлю для тех кому просто интересно посмотреть как скачать данные сообщений.

Код
async function getHistory(peerId, fromDate, fromMessageId) {
  debugLog("getting history started...")
  const limit = 200;
  
  let items = [];
  let groups = new Map();
  let profiles = new Map();
  
  while (true) {
    let response = await window.vkApi.api("messages.getHistory", {
      peer_id: peerId,
      offset: items.length,
      count: limit,
      extended: 1,
      v: "5.199"
    });
    
    if(!response) break;
    if(!response.items?.length) break;
    
    let filteredItems = response.items.filter(i => 
        (fromMessageId == null || i.id > fromMessageId) 
        && (fromDate == null || i.date > fromDate)
    );
    items.push(...filteredItems);
    if(response.groups) response.groups.forEach(i => groups.set(i.id, i));
    if(response.profiles) response.profiles.forEach(i => profiles.set(i.id, i));
    
    console.log(`Loaded ${items.length}/${response.count}`);
    
    let isAnyItemFiltered = filteredItems.length != response.items.length;
    if(isAnyItemFiltered) break;
    if(items.length >= response.count) break;
    
    await new Promise(r => setTimeout(r, 350)); // 0.35s
  }
  return { peer_id: peerId, items: items, groups: Array.from(groups.values()), profiles: Array.from(profiles.values()) };
}

function saveToFile(data, filename)
{
    let blob = new Blob([JSON.stringify(data, null, 0)], {type: 'application/json'});
    
    let a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = filename;
    a.click();
    URL.revokeObjectURL(a.href);
}


let peerId = 123456789; // нужно заполнить
let fromDate = null;
let fromMessageId = null;

let fromDateUnixTimestamp = fromDate != null ? Math.floor(fromDate.getTime() / 1000) : null;
let data = await getHistory(peerId, fromDateUnixTimestamp, fromMessageId);

let currentDate = Date.now();
let filename = `messages_peerId_${peerId}_${currentDate}.json`;
data.currentDate = currentDate;
saveToFile(data, filename);

Основная работа была сделана. Осталось только написать веб-редактор, который будет конвертировать сырые json данные в удобный для чтения markdown, скачивать вложения и давать возможность разгребать сообщения. Но этот процесс описывать не буду, думаю он не так интересен.

Если заинтересовала работа веб-редактора, то можно почитать readme файл на GitHub (Тык).

Часть 2. Наблюдения из разработки с агентом

Сразу дисклеймер: это был мой первый опыт агентской разработки, код написан агентом практически целиком. Качество кода оставляет желать лучшего, но для личных нужд сойдёт.

Теперь наблюдения:

Галлюцинации. Иногда модель статистически смещала веса для генерации токенов и вставляла символы других языков - например, китайские иероглифы посреди русского текста. Иногда внезапно переходил на английский. Плюс забавные ошибки орфографии. Возможно это фича запикивания матов :)

Орфография

Орфография

Обфускация умерла. Самое интересное: чтобы сделать вызовы к API VK, агент разобрался, как устроен обфусцированный JS-код веб-версии VK. То, ради чего раньше пришлось бы вручную перебирать обфусцированный код, агент сделал сам.

Заодно из исходников я узнал, что сообщения в VK можно выделять через Shift и пересылать пачкой до 100 штук за раз.

Лимиты токенов. Лимиты модели агента небольшие, но удалось разобрать обфусцированный код. За лимиты выходил один-два раза, когда забыл сказать агенту, что изучение надо вести экономно.

Прокрастинация. Пока агент думает, руки сами тянутся отвлечься. Постоянные переключения «поставил задачу-жду-вернулся» съедают фокус и время.

Выбор плохого решения агентом. Когда агент выбирает плохое решение или не до конца додумал задачу, я могу его поправить, потому что знаю контекст всего приложения. В продакшене на большой кодовой базе так делать уже будет трудновато.

UI и код вперемешку. Отделение UI от логики и данных получилось так себе. Возможно, если бы обсудил архитектуру с самого начала, вышло бы лучше.

Не инициализирует начальное состояние UI. Постоянно забывает подготовить состояние элементов интерфейса перед показом. Любопытно, что ровно это же наблюдается у начинающих программистов.

«И так сойдёт». Основной девиз агента. Генерит кучу неуверенного кода. Новый, не обучаемый джун be like :)

Выводы

Я выполнил свою задачу по бэкапу. Из моих ~1700 сообщений, осталось около 700, больше половины оказалось мусором, 100-200 постов из сообществ были удалены или скрыты авторами сообществ. Размер репозитория с контентом на GitHub занял 0.6 Gb

Впечатления от ИИ-агента интересные. С одной стороны для личных решений, которые можно в любой момент выкинуть, агент отлично справился с задачей. Web-разработка не моя специализация и тут он точно ускорил мне работу. С точки зрения продакшен разработки , его работа оставляет желать лучше, но думаю во многом играет роль моих скиллов работы с ИИ-агентом. Чтож посмотрю на более мощных моделях.

Если кто-то хочет потыкать проект на GitHub: Тык

Дополнительно

Если вас тоже интересует улучшение рабочих процессов, то возможно вас заинтересуют другие мои статьи:

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.