From 540b3af087451115e7a40207b747494177d2a0a2 Mon Sep 17 00:00:00 2001 From: hellcat <> Date: Sat, 12 Apr 2025 22:16:06 +0800 Subject: [PATCH] no message --- .../Controllers/Api/Tg/HookController.php | 230 +++++ app/Http/Controllers/CronController 2.php | 22 - app/Http/Controllers/TestsController.php | 52 + .../Controllers/TomApi/Tg/HookController.php | 924 ------------------ app/Http/Kernel.php | 2 +- bootstrap/app.php | 8 +- public/tests/hook.php | 6 +- routes/api.php | 17 + routes/web.php | 12 + 9 files changed, 321 insertions(+), 952 deletions(-) create mode 100755 app/Http/Controllers/Api/Tg/HookController.php delete mode 100755 app/Http/Controllers/CronController 2.php create mode 100755 app/Http/Controllers/TestsController.php delete mode 100755 app/Http/Controllers/TomApi/Tg/HookController.php create mode 100755 routes/api.php diff --git a/app/Http/Controllers/Api/Tg/HookController.php b/app/Http/Controllers/Api/Tg/HookController.php new file mode 100755 index 0000000..45ca8ef --- /dev/null +++ b/app/Http/Controllers/Api/Tg/HookController.php @@ -0,0 +1,230 @@ +middleware('csrf')->except(['cmd']); + // 或者 $this->middleware('csrf')->only(['specificMethod']); + } + + + public function cmd() + { + + $this->sApiToken = env('telegram_token'); + $this->sApiChatId = env('telegram_chatid'); + + $sUpdate = file_get_contents("php://input"); + + $aUpdate = json_decode($sUpdate, true); + + @file_put_contents('/www/_tg/bot_log.txt', json_encode($aUpdate, JSON_PRETTY_PRINT)); + + $aData['chatId'] = $aUpdate["message"]["chat"]["id"]; + $aData['fromId'] = $aUpdate["message"]["from"]["id"]; + + if (!isset($aUpdate["message"]["text"])) { + http_response_code(200); + echo "not have text"; + exit; + } + + $sText = $aUpdate["message"]["text"]; + + + // 打断 + if ($sText === "/break") { + + $oTgStep->clearByFromId($aData["fromId"]); + + $this->sendMessage("ok"); + + Http::response(200, 'ok'); + + } + + // 命令列表 + // /cmdList + if (strpos($sText, '/cmdList') === 0 || strpos($sText, '\/cmdList') === 0) { + + $aCmdList = [ + '优惠码list' => '/saleCodeList', + '优惠码find' => '/saleCodeFind xxhh', +// '优惠码add' => '/saleCodeAdd xxhh', +// '优惠码del' => '/saleCodeDel__xxhh', +// '优惠码set' => '/saleCodeSet__xxhh__field set', + '文章list' => '/articleList', + '文章like' => '/articleLike__field like', + '文章add' => '/articleAdd__name', + '文章del' => '/articleDel__id', + '文章set' => '/articleSet__id__fild set', + ]; + + $this->sendMessage(json_encode($aCmdList, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + + Http::response(200, 'ok'); + + } + + // 优惠list + if (strpos($sText, '/saleCodeList') === 0 || strpos($sText, '\/saleCodeList') === 0) { + + $aSaleCodeList = Article::select('sale_code', 'sale_rate') + ->distinct() + ->orderBy("sale_code") + ->get() + ->toArray(); + + $this->sendMessage(json_encode($aSaleCodeList, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + + Http::response(200, 'ok'); + } + + // 优惠find + if (strpos($sText, '/saleCodeFind') === 0 || strpos($sText, '\/saleCodeFind') === 0) { + + list(, $sSaleCode) = explode(" ", $sText); + + $aSaleCodeList = Article::select('sale_code', 'sale_rate') + ->where("sale_code", $sSaleCode) + ->distinct() + ->orderBy("sale_code") + ->get() + ->toArray(); + + $this->sendMessage(json_encode($aSaleCodeList, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + + Http::response(200, 'ok'); + + } + + // 文章list + if (strpos($sText, '/ArticleList') === 0 || strpos($sText, '\/ArticleList') === 0) { + + $aArticleList = Article::orderBy("user_name")->get()->toArray(); + + foreach ($aArticleList as $row) { + $this->sendMessage(json_encode($row, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + } + + Http::response(200, 'ok'); + } + + // 文章 like + // /ArticleLike__user_name xxx + if (strpos($sText, '/ArticleLike') === 0 || strpos($sText, '\/ArticleLike') === 0) { + + list($sCmd, $sLike) = explode(" ", $sText); + list(, $sField) = explode("__", $sCmd); + + $aArticleList = Article::where($sField, 'like', '%' . $sLike . '%') + ->orderBy("user_name") + ->get() + ->toArray(); + + + foreach ($aArticleList as $row) { + $this->sendMessage(json_encode($row, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + } + + Http::response(200, 'ok'); + } + + // 文章 add + if (strpos($sText, '/articleAdd') === 0 || strpos($sText, '\/articleAdd') === 0) { + + list(, $sUserName) = explode(" ", $sText); + + $newArticle = new Article(); + $newArticle->user_name = $sUserName; + $r = $newArticle->save(); + + $this->sendMessage(json_encode($r, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + + Http::response(200, 'ok'); + + } + + // 文章 del + if (strpos($sText, '/articleDel') === 0 || strpos($sText, '\/articleDel') === 0) { + + list(, $iId) = explode(" ", $sText); + + $article = Article::find($iId); + + if ($article) { + $r = $article->delete(); + } else { + $r = false; + } + + $this->sendMessage(json_encode($r, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + + Http::response(200, 'ok'); + + } + + // 文章 set + // /ArticleSet__id__user_name xxx + if (strpos($sText, '/ArticleSet') === 0 || strpos($sText, '\/ArticleSet') === 0) { + + list($sCmd, $sSet) = explode(" ", $sText); + list(, $iId, $sField) = explode("__", $sCmd, 3); + + $article = Article::find($iId); + + if ($article) { + $article->$sField = $sSet; + + $r = $article->save(); + } else { + // 处理未找到的情况 + } + + $this->sendMessage(json_encode($r, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + + Http::response(200, 'ok'); + } + + } + + private function sendMessage($sText = '?') { + + if (env('is_loc') === true) { + echo "
";
+            var_dump($sText);
+        } else {
+            $url = "https://api.telegram.org/bot$this->sApiToken/sendMessage?chat_id=$this->sApiChatId&text=" . urlencode($sText);
+            file_get_contents($url);
+        }
+        
+    }
+    
+}
diff --git a/app/Http/Controllers/CronController 2.php b/app/Http/Controllers/CronController 2.php
deleted file mode 100755
index e9e822a..0000000
--- a/app/Http/Controllers/CronController 2.php	
+++ /dev/null
@@ -1,22 +0,0 @@
-sToUrl = "https://github.loc/";
-
-    }
-    
-}
diff --git a/app/Http/Controllers/TestsController.php b/app/Http/Controllers/TestsController.php
new file mode 100755
index 0000000..cfa17da
--- /dev/null
+++ b/app/Http/Controllers/TestsController.php
@@ -0,0 +1,52 @@
+sMethod = "post";
+        $oHttp->sToUrl = "https://github.loc/api/tg/hook";
+        $oHttp->bIsJson = true;
+        $oHttp->aData = [
+            'update_id' => 123456789,
+            'message' => [
+                'message_id' => 1,
+                'from' => [
+                    'id' => 7740568271,
+                    'is_bot' => false,
+                    'first_name' => 'John',
+                    'last_name' => 'Doe',
+                    'username' => 'johndoe',
+                    'language_code' => 'en'
+                ],
+                'chat' => [
+                    'id' => -4668400285,
+                    'first_name' => 'John',
+                    'last_name' => 'Doe',
+                    'username' => 'johndoe',
+                    'type' => 'private'
+                ],
+                'date' => 1610000000,
+                "text" => "\/ArticleSet__7__user_name xxxzz",
+            ]
+        ];
+
+        $r = $oHttp->send();
+
+        echo($r);
+
+        exit;
+        
+    }
+    
+}
diff --git a/app/Http/Controllers/TomApi/Tg/HookController.php b/app/Http/Controllers/TomApi/Tg/HookController.php
deleted file mode 100755
index c9515cb..0000000
--- a/app/Http/Controllers/TomApi/Tg/HookController.php
+++ /dev/null
@@ -1,924 +0,0 @@
-sApiToken = Config::obtain('telegram_token');
-        $this->sApiChatId = Config::obtain('telegram_chatid');
-        
-        $sUpdate = file_get_contents("php://input");
-        
-        $aUpdate = json_decode($sUpdate, true);
-        
-        @file_put_contents('/www/_tg/bot_log.txt', json_encode($aUpdate, JSON_PRETTY_PRINT));
-        
-        $aData['chatId'] = $aUpdate["message"]["chat"]["id"];
-        $aData['fromId'] = $aUpdate["message"]["from"]["id"];
-        
-        if (!isset($aUpdate["message"]["text"])) {
-            http_response_code(200);
-            echo "not have text";
-            exit;
-        }
-        
-        $sText = $aUpdate["message"]["text"];
-        
-        // 先检查step
-        if (strpos($sText, "/s ") === 0 && $oTgStep->fromIdHit($aData['fromId'])) {
-            
-            $sText = ltrim($sText, '/s');
-            $sText = trim($sText);
-            
-            $aTgStepFirst = $oTgStep->find($aData["fromId"]);
-            
-            if ($aTgStepFirst["cmd"] == "reply") {
-                
-                if ($aTgStepFirst['step'] == 1) {
-                    $oHttp = new Http();
-                    
-                    $oHttp->sMethod = "put";
-                    $oHttp->sToUrl = $_ENV['baseUrl']."/api/tg/ticket/".$aTgStepFirst['cache']['ticketId'];
-                    $oHttp->bIsJson = true;
-                    $aData['comment'] = $sText;
-                    $aData['admin_name'] = $aUpdate["message"]["from"]["first_name"];
-                    $oHttp->aData = $aData;
-                    
-                    $r = @json_decode($oHttp->send(), true);
-                    
-                    // 不论失败成功都清除step
-                    $oTgStep->clearByFromId($aUpdate["message"]["from"]["id"]);
-                    
-                    if ($r["ret"] == 1) {
-                        $sMessage = "成功";
-                    } else {
-                        $sMessage = "失败";
-                        Http::response(500, json_encode($aData));
-                    }
-                    
-                    $this->sendMessage($sMessage);
-                    
-                    Http::response(200, 'ok');
-                }
-                
-            }
-            
-        }
-        
-        // 打断
-        if ($sText === "/break") {
-            
-            $oTgStep->clearByFromId($aData["fromId"]);
-            
-            $this->sendMessage("ok");
-            
-            http_response_code(200);exit;
-        }
-        
-        // 命令列表
-        // /cmdList
-        if (strpos($sText, '/cmdList') === 0 || strpos($sText, '\/cmdList') === 0) {
-            
-            $aCmdList = [
-                '流量报告'  => 'reportWidth',
-                '查找用户'  => 'userFind 11',
-                '查找订单'  => 'orderFindByUser 11',
-                '回复工单'  => 'reply 11 + s 你好',
-                '快捷回单'  => 'ry 11 你好',
-                '工单查找'  => 'ticketFind 11',
-                '用户报表'  => 'reportUser_day_7 && reportUser_date_2025-02-02 && reportUser_date_2025-02-02_2025-03-03',
-                'duck添加&转发'  => 'duckAdd jp02',
-                'duck删除&转发'  => 'duckDel jp02',
-                'duck修改&转发'  => 'duckOption|max_width|jp01 1.66#tb',
-                'duck列表&转发'  => 'duckList',
-                'duck查找'  => 'duckFind jp02',
-                '转发重置'  => 'zhuanfaReset-youshi 2025-02-02',
-                'node修改'  => 'nodeOption#name#11 haha',
-                '节点like'  => 'nodeLike#duck jp02',
-                'node删除'  => 'nodeDel 18',
-                'node复制'  => 'nodeCopy 18',
-                '节点列表简洁'=> 'nodeList',
-            ];
-            
-            $this->sendMessage(json_encode($aCmdList, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 流量报告
-        // /reportWidth
-        if (strpos($sText, '/reportWidth') === 0 || strpos($sText, '\/reportWidth') === 0) {
-            
-            $jobs = new \App\Services\Cron();
-            
-            $jobs->reportBandWidth();
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 查找用户
-        // /userFind 11
-        if (strpos($sText, '/userFind') === 0 || strpos($sText, '\/userFind') === 0) {
-            
-            list(, $iUserId) = explode(" ", $sText, 2);
-            
-            $oUser = User::find($iUserId);
-            
-            if ($oUser) {
-                $aUser = $oUser->toArray();
-                unset($aUser['pass']);
-                unset($aUser['passwd']);
-                unset($aUser['uuid']);
-                unset($aUser['method']);
-                unset($aUser['is_admin']);
-                unset($aUser['theme']);
-                unset($aUser['ga_token']);
-                unset($aUser['ga_enable']);
-                unset($aUser['api_token']);
-                unset($aUser['is_dark_mode']);
-                unset($aUser['locale']);
-                
-                $aUser['transfer_today'] = Tools::flowToGB($aUser['transfer_today']).'GB';
-                $aUser['transfer_total'] = Tools::flowToGB($aUser['transfer_total']).'GB';
-                $aUser['transfer_enable'] = Tools::flowToGB($aUser['transfer_enable']).'GB';
-                $aUser['last_use_time'] = date('Y-m-d H:i:s', $aUser['last_use_time']);
-            } else {
-                $aUser = ["not have id" => $iUserId];
-            }
-
-            $this->sendMessage(json_encode($aUser, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 查找订单
-        // orderFindByUser 11
-        if (strpos($sText, '/orderFindByUser') === 0 || strpos($sText, '\/orderFindByUser') === 0) {
-            
-            list(, $iUserId) = explode(" ", $sText, 2);
-            
-            $aOrder = Order::where("user_id", $iUserId)->get()->toArray();
-            
-            if ($aOrder) {
-                $aOrderNew = [];
-                foreach ($aOrder as $k => $v) {
-                    $v['create_time'] = date("Y-m-d H:i:m", $v['create_time']);
-                    $v['update_time'] = date("Y-m-d H:i:m", $v['update_time']);
-                    $v['product_content'] = json_decode($v['product_content']);
-                    $aOrderNew[] = $v;
-                }
-            } else {
-                $aOrderNew = ["not have id" => $iUserId];
-            }
-            
-            $this->sendMessage(json_encode($aOrderNew, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 回复工单
-        // /reply 11 + /s 你好
-        if (strpos($sText, '/reply') === 0) {
-            
-            // 先清除一遍,只进行一个进程
-            $oTgStep->clearByFromId($aData["fromId"]);
-                 
-            $iTicketId = str_replace('/reply', '', $sText);
-            $iTicketId = (int) trim($iTicketId);
-            
-            $oTgStep->add($aData['fromId'], 'reply', 1, ["ticketId" => $iTicketId]);
-            
-            $sMessage = "将回复工单【".$iTicketId."】,请输入回复内容。";
-
-            $this->sendMessage($sMessage);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 快捷回复工单
-        // /ry 11 你好
-        if (strpos($sText, '/ry') === 0 || strpos($sText, '\/ry') === 0) {
-            
-            try {
-                $sText = $this->trimText($sText, '/ry');
-                
-                list($iTicketId, $sText) = explode(" ", $sText, 2);
-                
-                $oHttp = new Http();
-                
-                $oHttp->sMethod = "put";
-                $oHttp->sToUrl = $_ENV['baseUrl']."/api/tg/ticket/".$iTicketId;
-                $oHttp->bIsJson = true;
-                $aData['comment'] = $sText;
-                $aData['admin_name'] = $aUpdate["message"]["from"]["first_name"];
-                $oHttp->aData = $aData;
-                
-                $r = @json_decode($oHttp->send(), true);
-                
-                // 不论失败成功都清除 step
-                $oTgStep->clearByFromId($aUpdate["message"]["from"]["id"]);
-                
-                if ($r["ret"] == 1) {
-                    $sMessage = "成功";
-                } else {
-                    $sMessage = "失败";
-                    Http::response(200, json_encode($aData));
-                }
-                
-                $this->sendMessage($sMessage);
-                
-                Http::response(200, 'ok');
-                
-            } catch (Exception $e) {
-                
-                $sMessage = "发生错误: " . $e->getMessage();
-                
-                $this->sendMessage($sMessage);
-                
-                Http::response(200, '内部服务器错误');
-                
-            }
-            
-        }
-        
-        // 复制节点
-        // /nodeCopy 11
-        if (strpos($sText, '/nodeCopy') === 0 || strpos($sText, '\/nodeCopy') === 0) {
-            
-            list(, $iNodeId) = explode(" ", $sText, 2);
-            
-            $oHttp = new Http();
-            
-            $oHttp->sMethod = "post";
-            $oHttp->sToUrl = $_ENV['baseUrl']."/api/tg/node/".$iNodeId."/copy";
-            $oHttp->bIsJson = true;
-            $oHttp->aData = $aData;
-            
-            $r = @json_decode($oHttp->send(), true);
-            
-            if ($r["ret"] == 1) {
-                $sMessage = "成功";
-            } else {
-                $sMessage = "失败";
-                Http::response(500, json_encode($aData));
-            }
-            
-            $this->sendMessage($sMessage);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 用户报表
-        // /reportUser_day_7 && /reportUser_date_2025-02-02 && /reportUser_date_2025-02-02_2025-03-03
-        if (strpos($sText, '/reportUser') === 0 || strpos($sText, '\/reportUser') === 0) {
-            
-            @list(, $sOption1, $sOption2, $sOption3) = explode("_", $sText, 4);
-            
-            $sMsg = '?';
-            
-            if ($sOption1 == 'day') {
-                
-                $sMsg = (new ServiceTgReportUser())->ByDay($sOption2);
-                
-            }
-            
-            if ($sOption1 == 'date') {
-                $sMsg = (new ServiceTgReportUser())->ByDate($sOption2, $sOption3);
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 优惠卷报表
-        // /reportCoupon#7
-        if (strpos($sText, '/reportCoupon') === 0 || strpos($sText, '\/reportCoupon') === 0) {
-            try {
-                @list($sCmd, $iDay) = explode("#", $sText, 2);
-                
-                // 确保 $iDay 是一个有效的数字
-                if (!is_numeric($iDay) || $iDay < 0) {
-                    $this->sendMessage('无效的天数参数');
-                    Http::response(200, '内部服务器错误');
-                }
-
-                $sStartTime = strtotime("-$iDay days");
-
-                $aOrderList = Order::where('update_time', '>=', $sStartTime)
-                        ->whereIn('status', ['activated', 'pending_activation']) // 添加状态条件
-                        ->select('coupon',
-                                 \App\Services\DB::raw('count(*) as total'),
-                                 \App\Services\DB::raw('SUM(price) as total_price'))
-                        ->groupBy('coupon')
-                        ->get()
-                        ->toArray();
-
-                $sMsg = '从 '.date("Y-m-d H:i:s", $sStartTime);
-                foreach ($aOrderList as $row) {
-                    $coupon = str_replace('.', '#', $row['coupon']);
-                    if (!$coupon) {
-                        $coupon = '无';
-                    }
-                    $sMsg .= "\n\n";
-                    $sMsg .= $coupon . ' - ' . $row['total_price'] . ' / ' . $row['total'];
-                }
-
-                $this->sendMessage($sMsg);
-                
-                Http::response(200, 'ok');
-            } catch (Exception $e) {
-                // 处理异常
-                $errorMsg = '发生错误: ' . $e->getMessage();
-                $this->sendMessage($errorMsg);
-                
-                // 返回错误响应
-                Http::response(200, '内部服务器错误');
-            }
-        }
-
-
-        // 节点列表(简洁)
-        // /nodeList
-        if (strpos($sText, '/nodeList') === 0 || strpos($sText, '\/nodeList') === 0) {
-            
-            $aNodeList = Node::where('type', 1)->orderBy('name', 'asc')->get()->toArray();
-            
-            $sMsg = '';
-            foreach ($aNodeList as $row) {
-                $sMsg .= "\n\n";
-                $sMsg .= $row['name'].', id:'.$row['id'].', duck:'.$row['duck_code'].', zf:'.$row['zhuanfa_code'].', sort:'.$row['sort'];
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 添加duck
-        // /duckAdd jp01
-        if (strpos($sText, '/duckAdd') === 0 || strpos($sText, '\/duckAdd') === 0) {
-            
-            list($sCmd, $sCode) = explode(" ", $sText, 2);
-            
-            try {
-                $oDucks = new Ducks();
-                $oDucks->code = $sCode;
-
-                if ($oDucks->save()) {
-                    $sMsg = "成功";
-                } else {
-                    $sMsg = "失败";
-                }
-            } catch (\Exception $e) {
-                $sMsg = json_encode($e->getMessage());
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 查找duck
-        // /duckFind jp01
-        if (strpos($sText, '/duckFind') === 0 || strpos($sText, '\/duckFind') === 0) {
-            
-            list($sCmd, $sCode) = explode(" ", $sText, 2);
-            
-            $aData = Ducks::where('code', $sCode)->first()->toArray();
-            
-            $aData['use_width'] = Tools::flowToGB($aData['use_width']).'GB';
-            $aData['max_width'] = Tools::flowToGB($aData['max_width']).'GB';
-            $aData['today_width'] = Tools::flowToGB($aData['today_width']).'GB';
-            
-            $this->sendMessage(json_encode($aData, JSON_PRETTY_PRINT));
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 添加zhuanfa
-        // /zhuanfaAdd jp01
-        if (strpos($sText, '/zhuanfaAdd') === 0 || strpos($sText, '\/zhuanfaAdd') === 0) {
-            
-            list($sCmd, $sCode) = explode(" ", $sText, 2);
-            
-            try {
-                $oZhuanfas = new Zhuanfas();
-                $oZhuanfas->code = $sCode;
-
-                if ($oZhuanfas->save()) {
-                    $sMsg = "成功";
-                } else {
-                    $sMsg = "失败";
-                }
-            } catch (\Exception $e) {
-                $sMsg = json_encode($e->getMessage());
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 删除duck
-        // /duckDel jp01
-        if (strpos($sText, '/duckDel') === 0 || strpos($sText, '\/duckDel') === 0) {
-            
-            list($sCmd, $sCode) = explode(" ", $sText, 2);
-            
-            try {
-                $oDucks = Ducks::where("code", $sCode)->first();
-
-                if ($oDucks) {
-                    // 尝试删除记录
-                    $deleted = $oDucks->delete();
-
-                    if ($deleted) {
-                        // 删除成功
-                        $sMsg = "成功";
-                    } else {
-                        // 删除失败
-                        $sMsg = "失败";
-                    }
-                } else {
-                    // 找不到记录
-                    $sMsg = "找不到记录";
-                }
-            } catch (\Exception $e) {
-                // 捕获异常并返回错误信息
-                $sMsg = json_encode($e->getMessage());
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 删除node
-        // /duckDel jp01
-        if (strpos($sText, '/nodeDel') === 0 || strpos($sText, '\/nodeDel') === 0) {
-            
-            list($sCmd, $iId) = explode(" ", $sText, 2);
-            
-            $sMsg = '?';
-            
-            try {
-                $oNode = Node::where("id", $iId)->first();
-
-                if ($oNode) {
-                    // 尝试删除记录
-                    $deleted = $oNode->delete();
-
-                    if ($deleted) {
-                        // 删除成功
-                        $sMsg = "成功";
-                    } else {
-                        // 删除失败
-                        $sMsg = "失败";
-                    }
-                } else {
-                    // 找不到记录
-                    $sMsg = "找不到记录";
-                }
-            } catch (\Exception $e) {
-                // 捕获异常并返回错误信息
-                $sMsg = json_encode($e->getMessage());
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 删除zhuanfa
-        // /zhuanfaDel jp01
-        if (strpos($sText, '/zhuanfaDel') === 0 || strpos($sText, '\/zhuanfaDel') === 0) {
-            
-            list($sCmd, $sCode) = explode(" ", $sText, 2);
-            
-            try {
-                $oZhuanfas = Zhuanfas::where("code", $sCode)->first();
-
-                if ($oZhuanfas) {
-                    // 尝试删除记录
-                    $deleted = $oZhuanfas->delete();
-
-                    if ($deleted) {
-                        // 删除成功
-                        $sMsg = "成功";
-                    } else {
-                        // 删除失败
-                        $sMsg = "失败";
-                    }
-                } else {
-                    // 找不到记录
-                    $sMsg = "找不到记录";
-                }
-            } catch (\Exception $e) {
-                // 捕获异常并返回错误信息
-                $sMsg = json_encode($e->getMessage());
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 修改duck
-        // /duckOption@end_date@jp01 2025_02_02
-        // /duckOption@max_width@jp01 1.66#tb
-        if (strpos($sText, '/duckOption') === 0 || strpos($sText, '\/duckOption') === 0) {
-            
-            list($sCmd, $sSet) = explode(" ", $sText, 2);
-            list(, $sField, $sCode) = explode("#", $sCmd, 3);
-        
-            if ($sSet) {
-                @list($iWidth, $sWidthType) = explode("|", $sSet, 2);
-            } else {
-                $sMsg = "没有参数";
-            }
-            
-            
-            if ($sWidthType == 'tb') {
-                $sSet = Tools::tomTbToB($iWidth);
-            }
-            
-            if ($sWidthType == 'gb') {
-                $sSet = Tools::tomGbToB($iWidth);
-            }
-            
-            $sMsg = '?';
-            try {
-                
-                $oDuck = Ducks::where('code', $sCode)->first();
-                
-                if (!$oDuck) {
-                    $sMsg = "没有这个code";
-                } else {
-                    $oDuck->$sField = $sSet;
-                    if ($oDuck->save()) {
-                        $sMsg = "成功"; // 保存成功
-                    } else {
-                        $sMsg = "失败"; // 保存失败
-                    }
-                }
-                
-            } catch (\Illuminate\Database\QueryException $e) {
-                
-                $sMsg = json_encode($e->getMessage());
-                
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 修改zhuanfa
-        // /zhuanfaOption-end_date-jp01 2025_02_02
-        // /zhuanfaOption-max_width-jp01 1.66#tb
-        if (strpos($sText, '/zhuanfaOption') === 0 || strpos($sText, '\/zhuanfaOption') === 0) {
-            
-            list($sCmd, $sSet) = explode(" ", $sText, 2);
-            list(, $sField, $sCode) = explode("-", $sCmd, 3);
-            @list($iWidth, $sWidthType) = explode("#", $sSet, 2);
-            
-            if ($sWidthType == 'tb') {
-                $sSet = Tools::tomTbToB($iWidth);
-            }
-            
-            if ($sWidthType == 'gb') {
-                $sSet = Tools::tomGbToB($iWidth);
-            }
-            
-            $sMsg = '?';
-            try {
-                
-                $oZhuanfas = Zhuanfas::where('code', $sCode)->first();
-                
-                if (!$oZhuanfas) {
-                    $sMsg = "没有这个code";
-                } else {
-                    $oZhuanfas->$sField = $sSet;
-                    if ($oZhuanfas->save()) {
-                        $sMsg = "成功"; // 保存成功
-                    } else {
-                        $sMsg = "失败"; // 保存失败
-                    }
-                }
-                
-            } catch (\Illuminate\Database\QueryException $e) {
-                
-                $sMsg = json_encode($e->getMessage());
-                
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 转发重置
-        // /zhuanfaReset-youshi 2025-02-02
-        if (strpos($sText, '/zhuanfaReset') === 0 || strpos($sText, '\/zhuanfaReset') === 0) {
-            
-            list($sCmd, $sDate) = explode(" ", $sText, 2);
-            list(, $sCode) = explode("-", $sCmd, 2);
-            
-            $sMsg = '?';
-            try {
-                
-                $oZhuanfas = Zhuanfas::where('code', $sCode)->first();
-                
-                if (!$oZhuanfas) {
-                    $sMsg = "没有这个code";
-                } else {
-                    $oZhuanfas->use_width = 0;
-                    $oZhuanfas->end_date = $sDate;
-                    if ($oZhuanfas->save()) {
-                        $sMsg = "成功"; // 保存成功
-                    } else {
-                        $sMsg = "失败"; // 保存失败
-                    }
-                }
-                
-            } catch (\Illuminate\Database\QueryException $e) {
-                
-                $sMsg = json_encode($e->getMessage());
-                
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // duck list
-        // /duckList
-        if (strpos($sText, '/duckList') === 0 || strpos($sText, '\/duckList') === 0) {
-            
-            $aDuckList = Ducks::orderBy('code')->get()->toArray();
-            
-            $aMsgData = [];
-            foreach ($aDuckList as $k => $v) {
-                $v['use_width'] = Tools::flowToGB($v['use_width']).'g';
-                $v['max_width'] = Tools::flowToGB($v['max_width']).'g';
-                $v['today_width'] = Tools::flowToGB($v['today_width']).'g';
-                $aMsgData[] = $v;
-            }
-            
-            $this->sendMessage(json_encode($aMsgData, JSON_PRETTY_PRINT));
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // zhuanfa list
-        // /zhuanfaList
-        if (strpos($sText, '/zhuanfaList') === 0 || strpos($sText, '\/zhuanfaList') === 0) {
-            
-            $aZhuanfaList = Zhuanfas::orderBy('code')->get()->toArray();
-            
-            $aMsgData = [];
-            foreach ($aZhuanfaList as $k => $v) {
-                $v['use_width'] = Tools::flowToTB($v['use_width'])."t";
-                $v['max_width'] = Tools::flowToTB($v['max_width']).'t';
-                $v['today_width'] = Tools::flowToGB($v['today_width']).'g';
-                $aMsgData[] = $v;
-            }
-            
-            $this->sendMessage(json_encode($aMsgData, JSON_PRETTY_PRINT));
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 节点设置变更
-        // /nodeOption@name@1 haha
-        if (strpos($sText, '/nodeOption') === 0 || strpos($sText, '\/nodeOption') === 0) {
-            
-            list($sCmd, $sSet) = explode(" ", $sText, 2);
-            
-            list(, $sField, $iNodeId) = explode("#", $sCmd, 3);
-            
-            switch ($sField) {
-                case "config":
-                    $sField = "custom_config";
-                    break;
-                case "duck":
-                    $sField = "duck_code";
-                    break;
-                case "zhuanfa":
-                    $sField = "zhuanfa_code";
-                    break;
-                default:
-                    $sField = $sField;
-                    break;
-            }
-            
-            $sMsg = '?';
-            try {
-                
-                $oNode = Node::find($iNodeId);
-                
-                if (!$oNode) {
-                    $sMsg = "没有这个id";
-                } else {
-                    $oNode->$sField = $sSet;
-                    $oNode->save();
-                    
-                    $sMsg = "ok";
-                }
-                
-            } catch (\Illuminate\Database\QueryException $e) {
-                
-                $sMsg = "数据库操作失败";
-                
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        // 节点搜索
-        // /nodeLike_duck_type1 jp02
-        if (strpos($sText, '/nodeLike') === 0 || strpos($sText, '\/nodeLike') === 0) {
-                
-            @list($sCmd, $sLike) = explode(" ", $sText);
-            
-            @list(, $sField, $sMod) = explode("#", $sCmd, 3);
-            
-            switch ($sField) {
-                case "port":
-                    $sField = "custom_config";
-                    break;
-                case "config":
-                    $sField = "custom_config";
-                    break;
-                case "duck":
-                    $sField = "duck_code";
-                    break;
-                case "zhuanfa":
-                    $sField = "zhuanfa_code";
-                    break;
-                default:
-                    $sField = $sField;
-                    break;
-            }
-            
-            $sMsg = '?';
-        
-            try {
-                
-                $oNodeList = Node::where($sField, 'like', '%' . $sLike . '%');
-                
-                if ($sMod == 'type1') {
-                    $oNodeList->where('type', 1);
-                }
-                
-                $aNodeList = $oNodeList->orderBy('type', 'desc')->orderBy('name', 'asc')->get()->toArray();
-                
-            } catch (\Illuminate\Database\QueryException $e) {
-                
-                $sMsg = '字段不存在';
-                
-            }
-            
-            if (empty($aNodeList)) {
-                
-                $sMsg = "没有";
-                
-            } else {
-                
-                $aNodeListNew = [];
-                foreach ($aNodeList as $row) {
-                    
-                    $row['custom_config'] = json_decode($row['custom_config']);
-                    $row['dynamic_rate_config'] = json_decode($row['dynamic_rate_config']);
-                    $row['node_bandwidth_limit'] = Tools::flowToGB($row['node_bandwidth_limit']).'GB';
-                    $row['node_bandwidth'] = Tools::flowToGB($row['node_bandwidth']).'GB';
-                    $row['node_heartbeat'] = date('Y-m-d H:i:s', $row['node_heartbeat']);
-                    unset($row['is_dynamic_rate']);
-                    unset($row['dynamic_rate_type']);
-                    unset($row['dynamic_rate_config']);
-                    unset($row['bandwidthlimit_resetday']);
-                    unset($row['is_dynamic_rate']);
-                    unset($row['password']);
-                    
-//                    $aNodeListNew[] = $row;
-                    
-                    $sMsg = json_encode($row, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
-                    
-                    $this->sendMessage($sMsg);
-                }
-                
-//                $sMsg = json_encode($aNodeListNew, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
-                Http::response(200, 'ok');
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-       
-        // 工单查找
-        // /ticketFind 11
-        if (strpos($sText, '/ticketFind') === 0) {
-            
-            $iTicketId = $this->trimText($sText, '/ticketFind');
-            
-            $aTicket = Ticket::where("id", $iTicketId)->first()->toArray();
-            
-            $sMsg = "title:".$aTicket['title']."。\n";
-            
-            $aTicketContent = json_decode($aTicket['content'], true);
-            
-            if (!is_array($aTicketContent[0])) {
-                $aTicketContent[] = $aTicketContent;
-            }
-            
-            foreach ($aTicketContent as $row) {
-                $sMsg .= "\n";
-                $sMsg .= "name:".$row['commenter_name']."\n";
-                $sMsg .= "comment:".$row['comment']."\n";
-            }
-            
-            $this->sendMessage($sMsg);
-            
-            Http::response(200, 'ok');
-            
-        }
-        
-        Http::response(200, '无');
-
-    }
-    
-    private function trimText($sText, $sTrim)
-    {
-        $sText = ltrim($sText, $sTrim);
-        $sText = trim($sText);
-        
-        return $sText;
-    }
-    
-    private function sendMessage($sText = '?') {
-        
-        if ($_ENV['is_loc'] === true) {
-            echo "
";
-            var_dump($sText);
-        } else {
-            $url = "https://api.telegram.org/bot$this->sApiToken/sendMessage?chat_id=$this->sApiChatId&text=" . urlencode($sText);
-            file_get_contents($url);
-        }
-        
-    }
-    
-}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index bd351ca..863608c 100755
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -1,7 +1,7 @@
  \App\Http\Middleware\Test::class,
+//    'test' => \App\Http\Middleware\Test::class,
 ];
 
 ?>
diff --git a/bootstrap/app.php b/bootstrap/app.php
index 9bbba82..adb2b31 100755
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -7,12 +7,16 @@ use Illuminate\Foundation\Configuration\Middleware;
 return Application::configure(basePath: dirname(__DIR__))
     ->withRouting(
         web: __DIR__.'/../routes/web.php',
+        api: __DIR__.'/../routes/api.php',
         commands: __DIR__.'/../routes/console.php',
         health: '/up',
     )
     ->withMiddleware(function (Middleware $middleware) {
-         $middleware->alias([
-             'test' => \App\Http\Middleware\Test::class,
+//         $middleware->alias([
+//             'test' => \App\Http\Middleware\Test::class,
+//         ]);
+         $middleware->validateCsrfTokens(except: [
+                 'api/*',
          ]);
     })
     ->withExceptions(function (Exceptions $exceptions) {
diff --git a/public/tests/hook.php b/public/tests/hook.php
index 9d2625b..a025cf1 100644
--- a/public/tests/hook.php
+++ b/public/tests/hook.php
@@ -2,7 +2,7 @@
 
 include("include/head.php");
 
-include("../../src/Services/TomTool/Http.php");
+include("../../App/Services/TomTool/Http.php");
 
 //include("../../config/.config.php");
 
@@ -33,10 +33,10 @@ $oHttp->aData = [
             'type' => 'private'
         ],
         'date' => 1610000000,
-        "text" => "\/ry 你好,网站是正常运行的。用不了一般是没配置对,调试调试。",
+        "text" => "\/saleCodeList",
     ]
 ];
-
+//echo 1111;exit;
 //{
 //    "update_id": 761180998,
 //    "message": {
diff --git a/routes/api.php b/routes/api.php
new file mode 100755
index 0000000..292041a
--- /dev/null
+++ b/routes/api.php
@@ -0,0 +1,17 @@
+group(function () {
+
+//    Route::post('/api/tg/hook', [HookController::class, 'cmd']);
+
+//});
diff --git a/routes/web.php b/routes/web.php
index 90aafb0..303cf71 100755
--- a/routes/web.php
+++ b/routes/web.php
@@ -2,7 +2,19 @@
 
 use Illuminate\Support\Facades\Route;
 use App\Http\Controllers\CronController;
+use App\Http\Controllers\TestsController;
+use App\Http\Controllers\Api\Tg\HookController;
 
 //Route::get('/', [ArticleListController::class, 'fn'])->middleware('test');
                                             
 Route::get('/cron', [CronController::class, 'index']);
+
+Route::get('/tests/hook', [TestsController::class, 'hook']);
+
+//Route::post('/api/tg/hook', [HookController::class, 'cmd']);
+
+//Route::middleware('api')->group(function () {
+                                
+Route::post('/api/tg/hook', [HookController::class, 'cmd']);
+    
+//});