private static async ValueTask GetLiveStatus(SoraApi soraApi, long biliUser, List <long> groupId, SubscriptionDBHelper dbHelper) { LiveInfo live; UserSpaceInfo biliUserInfo; //获取数据 try { biliUserInfo = UserApis.GetLiveRoomInfo(biliUser); live = LiveAPIs.GetLiveRoomInfo(biliUserInfo.LiveRoomInfo.ShortId); } catch (Exception e) { Log.Error("获取直播状态时发生错误", Log.ErrorLogBuilder(e)); return; } //需要更新数据的群 Dictionary <long, LiveStatusType> updateDict = groupId .Where(gid => dbHelper.GetLastLiveStatus(gid, biliUser) != live.LiveStatus) .ToDictionary(gid => gid, _ => live.LiveStatus); //更新数据库 foreach (var status in updateDict) { if (!dbHelper.UpdateLiveStatus(status.Key, biliUser, live.LiveStatus)) { Log.Error("Database", "更新直播订阅数据失败"); } } //需要消息提示的群 var targetGroup = updateDict.Where(group => group.Value == LiveStatusType.Online) .Select(group => group.Key) .ToList(); if (targetGroup.Count == 0) { return; } //构建提示消息 MessageBody message = $"{biliUserInfo.Name} 正在直播!\r\n{biliUserInfo.LiveRoomInfo.Title}" + CQCodes.CQImage(biliUserInfo.LiveRoomInfo.CoverUrl) + $"直播间地址:{biliUserInfo.LiveRoomInfo.LiveUrl}"; foreach (var gid in targetGroup) { Log.Info("直播订阅", $"获取到{biliUserInfo.Name}正在直播,向群[{gid}]发送动态信息"); await soraApi.SendGroupMessage(gid, message); } }
/// <summary> /// 初始化 /// </summary> /// <param name="serviceId">当前服务ID</param> /// <param name="connectionId">服务器链接标识</param> /// <param name="eventName">事件名</param> /// <param name="loginUid">当前使用的QQ号</param> /// <param name="time">连接时间</param> /// <param name="sourceType">来源</param> internal BaseSoraEventArgs(Guid serviceId, Guid connectionId, string eventName, long loginUid, long time, SourceFlag sourceType) { SoraApi = new SoraApi(serviceId, connectionId); ServiceGuid = serviceId; ConnId = connectionId; EventName = eventName; LoginUid = loginUid; TimeStamp = time; Time = time.ToDateTime(); IsContinueEventChain = true; SourceType = sourceType; }
private static async Task <List <GroupMemberInfo> > GetMemberList(SoraApi session, long groupId) { return((await session.GetGroupMemberList(groupId)).groupMemberList .Select(info => new GroupMemberInfo { GroupId = groupId, QQId = info.UserId, PermitType = info.Role switch { MemberRoleType.Owner => PermitType.Holder, MemberRoleType.Admin => PermitType.Manage, _ => PermitType.None } }).ToList());
public MonitorManage(TweeterMonitorConfig config, SoraApi soraApi) { _config = config; _soraApi = soraApi; }
/// <summary> /// 快速回复 /// </summary> /// <param name="message">消息</param> /// <param name="timeout">覆盖原有超时</param> /// <returns> /// <para><see cref="ApiStatusType"/> API执行状态</para> /// <para><see langword="messageId"/> 发送消息的id</para> /// </returns> public async ValueTask <(ApiStatus apiStatus, int messageId)> Reply(MessageBody message, TimeSpan?timeout = null) { return(await SoraApi.SendGroupMessage(SourceGroup.Id, message, timeout)); }
/// <summary> /// 撤回发送者消息 /// 只有在管理员以上权限才有效 /// </summary> public async ValueTask RecallSourceMessage() { await SoraApi.RecallMessage(Message.MessageId); }
private static async ValueTask GetDynamic(SoraApi soraApi, long biliUser, List <long> groupId, SubscriptionDBHelper dbHelper) { string textMessage; Dynamic biliDynamic; List <string> imgList = new(); //获取动态文本 try { var cardData = DynamicAPIs.GetLatestDynamic(biliUser); switch (cardData.cardType) { //检查动态类型 case CardType.PlainText: PlainTextCard plainTextCard = (PlainTextCard)cardData.cardObj; textMessage = plainTextCard.ToString(); biliDynamic = plainTextCard; break; case CardType.TextAndPic: TextAndPicCard textAndPicCard = (TextAndPicCard)cardData.cardObj; imgList.AddRange(textAndPicCard.ImgList); textMessage = textAndPicCard.ToString(); biliDynamic = textAndPicCard; break; case CardType.Forward: ForwardCard forwardCard = (ForwardCard)cardData.cardObj; textMessage = forwardCard.ToString(); biliDynamic = forwardCard; break; case CardType.Video: VideoCard videoCard = (VideoCard)cardData.cardObj; imgList.Add(videoCard.CoverUrl); textMessage = videoCard.ToString(); biliDynamic = videoCard; break; case CardType.Error: //Log.Error("动态获取", $"ID:{biliUser}的动态获取失败"); return; default: Log.Debug("动态获取", $"ID:{biliUser}的动态获取成功,动态类型未知"); foreach (var gid in groupId) { if (!dbHelper.UpdateDynamic(gid, biliUser, BotUtils.GetNowStampLong())) { Log.Error("数据库", "更新动态记录时发生了数据库错误"); } } return; } } catch (Exception e) { Log.Error("获取动态更新时发生错误", Log.ErrorLogBuilder(e)); return; } //获取用户信息 UserInfo sender = biliDynamic.GetUserInfo(); Log.Debug("动态获取", $"{sender.UserName}的动态获取成功"); //检查是否是最新的 List <long> targetGroups = groupId .Where(@group => !dbHelper.IsLatestDynamic(@group, sender.Uid, biliDynamic.UpdateTime)) .ToList(); //没有群需要发送消息 if (targetGroups.Count == 0) { Log.Debug("动态获取", $"{sender.UserName}的动态已是最新"); return; } //构建消息 List <CQCode> msgList = new(); StringBuilder msgBuilder = new(); msgBuilder.Append("获取到了来自 "); msgBuilder.Append(sender.UserName); msgBuilder.Append(" 的动态:\r\n"); msgBuilder.Append(textMessage); msgList.Add(CQCode.CQText(msgBuilder.ToString())); //添加图片 imgList.ForEach(imgUrl => msgList.Add(CQCode.CQImage(imgUrl))); msgBuilder.Clear(); msgBuilder.Append("\r\n更新时间:"); msgBuilder.Append(biliDynamic.UpdateTime.ToString("MM-dd HH:mm:ss")); msgList.Add(CQCode.CQText(msgBuilder.ToString())); //向未发生消息的群发送消息 foreach (var targetGroup in targetGroups) { Log.Info("动态获取", $"获取到{sender.UserName}的最新动态,向群{targetGroup}发送动态信息"); await soraApi.SendGroupMessage(targetGroup, msgList); if (!dbHelper.UpdateDynamic(targetGroup, sender.Uid, biliDynamic.UpdateTime)) { Log.Error("数据库", "更新动态记录时发生了数据库错误"); } } }
/// <summary> /// 撤回本条消息 /// </summary> public async ValueTask <ApiStatus> RecallMessage() { return(await SoraApi.RecallMessage(MessageId)); }
GetGroupFilesByFolder(string foldId) { return(await SoraApi.GetGroupFilesByFolder(Id, foldId)); }
/// <summary> /// 获取群文件系统信息 /// </summary> /// <returns> /// <para><see cref="APIStatusType"/> API执行状态</para> /// <para><see cref="GroupFileSysInfo"/> 文件系统信息</para> /// </returns> public async ValueTask <(APIStatusType apiStatus, GroupFileSysInfo groupFileSysInfo)> GetGroupFileSysInfo() { return(await SoraApi.GetGroupFileSysInfo(Id)); }
/// <summary> /// 拒绝当前申请 /// </summary> /// <param name="reason">原因</param> public async ValueTask Reject(string reason = null) { await SoraApi.SetGroupAddRequest(RequestFlag, SubType, false, reason); }
/// <summary> /// 同意当前申请 /// </summary> public async ValueTask Accept() { await SoraApi.SetGroupAddRequest(RequestFlag, SubType, true); }
/// <summary> /// 拒绝当前申请 /// </summary> public async ValueTask Reject() { await SoraApi.SetFriendAddRequest(RequestFlag, false); }
/// <summary> /// 同意当前申请 /// </summary> /// <param name="remark">设置备注</param> public async ValueTask Accept(string remark = null) { await SoraApi.SetFriendAddRequest(RequestFlag, true, remark); }
public static int SetGroupSpecialTitle(this SoraApi session, long groupId, long qqId, string specialTitle, TimeSpan time) { throw new NotImplementedException(); }
public static GreenOnionsMessages ToOnionsMessages(this MessageBody miraiMessage, long senderId, string senderName, long?senderGroup, SoraApi api) { GreenOnionsMessages greenOnionsMessages = new GreenOnionsMessages(); for (int i = 0; i < miraiMessage.Count; i++) { if (miraiMessage[i].Data is AtSegment atMsg) { //获取@群名片 if (long.TryParse(atMsg.Target, out long atId)) { var apiResult = api.GetGroupMemberList(senderGroup.Value).GetAwaiter().GetResult(); List <GroupMemberInfo> groupMemberInfos = apiResult.groupMemberList; GroupMemberInfo targetQQ = groupMemberInfos.Where(m => m.UserId == atId).FirstOrDefault(); string nickName = targetQQ?.Nick; greenOnionsMessages.Add(new GreenOnionsAtMessage(atId, nickName)); } else { greenOnionsMessages.Add(new GreenOnionsAtMessage(atId, atMsg.Name)); } } else if (miraiMessage[i].Data is TextSegment textMsg) { greenOnionsMessages.Add(textMsg.Content); } else if (miraiMessage[i].Data is ImageSegment imageMsg) { greenOnionsMessages.Add(new GreenOnionsImageMessage(imageMsg.Url, imageMsg.ImgFile)); } } greenOnionsMessages.SenderId = senderId; greenOnionsMessages.SenderName = senderName; return(greenOnionsMessages); }
public static async Task Connect(long qqId, string ip, ushort port, string authKey, Action <bool, string> ConnectedEvent) { ////设置log等级 //Log.LogConfiguration // .EnableConsoleOutput() // .SetLogLevel(LogLevel.Error); try { //实例化Sora服务 ISoraService service = SoraServiceFactory.CreateService(new ClientConfig() { Host = ip, Port = port, AccessToken = authKey }); service.Event.OnGroupMessage += MessageEvents.Event_OnGroupMessage; service.Event.OnPrivateMessage += MessageEvents.Event_OnPrivateMessage; //启动服务并捕捉错误 await service.StartService().RunCatch(e => Log.Error("Sora Service", Log.ErrorLogBuilder(e))); service.Event.OnClientConnect += async(eventType, eventArgs) => { SoraApi api = service.GetApi(service.ServiceId); BotInfo.QQId = api.GetLoginUserId(); List <FriendInfo> IFriendInfos = (await api.GetFriendList()).friendList; string nickname = "未知"; var self = IFriendInfos.Where(q => q.UserId == qqId).FirstOrDefault(); if (self != null) { nickname = self.Nick; } ConnectedEvent?.Invoke(true, nickname); }; BotInfo.IsLogin = true; RssWorker.StartRssTask((msgs, targetId, groupId) => { SoraApi api = service.GetApi(service.ServiceId); if (msgs != null && msgs.Count > 0) { if (msgs.First() is GreenOnionsForwardMessage forwardMessage) { _ = api.SendGroupForwardMsg(targetId, forwardMessage.ToCqHttpForwardMessage()); } else { if (targetId != -1) { _ = api.SendGroupMessage(targetId, msgs.ToCqHttpMessages(null)); } else if (groupId != -1) { _ = api.SendGroupMessage(groupId, msgs.ToCqHttpMessages(null)); } } } }); while (true) { BotInfo.IsLogin = true; if (Console.ReadLine() == "exit") { BotInfo.IsLogin = false; PluginManager.Disconnected(); ConnectedEvent?.Invoke(false, ""); break; } Task.Delay(100).Wait(); } } catch (Exception ex) { LogHelper.WriteErrorLog(ex); ConnectedEvent(false, ex.Message); } }
/// <summary> /// 发送群消息 /// </summary> /// <param name="message"> /// <para>消息<see cref="MessageBody"/></para> /// </param> /// <param name="timeout">覆盖原有超时</param> /// <returns> /// <para><see cref="ApiStatusType"/> API执行状态</para> /// <para><see langword="messageId"/> 消息ID</para> /// </returns> public async ValueTask <(ApiStatus apiStatus, int messageId)> SendPrivateMessage( MessageBody message, TimeSpan?timeout = null) { return(await SoraApi.SendPrivateMessage(Id, message, timeout)); }
GetGroupRootFiles() { return(await SoraApi.GetGroupRootFiles(Id)); }
/// <summary> /// 获取用户信息 /// </summary> /// <param name="useCache">使用缓存</param> /// <returns> /// <para><see cref="ApiStatusType"/> API执行状态</para> /// <para><see cref="UserInfo"/> 群成员信息</para> /// <para><see cref="string"/> qid</para> /// </returns> public async ValueTask <(ApiStatus apiStatus, UserInfo userInfo, string qid)> GetUserInfo( bool useCache = true) { return(await SoraApi.GetUserInfo(Id, useCache)); }
/// <summary> /// 获取群文件资源链接 /// </summary> /// <param name="fileId">文件ID</param> /// <param name="busid">文件类型</param> /// <returns>文件链接</returns> public async ValueTask <(APIStatusType apiStatus, string fileUrl)> GetGroupFileUrl( string fileId, int busid) { return(await SoraApi.GetGroupFileUrl(Id, fileId, busid)); }
/// <summary> /// 删除好友 /// </summary> /// <returns> /// <para><see cref="ApiStatusType"/> API执行状态</para> /// </returns> public async ValueTask <ApiStatus> DeleteFriend() { return(await SoraApi.DeleteFriend(Id)); }
/// <summary> /// 标记此消息已读 /// </summary> public async ValueTask <ApiStatus> MarkMessageRead() { return(await SoraApi.MarkMessageRead(MessageId)); }
public static async Task <bool> CheckHasFriend(this SoraApi api, long user) => Convert.ToBoolean((await api.GetFriendList()) .friendList?.Where(x => x.UserId == user).Any());
public static async Task <bool> CheckGroupHasUser(this SoraApi api, long group, long user) => Convert.ToBoolean((await api.GetGroupMemberList(group)) .groupMemberList?.Where(x => x.UserId == user).Any());
public static async Task <bool> CheckHasGroup(this SoraApi api, long group) => Convert.ToBoolean((await api.GetGroupList()) .groupList?.Where(x => x.GroupId == group).Any());
/// <summary> /// 获取发送者群成员信息 /// </summary> /// <param name="useCache">是否使用缓存</param> /// <returns> /// <para><see cref="ApiStatusType"/> API执行状态</para> /// <para><see cref="GroupMemberInfo"/> 群成员信息</para> /// </returns> public async ValueTask <(ApiStatus apiStatus, GroupMemberInfo memberInfo)> GetSenderMemberInfo( bool useCache = true) { return(await SoraApi.GetGroupMemberInfo(SourceGroup.Id, Sender.Id, useCache)); }
/// <summary> /// 没什么用的复读功能 /// </summary> /// <returns> /// <para><see cref="ApiStatusType"/> API执行状态</para> /// <para><see langword="messageId"/> 发送消息的id</para> /// </returns> public async ValueTask <(ApiStatus apiStatus, int messageId)> Repeat() { return(await SoraApi.SendPrivateMessage(Sender.Id, Message.MessageBody)); }
/// <summary> /// 没什么用的复读功能 /// </summary> /// <returns> /// <para><see cref="ApiStatusType"/> API执行状态</para> /// <para><see langword="messageId"/> 发送消息的id</para> /// </returns> public async ValueTask <(ApiStatus apiStatus, int messageId)> Repeat() { return(await SoraApi.SendGroupMessage(SourceGroup.Id, Message.MessageBody)); }
/// <summary> /// 遍历动态循环 /// </summary> public void Cycle(SoraApi api) { if (api == null) { return; } var path = "config.json"; string jsonString; using (System.IO.StreamReader file = System.IO.File.OpenText(path)) { using (JsonTextReader reader = new JsonTextReader(file)) { JObject o = (JObject)JToken.ReadFrom(reader); //遍历up for (int i = 0; i < o["up"].Count(); i++) { var up = o["up"][i]; int id = 0; int.TryParse(up["id"].ToString(), out id); if (id > 0) { // 获取entity var entity = moment.GetMoment(id).Result; if (entity.feedList == null || entity.feedList.Length == 0) { continue; } var entity1 = entity.feedList.First(); //判断是否有更新 bool isUpdated = false; try { isUpdated = (int.Parse(up["newmomentid"].ToString()) < int.Parse(entity1.moment.momentId)); } catch (Exception e) { Console.WriteLine(e.Message); } if (isUpdated) { long uid = 0; object[] msg = GetMessages(entity1); //对每个提醒qq发送消息 foreach (var notifyqq in up["notifyqq"]) { long.TryParse(notifyqq.ToString(), out uid); if (uid > 0) { api.SendPrivateMessage(uid, msg); } } //对每个提醒qq群发送消息 foreach (var notifygroup in up["notifygroup"]) { long.TryParse(notifygroup.ToString(), out uid); if (uid > 0) { api.SendPrivateMessage(uid, msg); } } //回写entityid o["up"][i]["newmomentid"] = entity1.moment.momentId; } //撤回消息 bool isCalceled = (int.Parse(up["newmomentid"].ToString()) > int.Parse(entity1.moment.momentId)); if (isCalceled) { //回写entityid o["up"][i]["newmomentid"] = entity1.moment.momentId; } } } //修改后存入字符串 jsonString = JsonConvert.SerializeObject(o); } } //回写config using (System.IO.StreamWriter writer = new System.IO.StreamWriter(path)) { writer.WriteLine(jsonString); writer.Flush(); } }