Compare commits

...

21 Commits

Author SHA1 Message Date
李寻欢
8f6b7cb68d Merge pull request 'hotfix' (#57) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/57
2024-06-14 08:36:55 +08:00
李寻欢
20aeeefb3c Merge remote-tracking branch 'origin/hotfix' into hotfix 2024-06-14 08:36:27 +08:00
李寻欢
08ffd4de6c 🎨 修改一个错别字 2024-06-14 08:36:21 +08:00
李寻欢
72a2e694f8 Merge pull request '🎨 优化好友列表同步处理逻辑' (#56) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/56
2024-06-13 07:02:45 +08:00
李寻欢
2238e23c8d 🎨 优化好友列表同步处理逻辑 2024-06-13 07:02:00 +08:00
李寻欢
a13e39dc0a Merge pull request '🎨 优化好友列表同步处理逻辑' (#55) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/55
2024-06-12 21:48:04 +08:00
李寻欢
0f506e5afc 🎨 优化好友列表同步处理逻辑 2024-06-12 21:47:35 +08:00
李寻欢
74f19e9d03 Merge pull request 'hotfix' (#54) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/54
2024-06-06 14:18:58 +08:00
李寻欢
44c45d11f2 Merge remote-tracking branch 'origin/hotfix' into hotfix 2024-06-06 14:18:23 +08:00
李寻欢
50e91680bb 🎨 逻辑优化 2024-06-06 14:18:18 +08:00
李寻欢
3554c95edc Merge pull request '🎨 消息总结新增传入群名称和过滤排行榜及前一天的总结消息' (#53) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/53
2024-05-31 07:27:55 +08:00
李寻欢
b2598f2406 🎨 消息总结新增传入群名称和过滤排行榜及前一天的总结消息 2024-05-31 07:27:17 +08:00
李寻欢
db8c460b42 Merge pull request '🎨 优化消息格式' (#52) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/52
2024-05-29 14:12:51 +08:00
李寻欢
6818b10f4a 🎨 优化消息格式 2024-05-29 14:12:26 +08:00
李寻欢
7747a4b634 Merge pull request '🎨 优化消息格式' (#51) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/51
2024-05-20 08:36:12 +08:00
李寻欢
727b06e143 🎨 优化消息格式 2024-05-16 08:32:44 +08:00
李寻欢
2226ec7e63 Merge pull request 'hotfix' (#50) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/50
2024-05-16 00:13:43 +08:00
李寻欢
c0c3864a8e 🐛 修复清理不活跃成员功能的BUG 2024-05-16 00:12:57 +08:00
李寻欢
8c2ab9376c 🐛 修复清理不活跃成员功能的BUG 2024-05-16 00:12:47 +08:00
李寻欢
b0be537c5d Merge pull request '🆕 新增清理不活跃成员功能' (#49) from hotfix into main
Reviewed-on: https://gitee.ltd/lxh/go-wxhelper/pulls/49
2024-05-15 17:20:12 +08:00
李寻欢
9c7e93660d 🆕 新增清理不活跃成员功能 2024-05-15 17:19:32 +08:00
13 changed files with 153 additions and 12 deletions

View File

@@ -20,6 +20,7 @@ type Friend struct {
EnableWelcome bool `json:"enableWelcome" gorm:"type:tinyint(1) default 0 not null"` // 是否启用迎新
EnableSummary bool `json:"enableSummary" gorm:"type:tinyint(1) default 0 not null"` // 是否启用总结
EnableNews bool `json:"enableNews" gorm:"type:tinyint(1) default 0 not null"` // 是否启用新闻
ClearMember int `json:"clearMember"` // 清理成员配置(多少天未活跃的)
IsOk bool `json:"isOk" gorm:"type:tinyint(1) default 0 not null"` // 是否正常
}

View File

@@ -4,6 +4,7 @@ import (
"github.com/go-resty/resty/v2"
"go-wechat/utils"
"log"
"net/http"
)
// KfcCrazyThursdayCmd
@@ -33,8 +34,9 @@ func kfcApi1() string {
res := resty.New()
resp, err := res.R().
Post("https://api.jixs.cc/api/wenan-fkxqs/index.php")
if err != nil {
log.Panicf("KFC接口1文案获取失败: %s", err.Error())
if err != nil || resp.StatusCode() != http.StatusOK {
log.Printf("KFC接口1文案获取失败: %v", err)
return ""
}
log.Printf("KFC接口1文案获取结果: %s", resp.String())
return resp.String()
@@ -58,8 +60,9 @@ func kfcApi2() string {
resp, err := res.R().
SetResult(&resData).
Post("https://api.jixs.cc/api/wenan-fkxqs/index.php")
if err != nil {
log.Panicf("KFC接口2文案获取失败: %s", err.Error())
if err != nil || resp.StatusCode() != http.StatusOK {
log.Printf("KFC接口2文案获取失败: %v", err)
return ""
}
log.Printf("KFC接口2文案获取结果: %s", resp.String())
if resData.Data.Msg != "" {
@@ -84,8 +87,9 @@ func kfcApi3() string {
resp, err := res.R().
SetResult(&resData).
Post("https://api.pearktrue.cn/api/kfc")
if err != nil {
log.Panicf("KFC接口3文案获取失败: %s", err.Error())
if err != nil || resp.StatusCode() != http.StatusOK {
log.Printf("KFC接口3文案获取失败: %v", err)
return ""
}
log.Printf("KFC接口3文案获取结果: %s", resp.String())
if resData.Text != "" {

View File

@@ -77,6 +77,15 @@ func GetAllEnableNews() (records []entity.Friend, err error) {
return
}
// GetAllEnableClearGroup
// @description: 获取所有需要清理成员的群组
// @return records
// @return err
func GetAllEnableClearGroup() (records []entity.Friend, err error) {
err = client.MySQL.Where("clear_member > 0").Where("is_ok IS TRUE").Find(&records).Error
return
}
// CheckIsEnableCommand
// @description: 检查用户是否启用了指令
// @param userId

View File

@@ -73,6 +73,8 @@ func GetTextMessagesById(id string) (records []vo.TextMessageItem, err error) {
Where("tm.`from_user` = ?", id).
Where(`(tm.type = 1 OR ( tm.type = 49 AND EXTRACTVALUE ( tm.content, "/msg/appmsg/type" ) IN (?) ))`, appMsgList).
Where("DATE ( tm.create_at ) = DATE ( CURDATE() - INTERVAL 1 DAY )").
Where("tm.content NOT LIKE '#昨日水群排行榜%'").
Where("tm.content NOT LIKE '#昨日消息总结%'").
Order("tm.create_at ASC")
err = tx.Find(&records).Error

View File

@@ -0,0 +1,68 @@
package cleargroupuser
import (
"fmt"
"go-wechat/client"
"go-wechat/entity"
"go-wechat/service"
"go-wechat/utils"
"log"
"strings"
)
// ClearGroupUser
// @description: 清理群成员
func ClearGroupUser() {
groups, err := service.GetAllEnableClearGroup()
if err != nil {
log.Printf("获取启用了聊天排行榜的群组失败, 错误信息: %v", err)
return
}
for _, group := range groups {
// 获取需要清理的群成员Id
members := getNeedDeleteMembers(group.Wxid, group.ClearMember)
memberCount := len(members)
log.Printf("群[%s(%s)]需要清理的成员数量: %d", group.Nickname, group.Wxid, memberCount)
if memberCount < 1 {
continue
}
var memberMap = make(map[string]string)
var deleteIds = make([]string, 0)
for _, member := range members {
deleteIds = append(deleteIds, member.Wxid)
// 昵称为空取id后4位
if member.Nickname == "" {
member.Nickname = "无名氏_" + member.Wxid[len(member.Wxid)-4:]
}
memberMap[member.Nickname] = member.LastActive.Format("2006-01-02 15:04:05")
}
// 调用接口
utils.DeleteGroupMember(group.Wxid, strings.Join(deleteIds, ","), 0)
// 发送通知到群里
ms := make([]string, 0)
for k, v := range memberMap {
ms = append(ms, fmt.Sprintf("昵称:%s\n最后活跃时间%s", k, v))
}
msg := fmt.Sprintf("#清理群成员\n\n很遗憾地通知各位就在刚刚有%d名群友因活跃度不够暂时离开了我们希望还健在的群友引以为戒、保持活跃\n\n详细信息: \n%s",
memberCount, strings.Join(ms, "\n"))
utils.SendMessage(group.Wxid, "", msg, 0)
}
}
// getNeedDeleteMembers
// @description: 获取需要删除的群成员
// @param groupId 群Id
// @param days 需要清理的未活跃的天数
// @return members
func getNeedDeleteMembers(groupId string, days int) (members []entity.GroupUser) {
err := client.MySQL.Model(&entity.GroupUser{}).Where("group_id = ?", groupId).
Where("is_member IS TRUE").
Where("DATEDIFF( NOW(), last_active ) >= ?", days).
Order("last_active DESC").
Find(&members).Error
if err != nil {
log.Printf("获取需要清理的群成员失败, 错误信息: %v", err)
}
return
}

View File

@@ -75,6 +75,7 @@ func Sync() {
EnableSummary: config.Conf.System.DefaultRule.Summary,
EnableWelcome: config.Conf.System.DefaultRule.Welcome,
EnableNews: config.Conf.System.DefaultRule.News,
ClearMember: 0,
LastActive: time.Now().Local(),
}).Error
if err != nil {
@@ -102,6 +103,7 @@ func Sync() {
"custom_account": friend.CustomAccount,
"pinyin": friend.Pinyin,
"pinyin_all": friend.PinyinAll,
"is_ok": true,
}
err = tx.Model(&entity.Friend{}).Where("wxid = ?", friend.Wxid).Updates(pm).Error
if err != nil {
@@ -121,18 +123,30 @@ func Sync() {
// 组装成一句话
msg := []string{"#新好友通知\n"}
for wxId, nickname := range newItmes {
msg = append(msg, "微信Id: "+wxId+" -> 昵称: "+nickname)
msg = append(msg, "微信Id: "+wxId+"\n昵称: "+nickname)
}
for _, user := range config.Conf.System.NewFriendNotify.ToUser {
if user != "" {
// 发送一条新消息
utils.SendMessage(user, "", strings.Join(msg, "\n"), 0)
utils.SendMessage(user, "", strings.Join(msg, "\n-------\n"), 0)
}
}
}
// 清理不在列表中的好友
err = tx.Model(&entity.Friend{}).Where("wxid NOT IN (?)", nowIds).Update("is_ok", false).Error
clearPm := map[string]any{
"is_ok": false,
"enable_chat_rank": false,
"enable_welcome": false,
"enable_summary": false,
"enable_news": false,
"clear_member": false,
"enable_ai": false,
}
err = tx.Model(&entity.Friend{}).Where("wxid NOT IN (?)", nowIds).Updates(clearPm).Error
if err != nil {
log.Printf("清理好友失败: %s", err.Error())
}
log.Println("同步好友列表完成")
}

View File

@@ -24,7 +24,7 @@ func DailyNews() {
return
}
newsStr := fmt.Sprintf("#每日早报#\n\n又是新的一天了让我们康康一觉醒来世界又发生了哪些变化~\n\n%s", strings.Join(news, "\n"))
newsStr := fmt.Sprintf("#每日早报\n\n又是新的一天了让我们康康一觉醒来世界又发生了哪些变化~\n\n%s", strings.Join(news, "\n"))
// 循环发送新闻
for _, group := range groups {

View File

@@ -42,11 +42,12 @@ func AiSummary() {
注意,他们可能是多个话题,请仔细甄别。
每一行代表一个人的发言,每一行的的格式为: {"{nickname}": "{content}"}--end--
群名称: %s
聊天记录如下:
%s
`
msg := fmt.Sprintf(msgTmp, strings.Join(content, "\n"))
msg := fmt.Sprintf(msgTmp, group.Nickname, strings.Join(content, "\n"))
// AI总结
messages := []openai.ChatCompletionMessage{

View File

@@ -3,6 +3,7 @@ package tasks
import (
"github.com/go-co-op/gocron"
"go-wechat/config"
"go-wechat/tasks/cleargroupuser"
"go-wechat/tasks/friends"
"go-wechat/tasks/news"
"go-wechat/tasks/summary"
@@ -56,6 +57,9 @@ func InitTasks() {
_, _ = s.Cron(config.Conf.Task.News.Cron).Do(news.DailyNews)
}
// 每天0点检查一次处理清理群成员
_, _ = s.Cron("0 0 * * *").Do(cleargroupuser.ClearGroupUser)
// 开启定时任务
s.StartAsync()
log.Println("定时任务初始化成功")

View File

@@ -32,7 +32,7 @@ func getRankData(groupId, date string) (rank []rankUser, err error) {
case "week":
tx.Where("YEARWEEK(date_format(tm.create_at, '%Y-%m-%d')) = YEARWEEK(now()) - 1")
case "month":
tx.Where("PERIOD_DIFF(date_format(now(), '%Y%m'), date_format(create_at, '%Y%m')) = 1")
tx.Where("PERIOD_DIFF(date_format(now(), '%Y%m'), date_format(tm.create_at, '%Y%m')) = 1")
case "year":
tx.Where("YEAR(tm.create_at) = YEAR(NOW()) - 1")
}

View File

@@ -121,3 +121,34 @@ func SendEmotion(toId, emotionHash string, retryCount int) {
}
log.Printf("发送表情包消息结果: %s", resp.String())
}
// DeleteGroupMember
// @description: 删除群成员
// @param chatRoomId 群Id
// @param memberIds 成员id,用','分隔
func DeleteGroupMember(chatRoomId, memberIds string, retryCount int) {
if retryCount > 5 {
log.Printf("重试五次失败,停止发送")
return
}
// 组装参数
param := map[string]any{
"chatRoomId": chatRoomId, // 群Id
"memberIds": memberIds, // 成员id
}
pbs, _ := json.Marshal(param)
res := resty.New()
resp, err := res.R().
SetHeader("Content-Type", "application/json;chartset=utf-8").
SetBody(string(pbs)).
Post(config.Conf.Wechat.GetURL("/api/delMemberFromChatRoom"))
if err != nil {
log.Printf("删除群成员失败: %s", err.Error())
// 休眠五秒后重新发送
time.Sleep(5 * time.Second)
SendImage(chatRoomId, memberIds, retryCount+1)
}
log.Printf("删除群成员结果: %s", resp.String())
}

View File

@@ -50,6 +50,9 @@
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
指令
</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
末位淘汰(天)
</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
操作
</th>
@@ -107,6 +110,9 @@
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
{{ template "command" . }}
</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
{{ .ClearMember }}
</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
<button class="btn btn-link" onclick="getGroupUsers({{.Wxid}}, {{.Nickname}})">成员</button>
</td>

View File

@@ -20,6 +20,7 @@ type FriendItem struct {
EnableCommand bool // 是否启用指令
EnableSummary bool // 是否启用总结
EnableNews bool // 是否启用新闻
ClearMember int // 清理成员配置(多少天未活跃的)
IsOk bool // 是否还在通讯库(群聊是要还在群里也算)
}