Skip to content
This repository has been archived by the owner on Mar 30, 2023. It is now read-only.

Commit

Permalink
点击飞书消息通知可打开窗口界面
Browse files Browse the repository at this point in the history
通过 hack html5 的 Notification 接口,将网页端的通知消息拦截并发送到 main.js,之后由 electron 侧重新发起一个消息通知,以便支持点击消息之后的回调
  • Loading branch information
Ericwyn committed Apr 26, 2021
1 parent 3727ed1 commit f8c4781
Showing 1 changed file with 64 additions and 4 deletions.
68 changes: 64 additions & 4 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const shell = electron.shell;
const app = electron.app;
const ipcMain = electron.ipcMain;
const BrowserWindow = electron.BrowserWindow;
const Notification = electron.Notification;
const Menu = electron.Menu;
if (process.mas) app.setName('飞书Feishu');

Expand Down Expand Up @@ -42,7 +43,8 @@ function createWindow(configJson) {
width: 1000,
height: 770,
webPreferences: {
nodeIntegration: true
nodeIntegration: true,
contextIsolation: false
},
icon: appConf.icon128
})
Expand Down Expand Up @@ -97,6 +99,37 @@ function createWindow(configJson) {
webContents.executeJavaScript(`if(document.getElementsByClassName('lark-water-mark-main').length > 0) document.getElementsByClassName('lark-water-mark-main')[0].remove()`)
}
}, 1500);

// 注入 js,hack html5 的 Notification 接口,并将通知内容转发到 main.js 里
webContents.executeJavaScript(`
let ipcRenderer = null;
try{ipcRenderer = require('electron').ipcRenderer} catch(e) {}
let oldNotification = window.Notification;
let newNotification = function(title, opt){
console.log("hack-title:" + title);
console.log("hack-opt:" + JSON.stringify(opt));
if(ipcRenderer != null) {
let sendMsg = JSON.stringify({
title: title,
opt: opt
})
try {
ipcRenderer.send("notification", sendMsg);
} catch (e) {
console.log("发送 ipc 消息报错", e);
return new oldNotification(title,opt);
}
} else {
return new oldNotification(title,opt);
}
}
newNotification.requestPermission = oldNotification.requestPermission.bind(oldNotification);
Object.defineProperty(newNotification, 'permission', {
get: () => {
return oldNotification.permission;
}
});
window.Notification = newNotification;`);
})

// 定义在 electron 内部打开的 url,除此之外的 url 都跳转浏览器打开,使用 indexOf >= 0 来判断
Expand Down Expand Up @@ -242,8 +275,6 @@ function getConfigJson(callback){
callback(JSON.parse(data))
}
});


}

// ------------------------ App ------------------------------------
Expand Down Expand Up @@ -284,4 +315,33 @@ app.on('activate', () => {
if (win == null) {
createWindow();
}
})
})

// 接受从载入页面发送过来的通知消息
ipcMain.on("notification", (event, msg) => {
console.log("收到消息")
// console.log(event)
console.log(msg)
let args = JSON.parse(msg)
// let title = args.title;
// let opt = args.opt;
// console.log(args.title, args.opt);
// title 是对话框名称,opt 是聊天的具体内容,想看格式的话可以去掉上面那行注释
showElectronNotify(args.title, args.opt)
event.returnValue = 'pong'
})

function showElectronNotify(title, opt){
if(Notification.isSupported()) {
let electronNotification = new Notification({
title: title,
subtitle : title,
body : opt.body,
icon: electron.nativeImage.createFromPath(appConf.dock32),
});
electronNotification.addListener('click', function(){
if(mainWindow != null) mainWindow.show();
})
electronNotification.show();
}
}

2 comments on commit f8c4781

@ttys3
Copy link
Contributor

@ttys3 ttys3 commented on f8c4781 Jun 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the window.Notification intercepts is awesome!

@ttys3
Copy link
Contributor

@ttys3 ttys3 commented on f8c4781 Jun 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I borrowed the idea here to my lark-gtk implements.

this hack will allow auto switch to the target group or person message area:

            window.notification_locate = window.notification_locate || ((selector) => {
                let target_feed_div = document.querySelector(selector);
                if (target_feed_div) {
                        target_feed_div.click();
                        console.info('target_feed_div click ok: ', selector);
                } else {
                        console.error('target_feed_div not found: ', selector);
                }
            });
            (() => {
                let selector = 'div[data-feed-id="channel_id"]';
                notification_locate(selector);
            })();

the channel_id is from the Notification opts 's channel_id field

#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LarkNotification {
    pub title: String,
    pub body: String,
    pub key: Option<String>,
    pub channel_id: Option<String>,
    pub channel_type: Option<i64>,
    pub extra: Option<LarkNotificationExtra>,
    pub message_id: Option<String>,
    pub position: Option<i64>,
    pub icon: Option<String>,
    #[serde(rename = "type")]
    pub type_field: Option<i64>,
}

Please sign in to comment.