Отправка личных сообщений ВКонтакте задним числом

Примечание: это гостевой пост. Статья написана одним из читателей блога.

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

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

Начнем.

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

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

https://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]:

# -*- coding: utf-8 -*-

import codecs
import ConfigParser
import datetime
import json
import sys
import urllib2
from urllib import urlencode

import vk_auth

def _api(method, params, token):
    params.append(("access_token", token))
    url = "https://api.vk.com/method/%s?%s" % (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 = False
elif messages_type == "chat":
    is_chat = True
else:
    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 uids
human_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 = 0
max_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_part
if 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:

while (true) {
    doc = XDocument . Load("https://api.vk.com/method/messages.getHistory.xml?uid=12345&offset=" + 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:

private 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.

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

# mv /etc/localtime /etc/localtime.bak
ln -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 сообщение. Таких снифферов в интернете куча. Но качественных и бесплатных найти сложно. Однако, они стоят не так дорого.

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

15 комментария(ев) к записи “Отправка личных сообщений ВКонтакте задним числом”

  1. Артем:

    О, спасибо. Надо попробовать тоже самое на php сделать)

  2. Tim:

    Здравствуйте.Спасибо за статью
    Подскажите пожалуйста,а можно ли комментировать фото задним числом?Спасибо заранее

  3. ant-coding:

    Интересно. Спасибо

  4. Павел:

    Не дозвонились до Вас, посмотрите презентацию http://advertuper.ru/video?activation=4ef8f98a

  5. Приветик, для Вас хорошая новизна!

    Сезонная весна пришла и мы приготовили вам подарок:

    14000$ — наградной фонд! 250 призёрских мест!
    5000$ — приз первого места!

    Итак, матч на сумму ставок по отношениях Слотам и Кено!

    С уважением, http://grand-casino.coca.bz

  6. CharlesGuift:

    Ваш сайт взарвется от посещаемости

    извините если это письмо вы получили случайно.
    Вы создали сайт едва ради вашем сайте нету посещаемости? Нету звонков и клиентов?
    Это временно ныне мы с посредством своих мего прогонов подымим Ваш сайт!
    Вы получите поситителей и клиентов. Так же нарастите траст вашего сайта.
    Подробнее для сайте http://progoni-xrumer

  7. CharlesGuift:

    Это не спам

    извините если это письмо вы получили случайно.
    Вы создали сайт чистый ради вашем сайте нету посещаемости? Нету звонков и клиентов?
    Это покуда теперь мы с через своих мего прогонов подымим Ваш сайт!
    Вы получите поситителей и клиентов. Так же нарастите траст вашего сайта.
    Подробнее дабы сайте http://progoni-xrumer

  8. CharlesGuift:

    Пляжный сезон не загорами

    Уже весна и пляжный сезон не загорами. Не нужно изнурять себя тренировками.
    Худей и отдыхай. Только сейчас супер АКЦИЯ. Успевай-покупай! Жми http://mazda-club.dn.ua/15FWkr

  9. Вышка-тура — это передвижные, сборно-разборные леса башенного типа, оснащённые мобильным основанием и содержащие одну или несколько секций.

    Основные элементы:

    колесная база, состоящая из двух балок, соединённых диагональю. Винтовые домкраты(стабилизаторы) по краям балок позволяют закрепить конструкцию на неровной поверхности
    секция ограждения
    промежуточные секции, размещаемые одна на другой
    настил с люком или сплошной
    стабилизирующие опоры (нужны при высоте более 5м)
    Быстрота сборки, возможность перемещения без демонтажа, высокая грузоподъёмность, удобство транспортировки и компактность хранения сделали передвижные туры востребованными во многих областях, где требуется доступ на высоту:

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

    Строительные вышки применяют как внутри, так и снаружи зданий. Они могут быть разборными и мачтовыми неразборными, с ножничным или телескопическим механизмом подъёма рабочей площадки.

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

    Вышки передвижные могут различаться по материалу изготовления:

    алюминий обеспечивает лёгкость сооружения и возведение его на высоту до 22м
    сталь придаёт дополнительную прочность и надёжность, но ограничивает подвижность из-за увеличения веса
    стекловолокно, имеющее диэлектрические свойства, применяют при монтаже электросетей
    Грузоподъёмность строительных тур составляет 150-250 кг/м2.

    В зависимости от высоты использования (от 3 до 22м) леса вышки должны иметь:

    анкерные крепления (при достижении точки в 10м)
    угловые опоры (при наличии более 3-х промежуточных секций)
    ограничительные поручни (при выводе рабочей площадки на высоту более 2м)
    страховочный настил (когда рабочая высота составляет более 6м)
    Габаритные размеры настила зависят от требований к нагрузке.

    Преимущества:

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

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

    выбрать вышку туру

  10. Ярослав:

    Добрый день. Это наша презентация http://oppilre.ru/video?activation=a5832790

  11. Алексей:

    Здравствуйте. Наша презентация, посмотрите http://socilasail.ru/?activation=630ece8e

  12. Святослав:

    Здравствуйте. Обещал отправить http://olenemux.ru/

  13. Тимур:

    Добрый день. Не дозвонились до Вас, посмотрите http://orserkester.ru/

  14. Антон:

    Здравствуйте! Не дозвонился до Вас, посмотрите презентацию http://jastem.ru/

  15. Лев:

    Здравствуйте! Не получилось перезвонить, высылаю как обещал презентацию http://nelesem.ru/

Оставить комментарий к записи ant-coding

(обязательно)

(обязательно)