领英批量加人

领英批量加人功能

目前为 2020-04-06 提交的版本。查看 最新版本

// ==UserScript==
// @name         领英批量加人
// @namespace    ༺黑白༻
// @version      1.8
// @description  领英批量加人功能
// @author       Paul
// @connect      *
// @match        *linkedin.com/search/results/people*
// @include      *linkedin.com/search/results/people*
// @match        *linkedin.com/in/*?local_name=*
// @include      *linkedin.com/in/*?local_name=*
// @require      https://cdn.bootcss.com/vue/2.6.11/vue.min.js
// @require      https://cdn.bootcss.com/element-ui/2.13.0/index.js
// @resource elementui https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/index.css
// @grant        GM_addStyle
// @grant        GM_openInTab
// @grant        GM_addValueChangeListener
// @grant        GM_removeValueChangeListener
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_getResourceText 
// @run-at       document-end
// @noframes     true
// ==/UserScript==
(function () {
    ({
        commonUtils: {
            queueStorageName: 'local_name',
            appendBodyHtml: function (html) {
                var temp = document.createElement('div');
                temp.innerHTML = html;
                var frag = document.createDocumentFragment();
                while ((temp = temp.firstChild)) {
                    frag.appendChild(temp);
                }
                document.body.appendChild(frag);
            },
            append: function (dom, html) {
                var temp = document.createElement('div');
                temp.innerHTML = html;
                var frag = document.createDocumentFragment();
                while ((temp = temp.firstChild)) {
                    frag.appendChild(temp);
                }
                dom.appendChild(frag);
            },
            execByPromiseAsync: function (scope, fn) {
                var args = Array.prototype.slice.call(arguments);
                args.splice(0, 2)
                return new Promise((resolve, reject) => {
                    args.unshift({
                        resolve: resolve,
                        reject: reject
                    });
                    fn.apply(scope, args);
                });
            },
            chkAsync(chkFn, ts) {
                ts = ts || 1000;
                if (typeof chkFn != 'function') chkFn = () => true;
                var setTimeoutFn = dfd => { var isok = chkFn(); if (isok) dfd.resolve(); else setTimeout(setTimeoutFn, ts, dfd); }
                return this.execByPromiseAsync(this, setTimeoutFn);
            },
            sleepAsync(ts) {
                ts = ts || 1000;
                return this.chkAsync(null, ts);
            },
            getRandom(n, m) {
                return parseInt(Math.random() * (m - n + 1) + n);
            }
            ,
            log(msg) {
                console.log(msg);
            },
            getQueryVariable: function (variable) {
                var query = window.location.search.substring(1);
                var vars = query.split("&");
                for (var i = 0; i < vars.length; i++) {
                    var pair = vars[i].split("=");
                    if (pair[0] == variable) { return pair[1]; }
                }
                return "";
            },
            fireKeyEvent(el, evtType, keyCode) {
                var evtObj;
                if (document.createEvent) {
                    if (unsafeWindow.KeyEvent) {//firefox 浏览器下模拟事件
                        evtObj = document.createEvent('KeyEvents');
                        evtObj.initKeyEvent(evtType, true, true, unsafeWindow, true, false, false, false, keyCode, 0);
                    } else {//chrome 浏览器下模拟事件
                        evtObj = document.createEvent('UIEvents');
                        evtObj.initUIEvent(evtType, true, true, unsafeWindow, 1);

                        delete evtObj.keyCode;
                        if (typeof evtObj.keyCode === "undefined") {//为了模拟keycode
                            Object.defineProperty(evtObj, "keyCode", { value: keyCode });
                        } else {
                            evtObj.key = String.fromCharCode(keyCode);
                        }

                        if (typeof evtObj.ctrlKey === 'undefined') {//为了模拟ctrl键
                            Object.defineProperty(evtObj, "ctrlKey", { value: true });
                        } else {
                            evtObj.ctrlKey = true;
                        }
                    }
                    el.dispatchEvent(evtObj);

                } else if (document.createEventObject) {//IE 浏览器下模拟事件
                    evtObj = document.createEventObject();
                    evtObj.keyCode = keyCode
                    el.fireEvent('on' + evtType, evtObj);
                }
            }
        },
        listPageMethods: function () {
            GM_addStyle(GM_getResourceText("elementui"));
            // 加载 element 字体
            GM_addStyle('@font-face{font-family:element-icons;src:url(https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/fonts/element-icons.woff) format("woff"),url(https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/fonts/element-icons.ttf) format("truetype");font-weight:400;font-display:"auto";font-style:normal}');
            GM_addStyle(`
input.people_ck{ position: absolute;top: 20px;opacity: 100;cursor: pointer;pointer-events:all;}
.ellipsisText{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;line-height: 23px; }
.ctrpanel{ position:fixed;top:0;right:0;height:100%;z-index:999;background-color:#fff; }
.ctrpanel .el-main { width:220px; }
.ctrpanel .hide { display:none; }
`);
            ({
                vueExt() {
                    // v-dialogDrag: 弹窗拖拽
                    Vue.directive('dialogdrag', {
                        bind(el, binding, vnode, oldVnode) {
                            const dialogHeaderEl = el.querySelector('.el-dialog__header')
                            const dragDom = el.querySelector('.el-dialog')
                            dialogHeaderEl.style.cursor = 'move'

                            // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
                            const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)

                            dialogHeaderEl.onmousedown = (e) => {
                                // 鼠标按下,计算当前元素距离可视区的距离
                                const disX = e.clientX - dialogHeaderEl.offsetLeft
                                const disY = e.clientY - dialogHeaderEl.offsetTop

                                // 获取到的值带px 正则匹配替换
                                let styL, styT

                                // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
                                if (sty.left.includes('%')) {
                                    styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
                                    styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
                                } else {
                                    styL = +sty.left.replace(/\px/g, '')
                                    styT = +sty.top.replace(/\px/g, '')
                                }

                                document.onmousemove = function (e) {
                                    // 通过事件委托,计算移动的距离
                                    const l = e.clientX - disX
                                    const t = e.clientY - disY

                                    // 移动当前元素
                                    dragDom.style.left = `${l + styL}px`
                                    dragDom.style.top = `${t + styT}px`

                                    // 将此时的位置传出去
                                    // binding.value({x:e.pageX,y:e.pageY})
                                }

                                document.onmouseup = function (e) {
                                    document.onmousemove = null
                                    document.onmouseup = null
                                }
                            }
                        }
                    })
                },
                run: function (commonUtils) {
                    this.vueExt();
                    unsafeWindow.App = new Vue({
                        el: '#vue',
                        data: function () {
                            this.commonUtils = commonUtils;
                            this.selectedCheckboxList = [];
                            this.sendList = [];
                            this.sendTextListKey = "linkin_SendTextList";
                            this.editorIdx = -1;
                            return {
                                loading: false,
                                textListDialogVisible: false,
                                textListData: [],
                                textAddDialogVisible: false,
                                sendingDialogVisible: false,
                                isExecuting: false,
                                isCompleted: false,
                                currentPeopleName: '',
                                connectSeconds: 0,
                                totalConnectPeopleCount: 0,
                                currentConnectPeopleCount: 0,
                                toggleHidePanel: false,
                                textAddForm: {
                                    content: ""
                                },
                                textAddFormRules: {
                                    content: [
                                        { required: true, message: '请输入内容', trigger: 'blur' },
                                        { min: 1, max: 290, message: '长度在 1 到 290 个字符', trigger: 'blur' }
                                    ]
                                }
                            };
                        },
                        beforeCreate: function () {
                            // 创建面板
                            commonUtils.appendBodyHtml(
                                `<div id="vue" >
                                    <el-container class="ctrpanel" >
                                        <el-aside width="10px" style="background-color:red;cursor: pointer;" >
                                            <span @click="toggleHidePanel=!toggleHidePanel" style="height:100%;widht:100%;display:block;">&nbsp;</span>
                                         </el-aside>
                                        <el-main :class="{ hide : toggleHidePanel }">
                                            <span style="color:red;">软件、网页工具定制,请联系[email protected]</span>
                                            <span v-if="loading">
                                                正在加载数据...
                                            </span>
                                            <template v-else>
                                                <el-row style="margin-top:10px;">
                                                    <el-col :span="12"><el-button type="primary"  @click="sellectedAll" >全选</el-button></el-col>
                                                    <el-col :span="12"><el-button type="primary"  @click="refreshInitPage" >刷新</el-button></el-col>
                                                </el-row>
                                                <el-row style="margin-top:10px;">
                                                    <el-col :span="24"><el-button type="primary"  @click="selectedSendText" >下一步</el-button></el-col>
                                                </el-row>
                                            </template>
                                         </el-main>
                                    </el-container>
                                    <el-dialog title="发送内容模板" :close-on-click-modal="false" :modal="false" :visible.sync="textListDialogVisible" width="50%" >
                                        <el-container>
                                            <el-header height="50px">
                                                <el-link type="primary" @click="showAddTextContent(true)">添加模板</el-link>
                                            </el-header>
                                            <el-main>
                                                <el-table :data="textListData" max-height="300" >
                                                   <el-table-column type="index"  width="50"></el-table-column>
                                                   <el-table-column label="内容">
                                                       <template slot-scope="scope">
                                                            <div class="ellipsisText">{{scope.row.content}}</div>
                                                       </template>
                                                   </el-table-column>
                                                   <el-table-column  label="状态" width="80" >
                                                         <template slot-scope="scope">
                                                            <span v-if="scope.row.enabled" style="color:#67C23A;">启用中</span>
                                                            <span v-else style="color:#E6A23C;">已禁用</span>
                                                         </template>
                                                   </el-table-column>
                                                   <el-table-column  label="状态" width="120" >
                                                        <template slot-scope="scope">
                                                            <el-dropdown split-button type="primary" @click="editTextContent(scope.$index)" width="120">
                                                                编辑
                                                                <el-dropdown-menu slot="dropdown">
                                                                     <el-dropdown-item v-if="scope.row.enabled" @click.native.prevent="toggleSendTextRowStatus(scope.$index,false)" style="color:#E6A23C;">禁用</el-dropdown-item>
                                                                     <el-dropdown-item v-else style="color:#67C23A;" @click.native.prevent="toggleSendTextRowStatus(scope.$index,true)">启用</el-dropdown-item>
                                                                     <el-dropdown-item style="color:#F56C6C;" @click.native.prevent="deleteSendTextRow(scope.$index, textListData)">移除</el-dropdown-item>
                                                                </el-dropdown-menu> 
                                                            </el-dropdown>
                                                        </template>
                                                    </el-table-column>
                                                </el-table>
                                            </el-main>
                                            <el-footer height="50px">
                                                <el-button type="primary" @click="beginConnectedPeople">开始联系</el-button>
                                            </el-footer>
                                       </el-container>
                                    </el-dialog>
                                    <el-dialog title="添加发送内容" :close-on-click-modal="false" :modal="false" :visible.sync="textAddDialogVisible" width="30%" >
                                       <el-container>
                                            <el-main>
                                               <el-form ref="textAddForm" :rules="textAddFormRules" :model="textAddForm" label-width="80px">
                                                     <el-form-item label="内容" prop="content">
                                                        <el-input type="textarea" :rows="10" v-model="textAddForm.content"></el-input>
                                                     </el-form-item>
                                                    <el-form-item>
                                                        <el-button type="primary" @click="updateTextContent('textAddForm')">确定</el-button>
                                                        <el-button @click="closeTextAddDialog('textAddForm')">取消</el-button>
                                                    </el-form-item>
                                               </el-form>
                                            </el-main>
                                       </el-container>
                                    </el-dialog>
                                    <el-dialog v-dialogdrag title="发送情况" :close-on-click-modal="false" :modal="false" :show-close="false" :visible.sync="sendingDialogVisible" width="20%" >
                                           <el-row>
                                               <el-col :span="24">{{executedMessage}}</el-col>
                                           </el-row>
                                           <el-row style="margin-top:10px;">
                                               <el-col :span="8">进度({{totalConnectPeopleCount}}):</el-col>
                                               <el-col :span="16"><el-progress :text-inside="true" :stroke-width="20" :percentage="progress"></el-progress></el-col>
                                           </el-row>
                                           <el-row style="margin-top:10px;">
                                               <el-col :span="24">
                                                    <el-button v-if="isCompleted" size="small" @click="closeSendingDialog">关闭</el-button>
                                                    <el-button type="danger" size="small" @click="stopSending" v-else >取消</el-button></el-col>
                                           </el-row>
                                    </el-dialog>
                                </div>`
                            );
                        },
                        mounted: function () {

                            this.initPeopleAsync().then(() => {
                                var dom = document.querySelector('artdeco-pagination ul');
                                if (dom) {
                                    dom.parentElement.addEventListener('click', async e => {
                                        //this.commonUtils.log('click');
                                        //this.commonUtils.log(e);
                                        if (e && e.target) {
                                            if (e.target.tagName.toLowerCase() != 'ul') {
                                                document.querySelectorAll('.search-results__list li').forEach(o => {
                                                    o.parentNode.removeChild(o);
                                                });
                                                await this.commonUtils.chkAsync(() => {
                                                    return document.querySelectorAll('.search-results__list li').length > 0;
                                                }, 500);
                                                //this.commonUtils.log(document.querySelectorAll('.search-results__list li'))
                                                this.initPeopleAsync();
                                            }
                                        }
                                    });
                                }
                            });
                        },
                        computed: {
                            executedMessage() {
                                return this.isExecuting ? `正在联系 ${this.currentPeopleName}...` : this.isCompleted ? "联系完成!" : `${this.connectSeconds}秒后联系下一个人。`;
                            },
                            progress() {
                                return Math.round((this.currentConnectPeopleCount / this.totalConnectPeopleCount) * 100);
                            }
                        },
                        methods: {
                            _initPeopleAsync: async function (dfd) {
                                this.loading = true;
                                var domlis, scrollY = 0;
                                await this.commonUtils.chkAsync(() => {
                                    if (document.querySelectorAll('.search-results__list li.search-result__occlusion-hint').length <= 0) {
                                        return true;
                                    }
                                    scrollY += 100;
                                    if (scrollY > document.body.scrollHeight) scrollY = 0;
                                    unsafeWindow.scrollBy(0, scrollY);
                                    return false;
                                }, 20);

                                await this.commonUtils.sleepAsync(2000);

                                domlis = document.querySelectorAll('.search-results__list li');
                                domlis.forEach(item => {
                                    var btn = item.querySelector('button')
                                    if (!item.querySelector("input.people_ck")
                                        && btn
                                        && (btn.childElementCount > 0 || btn.innerHTML.toLowerCase() == 'connect')) {
                                        item.style.position = "relative";
                                        this.commonUtils.append(item,
                                            '<input type="checkbox" class="people_ck" />');
                                    }
                                });
                                dfd.resolve();
                                this.loading = false;
                            },
                            initPeopleAsync: function () {
                                return this.commonUtils.execByPromiseAsync(this, this._initPeopleAsync);
                            },
                            sellectedAll() {
                                var cks = document.querySelectorAll('input.people_ck');
                                cks.forEach(item => { if (!item.checked) item.checked = true });
                            },
                            refreshInitPage() {
                                this.initPeopleAsync().then(() => {
                                    this.$message({
                                        type: 'success',
                                        message: '已刷新选择框!'
                                    });
                                });
                            },
                            getCheckedPeopleList() {
                                return document.querySelectorAll('input.people_ck:checked');
                            },
                            // 选择发送文本
                            selectedSendText() {
                                var cks = this.getCheckedPeopleList();
                                if (cks.length <= 0) {
                                    alert("请选择要联系的人员!")
                                    return;
                                }
                                // 组合数据
                                //this.selectedCheckboxList = cks;
                                this.refreshSendTextList();
                                this.textListDialogVisible = true;
                            },
                            // 从缓存中获取发送文本列表
                            getSendTextListByCahce() {
                                return GM_getValue(this.sendTextListKey, '[]');
                            },
                            // 设置发送文本列表到缓存
                            setSendTextListToCache() {
                                GM_setValue(this.sendTextListKey, JSON.stringify(this.textListData));
                            },
                            // 删除列表项
                            deleteSendTextRow(index, rows) {
                                this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
                                    confirmButtonText: '确定',
                                    cancelButtonText: '取消',
                                    type: 'warning'
                                }).then(() => {
                                    this.$message({
                                        type: 'success',
                                        message: '删除成功!'
                                    });
                                    rows.splice(index, 1);
                                    this.setSendTextListToCache();
                                }).catch(() => {
                                });
                            },
                            // 切换列表项状态
                            toggleSendTextRowStatus(index, enabled) {
                                this.textListData[index].enabled = enabled;
                            },
                            // 刷新列表
                            refreshSendTextList() {
                                var dataJson = this.getSendTextListByCahce();
                                this.textListData = JSON.parse(dataJson);
                            },
                            // 显示添加内容
                            showAddTextContent(isAdd) {
                                if (isAdd) this.editorIdx = -1;
                                this.textAddDialogVisible = true;
                            },
                            // 编辑内容
                            editTextContent(index) {
                                this.editorIdx = index;
                                this.textAddForm.content = this.textListData[index].content;
                                this.showAddTextContent(false);
                            },
                            // 更新内容
                            updateTextContent(formName) {
                                this.$refs[formName].validate((valid) => {
                                    if (valid) {
                                        if (this.editorIdx != -1) {
                                            this.textListData[this.editorIdx].content = this.textAddForm.content;
                                        } else {
                                            this.textListData.push({
                                                content: this.textAddForm.content,
                                                enabled: true
                                            });
                                        }
                                        this.setSendTextListToCache();
                                        this.closeTextAddDialog(formName);
                                    } else {
                                        return false;
                                    }
                                });
                            },
                            // 关闭显示添加内容
                            closeTextAddDialog(formName) {
                                this.$refs[formName].resetFields();
                                this.textAddDialogVisible = false;
                            },
                            // 关闭选择文本框
                            closeSelectSendTextDialog() {
                                this.textListDialogVisible = false;
                            },
                            // 关闭发送框
                            closeSendingDialog() {
                                this.sendingDialogVisible = false;
                            },
                            // 停止联系
                            stopSending() {
                                this.$confirm('此操作将终止本轮联系发送, 是否继续?', '提示', {
                                    confirmButtonText: '确定',
                                    cancelButtonText: '取消',
                                    type: 'warning'
                                }).then(() => {
                                    this.$message({
                                        type: 'success',
                                        message: '取消成功!'
                                    });
                                    this.isCompleted = true;
                                }).catch(() => {
                                });
                            },
                            // 开始联系
                            beginConnectedPeople() {
                                var sendList = this.textListData.filter(o => o.enabled);
                                if (sendList.length <= 0) {
                                    alert("没有可发送文本");
                                    return;
                                }

                                var cks = this.getCheckedPeopleList();
                                if (cks.length <= 0) {
                                    alert("没有可以联系的人员!")
                                    return;
                                }

                                this.selectedCheckboxList = Array.prototype.slice.call(cks);
                                this.sendList = sendList;
                                this.closeSelectSendTextDialog();
                                this.totalConnectPeopleCount = this.selectedCheckboxList.length;
                                this.currentConnectPeopleCount = 0;
                                this.sendingDialogVisible = true;

                                this.connect();
                            },
                            // 执行联系
                            connect() {
                                if (this.selectedCheckboxList.length <= 0) {
                                    this.isCompleted = true;
                                    return;
                                }
                                this.isCompleted = false;
                                this.currentConnectPeopleCount += 1;
                                this.currentPeopleName = '';
                                this.isExecuting = true;
                                //this.commonUtils.log("selectedCheckboxList:" + this.selectedCheckboxList.length);
                                setTimeout(this.doConnectAsync.bind(this, this.selectedCheckboxList.shift()), 100);
                            },
                            // 处理单个联系
                            async doConnectAsync(checkbox) {
                                var item = checkbox.parentElement;
                                var btn = item.querySelector('button.search-result__action-button');
                                // 随机获取一篇 文章
                                var idx = this.commonUtils.getRandom(0, this.sendList.length - 1);
                                var sendText = this.sendList[idx].content;
                                if (sendText.indexOf("{{Name}}") != -1) {
                                    var replaceText = '';
                                    var actorNameDom = item.querySelector('span.actor-name');
                                    if (actorNameDom) {
                                        replaceText = actorNameDom.innerHTML.split(' ')[0];
                                    }
                                    this.currentPeopleName = replaceText;
                                    sendText = sendText.replace('{{Name}}', replaceText);
                                }
                                this.commonUtils.log(sendText);
                                if (btn && btn.innerHTML.toLowerCase().indexOf('connect') != -1) {
                                    await this.doSimpleConnectAsync(btn, sendText);
                                } else {
                                    await this.doDetailConnectAsync(item, sendText);
                                }
                                this.isExecuting = false;
                                if (this.selectedCheckboxList.length > 0) {

                                    // 等待多少秒后执行
                                    this.connectSeconds = this.commonUtils.getRandom(10, 60);
                                    await this.commonUtils.chkAsync(() => {
                                        if (this.isCompleted) return true;
                                        this.connectSeconds -= 1;
                                        return this.connectSeconds <= 0;
                                    }, 1000);
                                }
                                if (!this.isCompleted) {
                                    setTimeout(this.connect.bind(this), 100);
                                }
                            },
                            // 简单联系
                            async doSimpleConnectAsync(connectBtn, sendText) {
                                connectBtn.click();
                                await this.commonUtils.chkAsync(() => {
                                    var chkDom = document.querySelector('#artdeco-modal-outlet');
                                    return chkDom && chkDom.innerHTML.trim().length > 0
                                }, 1000);
                                await this.commonUtils.sleepAsync(1000);
                                var addNoteBtn = document.querySelector('button[aria-label="Add a note"]');
                                if (addNoteBtn) {
                                    this.commonUtils.log("simple addNoteBtn!")
                                    addNoteBtn.click();
                                    await this.commonUtils.sleepAsync(1000);
                                    var textdom = document.querySelector('#custom-message');
                                    textdom.value = sendText;
                                    this.commonUtils.fireKeyEvent(textdom, "keyup");
                                    await this.commonUtils.sleepAsync(1000);
                                    var doneBtn = document.querySelector('button[aria-label="Done"]');
                                    if (!doneBtn) doneBtn = document.querySelector('button[aria-label="Send invitation"]');
                                    if (doneBtn) {
                                        this.commonUtils.log("simple doneBtn!")
                                        //doneBtn.removeAttribute("disabled");
                                        //doneBtn.focus();
                                        doneBtn.click();
                                        await this.commonUtils.chkAsync(() => {
                                            var chkDom = document.querySelector('#artdeco-modal-outlet');
                                            return !chkDom || chkDom.innerHTML.trim().length <= 0
                                        }, 1000);
                                    }
                                }
                            },
                            // 开tab页联系
                            async doDetailConnectAsync(item, sendText) {
                                var a, href;
                                if ((a = item.querySelector('a')) && (href = a.getAttribute('href')) && href.indexOf('/in/') != -1) {
                                    GM_setValue("linkin_sendtext", sendText);
                                    await this.openLoadPageAsync(unsafeWindow.location.origin + href);
                                } else {
                                    this.commonUtils.log("无法跳转详情!");
                                }
                            },
                            _valueChangeListener: function (dfd, listennerName, listennerTabName, name, old_v, new_v, remote) {
                                if (new_v && remote) {
                                    this.commonUtils.log(new_v);
                                    GM_deleteValue(name);
                                    GM_removeValueChangeListener(this[listennerName]);
                                    delete this[listennerName];
                                    if (this[listennerTabName]) this[listennerTabName].close();
                                    delete this[listennerTabName];
                                    dfd.resolve();
                                }
                            },
                            openLoadPageAsync: async function (url) {
                                return this.commonUtils.execByPromiseAsync(this, dfd => {
                                    var index = 0;
                                    var name = +new Date() + '_' + index, listennerName = "listener_" + index, listennerTabName = 'listener_tab_' + index;
                                    // 封装下 url
                                    if (url.indexOf('?') == -1) {
                                        url += "?"
                                    } else {
                                        url += "&"
                                    }
                                    url += `${this.commonUtils.queueStorageName}=${name}`;
                                    this[listennerName] = GM_addValueChangeListener(name, this._valueChangeListener.bind(this, dfd, listennerName, listennerTabName));
                                    this[listennerTabName] = GM_openInTab(url);
                                });
                            },

                        }
                    });
                }
            }).run(this.commonUtils);
        },
        UserInfoFn() {
            ({
                async _getInfoAsync(dfd) {
                    this.commonUtils.log("_getInfoAsync");
                    await this.commonUtils.chkAsync(() => document.querySelectorAll('artdeco-dropdown-item.pv-s-profile-actions').length > 0);
                    this.commonUtils.log("_getInfoAsync wait complete");
                    var items = document.querySelectorAll('artdeco-dropdown-item.pv-s-profile-actions')
                    var item = Array.prototype.find.call(items, o => {
                        var span = o.querySelector('span.pv-s-profile-actions__label');
                        if (!span) return false;
                        return span.innerHTML.toLowerCase().indexOf('connect') != -1;
                    });
                    var message = "not";
                    if (item) {
                        this.commonUtils.log("item");
                        item.click();
                        await this.commonUtils.chkAsync(() => {
                            var chkDom = document.querySelector('#artdeco-modal-outlet');
                            return chkDom && chkDom.innerHTML.trim().length > 0
                        }, 1000);
                        await this.commonUtils.sleepAsync(1000);
                        var addNoteBtn = document.querySelector('button[aria-label="Add a note"]');
                        if (addNoteBtn) {
                            this.commonUtils.log("addNoteBtn");
                            addNoteBtn.click();
                            await this.commonUtils.sleepAsync(1000);
                            var textdom = document.querySelector('#custom-message');
                            textdom.value = GM_getValue("linkin_sendtext", '');
                            this.commonUtils.fireKeyEvent(textdom, "keyup");
                            await this.commonUtils.sleepAsync(1000);
                            var doneBtn = document.querySelector('button[aria-label="Done"]');
                            if (!doneBtn) doneBtn = document.querySelector('button[aria-label="Send invitation"]');
                            if (doneBtn) {
                                this.commonUtils.log("doneBtn");
                                doneBtn.click();
                                await this.commonUtils.chkAsync(() => {
                                    var chkDom = document.querySelector('#artdeco-modal-outlet');
                                    return !chkDom || chkDom.innerHTML.trim().length <= 0
                                }, 1000);
                            }
                        }
                        message = "ok";
                    }
                    dfd.resolve(message);
                },
                getInfoAsync() {
                    return this.commonUtils.execByPromiseAsync(this, this._getInfoAsync);
                },
                run(commonUtils) {
                    this.commonUtils = commonUtils;
                    var name = this.commonUtils.getQueryVariable(this.commonUtils.queueStorageName);
                    //this.commonUtils.log("name:" + name);
                    this.getInfoAsync().then(function (rs) {
                        this.commonUtils.log("name:" + name);
                        this.commonUtils.log("getmessage:" + rs);
                        // 存入数据
                        GM_setValue(name, rs);
                    }.bind(this));
                }
            }).run(this.commonUtils);
        },
        run: function () {
            if (unsafeWindow.location.href.toLowerCase().indexOf('linkedin.com/search/results/people') != -1) {
                this.listPageMethods();
            } else {
                this.UserInfoFn();
            }
        }
    }).run();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址