# 任务失败通知集成推送助手

dependabot/pip/spug_api/paramiko-3.4.0
vapao 2023-11-08 18:08:43 +08:00
parent 26753a807e
commit 3d83dbb117
4 changed files with 67 additions and 24 deletions

View File

@ -55,17 +55,20 @@ class GroupView(View):
class ContactView(View): class ContactView(View):
@auth('alarm.contact.view|alarm.group.view') @auth('alarm.contact.view|alarm.group.view|schedule.schedule.add|schedule.schedule.edit')
def get(self, request): def get(self, request):
form, error = JsonParser( form, error = JsonParser(
Argument('with_push', required=False), Argument('with_push', required=False),
Argument('only_push', required=False),
).parse(request.GET) ).parse(request.GET)
if error is None: if error is None:
response = [] response = []
if form.with_push: if form.with_push or form.only_push:
push_key = AppSetting.get('spug_push_key') push_key = AppSetting.get('spug_push_key')
if push_key: if push_key:
response = get_contacts(push_key) response = get_contacts(push_key)
if form.only_push:
return json_response(response)
for item in Contact.objects.all(): for item in Contact.objects.all():
response.append(item.to_dict()) response.append(item.to_dict())

View File

@ -3,6 +3,8 @@
# Released under the AGPL-3.0 License. # Released under the AGPL-3.0 License.
from libs.utils import human_datetime from libs.utils import human_datetime
from libs.spug import Notification from libs.spug import Notification
from libs.push import push_server
from apps.setting.utils import AppSetting
import json import json
@ -79,3 +81,18 @@ def _do_notify(task, mode, url, msg):
} }
} }
Notification.handle_request(url, data, 'fs') Notification.handle_request(url, data, 'fs')
elif mode == '5':
spug_push_key = AppSetting.get_default('spug_push_key')
if not spug_push_key:
return
data = {
'source': 'schedule',
'token': spug_push_key,
'targets': url,
'dataset': {
'name': task.name,
'type': task.type,
'message': msg or '请在任务计划执行历史中查看详情',
}
}
Notification.handle_request(f'{push_server}/spug/message/', data, 'spug')

View File

@ -161,6 +161,7 @@ class Notification:
make_no_push_key_notify() make_no_push_key_notify()
return return
data = { data = {
'source': 'monitor',
'token': self.spug_push_key, 'token': self.spug_push_key,
'targets': list(targets), 'targets': list(targets),
'dataset': { 'dataset': {

View File

@ -1,16 +1,25 @@
import React, { useState } from 'react'; import React, {useState, useEffect} from 'react';
import {observer} from 'mobx-react'; import {observer} from 'mobx-react';
import {Form, Input, Select, Modal, Button, Radio} from 'antd'; import {Form, Input, Select, Modal, Button, Radio} from 'antd';
import {ExclamationCircleOutlined} from '@ant-design/icons'; import {ExclamationCircleOutlined} from '@ant-design/icons';
import {LinkButton, ACEditor} from 'components'; import {LinkButton, ACEditor} from 'components';
import TemplateSelector from '../exec/task/TemplateSelector'; import TemplateSelector from '../exec/task/TemplateSelector';
import { cleanCommand } from 'libs'; import {cleanCommand, http} from 'libs';
import store from './store'; import store from './store';
export default observer(function () { export default observer(function () {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [showTmp, setShowTmp] = useState(false); const [showTmp, setShowTmp] = useState(false);
const [command, setCommand] = useState(store.record.command || ''); const [command, setCommand] = useState(store.record.command || '');
const [rstValue, setRstValue] = useState({});
const [contacts, setContacts] = useState([]);
useEffect(() => {
const {mode, value} = store.record.rst_notify
setRstValue({[mode]: value})
http.get('/api/alarm/contact/?only_push=1')
.then(res => setContacts(res))
}, []);
function handleAddZone() { function handleAddZone() {
let type; let type;
@ -39,8 +48,10 @@ export default observer(function () {
} }
function handleNext() { function handleNext() {
store.page += 1; const notifyMode = store.record.rst_notify.mode
store.record.rst_notify.value = rstValue[notifyMode]
Object.assign(store.record, form.getFieldsValue(), {command: cleanCommand(command)}) Object.assign(store.record, form.getFieldsValue(), {command: cleanCommand(command)})
store.page += 1;
} }
function handleSelect(tpl) { function handleSelect(tpl) {
@ -67,6 +78,7 @@ export default observer(function () {
modePlaceholder = '请输入' modePlaceholder = '请输入'
} }
const notifyMode = store.record.rst_notify.mode
return ( return (
<Form form={form} initialValues={store.record} labelCol={{span: 6}} wrapperCol={{span: 14}}> <Form form={form} initialValues={store.record} labelCol={{span: 6}} wrapperCol={{span: 14}}>
<Form.Item required label="任务类型" style={{marginBottom: 0}}> <Form.Item required label="任务类型" style={{marginBottom: 0}}>
@ -104,21 +116,31 @@ export default observer(function () {
<a target="_blank" rel="noopener noreferrer" <a target="_blank" rel="noopener noreferrer"
href="https://spug.cc/docs/use-problem#use-dd">钉钉收不到通知</a> href="https://spug.cc/docs/use-problem#use-dd">钉钉收不到通知</a>
</span>)}> </span>)}>
<Input <Input.Group compact>
value={store.record.rst_notify.value} <Select style={{width: '25%'}} value={notifyMode}
onChange={e => store.record.rst_notify.value = e.target.value}
addonBefore={(
<Select style={{width: 100}} value={store.record.rst_notify.mode}
onChange={v => store.record.rst_notify.mode = v}> onChange={v => store.record.rst_notify.mode = v}>
<Select.Option value="0">关闭</Select.Option> <Select.Option value="0">关闭</Select.Option>
<Select.Option value="1">钉钉</Select.Option> <Select.Option value="1">钉钉</Select.Option>
<Select.Option value="4">飞书</Select.Option> <Select.Option value="4">飞书</Select.Option>
<Select.Option value="3">企业微信</Select.Option> <Select.Option value="3">企业微信</Select.Option>
<Select.Option value="2">Webhook</Select.Option> <Select.Option value="2">Webhook</Select.Option>
<Select.Option value="5">推送助手</Select.Option>
</Select> </Select>
)} <Select hidden={notifyMode !== '5'} mode="multiple" style={{width: '75%'}} value={rstValue[notifyMode]}
disabled={store.record.rst_notify.mode === '0'} onChange={v => setRstValue(Object.assign({}, rstValue, {[notifyMode]: v}))}
placeholder="请选择推送对象">
{contacts.map(item => (
<Select.Option value={item.id} key={item.id}>{item.name}</Select.Option>
))}
</Select>
<Input
hidden={notifyMode === '5'}
style={{width: '75%'}}
value={rstValue[notifyMode]}
onChange={e => setRstValue(Object.assign({}, rstValue, {[notifyMode]: e.target.value}))}
disabled={notifyMode === '0'}
placeholder={modePlaceholder}/> placeholder={modePlaceholder}/>
</Input.Group>
</Form.Item> </Form.Item>
<Form.Item name="desc" label="备注信息"> <Form.Item name="desc" label="备注信息">
<Input.TextArea placeholder="请输入模板备注信息"/> <Input.TextArea placeholder="请输入模板备注信息"/>