创建机器人

点击抵达BotFather注册一个bot https://t.me/BotFather,输入 /newbot,按照提示输入bot名字

1
2
3

Alright, a new bot. How are we going to call it? Please choose a name for your bot.
Good. Now let's choose a username for your bot. It must end in `bot`. Like this, for example: TetrisBot or tetris_bot.

创建成功会返回机器人的token,访问t.me/XXXXTest_bot即可访问创建的机器人

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Done! Congratulations on your new bot. You will find it at t.me/XXXXTest_bot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you've finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this.

  

Use this token to access the HTTP API:

tokenxxxxxxxxxxxxxxxxxxxxxxx

Keep your token **secure** and **store it safely**, it can be used by anyone to control your bot.

  

For a description of the Bot API, see this page: https://core.telegram.org/bots/api

开发准备

https://github.com/go-telegram-bot-api/telegram-bot-api

添加一个获取本机资源和分析日志的脚本

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  
func isDateFormat(keyword string) bool {  
   pattern := `^\d{4}-\d{2}-\d{2}$`  
   match, _ := regexp.MatchString(pattern, keyword)  
   return match  
}  
func bytesToGB(bytes uint64) float64 {  
   gb := float64(bytes) / (1024 * 1024 * 1024)  
   return gb  
}  
  
func getLog(getdata string) (msg string) {  
   filePath := os.Getenv("LOG_PATH")  
   file, err := os.Open(filePath)  
   if err != nil {  
      log.Println(err)  
      return  
   }  
   defer file.Close()  
  
   scanner := bufio.NewScanner(file)  
   dateMap := make(map[string]map[string]int)  
  
   re := regexp.MustCompile(`INFO.*path": "(.*?)".*"ip": "(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"`)  
  
   for scanner.Scan() {  
      line := scanner.Text()  
  
      // 对每行日志使用正则表达式进行匹配  
      matches := re.FindStringSubmatch(line)  
      if len(matches) == 3 {  
         path := matches[1]  
         ip := matches[2]  
  
         // 从时间戳中提取日期  
         date := strings.SplitN(line, "T", 2)[0]  
  
         // 只处理关键字匹配的日期  
         if date == getdata {  
            // 初始化日期的map  
            if dateMap[date] == nil {  
               dateMap[date] = make(map[string]int)  
            }  
  
            // 增加路径和IP的请求次数  
            dateMap[date][fmt.Sprintf("路径: %s, IP: %s", path, ip)]++  
         }  
      }  
   }  
  
   if err := scanner.Err(); err != nil {  
      log.Println(err)  
      return  
   }  
  
   // 打印指定日期的路径、IP和请求次数  
   msg = fmt.Sprintf("日期: %s\n", getdata)  
   entries, found := dateMap[getdata]  
   if !found {  
      log.Println("没有找到匹配的日志")  
      return  
   } else {  
      for entry, count := range entries {  
         msg += fmt.Sprintf("%s, 请求次数: %d\n", entry, count)  
      }  
   }  
   return  
}  
  
func getResource() (info string) {  
   // 获取 CPU 使用信息  
   percent, err := cpu.Percent(time.Second, false)  
   if err != nil {  
      log.Println(err)  
      return  
   }  
  
   // 获取内存使用信息  
   memInfo, err := mem.VirtualMemory()  
   if err != nil {  
      log.Println(err)  
      return  
   }  
  
   // 获取磁盘使用信息  
   usage, err := disk.Usage("/")  
   if err != nil {  
      log.Println(err)  
      return  
   }  
  
   // 获取网络接口的流量统计信息  
   counters, err := net.IOCounters(true)  
   if err != nil {  
      log.Println(err)  
      return  
   }  
  
   // 遍历每个网络接口的统计信息  
   netmsg := ""  
   for _, counter := range counters {  
      if counter.Name == os.Getenv("NET_DEVICE") {  
         netmsg += fmt.Sprintf("传入流量: %.2f GB\n传出流量: %.2f GB\n", bytesToGB(counter.BytesRecv), bytesToGB(counter.BytesSent))  
         break  
      }  
   }  
  
   info = fmt.Sprintf(  
      "%s\n"+  
         "CPU使用率: %.2f%%\n"+  
         "mem使用率: %.2f%%\n"+  
         "disk使用率: %.2f%%\n"+  
         "总内存: %dMB\n"+  
         "可用内存: %dMB\n"+  
         "已用内存: %dMB\n"+  
         "可用空间: %.2fGB\n"+  
         "已用空间: %.2fGB\n"+  
         "%s\n",  
  
      time.Now().Format("2006-01-02 15:04:05"), percent[0], memInfo.UsedPercent, usage.UsedPercent, memInfo.Total/1024/1024, memInfo.Available/1024/1024, memInfo.Used/1024/1024, bytesToGB(usage.Free), bytesToGB(usage.Used), netmsg)  
   return  
}  
  
func getResourceInfo(keyword string) (string, error) {  
   // 在这里根据关键字执行相应的逻辑,例如从数据库或 API 中获取资源信息  
   // 这里只是一个示例,你需要根据你的实际情况进行实现  
  
   if keyword == "top" {  
      return getResource(), nil  
   } else if isDateFormat(keyword) {  
      return getLog(keyword), nil  
   } else {  
      return "", errors.New("未找到相关资源")  
   }  
}  
  
func handleKeyword(bot *tgbotapi.BotAPI, update tgbotapi.Update) {  
   // 获取用户发送的关键字  
   keyword := update.Message.Text  
  
   // 根据关键字获取相关信息(这里假设根据关键字查询资源的函数为 getResourceInfo)  
   info, err := getResourceInfo(keyword)  
   if err != nil {  
      log.Println("Failed to get resource info:", err)  
      return  
   }  
  
   // 构造要发送的消息  
   replyMsg := tgbotapi.NewMessage(update.Message.Chat.ID, info)  
  
   // 发送消息  
   _, err = bot.Send(replyMsg)  
   if err != nil {  
      log.Println("Failed to send message:", err)  
   }  
}  
  
func main() {  
   bot, err := tgbotapi.NewBotAPI(os.Getenv("TELEGRAM_APITOKEN"))  
   if err != nil {  
      log.Println(err)  
      return  
   }  
  
   bot.Debug = true  
  
   log.Printf("Authorized on account %s", bot.Self.UserName)  
  
   u := tgbotapi.NewUpdate(0)  
   u.Timeout = 60  
  
   updates := bot.GetUpdatesChan(u)  
  
   for update := range updates {  
      if update.Message != nil { // If we got a message  
         handleKeyword(bot, update)  
      }  
   }  
}

配置环境变量 LOG_PATH=: 日志文件 NET_DEVICE: 网卡 TELEGRAM_APITOKEN: BotToken

访问

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
input: top

2023-10-24 19:59:17
CPU使用率: 18.87%
mem使用率: 68.89%
disk使用率: 18.96%
总内存: 16384MB
可用内存: 5097MB
已用内存: 11286MB
可用空间: 373.13GB
已用空间: 87.30GB
传入流量: 417.51 GB
传出流量: 33.11 GB

input: 2023-10-24

日期: 2023-10-24
路径: /api/v1/gettype, IP: 116.x, 请求次数: 1
路径: /api/v1/gettype, IP: 185.x, 请求次数: 1
...
..
.