背景
需要给许多个用户发同样的私信时需要大量重复工作,如果能自动发送私信就能节省许多人力
难点分析
- chrome各端如何相互通信
- 私信怎么发给不同人
- 怎么发送私信
chrome插件怎么开发,各端如何通信
参照<font color=blue>这篇博客</font>,超级详细
私信怎么发给不同人
在网页微博中可以发现点击私信一个陌生人后,会跳转到一个私信窗口,此时url中是携带一个用户uid的,根据这个uid我们通过跳转url来实现给不同用户发私信
怎么发送私信
- 在inject-script中选中输入框
- 给输入框赋值value
- 用js触发敲击空格事件
- 用js触发敲击回车事件
- 需要触发空格事件的缘由:单纯赋值并不能触发onChange事件,导致回车不能将消息发出去,触发回车后即可
- 第二步到第四步必须依次触发,键盘io是异步的,所以可以使用定时器控制
inject-script
用途:获取dom,发送私信
function fireKeyEvent(el, evtType, keyCode){
var doc = el.ownerDocument,
win = doc.defaultView || doc.parentWindow,
evtObj;
if(doc.createEvent){
if(win.KeyEvent) {
evtObj = doc.createEvent( KeyEvents );
evtObj.initKeyEvent( evtType, true, true, win, false, false, false, false, keyCode, 0 );
}
else {
evtObj = doc.createEvent( UIEvents );
Object.defineProperty(evtObj, keyCode , {
get : function() { return this.keyCodeVal; }
});
Object.defineProperty(evtObj, which , {
get : function() { return this.keyCodeVal; }
});
evtObj.initUIEvent( evtType, true, true, win, 1 );
evtObj.keyCodeVal = keyCode;
if (evtObj.keyCode !== keyCode) {
console.log("keyCode " + evtObj.keyCode + " 和 (" + evtObj.which + ") 不匹配");
}
}
el.dispatchEvent(evtObj);
}
else if(doc.createEventObject){
evtObj = doc.createEventObject();
evtObj.keyCode = keyCode;
el.fireEvent( on + evtType, evtObj);
}
}
function sendText() {
const target = document.querySelector( #webchat-textarea )
let textTimer
if (target) {
clearTimeout(textTimer)
target.value = xxx
setTimeout(() => {
target.focus()
fireKeyEvent(target, keydown , 8)
setTimeout(() => {
fireKeyEvent(target, keydown , 13)
}, 1000)
}, 1000)
} else {
textTimer = setTimeout(() => {
sendText()
}, 200)
}
}
setTimeout(() => {
sendText()
}, 0)
content-script
用途:注入inject-script,可以与popup.js做通信
function injectCustomJs(jsPath) {
jsPath = jsPath || js/inject.js
var temp = document.createElement( script )
temp.setAttribute( type , text/javascript )
temp.src = chrome.extension.getURL(jsPath)
temp.onload = function () {
this.parentNode.removeChild(this)
}
document.head.appendChild(temp)
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
function Toast(msg, duration) {
duration = isNaN(duration) ? 3000 : duration
var m = document.createElement( div )
m.innerHTML = msg
m.style.cssText =
max-width:60%;min-width: 150px;padding:0 14px;height: 40px;color: rgb(255, 255, 255);line-height: 40px;text-align: center;border-radius: 4px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.7);font-size: 16px;
document.body.appendChild(m)
setTimeout(function () {
var d = 0.5
m.style.webkitTransition =
-webkit-transform + d + s ease-in, opacity + d + s ease-in
m.style.opacity = 0
setTimeout(function () {
document.body.removeChild(m)
}, d * 1000)
}, duration)
}
window.addEventListener( load , function() {
injectCustomJs()
})
let timer
let sendTimer
let uidArr = []
let interval
let initinterval
let status =
chrome.extension.onMessage.addListener(function (
request,
sender,
sendResponse
) {
if (request.cmd == start ) {
Toast( 已开始发私信 , 2000)
uidArr = request.uids
initinterval = request.interval
interval = (+request.interval + getRandomInt(1, 5)) * 1000
status = start
timer = setInterval(() => {
if (uidArr.length) {
window.open(
`https://api.weibo.com/chat/#/chat?to_uid=${uidArr[0]}&source_from=9`,
_blank
)
uidArr.shift()
sendResponse( recived )
} else {
clearInterval(timer)
}
}, interval)
}
if (request.cmd == stop ) {
status = stop
Toast( 已结束发私信 , 2000)
clearInterval(timer)
}
if (request.cmd == continue ) {
status = continue
Toast( 已继续发私信 , 2000)
timer = setInterval(() => {
if (uidArr.length) {
window.open(
`https://api.weibo.com/chat/#/chat?to_uid=${uidArr[0]}&source_from=9`,
_blank
)
uidArr.shift()
sendResponse( recived )
} else {
clearInterval(timer)
}
}, interval)
}
})
sendTimer = setInterval(() => {
chrome.extension.sendMessage(
{ greeting: uidArr, status: status, interval: initinterval },
function (response) {
// console.log( 收到来自后台的回复: + response);
}
)
}, 1000)
if (status === stop ) {
clearInterval(sendTimer)
}
index.html
用途:点击插件后弹框的结构样式
manifest.json
用途:各种配置项,详情见上文博客
popup-script
用途:index.html的js文件,在index.html中引入,可以做一些事件监听,dom操作的事情
let uidArr = []
let interval = 30
function sendMessageToContentScript(message, callback) {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, message, function (response) {
if (callback) callback(response)
})
})
}
document.querySelector( #start ).addEventListener( click , function () {
uidArr = document.querySelector( #list ).value.split(/
|
/)
interval = document.querySelector( #interval ).value
sendMessageToContentScript(
{ cmd: start , uids: uidArr, interval: interval },
function (response) {
console.log( 来自content的回复: + response)
}
)
})
document.querySelector( #stop ).addEventListener( click , function () {
if (document.querySelector( #stop ).innerHTML === 停止 ) {
document.querySelector( #stop ).innerHTML = 继续
sendMessageToContentScript({ cmd: stop }, function (response) {
console.log( 来自content的回复: + response)
})
} else {
document.querySelector( #stop ).innerHTML = 停止
sendMessageToContentScript({ cmd: continue }, function (response) {
console.log( 来自content的回复: + response)
})
}
})
chrome.extension.onMessage.addListener(function (
request,
sender,
sendResponse
) {
if (request.greeting.length) {
document.querySelector( #list ).value = request.greeting.join(
)
}
if (request.status && request.status === stop ) {
document.querySelector( #stop ).innerHTML = 继续
}
if (request.status && request.status === continue ) {
document.querySelector( #stop ).innerHTML = 停止
}
if (request.interval) {
document.querySelector( #interval ).value = request.interval
}
})
源码地址
https://github.com/chuheji/weibo-sendMessage-Chromextension/tree/master
后记
这个插件是半年前开发的,当时水平有限,代码比较粗糙,见谅
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END

















暂无评论内容