Flerry / ShowVKAttachMessage

// ==UserScript==
// @name         ShowVKAttachMessage
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Добавляет кнопку, которая позволяет перейти к сообщению с вложением
// @author       You
// @match        http://tampermonkey.net/
// @match        *://vk.com/*
// @grant        none
// @run-at       document-end
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @license      MIT
// ==/UserScript==
(function () {
  'use strict';

  if (typeof API !== "function")
    window.API = function (method, data) {
      if (!data) data = {};
      var time = new Date();
      API.time = Math.max(time, API.time) + 334;
      return new Promise(function (resolve, reject) {

        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://vk.com/dev/execute', true);
        xhr.onreadystatechange = function () {
          if (xhr.readyState != 4) return;

          var hash = xhr.responseText.match(/Dev\.methodRun\(\'([a-z0-9\:]+)/im);
          if (!hash) return reject("Invalid hash");

          var _data = new FormData();
          _data.append("act", "a_run_method");
          _data.append("al", 1);
          _data.append("hash", hash[1]);
          _data.append("method", "execute");
          _data.append("param_code", method == "execute" ? data.code : "return API." + method + "(" + JSON.stringify(data) + ");");
          _data.append("param_v", "5.73");

          if (method == "execute")
            for (var name in data)
              _data.append("param_" + name, data[name]);

          var req = new XMLHttpRequest();
          req.open('POST', 'https://vk.com/dev', true);
          req.onreadystatechange = function () {
            if (req.readyState != 4) return;
            if (xhr.status !== 200) return reject("I/O Error", xhr.status);
            var _response = req.response;
            try {
              _response = JSON.parse(req.response.replace(/^.+?\{/, "{"));
            }
            catch (e) {}
            if (_response.response) {
              resolve(_response);
            }
            else if (_response.error && _response.error.error_code == 6) {
              API(method, data).then(resolve, reject);
            }
            else {
              reject(_response);
            }
          };

          req.send(_data);
        };
        setTimeout(xhr.send.bind(xhr), Math.max(API.time - time, 1));
      });
    };
  API.time = new Date();

  var checkLink = window.location.href;
  new MutationObserver(function () {
    if ($(location).attr('href').includes("vk.com/im")) {
      var checkButton = document.querySelector("#pv_like > span.pv_like_link._link");
      if (checkButton !== null && checkLink !== window.location.href) {
        checkLink = window.location.href;

        var actionsBar = $('#pv_box > div.clear_fix.pv_photo_wrap > div.no_select.pv_left_wrap > div.pv_bottom_info.clear_fix > div > div.pv_bottom_actions');

        var separator = '<span class="divider"></span>';
        var linkButton = '<a>Показать в сообщении</a>';

        actionsBar.prepend(separator);
        actionsBar.prepend(linkButton).click(function () {
          createLink();
        });
      }
    }
  }).observe(document.body, {
    childList: true,
    subtree: true
  });

  function createLink() {
    var chatId = findGetParameter("sel");
    if (chatId.includes("c")) {
      chatId = 2000000000 + parseInt(chatId.substring(1));
    }

    var photoNumber = parseInt($('#pv_box > div.clear_fix.pv_photo_wrap > div.no_select.pv_left_wrap > div.pv_bottom_info.clear_fix > div > div.pv_bottom_info_left > span.pv_counter').text().match(/^\d+/));

    if (photoNumber > 0) {
      var data = {
        "peer_id": chatId,
        "media_type": "photo",
        "count": photoNumber + 1
      };

      API("messages.getHistoryAttachments", data).then(value => {
        var photos = value.response.items;
        var photo = photos[photos.length - 2];

        var saveLink = 'https://vk.com/im?msgid=' + photo.message_id + '&sel=' + chatId;
        window.location = saveLink;
      });
    }
    else {
      var data = {
        "peer_id": chatId,
        "media_type": "photo",
        "count": 1
      };

      API("messages.getHistoryAttachments", data).then(value => {
        var photo = value.response.items[0];

        var saveLink = 'https://vk.com/im?msgid=' + photo.message_id + '&sel=' + chatId;
        window.location = saveLink;
      });
    }

  }

  function findGetParameter(parameterName) {
    var result = null,
      tmp = [];
    location.search
      .substr(1)
      .split("&")
      .forEach(function (item) {
        tmp = item.split("=");
        if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
      });
    return result;
  }
})();