-
-
Save Tunaki/08c4cc05c5ac2a8b3269d7bdc8ad0873 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Natty Reporter | |
// @namespace https://github.com/Tunaki/stackoverflow-userscripts | |
// @version 0.13 | |
// @description Adds a Natty link below answers that sends a report for the bot in SOBotics. Intended to be used to give feedback on reports (true positive / false positive / needs edit) or report NAA/VLQ-flaggable answers. | |
// @author Tunaki | |
// @include /^https?:\/\/(www\.)?stackoverflow\.com\/.*/ | |
// @grant GM_xmlhttpRequest | |
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js | |
// @downloadURL https://github.com/Tunaki/stackoverflow-userscripts/raw/master/NattyReporter.user.js | |
// ==/UserScript== | |
var room = 111347; | |
var isMod = $('.js-mod-inbox-button').length > 0; | |
function sendChatMessage(msg, answerId) { | |
GM_xmlhttpRequest({ | |
method: 'GET', | |
url: 'http://chat.stackoverflow.com/rooms/' + room, | |
onload: function (response) { | |
var fkey = response.responseText.match(/hidden" value="([\dabcdef]{32})/)[1]; | |
GM_xmlhttpRequest({ | |
method: 'POST', | |
url: 'http://chat.stackoverflow.com/chats/' + room + '/messages/new', | |
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, | |
data: 'text=' + encodeURIComponent(msg) + '&fkey=' + fkey, | |
onload: function (r) { | |
$('[data-answerid="' + answerId + '"] a.report-natty-link').addClass('natty-reported').html('Reported to Natty!'); | |
} | |
}); | |
} | |
}); | |
} | |
function sendSentinelAndChat(answerId, feedback) { | |
var link = 'http://stackoverflow.com/a/' + answerId; | |
var match = /(?:https?:\/\/)?(?:www\.)?(.*)\.com\/(.*)(?:\/([0-9]+))?/g.exec(link); | |
var sentinelUrl = 'http://www.' + match[1] + '.com/' + match[2]; | |
GM_xmlhttpRequest({ | |
method: 'GET', | |
url: 'http://sentinel.erwaysoftware.com/api/posts/by_url?key=1e7cb25155eb89910e2f0cb2b3a246ef49a0658bdd014f2b53903e480287deda&url=' + encodeURIComponent(sentinelUrl), | |
onload: function (sentinelResponse) { | |
if (sentinelResponse.status !== 200) { | |
alert('Error while reporting: status ' + sentinelResponse.status); | |
return; | |
} | |
var sentinelJson = JSON.parse(sentinelResponse.responseText); | |
if (sentinelJson.items.length > 0) { | |
sendChatMessage('@Natty feedback ' + link + ' ' + feedback, answerId); | |
} else if (feedback === 'tp' && !isMod) { | |
sendChatMessage('@Natty report ' + link, answerId); | |
} | |
}, | |
onerror: function (sentinelResponse) { | |
alert('Error while reporting: ' + sentinelResponse.responseText); | |
} | |
}); | |
} | |
function sendRequest(event) { | |
var messageJSON; | |
try { | |
messageJSON = JSON.parse(event.data); | |
} catch (zError) { } | |
if (!messageJSON) return; | |
if (messageJSON[0] == 'postHrefReportNatty') { | |
$.get('//api.stackexchange.com/2.2/posts/'+messageJSON[1]+'?site=stackoverflow&key=qhq7Mdy8)4lSXLCjrzQFaQ((&filter=!3tz1WbZYQxC_IUm7Z', function(aRes) { | |
// post is deleted, just report it (it can only be an answer since VLQ-flaggable question are only from review, thus not deleted), otherwise, check that it is really an answer and then its date | |
if (aRes.items.length === 0) { | |
sendSentinelAndChat(messageJSON[1], messageJSON[2]); | |
} else if (aRes.items[0]['post_type'] === 'answer') { | |
var answerDate = aRes.items[0]['creation_date']; | |
var currentDate = Date.now() / 1000; | |
// only do something when answer was less than 2 days ago | |
if (Math.round((currentDate - answerDate) / (24 * 60 * 60)) <= 2) { | |
$.get('//api.stackexchange.com/2.2/answers/'+messageJSON[1]+'/questions?site=stackoverflow&key=qhq7Mdy8)4lSXLCjrzQFaQ((&filter=!)8aBxR_Gih*BsCr', function(qRes) { | |
var questionDate = qRes.items[0]['creation_date']; | |
// only do something when answer was posted at least 30 days after the question | |
if (Math.round((answerDate - questionDate) / (24 * 60 * 60)) >= 30) { | |
sendSentinelAndChat(messageJSON[1], messageJSON[2]); | |
} | |
}); | |
} | |
} | |
}); | |
} | |
}; | |
window.addEventListener('message', sendRequest, false); | |
const ScriptToInject = function() { | |
function addXHRListener(callback) { | |
let open = XMLHttpRequest.prototype.open; | |
XMLHttpRequest.prototype.open = function() { | |
this.addEventListener('load', callback.bind(null, this), false); | |
open.apply(this, arguments); | |
}; | |
}; | |
function reportToNatty(e) { | |
e.preventDefault(); | |
var $this = $(this); | |
if ($this.closest('a.natty-reported').length > 0) return false; | |
var postId = $this.closest('div.post-menu').find('a.short-link').attr('id').split('-')[2]; | |
var feedback = $this.text(); | |
if (!confirm('Do you really want to report this post with feedback \'' + feedback + '\'?')) return false; | |
window.postMessage(JSON.stringify(['postHrefReportNatty', postId, feedback]), "*"); | |
} | |
function handleAnswers(postId) { | |
var $posts; | |
if(!postId) { | |
$posts = $('.answer .post-menu'); | |
} else { | |
$posts = $('[data-answerid="' + postId + '"] .post-menu'); | |
} | |
$posts.each(function() { | |
var $this = $(this); | |
$this.append($('<span>').attr('class', 'lsep').html('|')); | |
var $dropdown = $('<dl>').css({ 'margin': '0', 'z-index': '1', 'position': 'absolute', 'white-space': 'nowrap', 'background': '#FFF' }).hide(); | |
$.each(['tp', 'fp', 'ne'], function(i, val) { $dropdown.append($('<dd>').append($('<a>').css({ 'display': 'block', 'width': '35px' }).click(reportToNatty).text(val))); }); | |
$this.append($('<a>').attr('class', 'report-natty-link').html('Natty').hover(function() { $dropdown.toggle(); }).append($dropdown)); | |
}); | |
}; | |
addXHRListener(function(xhr) { | |
if (/ajax-load-realtime/.test(xhr.responseURL)) { | |
let matches = /answer" data-answerid="(\d+)/.exec(xhr.responseText); | |
if (matches !== null) { | |
handleAnswers(matches[1]); | |
} | |
} | |
}); | |
addXHRListener(function(xhr) { | |
var matches = /flags\/posts\/(\d+)\/add\/(AnswerNotAnAnswer|PostLowQuality)/.exec(xhr.responseURL); | |
var matched = matches !== null && xhr.status === 200; | |
if (!matched) { | |
matches = /posts\/(\d+)\/vote\/10/.exec(xhr.responseURL); | |
matched = matches !== null && JSON.parse(xhr.responseText)['Success'] && $('.js-mod-inbox-button').length > 0; | |
} | |
if (matched) { | |
window.postMessage(JSON.stringify(['postHrefReportNatty', matches[1], 'tp']), "*"); | |
} | |
}); | |
$(document).ready(function() { | |
handleAnswers(); | |
}); | |
} | |
const ScriptToInjectNode = document.createElement('script'); | |
document.body.appendChild(ScriptToInjectNode); | |
const ScriptToInjectContent = document.createTextNode('(' + ScriptToInject.toString() + ')()'); | |
ScriptToInjectNode.appendChild(ScriptToInjectContent); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment