feat: bot

This commit is contained in:
hashbro
2026-08-15 23:05:51 +08:00
parent 9049fdccad
commit 376b442880
26 changed files with 944 additions and 352 deletions
+50 -5
View File
@@ -33,6 +33,9 @@
<script type="text/html" id="LAY-agent-ops">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="channels">渠道链接</a>
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="edit">编辑</a>
@{{# if (d.telegram_ready) { }}
<a class="layui-btn layui-btn-xs" lay-event="tgtest">测试TG</a>
@{{# } }}
</script>
</div>
</div>
@@ -43,6 +46,8 @@
layui.use(['table', 'form', 'layer'], function () {
var table = layui.table, form = layui.form, layer = layui.layer, $ = layui.$;
var token = @json(csrf_token());
var botUsername = @json($botUsername ?? '');
var botInviteUrl = @json($botInviteUrl ?? '');
function esc(s) {
return String(s == null ? '' : s)
@@ -72,7 +77,7 @@ layui.use(['table', 'form', 'layer'], function () {
{ field: 'comment', title: '备注', minWidth: 100 },
{ field: 'channels_count', title: '渠道数', width: 90 },
{ field: 'created_at', title: '创建时间', width: 160, sort: true },
{ title: '操作', width: 180, align: 'center', fixed: 'right', toolbar: '#LAY-agent-ops' }
{ title: '操作', width: 240, align: 'center', fixed: 'right', toolbar: '#LAY-agent-ops' }
]],
page: true, limit: 20, limits: [10, 20, 30, 50],
request: { pageName: 'page', limitName: 'limit' },
@@ -97,17 +102,45 @@ layui.use(['table', 'form', 'layer'], function () {
'<input name="password" type="password" class="layui-input" placeholder="' + (values.id ? '留空不改' : '必填') + '"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">备注</label><div class="layui-input-block">' +
'<input name="comment" class="layui-input" value="' + esc(values.comment || '') + '"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">Bot Token</label><div class="layui-input-block">' +
'<input name="bot_token" class="layui-input" placeholder="代理 Telegram Bot Token" value="' + esc(values.bot_token || '') + '"></div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">Chat ID</label><div class="layui-input-block">' +
'<input name="chat_id" class="layui-input" placeholder="代理通知群 chat_id" value="' + esc(values.chat_id || '') + '"></div></div>' +
'<div class="layui-form-item"><div class="layui-input-block" style="color:#888;font-size:12px;line-height:1.5;">配置后该代理渠道通知发往此 Bot/群;指令仅可查本代理数据,不支持 /transfer。<br>Webhook: <code>/hooks/telegram/agent/{id}</code>,保存后执行 <code>php artisan telegram:set-webhook --agent={id}</code></div></div>' +
'<div style="display:flex;gap:8px;align-items:center;">' +
'<input name="chat_id" class="layui-input" placeholder="代理通知群 chat_id" value="' + esc(values.chat_id || '') + '" style="flex:1;">' +
'<button type="button" class="layui-btn layui-btn-primary" id="LAY-agent-tg-test" style="flex-shrink:0;">测试推送</button>' +
'</div></div></div>' +
'<div class="layui-form-item"><div class="layui-input-block" style="color:#888;font-size:12px;line-height:1.5;">' +
(botUsername
? '请邀请 <b>' + esc(botUsername) + '</b> 进群' + (botInviteUrl ? '(<a href="' + esc(botInviteUrl) + '" target="_blank" rel="noopener">点此邀请</a>)' : '') + ',进群后 Bot 会回复 Chat ID,再填到这里。'
: '请先在系统设置保存有效 Bot Token(会自动识别 @用户名),再邀请该 Bot 进群。') +
' 填 Chat ID 后,该代理渠道通知会同时发到此群和官方群。</div></div>' +
'<div class="layui-form-item"><label class="layui-form-label">状态</label><div class="layui-input-block">' +
'<input type="checkbox" name="status_switch" lay-skin="switch" lay-text="启用|禁用" ' + ((values.status == null || values.status == 1) ? 'checked' : '') + '>' +
'</div></div>' +
'</form>',
success: function () {
form.render();
$('#LAY-agent-tg-test').on('click', function () {
var $btn = $(this);
if ($btn.prop('disabled')) return;
$btn.prop('disabled', true);
$.ajax({
url: @json(route('admin.agents.telegramTest')),
method: 'POST',
data: {
_token: token,
chat_id: $('#LAY-agent-form input[name=chat_id]').val(),
agent_id: values.id || ''
},
success: function (res) {
layer.msg(res.msg || (res.code === 0 ? '已发送' : '失败'));
},
error: function (xhr) {
layer.msg((xhr.responseJSON && xhr.responseJSON.message) || '测试失败');
},
complete: function () {
$btn.prop('disabled', false);
}
});
});
},
btn: ['保存', '取消'],
yes: function (index) {
@@ -154,6 +187,18 @@ layui.use(['table', 'form', 'layer'], function () {
}
});
});
} else if (obj.event === 'tgtest') {
$.ajax({
url: @json(route('admin.agents.telegramTest')),
method: 'POST',
data: { _token: token, agent_id: d.id, chat_id: d.chat_id },
success: function (res) {
layer.msg(res.msg || (res.code === 0 ? '已发送' : '失败'));
},
error: function (xhr) {
layer.msg((xhr.responseJSON && xhr.responseJSON.message) || '测试失败');
}
});
} else if (obj.event === 'channels') {
$.getJSON(@json(url('/admin/agents')) + '/' + d.id + '/channels', function (res) {
var html = (res.data || []).map(function (c) {