здравствуйте,нужна переписка задним числом,сможете помочь? - вопрос №2654793

Ответы

Здравствуйте. Сегодня мы научимся изменять дату отправки личных сообщений в социальной сети ВКонтакте. Хочу сказать сразу, что я не рассказываю что-то новое. В интернете полно аналогичных методов и я сам какие-то куски кода брал оттуда. Поэтому, не судите строго.

Итак, во первых, нам нужно иметь полный доступ к двум аккаунтам ВК. Например, первый аккаунт Ваш, а второй фэйковый. Во вторых, Вы должны иметь хоть какие-то азы в программировании. Но не волнуйтесь. Большую часть работы сделаю я сам. Все способы являются легкими и быстрыми в исполнении из-за «дыр» в данной социальной сети. Однако, нет гарантий, что каждый метод у Вас будет работать. Но хоть один точно сработает.

Начнем.

Первый способ. Метод вложенной переписки.

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

oauth.vk.com/authorize?client_id=3245775&redirect_uri=http://api.vk.com/blank.html&scope=messages&display=page&response_type=token

В следствии, приложению будут доступны все данные пользователя. Не забудьте запомнить свой токен.

Далее, вытащим личные сообщения. Я буду использовать Python. Чтобы получить историю сообщений используем messages.getHistory [https://vk.com/dev/messages.getHistory]:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123# -*- coding: utf-8 -*- import codecsimport ConfigParserimport datetimeimport jsonimport sysimport urllib2from urllib import urlencode import vk_auth def _api(method, params, token):    params.append(("access_token", token))    url = "<a href="https://api.vk.com/method/%s?%s">https://api.vk.com/method/%s?%s</a>" % (method, urlencode(params))     return json.loads(urllib2.urlopen(url).read())["response"] # read config values Config = ConfigParser.ConfigParser()Config.read("config.ini") login = Config.get("auth", "username")password = Config.get("auth", "password")messages_id = Config.get("messages", "chat_id")messages_type = Config.get("messages", "chat_type")app_id = Config.get("application", "app_id") # some chat preparation if messages_type == "interlocutor":    is_chat = Falseelif messages_type == "chat":    is_chat = Trueelse:    sys.exit("Messages type must be either interlocutor or chat.") # auth to get token try:    token, user_id = vk_auth.auth(login, password, app_id, 'messages')except RuntimeError:    sys.exit("Incorrect login/password. Please check it.") sys.stdout.write('Authorized vk\n') # get some information about chat selector = "chat_id" if is_chat else "uid"messages = _api("messages.getHistory", [(selector, messages_id)], token) out = codecs.open(    'vk_exported_dialogue_%s%s.txt' % ('ui' if not is_chat else 'c', messages_id),    "w+", "utf-8") human_uids = [messages[1]["uid"]] # Export uids from dialogue.# Due to vk.api, start from 1.for i in range(1, 100):    try:        if messages[i]["uid"] != human_uids[0]:            human_uids.append(messages[i]["uid"])    except IndexError:        pass # Export details from uidshuman_details = _api(    "users.get",    [("uids", ','.join(str(v) for v in human_uids))],    token) human_details_index = {}for human_detail in human_details:    human_details_index[human_detail["uid"]] = human_detail def write_message(who, to_write):    out.write(u'[{date}] {full_name}:\n {message} \n\n\n'.format(**{        'date': datetime.datetime.fromtimestamp(            int(to_write["date"])).strftime('%Y-%m-%d %H:%M:%S'),            'full_name': '%s %s' % (                human_details_index[who]["first_name"], human_details_index[who]["last_name"]),                'message': to_write["body"].replace('', '\n')    })) mess = 0max_part = 200 # Due to vk.api cnt = messages[0]sys.stdout.write("Count of messages: %s\n" % cnt) while mess != cnt:    # Try to retrieve info anyway while True:    try:        message_part = _api(            "messages.getHistory",            [(selector, messages_id), ("offset", mess), ("count", max_part), ("rev", 1)],            token        )    except Exception as e:        sys.stderr.write('Got error %s, continue...\n' % e)        continue    break try:    for i in range(1, 201):        write_message(message_part[i]["uid"], message_part[i])except IndexError:    break result = mess + max_partif result > cnt:    result = (mess - cnt) + mess    mess = result    sys.stdout.write("Exported %s messages of %s\n" % (mess, cnt)) out.close()sys.stdout.write(‘done!\n')

Далее, для простоты, поставим одну и ту же дату на все сообщения. Я не претендую на оптимизированный код и очевидно, что его можно ужать, но я хочу продемонстрировать как можно подробную работу парсера с подобными XML:

12345678910111213141516171819while (true) {    doc = XDocument. Load("<a href="https://api.vk.com/method/messages.getHistory.xml?uid=12345&offset=">https://api.vk.com/method/messages.getHistory.xml?uid=12345&offset=</a>" + m + "&count=200&access_token=" + token);    foreach (XElement el in doc. Root. Elements()) {        if (el. Name. ToString() == "message") {            foreach (XElement el_msg in el. Elements()) {                if (el_msg. Name == "date") {                    foreach (XElement el_date in el_msg. Elements()) {                        if (el_date. Name == " 1403320931") {                            el_date. Name = '1403429673';                            // то есть меняем дату на любую другую                            k++;                        }                    }                }            }        }    }    m += 200;}

Я думаю, что основная идея здесь понятна. Осталось вернуть сообщения на сервер. Для этого нам понадобиться функция message.send(). Объект message должен обратиться к полю date, но сервер ВКонтакте устанавливает время у себя на сервере сам. Однако, если мы отправим сообщения как вложенную переписку — все получиться.

Наши письма должны имеют вложенную структуру, значит надо вызывать метод парсинга рекурсивно. Но в Java можно поступить проще. Всё, что находиться внутри цикла forEach, мы будем помещать в отдельный класс. В следствии, в методе accept будет происходить всё то, что было бы в теле цикла. В VkApiMessage есть поле fwd_messages. В нем будет хранится список из объектов пересланных сообщений VkApiMessage:

12345678910private static class MessageConsumer implements Consumer<VKApiMessage> {    @Override public void accept(VKApiMessage message) {}} messages.stream().forEach(new MessageConsumer());if (!message.fwd_messages.isEmpty()) {    System.out.println("<div class='wall'>");    message.fwd_messages.forEach(new MessageConsumer());    System.out.println("</div>");}

Далее, просто отправляем сообщения назад на сервер. Здесь, думаю, все очевидно. Аналогично, можно легко использовать поле “attachment” объекта message. [https://vk.com/dev/messages.send]

В общем, результат выглядит ничем не хуже оригинала в ВК:

Второй способ. Метод изменения GMT на сервере.

Алгоритм: меняем время на сервере, отправляем сообщения.

Второй метод несколько легче первого, так как нам не нужно старые(но измененные) сообщения возвращать назад на сервер (кстати, иногда, это не получается сделать из-за “глупого” сервера). Второй же способ работает более надежно.

Здесь нам не нужны готовые сообщения. Мы их создадим сами и перешлем на сервер, предварительно изменив GMT (часовой пояс). Для таких целей нам понадобиться абузоустойчивый VPS. Желательно на базе CentOS.

Сначала, меняем время и дату на сервере. Опять же, это можно сделать любым другим способом. Можно так:

12345# mv /etc/localtime /etc/localtime.bakln -s /usr/share/zoneinfo/Europe/USA /etc/localtime# date MMDDhhmm# date 03182015# man date

Настраиваем наш сервер под данные сервера ВК:
IP:87.240.182.185
Browser: Mozilla/5.0 (compatible; vkShare; +http://vk.com/dev/Share)
Port: 36035
Host: srv185-182-240-87.vk.com

Не забываем про регистрация на API (см. Первый способ). Отправляем сообщения через уже знакомую функцию message.send().

Объект message, описывающий личное сообщение, возвращает поле “date” — дата отправки сообщения в формате unixtime. Обратите внимание на фразу “дата отправки”. Ничего не говорится про дату получения сообщения сервером ВКонтакте. [https://vk.com/dev/message]

Вот и все. Результат аналогичный первому. Все очень просто.

Третий способ. Сниффер трафика.

Алгоритм: качаем/покупаем сниффер, радуемся.
Самый простой метод. Но, к сожалению, методика зависит от качества программы, которую мы качаем из интернета.
Итак, можно просто попробовать скачать/купить что-то типо Charles, словить запрос, редактировать его (дату) и дублировать. Программа перехватывает пакет, меняет время отправки внутри пакета и отправляет контакту. Сервис ВК получает уже заданное unixtime сообщение. Таких снифферов в интернете куча. Но качественных и бесплатных найти сложно. Однако, они стоят не так дорого.

изображение из вопроса

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

06.12.17

Ирина

Читать ответы
Посмотреть всех экспертов из раздела Дом, отдых, хобби > Знакомства
Пользуйтесь нашим приложением Доступно на Google Play Загрузите в App Store