mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-10-06 13:54:10 +08:00
feat: 退群监控增加重新发送功能
This commit is contained in:
@@ -1175,6 +1175,9 @@ app.whenReady().then(async () => {
|
|||||||
)
|
)
|
||||||
ipcMain.handle('group-exit-monitor:checkNow', () => groupExitMonitorService.checkNow())
|
ipcMain.handle('group-exit-monitor:checkNow', () => groupExitMonitorService.checkNow())
|
||||||
ipcMain.handle('group-exit-monitor:clearEvents', () => groupExitMonitorService.clearEvents())
|
ipcMain.handle('group-exit-monitor:clearEvents', () => groupExitMonitorService.clearEvents())
|
||||||
|
ipcMain.handle('group-exit-monitor:resendEvent', (_, eventId: string) =>
|
||||||
|
groupExitMonitorService.resendEvent(eventId)
|
||||||
|
)
|
||||||
ipcMain.handle('group-exit-monitor:markRead', (_, readAt?: number) =>
|
ipcMain.handle('group-exit-monitor:markRead', (_, readAt?: number) =>
|
||||||
groupExitMonitorService.markRead(readAt)
|
groupExitMonitorService.markRead(readAt)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -602,7 +602,8 @@ class GroupExitMonitorService {
|
|||||||
|
|
||||||
private async notifyGroup(
|
private async notifyGroup(
|
||||||
group: GroupSnapshotRecord,
|
group: GroupSnapshotRecord,
|
||||||
event: GroupExitMonitorEvent
|
event: GroupExitMonitorEvent,
|
||||||
|
idempotencyKey = `member_left_notification:${event.id}`
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
event.notificationStatus = 'pending'
|
event.notificationStatus = 'pending'
|
||||||
event.notification = { status: 'pending' }
|
event.notification = { status: 'pending' }
|
||||||
@@ -610,7 +611,7 @@ class GroupExitMonitorService {
|
|||||||
this.broadcast()
|
this.broadcast()
|
||||||
try {
|
try {
|
||||||
const result = await this.actionGateway.execute({
|
const result = await this.actionGateway.execute({
|
||||||
idempotencyKey: `member_left_notification:${event.id}`,
|
idempotencyKey,
|
||||||
origin: 'member_monitor',
|
origin: 'member_monitor',
|
||||||
purpose: 'member_left_notification',
|
purpose: 'member_left_notification',
|
||||||
triggerType: 'automation',
|
triggerType: 'automation',
|
||||||
@@ -665,6 +666,17 @@ class GroupExitMonitorService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async resendEvent(eventId: string): Promise<GroupExitMonitorState> {
|
||||||
|
const event = this.events.find((item) => item.id === eventId)
|
||||||
|
if (!event) throw new Error('退群动态不存在')
|
||||||
|
await this.notifyGroup(
|
||||||
|
{ roomId: event.roomId, groupName: event.groupName } as GroupSnapshotRecord,
|
||||||
|
event,
|
||||||
|
`member_left_notification:${event.id}:retry:${Date.now()}`
|
||||||
|
)
|
||||||
|
return this.getState()
|
||||||
|
}
|
||||||
|
|
||||||
private filePath(): string {
|
private filePath(): string {
|
||||||
return path.join(app.getPath('userData'), 'group-exit-monitor.json')
|
return path.join(app.getPath('userData'), 'group-exit-monitor.json')
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
@@ -275,6 +275,7 @@ declare global {
|
|||||||
setGroupExitMonitorNotificationTemplate: (template: string) => Promise<GroupExitMonitorState>
|
setGroupExitMonitorNotificationTemplate: (template: string) => Promise<GroupExitMonitorState>
|
||||||
checkGroupExitMonitorNow: () => Promise<GroupExitMonitorState>
|
checkGroupExitMonitorNow: () => Promise<GroupExitMonitorState>
|
||||||
clearGroupExitMonitorEvents: () => Promise<GroupExitMonitorState>
|
clearGroupExitMonitorEvents: () => Promise<GroupExitMonitorState>
|
||||||
|
resendGroupExitMonitorEvent: (eventId: string) => Promise<GroupExitMonitorState>
|
||||||
markGroupExitMonitorRead: (readAt?: number) => Promise<GroupExitMonitorState>
|
markGroupExitMonitorRead: (readAt?: number) => Promise<GroupExitMonitorState>
|
||||||
listWechatActionLogs: () => Promise<ActionLogEntry[]>
|
listWechatActionLogs: () => Promise<ActionLogEntry[]>
|
||||||
onGroupExitMonitorState: (callback: (state: GroupExitMonitorState) => void) => () => void
|
onGroupExitMonitorState: (callback: (state: GroupExitMonitorState) => void) => () => void
|
||||||
|
|||||||
@@ -155,6 +155,8 @@ const api = {
|
|||||||
ipcRenderer.invoke('group-exit-monitor:checkNow'),
|
ipcRenderer.invoke('group-exit-monitor:checkNow'),
|
||||||
clearGroupExitMonitorEvents: (): Promise<GroupExitMonitorState> =>
|
clearGroupExitMonitorEvents: (): Promise<GroupExitMonitorState> =>
|
||||||
ipcRenderer.invoke('group-exit-monitor:clearEvents'),
|
ipcRenderer.invoke('group-exit-monitor:clearEvents'),
|
||||||
|
resendGroupExitMonitorEvent: (eventId: string): Promise<GroupExitMonitorState> =>
|
||||||
|
ipcRenderer.invoke('group-exit-monitor:resendEvent', eventId),
|
||||||
markGroupExitMonitorRead: (readAt?: number): Promise<GroupExitMonitorState> =>
|
markGroupExitMonitorRead: (readAt?: number): Promise<GroupExitMonitorState> =>
|
||||||
ipcRenderer.invoke('group-exit-monitor:markRead', readAt),
|
ipcRenderer.invoke('group-exit-monitor:markRead', readAt),
|
||||||
listWechatActionLogs: (): Promise<ActionLogEntry[]> =>
|
listWechatActionLogs: (): Promise<ActionLogEntry[]> =>
|
||||||
|
|||||||
@@ -85,10 +85,14 @@ const sendCapabilityTone = (capability: PersonalWechatSendCapability | null): st
|
|||||||
|
|
||||||
function EventNotificationStatus({
|
function EventNotificationStatus({
|
||||||
event,
|
event,
|
||||||
onOpenSendSettings
|
onOpenSendSettings,
|
||||||
|
onResend,
|
||||||
|
resending
|
||||||
}: {
|
}: {
|
||||||
event: GroupExitMonitorState['events'][number]
|
event: GroupExitMonitorState['events'][number]
|
||||||
onOpenSendSettings?: () => void
|
onOpenSendSettings?: () => void
|
||||||
|
onResend?: () => void
|
||||||
|
resending?: boolean
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
const status = event.notificationStatus || event.notification?.status || 'not_requested'
|
const status = event.notificationStatus || event.notification?.status || 'not_requested'
|
||||||
const details =
|
const details =
|
||||||
@@ -120,6 +124,11 @@ function EventNotificationStatus({
|
|||||||
去设置
|
去设置
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
{status !== 'sent' && status !== 'pending' && onResend ? (
|
||||||
|
<Button variant="link" size="sm" onClick={onResend} disabled={resending}>
|
||||||
|
{resending ? '发送中...' : '重新发送'}
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -455,6 +464,7 @@ export function GroupExitMonitorWorkspace({
|
|||||||
const [templateError, setTemplateError] = React.useState('')
|
const [templateError, setTemplateError] = React.useState('')
|
||||||
const [selectedRoomId, setSelectedRoomId] = React.useState('all')
|
const [selectedRoomId, setSelectedRoomId] = React.useState('all')
|
||||||
const [view, setView] = React.useState<'events' | 'manage'>('events')
|
const [view, setView] = React.useState<'events' | 'manage'>('events')
|
||||||
|
const [resendingEventId, setResendingEventId] = React.useState<string | null>(null)
|
||||||
const [manageKeyword, setManageKeyword] = React.useState('')
|
const [manageKeyword, setManageKeyword] = React.useState('')
|
||||||
const [manageFilter, setManageFilter] = React.useState<GroupSelectionFilter>('all')
|
const [manageFilter, setManageFilter] = React.useState<GroupSelectionFilter>('all')
|
||||||
const [selectedManageRoomIds, setSelectedManageRoomIds] = React.useState<Set<string>>(
|
const [selectedManageRoomIds, setSelectedManageRoomIds] = React.useState<Set<string>>(
|
||||||
@@ -594,6 +604,19 @@ export function GroupExitMonitorWorkspace({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resendEvent = async (eventId: string): Promise<void> => {
|
||||||
|
if (resendingEventId || typeof window.api.resendGroupExitMonitorEvent !== 'function') return
|
||||||
|
setResendingEventId(eventId)
|
||||||
|
setError('')
|
||||||
|
try {
|
||||||
|
setState(await window.api.resendGroupExitMonitorEvent(eventId))
|
||||||
|
} catch (reason) {
|
||||||
|
setError(reason instanceof Error ? reason.message : String(reason))
|
||||||
|
} finally {
|
||||||
|
setResendingEventId(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const saveGroups = async (): Promise<void> => {
|
const saveGroups = async (): Promise<void> => {
|
||||||
const api = window.api
|
const api = window.api
|
||||||
if (saving || !dbReady || typeof api.setGroupExitMonitorGroups !== 'function') return
|
if (saving || !dbReady || typeof api.setGroupExitMonitorGroups !== 'function') return
|
||||||
@@ -857,6 +880,8 @@ export function GroupExitMonitorWorkspace({
|
|||||||
<EventNotificationStatus
|
<EventNotificationStatus
|
||||||
event={event}
|
event={event}
|
||||||
onOpenSendSettings={onOpenSendSettings}
|
onOpenSendSettings={onOpenSendSettings}
|
||||||
|
onResend={() => void resendEvent(event.id)}
|
||||||
|
resending={resendingEventId === event.id}
|
||||||
/>
|
/>
|
||||||
<dl className="exit-monitor-event-details">
|
<dl className="exit-monitor-event-details">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user