简介

1、该魔改版本的修改分为两部分:(1)对本体进行了修改,(2)一个实现自动发送邮件提醒用户的脚本。

2、最开始只想用python写一堆脚本用crontab运行,直到我发现这种想法实在太蠢,于是开始自学恶补go,但是这个时候过期时间判断与邮件发送的部分已经写完了,于是出现了外挂一个脚本用crontab运行,后期打算用go重写并且合并到x-ui源码中。

开发计划

1、多服务器控制,计划将项目拆分为master和child。 管理员只需在主服务器上修改用户配置,修改后的配置将同步到子节点。 到期时间也会同步。

说明

对于x-ui项目的修改主要为:

1、在添加inbound时,允许填入联系方式,该联系方式保存在数据库中,我使用脚本调取这些联系方式利用gmail向各个用户发送到期提醒邮件。当然,也可以填入手机号保存进数据库,把下面的脚本改一改利用手机发送提醒。
2、添加了一个可以一键重置所有inbound流量的按钮,不用再一个个的点开“操作”去重置流量了。
3、这个修改版本只可用于"利用nginx转发vless与vmess流量"的架构,也就是俗称的"v2ray(xray)+tls+web"。如果你没有用什么脚本一键搭建nginx+x-ui那你就会发现,每次在x-ui添加inbound时,还要到nginx的配置文件中也添加相应的配置,这实在很麻烦,于是我对x-ui源码添加了一些function,令它可以在添加inbound的同时对nginx的配置文件作相应修改。注意:nginx的配置文件绝对路径必须是"/etc/nginx/sites-enabled/default"。

4、所有即将到期的用户的名称(备注)将被记录至一个mysql数据库中以供管理者查看。

项目与代码

1、x-ui修改项目源代码:x-ui_corpa_edition

在项目中有一个文件:x-ui,是我已经编译好的可执行文件(linux64_x86),可以直接下载下来,然后替换掉服务器中的"/usr/local/x-ui/x-ui",替换后记得"chmod +x x-ui"赋予可执行权限。

2、邮件提醒python脚本代码,注意这其中的"token.json"、"credentials.json",请换成该文件所在的绝对路径。以及注意填写mysql数据库的地址、用户、密码以及数据库名。

import moment,sqlite3,smtplib,base64,pymysql
from email.mime.text import MIMEText
#google auth about
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from apiclient import errors

#sqlite3 database connect
db_con = sqlite3.connect('a place to store the x-uis db file')
#create a cursor point for the connection has created
c = db_con.cursor()
#print("database connect successfully")
print("None will be expiring today|||%s" % moment.now().format("YYYY-M-D"))
#MySQL database connect(transport to japan database)
db_con_msq = pymysql.connect(host="",user="",password="",database="")
c1 = db_con_msq.cursor()

#select sql table
sql_table = c.execute("select id,remark,enable,expiry_time,contact from inbounds")
#math date
def date_math():
    notice_date_3=moment.unix(row[3]).subtract(days=3).format("YYYY-M-D")
    notice_date_2=moment.unix(row[3]).subtract(days=2).format("YYYY-M-D")
    notice_date_1=moment.unix(row[3]).subtract(days=1).format("YYYY-M-D")
    if(moment.now().format("YYYY-M-D")==notice_date_3):
        return 3
    elif(moment.now().format("YYYY-M-D")==notice_date_2):
        return 2
    elif(moment.now().format("YYYY-M-D")==notice_date_1):
        return 1
    else:
        return 0

#gmail api
SCOPES = ['https://www.googleapis.com/auth/gmail.modify']
def get_auth():
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
    return build('gmail', 'v1', credentials=creds)

#create mail
def create_message(sender,to,subject,message_text):
    message = MIMEText(message_text)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    b64_bytes = base64.urlsafe_b64encode(message.as_bytes())
    b64_string = b64_bytes.decode()
    return {'raw': b64_string}
#send mail
def send_message(service,user_id,message):
  try:
    message = (service.users().messages().send(userId=user_id, body=message)
               .execute())
    print('Message Id: %s' % message['id'])
    return message
  except errors.HttpError as error:
    print('An error occurred: %s' % error)

#mysql database insert
def mysql_insert(user):
    try:
        db_con_msq.ping(reconnect=True)
        c1.execute("INSERT INTO `xui`.`%s` (`用户名`) VALUES ('%s');" % (moment.now().format("YYYY-M-D"),user))
        db_con_msq.commit()
    except pymysql.err.ProgrammingError:
        db_con_msq.ping(reconnect=True)
        c1.execute("CREATE TABLE `xui`.`%s`  (`用户名` varchar(255) NULL);" % moment.now().format("YYYY-M-D"))
        c1.execute("INSERT INTO `xui`.`%s` (`用户名`) VALUES ('%s');" % (moment.now().format("YYYY-M-D"),user))
        db_con_msq.commit()

#get date and judge it,then send mail and msg
for row in sql_table:
    if(date_math()==3 and row[2]==1 and row[4]!=None):
        send_message(get_auth(),"me",create_message("sender@gmail.com","%s" % row[4],"提醒","用户“%s”还有三天到期" % row[1]))
        mysql_insert(row[1])
    elif(date_math()==2 and row[2]==1 and row[4]!=None):
        send_message(get_auth(),"me",create_message("sender@gmail.com","%s" % row[4],"提醒","用户“%s”还有二天到期" % row[1]))
        mysql_insert(row[1])
    elif(date_math()==1 and row[2]==1 and row[4]!=None):
        send_message(get_auth(),"me",create_message("sender@gmail.com","%s" % row[4],"提醒","用户“%s”还有一天到期" % row[1]))
        mysql_insert(row[1])
    else:
        #print("%s|%s is well!" % ((moment.now().format("YYYY-M-D"),row[1])))
        continue
    db_con_msq.close()

致谢

感谢x-ui与xray-core项目,x-uiXray-core