aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: d65d533b5d055dc14298e3dee4acfb212808f870 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# vk-messages-post-archive

> **Дисклеймер:** информация актуальна на осень 2020 года. Может, во ВКонтакте уже всё поменялось и скрипт более
> не нужен, а может, поменялся формат отдаваемого архива и скрипт не сработает. Смотрите сами.

Во ВКонтакте существует [функция](https://vk.com/data_protection?section=rules&scroll_to_archive=1) выгрузки информации 
в ZIP-архиве, в т.ч. всех сообщений. Сделана она как попало: история сообщений, полученная таким образом, содержит
только текст самих сообщений (там даже нет пересланных! сложно было положить, что ли?), ссылки на фото и нерабочие (!)
ссылки на документы. Но лучше так, чем никак.

Этот репозиторий содержит простенькие инструменты и инструкции, с помощью которых можно дополнительно выкачать все
фотографии из истории, а также получить и сохранить объекты сообщений с вложениями из API (рекомендуется как минимум
для получения рабочих ссылок на документы).

Это проще, чем выкачивать всё через API с нуля. Пусть ВКонтактик соберёт нам свой архив, там уже есть более-менее
нормальная навигация и оформление, а мы потом просто скачаем все, чего не хватает. Все-таки простых текстовых сообщений 
без вложений должно быть на порядок больше.

# Системные требования

- bash
- PHP >= 7.1
    - composer
    - php-iconv
    - php-curl
    - наверное, неплохой идеей будет включить opcache для cli в `php.ini` (путь которого можно узнать через `php --ini`):
      ```
      opcache.enable=1
      opcache.enable_cli=1
      opcache.file_cache=/tmp/php-opcache
      ```
- iconv
- wget
- sqlite3
- стандартные утилиты типа cat, find, grep, xargs и т.д.

# "Поехали", как говорил Юра

## Скачиваем фоточки

Склонили репозиторий, устанавливаем зависимости:
```
git clone https://github.com/gch1p/vk-messages-post-archive
cd vk-messages-post-archive
composer install
```

Перейти в папку с распакованным архивом от ВК:
```
cd path/to/Archive
```

Запускаем нехитрый парсер:
```
for f in $(find messages -type f -name "*.html"); do
    cat "$f" | iconv -f windows-1251 | php path/to/get-attaches.php >> to-download.txt
done
```
В файле `to-download.txt` будут ID сообщений с аттачами вперемешку со ссылками на фотки.

Выкачиваем фотки. `-P8` означает, что будет параллельно запущено 8 процессов wget. Можете написать другое число.
```
cat to-download.txt | grep https | xargs -P8 wget -x -i
```

Заменяем ссылки (`<a>`) на изображения (`<img>`). Тут в `-P` разумно передать количество ядер. 
```
find messages -type f -name "*.html" | xargs -I{} -P4 php path/to/replace-photos.php "{}"
```

## Достаём остальную информацию из API
  
Теперь давайте залезем в API. ВК недавно отключил сторонним приложениям доступ к сообщениям, но кого это остановит?
Скачайте [десктопный мессенджер](https://vk.com/messenger), авторизуйтесь в нём, потом закройте и зайдите в папку, где
он хранит конфиг (`~/.config/VK` на Linux, `~/Library/Application Support/VK` на маке, на винде по логике должно быть
`%APPDATA%\Roaming\VK`), там будет sqlite3 база `vk.db`. Зайдём в неё:
```
sqlite3 vk.db
```

Осмотримся.
```
sqlite> .tables
auth             debug_api_fails  recents          users          
communities      friends          settings
```

Хм, табличка `auth` выглядит многообещающе. Посмотрим структуру:
```
sqlite> .schema auth
CREATE TABLE auth (
  id INTEGER PRIMARY KEY,
  user_id INTEGER,
  ts INTEGER,
  access_token TEXT
, is_encrypted INTEGER);
```

О! То, что нужно. Нам нужен `access_token`.
```
sqlite>  SELECT access_token FROM auth;
```

Скопируйте токен и можно выходить (`Ctrl+D`) отсюда.

Теперь откройте скрипт `common.php` и пропишите этот токен в константу `ACCESS_TOKEN`, а так же путь к папке
`Archive` в константу `ARCHIVE_DIR`.

После этого можно запустить скрипт `fetch-messages.php` для слива объектов сообщений. Они будут сохраняться в папку `api`
с именами `{dir}/{id}.txt`, где `{id}` – это ID сообщения, а `{dir}` – это остаток от деления ID сообщения на 100.

Метод [messages.getById](https://vk.com/dev.php?method=messages.getById) вконтактовского API может вернуть до 100
сообщений за 1 запрос, плюс нужно учитывать стандартное ограничение на 3 запроса в секунду, иначе нам прилетит капча.
`xargs` поможет запустить не более 3-х инстансов скрипта за раз и передать не более 100 идентификаторов в каждый, а 
`sleep(1)` сделает сам скрипт в конце.  

```
cat to-download.txt | grep -v https | xargs -n100 -P3 php path/to/fetch-messages.php
```

Теперь добавим возможность просмотра этих объектов на страничках истории.
```
find messages -type f -name "*.html" | xargs -I{} -P4 php path/to/insert-api-objects.php "{}"
```

## Скачиваем документы

```
php fetch-documents.php
```

Ну вот, вроде, и всё.