Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Tg bot related function #161

Merged
merged 1 commit into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Update Tg bot related function
  • Loading branch information
FranzKafkaYu committed Apr 17, 2022
commit 72e206879af3d1fc4f3a4cd6a813b94d4b4b25f2
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,4 @@ jobs:
upload_url: ${{ needs.release.outputs.upload_url }}
asset_path: x-ui-linux-s390x.tar.gz
asset_name: x-ui-linux-s390x.tar.gz
asset_content_type: application/gzip
asset_content_type: application/gzip
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
- 流量统计,限制流量,限制到期时间
- 可自定义 xray 配置模板
- 支持 https 访问面板(自备域名 + ssl 证书)
- 支持一键SSL证书申请且自动续签
- 更多高级配置项,详见面板


# 安装&升级
```
bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
Expand Down Expand Up @@ -58,6 +60,44 @@ docker run -itd --network=host \
```shell
docker build -t x-ui .
```
## SSL证书申请
>此功能与教程由[FranzKafkaYu](https://github.com/FranzKafkaYu)提供

脚本内置SSL证书申请功能,使用该脚本申请证书,需满足以下条件:
- 知晓Cloudflare 注册邮箱
- 知晓Cloudflare Global API Key
- 域名已通过cloudflare进行解析到当前服务器

获取Cloudflare Global API Key的方法:
![](media/bda84fbc2ede834deaba1c173a932223.png)
![](media/d13ffd6a73f938d1037d0708e31433bf.png)

使用时只需输入`域名`, `邮箱`, `API KEY`即可,示意图如下:
![](media/2022-04-04_141259.png)

注意事项:
- 该脚本使用DNS API进行证书申请
- 默认使用Let'sEncrypt作为CA方
- 证书安装目录为/root/cert目录
- 本脚本申请证书均为泛域名证书

## Tg机器人使用
>此功能与教程由[FranzKafkaYu](https://github.com/FranzKafkaYu)提供

X-UI支持通过Tg机器人实现每日流量通知,面板登录提醒等功能,使用Tg机器人,需要自行申请
具体申请教程可以参考[博客链接](https://coderfan.net/how-to-use-telegram-bot-to-alarm-you-when-someone-login-into-your-vps.html)
使用说明:在面板后台或通过脚本设置机器人相关参数,具体包括
- Tg机器人Token
- Tg机器人ChatId
- Tg机器人周期运行时间,采用crontab语法

参考示例:
每小时定时通知
![](media/2022-04-17_110907.png)
每分钟的第30s通知
![](media/2022-04-17_111321.png)
效果示意图:
![](media/2022-04-17_111705.png)

## 建议系统
- CentOS 7+
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/gin-contrib/sessions v0.0.3
github.com/gin-gonic/gin v1.7.1
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect
github.com/nicksnyder/go-i18n/v2 v2.1.2
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/robfig/cron/v3 v3.0.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
Expand Down
16 changes: 8 additions & 8 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ install_base() {

#This function will be called when user installed x-ui out of sercurity
config_after_install() {
echo -e "${yellow}出于安全考虑,安装完成后需要强制修改端口与账户密码${plain}"
read -p "请设置您的账户名:" config_account
echo -e "${yellow}您的账户名将设定为:${config_account}${plain}"
read -p "请设置您的账户密码:" config_password
echo -e "${yellow}您的账户密码将设定为:${config_password}${plain}"
read -p "请设置面板访问端口:" config_port
echo -e "${yellow}您的面板访问端口将设定为:${config_port}${plain}"
read -p "确认设定完成?[y/n]": config_confirm
echo -e "${yellow}出于安全考虑,安装/更新完成后需要强制修改端口与账户密码${plain}"
read -p "确认是否继续?[y/n]": config_confirm
if [[ x"${config_confirm}" == x"y" || x"${config_confirm}" == x"Y" ]]; then
read -p "请设置您的账户名:" config_account
echo -e "${yellow}您的账户名将设定为:${config_account}${plain}"
read -p "请设置您的账户密码:" config_password
echo -e "${yellow}您的账户密码将设定为:${config_password}${plain}"
read -p "请设置面板访问端口:" config_port
echo -e "${yellow}您的面板访问端口将设定为:${config_port}${plain}"
echo -e "${yellow}确认设定,设定中${plain}"
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
echo -e "${yellow}账户密码设定完成${plain}"
Expand Down
107 changes: 105 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"flag"
"fmt"
"github.com/op/go-logging"
"log"
"os"
"os/signal"
Expand All @@ -16,6 +15,8 @@ import (
"x-ui/web"
"x-ui/web/global"
"x-ui/web/service"

"github.com/op/go-logging"
)

func runWebServer() {
Expand Down Expand Up @@ -50,6 +51,7 @@ func runWebServer() {
}

sigCh := make(chan os.Signal, 1)
//信号量捕获处理
signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGKILL)
for {
sig := <-sigCh
Expand Down Expand Up @@ -90,6 +92,90 @@ func resetSetting() {
}
}

func showSetting(show bool) {
if show {
settingService := service.SettingService{}
port, err := settingService.GetPort()
if err != nil {
fmt.Println("get current port fialed,error info:", err)
}
userService := service.UserService{}
userModel, err := userService.GetFirstUser()
if err != nil {
fmt.Println("get current user info failed,error info:", err)
}
username := userModel.Username
userpasswd := userModel.Password
if (username == "") || (userpasswd == "") {
fmt.Println("current username or password is empty")
}
fmt.Println("current pannel settings as follows:")
fmt.Println("username:", username)
fmt.Println("userpasswd:", userpasswd)
fmt.Println("port:", port)
}
}

func updateTgbotEnableSts(status bool) {
settingService := service.SettingService{}
currentTgSts, err := settingService.GetTgbotenabled()
if err != nil {
fmt.Println(err)
return
}
logger.Infof("current enabletgbot status[%v],need update to status[%v]", currentTgSts, status)
if currentTgSts != status {
err := settingService.SetTgbotenabled(status)
if err != nil {
fmt.Println(err)
return
} else {
logger.Infof("SetTgbotenabled[%v] success", status)
}
}
return
}

func updateTgbotSetting(tgBotToken string, tgBotChatid int, tgBotRuntime string) {
err := database.InitDB(config.GetDBPath())
if err != nil {
fmt.Println(err)
return
}

settingService := service.SettingService{}

if tgBotToken != "" {
err := settingService.SetTgBotToken(tgBotToken)
if err != nil {
fmt.Println(err)
return
} else {
logger.Info("updateTgbotSetting tgBotToken success")
}
}

if tgBotRuntime != "" {
err := settingService.SetTgbotRuntime(tgBotRuntime)
if err != nil {
fmt.Println(err)
return
} else {
logger.Infof("updateTgbotSetting tgBotRuntime[%s] success", tgBotRuntime)
}
}

if tgBotChatid != 0 {
err := settingService.SetTgBotChatId(tgBotChatid)
if err != nil {
fmt.Println(err)
return
} else {
logger.Info("updateTgbotSetting tgBotChatid success")
}
}
}

func updateSetting(port int, username string, password string) {
err := database.InitDB(config.GetDBPath())
if err != nil {
Expand Down Expand Up @@ -137,11 +223,21 @@ func main() {
var port int
var username string
var password string
var tgbottoken string
var tgbotchatid int
var enabletgbot bool
var tgbotRuntime string
var reset bool
settingCmd.BoolVar(&reset, "reset", false, "reset all setting")
var show bool
settingCmd.BoolVar(&reset, "reset", false, "reset all settings")
settingCmd.BoolVar(&show, "show", false, "show current settings")
settingCmd.IntVar(&port, "port", 0, "set panel port")
settingCmd.StringVar(&username, "username", "", "set login username")
settingCmd.StringVar(&password, "password", "", "set login password")
settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "set telegrame bot token")
settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "set telegrame bot cron time")
settingCmd.IntVar(&tgbotchatid, "tgbotchatid", 0, "set telegrame bot chat id")
settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "enable telegram bot notify")

oldUsage := flag.Usage
flag.Usage = func() {
Expand Down Expand Up @@ -188,6 +284,13 @@ func main() {
} else {
updateSetting(port, username, password)
}
if show {
showSetting(show)
}
updateTgbotEnableSts(enabletgbot)
if (tgbottoken != "") || (tgbotchatid != 0) || (tgbotRuntime != "") {
updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime)
}
default:
fmt.Println("except 'run' or 'v2-ui' or 'setting' subcommands")
fmt.Println()
Expand Down
Binary file added media/2022-04-04_141259.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/2022-04-17_110907.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/2022-04-17_111321.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/2022-04-17_111705.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/2022-04-17_111910.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/bda84fbc2ede834deaba1c173a932223.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/d13ffd6a73f938d1037d0708e31433bf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions util/common/format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package common

import (
"fmt"
)

func FormatTraffic(trafficBytes int64) (size string) {
if trafficBytes < 1024 {
return fmt.Sprintf("%.2fB", float64(trafficBytes)/float64(1))
} else if trafficBytes < (1024 * 1024) {
return fmt.Sprintf("%.2fKB", float64(trafficBytes)/float64(1024))
} else if trafficBytes < (1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fMB", float64(trafficBytes)/float64(1024*1024))
} else if trafficBytes < (1024 * 1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fGB", float64(trafficBytes)/float64(1024*1024*1024))
} else if trafficBytes < (1024 * 1024 * 1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fTB", float64(trafficBytes)/float64(1024*1024*1024*1024))
} else {
return fmt.Sprintf("%.2fEB", float64(trafficBytes)/float64(1024*1024*1024*1024*1024))
}
}
9 changes: 9 additions & 0 deletions util/common/stringUtil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package common

import "sort"

func IsSubString(target string, str_array []string) bool {
sort.Strings(str_array)
index := sort.SearchStrings(str_array, target)
return index < len(str_array) && str_array[index] == target
}
4 changes: 3 additions & 1 deletion web/assets/js/model/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ class AllSetting {
this.webCertFile = "";
this.webKeyFile = "";
this.webBasePath = "/";

this.tgBotToken = "";
this.tgBotChatId = 0;
this.tgRunTime = "";
this.xrayTemplateConfig = "";

this.timeLocation = "Asia/Shanghai";
Expand Down
9 changes: 8 additions & 1 deletion web/controller/index.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package controller

import (
"github.com/gin-gonic/gin"
"net/http"
"time"
"x-ui/logger"
"x-ui/web/job"
"x-ui/web/service"
"x-ui/web/session"

"github.com/gin-gonic/gin"
)

type LoginForm struct {
Expand Down Expand Up @@ -59,6 +62,10 @@ func (a *IndexController) login(c *gin.Context) {
logger.Infof("wrong username or password: \"%s\" \"%s\"", form.Username, form.Password)
pureJsonMsg(c, false, "用户名或密码错误")
return
} else {
timeStr := time.Now().Format("2006-01-02 15:04:05")
logger.Infof("%s login success,Ip Address:%s\n", form.Username, getRemoteIp(c))
job.NewStatsNotifyJob().UserLoginNotify(form.Username, getRemoteIp(c), timeStr)
}

err = session.SetLoginUser(c, user)
Expand Down
14 changes: 8 additions & 6 deletions web/entity/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ type Pager struct {
}

type AllSetting struct {
WebListen string `json:"webListen" form:"webListen"`
WebPort int `json:"webPort" form:"webPort"`
WebCertFile string `json:"webCertFile" form:"webCertFile"`
WebKeyFile string `json:"webKeyFile" form:"webKeyFile"`
WebBasePath string `json:"webBasePath" form:"webBasePath"`

WebListen string `json:"webListen" form:"webListen"`
WebPort int `json:"webPort" form:"webPort"`
WebCertFile string `json:"webCertFile" form:"webCertFile"`
WebKeyFile string `json:"webKeyFile" form:"webKeyFile"`
WebBasePath string `json:"webBasePath" form:"webBasePath"`
TgBotToken string `json:"tgBotToken" form:"tgBotToken"`
TgBotChatId int `json:"tgBotChatId" form:"tgBotChatId"`
TgRunTime string `json:"tgRunTime" form:"tgRunTime"`
XrayTemplateConfig string `json:"xrayTemplateConfig" form:"xrayTemplateConfig"`

TimeLocation string `json:"timeLocation" form:"timeLocation"`
Expand Down
9 changes: 8 additions & 1 deletion web/html/xui/setting.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,14 @@
<setting-list-item type="textarea" title="xray 配置模版" desc="以该模版为基础生成最终的 xray 配置文件,重启面板生效" v-model="allSetting.xrayTemplateConfig"></setting-list-item>
</a-list>
</a-tab-pane>
<a-tab-pane key="4" tab="其他设置">
<a-tab-pane key="4" tab="TG提醒相关设置">
<a-list item-layout="horizontal" style="background: white">
<setting-list-item type="text" title="电报机器人TOKEN" desc="重启面板生效" v-model="allSetting.tgBotToken"></setting-list-item>
<setting-list-item type="number" title="电报机器人ChatId" desc="重启面板生效" v-model.number="allSetting.tgBotChatId"></setting-list-item>
<setting-list-item type="text" title="电报机器人通知时间" desc="采用Crontab定时格式" v-model="allSetting.tgRunTime"></setting-list-item>
</a-list>
</a-tab-pane>
<a-tab-pane key="5" tab="其他设置">
<a-list item-layout="horizontal" style="background: white">
<setting-list-item type="text" title="时区" desc="定时任务按照该时区的时间运行,重启面板生效" v-model="allSetting.timeLocation"></setting-list-item>
</a-list>
Expand Down
Loading