From d414ef2dc1d96a0a2f91be051f243d82bd27495b Mon Sep 17 00:00:00 2001 From: changxiaoqiang Date: Tue, 30 Jan 2018 10:59:14 +0800 Subject: [PATCH 1/2] fix():set ProtocolVersion --- io/rong/util/RongHttpClient.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/io/rong/util/RongHttpClient.cs b/io/rong/util/RongHttpClient.cs index aef54e6..2a7dd55 100644 --- a/io/rong/util/RongHttpClient.cs +++ b/io/rong/util/RongHttpClient.cs @@ -44,6 +44,7 @@ public static String ExecutePost(String appkey, String appSecret, String methodU } else { myRequest.ContentType = contentType; } + myRequest.ProtocolVersion = HttpVersion.Version10; myRequest.Headers.Add("App-Key", appkey); @@ -132,4 +133,4 @@ public static string returnResult(HttpWebRequest myRequest) { } } -} \ No newline at end of file +} From 7c01b03ccdf170ef84e9536537f895c9e87cdc16 Mon Sep 17 00:00:00 2001 From: changxiaoqiang Date: Mon, 10 Jun 2019 19:21:34 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=96=B0=E5=A2=9Epush=E5=92=8C=E5=B9=BF?= =?UTF-8?q?=E6=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Properties/Resources.resx | 120 + PushMessage.json | 40 - RongCloud.cs | 101 + bin/Debug/Newtonsoft.Json.dll | Bin 0 -> 489472 bytes bin/Debug/Newtonsoft.Json.xml | 9229 +++++++++++++++++ example/chatroom/BanExample.cs | 81 + example/chatroom/BlockExample.cs | 86 + example/chatroom/ChatroomExample.cs | 98 + example/chatroom/DemotionExample.cs | 74 + example/chatroom/DistributeExample.cs | 66 + example/chatroom/GagExample.cs | 92 + example/chatroom/KeepaliveExample.cs | 75 + example/chatroom/whitelist/MessageExample.cs | 66 + example/chatroom/whitelist/UserExample.cs | 75 + example/conversation/ConversationExample.cs | 68 + example/group/GagExample.cs | 92 + example/group/GroupExample.cs | 202 + example/messages/MessageExample.cs | 365 + example/sensitive/SensitiveExample.cs | 103 + example/user/BlackListExample.cs | 76 + example/user/BlockExample.cs | 74 + example/user/UserExample.cs | 63 + exception/Error.cs | 49 + exception/ParamError.cs | 30 + exception/ParamException.cs | 43 + exception/RcloudException.cs | 67 + io.rong.csproj | 127 - io.rong.csproj.user | 3 - io/rong/Example.cs | 329 - io/rong/RongCloud.cs | 57 - io/rong/messages/CmdMsgMessage.cs | 78 - io/rong/messages/CmdNtfMessage.cs | 78 - io/rong/messages/ContactNtfMessage.cs | 141 - io/rong/messages/CustomTxtMessage.cs | 57 - io/rong/messages/ImgMessage.cs | 99 - io/rong/messages/ImgTextMessage.cs | 141 - io/rong/messages/InfoNtfMessage.cs | 78 - io/rong/messages/LBSMessage.cs | 143 - io/rong/messages/ProfileNtfMessage.cs | 99 - io/rong/messages/TxtMessage.cs | 78 - io/rong/messages/VoiceMessage.cs | 99 - io/rong/methods/Chatroom.cs | 416 - io/rong/methods/Group.cs | 318 - io/rong/methods/Message.cs | 380 - io/rong/methods/Push.cs | 66 - io/rong/methods/SMS.cs | 112 - io/rong/methods/User.cs | 237 - io/rong/methods/Wordfilter.cs | 83 - io/rong/models/BlockChatRoomUser.cs | 64 - io/rong/models/BlockUsers.cs | 64 - io/rong/models/ChatRoom.cs | 85 - io/rong/models/ChatRoomInfo.cs | 64 - io/rong/models/ChatRoomUser.cs | 64 - io/rong/models/ChatroomQueryReslut.cs | 85 - io/rong/models/ChatroomUserQueryReslut.cs | 106 - io/rong/models/CheckOnlineReslut.cs | 85 - io/rong/models/CodeSuccessReslut.cs | 64 - io/rong/models/GagChatRoomUser.cs | 64 - io/rong/models/GagGroupUser.cs | 64 - io/rong/models/GroupInfo.cs | 64 - io/rong/models/GroupUser.cs | 43 - io/rong/models/GroupUserQueryReslut.cs | 85 - io/rong/models/HistoryMessageReslut.cs | 106 - io/rong/models/ListBlockChatroomUserReslut.cs | 85 - io/rong/models/ListGagChatroomUserReslut.cs | 85 - io/rong/models/ListGagGroupUserReslut.cs | 85 - io/rong/models/ListWordfilterReslut.cs | 85 - io/rong/models/MsgObj.cs | 64 - io/rong/models/Notification.cs | 85 - io/rong/models/PlatformNotification.cs | 64 - io/rong/models/PushMessage.cs | 127 - io/rong/models/QueryBlacklistUserReslut.cs | 85 - io/rong/models/QueryBlockUserReslut.cs | 85 - io/rong/models/SMSImageCodeReslut.cs | 106 - io/rong/models/SMSSendCodeReslut.cs | 85 - io/rong/models/TagObj.cs | 85 - io/rong/models/TemplateMessage.cs | 190 - io/rong/models/TokenReslut.cs | 106 - io/rong/models/UserTag.cs | 64 - jsonsource/PushMessage.json | 14 + .../TemplateMessage.json | 14 +- UserTag.json => jsonsource/UserTag.json | 0 jsonsource/broadcast/api.json | 50 + jsonsource/broadcast/verify.json | 42 + jsonsource/chatroom/api.json | 169 + jsonsource/chatroom/block/api.json | 136 + jsonsource/chatroom/demotion/api.json | 105 + jsonsource/chatroom/distribute/api.json | 76 + jsonsource/chatroom/global-gag/api.json | 117 + jsonsource/chatroom/keepalive/api.json | 97 + jsonsource/chatroom/member-gag/api.json | 111 + jsonsource/chatroom/verify.json | 145 + .../chatroom/whitelist/message/api.json | 108 + jsonsource/chatroom/whitelist/user/api.json | 122 + jsonsource/conversation/api.json | 80 + jsonsource/conversation/verify.json | 68 + jsonsource/group/api.json | 353 + jsonsource/group/gag/api.json | 135 + jsonsource/group/verify.json | 131 + jsonsource/message/TemplateMessage.json | 16 + jsonsource/message/_private/api.json | 154 + jsonsource/message/api.json | 133 + jsonsource/message/chatroom/api.json | 90 + jsonsource/message/discussion/api.json | 92 + jsonsource/message/group/api.json | 149 + jsonsource/message/history/api.json | 67 + jsonsource/message/recall/api.json | 38 + jsonsource/message/system/api.json | 154 + jsonsource/message/verify.json | 337 + jsonsource/sensitiveword/api.json | 156 + jsonsource/sensitiveword/verify.json | 77 + jsonsource/user/api.json | 90 + jsonsource/user/blacklist/api.json | 125 + jsonsource/user/block/api.json | 94 + jsonsource/user/online-status/api.json | 39 + jsonsource/user/verify.json | 77 + messages/BaseMessage.cs | 15 + messages/CmdMsgMessage.cs | 45 + messages/CmdNtfMessage.cs | 45 + messages/ContactNtfMessage.cs | 59 + messages/CustomTxtMessage.cs | 59 + messages/ImgMessage.cs | 53 + messages/ImgTextMessage.cs | 62 + messages/InfoNtfMessage.cs | 58 + messages/LBSMessage.cs | 61 + messages/ProfileNtfMessage.cs | 51 + messages/TxtMessage.cs | 46 + messages/VoiceMessage.cs | 50 + methods/chatroom/Chatroom.cs | 195 + methods/chatroom/ban/Ban.cs | 128 + methods/chatroom/block/Block.cs | 137 + methods/chatroom/demotion/Demotion.cs | 117 + methods/chatroom/distribute/Distribute.cs | 93 + methods/chatroom/gag/Gag.cs | 143 + methods/chatroom/keepalive/Keepalive.cs | 102 + methods/chatroom/whitelist/Messages.cs | 124 + methods/chatroom/whitelist/User.cs | 147 + methods/chatroom/whitelist/Whitelist.cs | 50 + methods/conversation/Conversation.cs | 105 + methods/group/Group.cs | 326 + methods/group/gag/Gag.cs | 140 + methods/message/Message.cs | 58 + methods/message/_private/Private.cs | 198 + methods/message/chatroom/Chatroom.cs | 115 + methods/message/discussion/Discussion.cs | 153 + methods/message/group/Group.cs | 216 + methods/message/history/History.cs | 98 + methods/message/system/MsgSystem.cs | 207 + methods/sensitive/SensitiveWord.cs | 174 + methods/sensitive/Wordfilter.cs | 112 + methods/user/User.cs | 124 + methods/user/blacklist/Blacklist.cs | 139 + methods/user/block/Block.cs | 114 + methods/user/onlineStatus/OnlineStatus.cs | 73 + models/BlockUsers.cs | 35 + models/CheckMethod.cs | 50 + models/Result.cs | 76 + models/Templates.cs | 88 + models/chatroom/ChatroomMember.cs | 81 + models/chatroom/ChatroomModel.cs | 88 + models/conversation/ConversationModel.cs | 44 + models/group/GroupMember.cs | 52 + models/group/GroupModel.cs | 57 + models/group/UserGroup.cs | 50 + models/message/BroadcastMessage.cs | 27 + models/message/ChatroomMessage.cs | 23 + models/message/DiscussionMessage.cs | 57 + models/message/GroupMessage.cs | 58 + models/message/MentionMessage.cs | 57 + models/message/MentionMessageContent.cs | 34 + models/message/MentionedInfo.cs | 32 + models/message/MessageModel.cs | 72 + models/message/PrivateMessage.cs | 61 + models/message/RecallMessage.cs | 54 + models/message/SystemMessage.cs | 44 + models/message/TemplateMessage.cs | 58 + models/response/BlackListResult.cs | 51 + models/response/BlockUserList.cs | 54 + models/response/BlockUserResult.cs | 29 + models/response/ChatroomDemotionMsgResult.cs | 39 + models/response/ChatroomKeepaliveResult.cs | 29 + models/response/ChatroomQueryResult.cs | 33 + models/response/ChatroomUserQueryResult.cs | 53 + models/response/ChatroomWhitelistMsgResult.cs | 39 + models/response/CheckChatRoomUserResult.cs | 34 + models/response/CheckOnlineResult.cs | 48 + models/response/GagGroupUser.cs | 72 + models/response/GroupUser.cs | 29 + models/response/GroupUserQueryResult.cs | 52 + models/response/HistoryMessageResult.cs | 41 + .../response/ListBlockChatroomUserResult.cs | 43 + models/response/ListGagChatroomUserResult.cs | 43 + models/response/ListGagGroupUserResult.cs | 56 + models/response/ListWordfilterResult.cs | 37 + models/response/ResponseResult.cs | 24 + models/response/TokenResult.cs | 49 + models/response/UserList.cs | 60 + models/response/WhiteListResult.cs | 49 + models/sensitiveword/SensitiveWordModel.cs | 54 + models/user/BlockUser.cs | 11 + models/user/UserModel.cs | 142 + util/CodeUtil.cs | 279 + util/CommonUtil.cs | 683 ++ util/HostType.cs | 22 + {io/rong/util => util}/RongHttpClient.cs | 271 +- {io/rong/util => util}/RongJsonUtil.cs | 2 +- 206 files changed, 23030 insertions(+), 5996 deletions(-) create mode 100644 Properties/Resources.resx delete mode 100644 PushMessage.json create mode 100644 RongCloud.cs create mode 100644 bin/Debug/Newtonsoft.Json.dll create mode 100644 bin/Debug/Newtonsoft.Json.xml create mode 100644 example/chatroom/BanExample.cs create mode 100644 example/chatroom/BlockExample.cs create mode 100644 example/chatroom/ChatroomExample.cs create mode 100644 example/chatroom/DemotionExample.cs create mode 100644 example/chatroom/DistributeExample.cs create mode 100644 example/chatroom/GagExample.cs create mode 100644 example/chatroom/KeepaliveExample.cs create mode 100644 example/chatroom/whitelist/MessageExample.cs create mode 100644 example/chatroom/whitelist/UserExample.cs create mode 100644 example/conversation/ConversationExample.cs create mode 100644 example/group/GagExample.cs create mode 100644 example/group/GroupExample.cs create mode 100644 example/messages/MessageExample.cs create mode 100644 example/sensitive/SensitiveExample.cs create mode 100644 example/user/BlackListExample.cs create mode 100644 example/user/BlockExample.cs create mode 100644 example/user/UserExample.cs create mode 100644 exception/Error.cs create mode 100644 exception/ParamError.cs create mode 100644 exception/ParamException.cs create mode 100644 exception/RcloudException.cs delete mode 100644 io.rong.csproj delete mode 100644 io.rong.csproj.user delete mode 100644 io/rong/Example.cs delete mode 100644 io/rong/RongCloud.cs delete mode 100644 io/rong/messages/CmdMsgMessage.cs delete mode 100644 io/rong/messages/CmdNtfMessage.cs delete mode 100644 io/rong/messages/ContactNtfMessage.cs delete mode 100644 io/rong/messages/CustomTxtMessage.cs delete mode 100644 io/rong/messages/ImgMessage.cs delete mode 100644 io/rong/messages/ImgTextMessage.cs delete mode 100644 io/rong/messages/InfoNtfMessage.cs delete mode 100644 io/rong/messages/LBSMessage.cs delete mode 100644 io/rong/messages/ProfileNtfMessage.cs delete mode 100644 io/rong/messages/TxtMessage.cs delete mode 100644 io/rong/messages/VoiceMessage.cs delete mode 100644 io/rong/methods/Chatroom.cs delete mode 100644 io/rong/methods/Group.cs delete mode 100644 io/rong/methods/Message.cs delete mode 100644 io/rong/methods/Push.cs delete mode 100644 io/rong/methods/SMS.cs delete mode 100644 io/rong/methods/User.cs delete mode 100644 io/rong/methods/Wordfilter.cs delete mode 100644 io/rong/models/BlockChatRoomUser.cs delete mode 100644 io/rong/models/BlockUsers.cs delete mode 100644 io/rong/models/ChatRoom.cs delete mode 100644 io/rong/models/ChatRoomInfo.cs delete mode 100644 io/rong/models/ChatRoomUser.cs delete mode 100644 io/rong/models/ChatroomQueryReslut.cs delete mode 100644 io/rong/models/ChatroomUserQueryReslut.cs delete mode 100644 io/rong/models/CheckOnlineReslut.cs delete mode 100644 io/rong/models/CodeSuccessReslut.cs delete mode 100644 io/rong/models/GagChatRoomUser.cs delete mode 100644 io/rong/models/GagGroupUser.cs delete mode 100644 io/rong/models/GroupInfo.cs delete mode 100644 io/rong/models/GroupUser.cs delete mode 100644 io/rong/models/GroupUserQueryReslut.cs delete mode 100644 io/rong/models/HistoryMessageReslut.cs delete mode 100644 io/rong/models/ListBlockChatroomUserReslut.cs delete mode 100644 io/rong/models/ListGagChatroomUserReslut.cs delete mode 100644 io/rong/models/ListGagGroupUserReslut.cs delete mode 100644 io/rong/models/ListWordfilterReslut.cs delete mode 100644 io/rong/models/MsgObj.cs delete mode 100644 io/rong/models/Notification.cs delete mode 100644 io/rong/models/PlatformNotification.cs delete mode 100644 io/rong/models/PushMessage.cs delete mode 100644 io/rong/models/QueryBlacklistUserReslut.cs delete mode 100644 io/rong/models/QueryBlockUserReslut.cs delete mode 100644 io/rong/models/SMSImageCodeReslut.cs delete mode 100644 io/rong/models/SMSSendCodeReslut.cs delete mode 100644 io/rong/models/TagObj.cs delete mode 100644 io/rong/models/TemplateMessage.cs delete mode 100644 io/rong/models/TokenReslut.cs delete mode 100644 io/rong/models/UserTag.cs create mode 100644 jsonsource/PushMessage.json rename TemplateMessage.json => jsonsource/TemplateMessage.json (76%) rename UserTag.json => jsonsource/UserTag.json (100%) create mode 100644 jsonsource/broadcast/api.json create mode 100644 jsonsource/broadcast/verify.json create mode 100644 jsonsource/chatroom/api.json create mode 100644 jsonsource/chatroom/block/api.json create mode 100644 jsonsource/chatroom/demotion/api.json create mode 100644 jsonsource/chatroom/distribute/api.json create mode 100644 jsonsource/chatroom/global-gag/api.json create mode 100644 jsonsource/chatroom/keepalive/api.json create mode 100644 jsonsource/chatroom/member-gag/api.json create mode 100644 jsonsource/chatroom/verify.json create mode 100644 jsonsource/chatroom/whitelist/message/api.json create mode 100644 jsonsource/chatroom/whitelist/user/api.json create mode 100644 jsonsource/conversation/api.json create mode 100644 jsonsource/conversation/verify.json create mode 100644 jsonsource/group/api.json create mode 100644 jsonsource/group/gag/api.json create mode 100644 jsonsource/group/verify.json create mode 100644 jsonsource/message/TemplateMessage.json create mode 100644 jsonsource/message/_private/api.json create mode 100644 jsonsource/message/api.json create mode 100644 jsonsource/message/chatroom/api.json create mode 100644 jsonsource/message/discussion/api.json create mode 100644 jsonsource/message/group/api.json create mode 100644 jsonsource/message/history/api.json create mode 100644 jsonsource/message/recall/api.json create mode 100644 jsonsource/message/system/api.json create mode 100644 jsonsource/message/verify.json create mode 100644 jsonsource/sensitiveword/api.json create mode 100644 jsonsource/sensitiveword/verify.json create mode 100644 jsonsource/user/api.json create mode 100644 jsonsource/user/blacklist/api.json create mode 100644 jsonsource/user/block/api.json create mode 100644 jsonsource/user/online-status/api.json create mode 100644 jsonsource/user/verify.json create mode 100644 messages/BaseMessage.cs create mode 100644 messages/CmdMsgMessage.cs create mode 100644 messages/CmdNtfMessage.cs create mode 100644 messages/ContactNtfMessage.cs create mode 100644 messages/CustomTxtMessage.cs create mode 100644 messages/ImgMessage.cs create mode 100644 messages/ImgTextMessage.cs create mode 100644 messages/InfoNtfMessage.cs create mode 100644 messages/LBSMessage.cs create mode 100644 messages/ProfileNtfMessage.cs create mode 100644 messages/TxtMessage.cs create mode 100644 messages/VoiceMessage.cs create mode 100644 methods/chatroom/Chatroom.cs create mode 100644 methods/chatroom/ban/Ban.cs create mode 100644 methods/chatroom/block/Block.cs create mode 100644 methods/chatroom/demotion/Demotion.cs create mode 100644 methods/chatroom/distribute/Distribute.cs create mode 100644 methods/chatroom/gag/Gag.cs create mode 100644 methods/chatroom/keepalive/Keepalive.cs create mode 100644 methods/chatroom/whitelist/Messages.cs create mode 100644 methods/chatroom/whitelist/User.cs create mode 100644 methods/chatroom/whitelist/Whitelist.cs create mode 100644 methods/conversation/Conversation.cs create mode 100644 methods/group/Group.cs create mode 100644 methods/group/gag/Gag.cs create mode 100644 methods/message/Message.cs create mode 100644 methods/message/_private/Private.cs create mode 100644 methods/message/chatroom/Chatroom.cs create mode 100644 methods/message/discussion/Discussion.cs create mode 100644 methods/message/group/Group.cs create mode 100644 methods/message/history/History.cs create mode 100644 methods/message/system/MsgSystem.cs create mode 100644 methods/sensitive/SensitiveWord.cs create mode 100644 methods/sensitive/Wordfilter.cs create mode 100644 methods/user/User.cs create mode 100644 methods/user/blacklist/Blacklist.cs create mode 100644 methods/user/block/Block.cs create mode 100644 methods/user/onlineStatus/OnlineStatus.cs create mode 100644 models/BlockUsers.cs create mode 100644 models/CheckMethod.cs create mode 100644 models/Result.cs create mode 100644 models/Templates.cs create mode 100644 models/chatroom/ChatroomMember.cs create mode 100644 models/chatroom/ChatroomModel.cs create mode 100644 models/conversation/ConversationModel.cs create mode 100644 models/group/GroupMember.cs create mode 100644 models/group/GroupModel.cs create mode 100644 models/group/UserGroup.cs create mode 100644 models/message/BroadcastMessage.cs create mode 100644 models/message/ChatroomMessage.cs create mode 100644 models/message/DiscussionMessage.cs create mode 100644 models/message/GroupMessage.cs create mode 100644 models/message/MentionMessage.cs create mode 100644 models/message/MentionMessageContent.cs create mode 100644 models/message/MentionedInfo.cs create mode 100644 models/message/MessageModel.cs create mode 100644 models/message/PrivateMessage.cs create mode 100644 models/message/RecallMessage.cs create mode 100644 models/message/SystemMessage.cs create mode 100644 models/message/TemplateMessage.cs create mode 100644 models/response/BlackListResult.cs create mode 100644 models/response/BlockUserList.cs create mode 100644 models/response/BlockUserResult.cs create mode 100644 models/response/ChatroomDemotionMsgResult.cs create mode 100644 models/response/ChatroomKeepaliveResult.cs create mode 100644 models/response/ChatroomQueryResult.cs create mode 100644 models/response/ChatroomUserQueryResult.cs create mode 100644 models/response/ChatroomWhitelistMsgResult.cs create mode 100644 models/response/CheckChatRoomUserResult.cs create mode 100644 models/response/CheckOnlineResult.cs create mode 100644 models/response/GagGroupUser.cs create mode 100644 models/response/GroupUser.cs create mode 100644 models/response/GroupUserQueryResult.cs create mode 100644 models/response/HistoryMessageResult.cs create mode 100644 models/response/ListBlockChatroomUserResult.cs create mode 100644 models/response/ListGagChatroomUserResult.cs create mode 100644 models/response/ListGagGroupUserResult.cs create mode 100644 models/response/ListWordfilterResult.cs create mode 100644 models/response/ResponseResult.cs create mode 100644 models/response/TokenResult.cs create mode 100644 models/response/UserList.cs create mode 100644 models/response/WhiteListResult.cs create mode 100644 models/sensitiveword/SensitiveWordModel.cs create mode 100644 models/user/BlockUser.cs create mode 100644 models/user/UserModel.cs create mode 100644 util/CodeUtil.cs create mode 100644 util/CommonUtil.cs create mode 100644 util/HostType.cs rename {io/rong/util => util}/RongHttpClient.cs (91%) rename {io/rong/util => util}/RongJsonUtil.cs (89%) diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PushMessage.json b/PushMessage.json deleted file mode 100644 index be3c5ed..0000000 --- a/PushMessage.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "platform":[ - "ios", - "android" - ], - "fromuserid":"fromuseId1", - "audience":{ - "tag":[ - "女", - "年轻", - "北京" - ], - "userid":[ - "123", - "456" - ], - "is_to_all":false - }, - "message":{ - "content":"{\"content\":\"1111\",\"extra\":\"aa\"}", - "objectName":"RC:TxtMsg" - }, - "notification":{ - "alert":"this is a push", - "ios":{ - "alert":"override alert", - "extras":{ - "id":"1", - "name":"2" - } - }, - "android":{ - "alert":"override alert", - "extras":{ - "id":"1", - "name":"2" - } - } - } -} \ No newline at end of file diff --git a/RongCloud.cs b/RongCloud.cs new file mode 100644 index 0000000..09aebdf --- /dev/null +++ b/RongCloud.cs @@ -0,0 +1,101 @@ +using io.rong.methods.conversation; +using io.rong.methods.message; +using io.rong.methods.user; +using io.rong.methods.group; +using io.rong.methods.sensitive; +using io.rong.methods.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong +{ + class RongCloud + { + private static Dictionary rongCloud = new Dictionary(); + + public User user; + public Message message; + public Wordfilter wordfilter; + public SensitiveWord sensitiveword; + public Group group; + public Chatroom chatroom; + public Conversation conversation; + + private List apiHostType = new List { + new HostType("https://api.cn.ronghub.com"), + new HostType("https://api-cn.ronghub.com") + }; + private volatile int errNum = 0; + private volatile int apiIndex = 0; + private HostType smsHostType = new HostType("http://api.sms.ronghub.com"); + + public int ErrNum + { + get { return errNum; } + set { errNum = value; } + } + + public HostType ApiHostType + { + get { + if (apiIndex < apiHostType.Count && errNum <= 3) + { + return apiHostType[apiIndex]; + } else + { + return apiHostType[0]; + } + } + } + + public HostType SmsHostType + { + get { return this.smsHostType; } + set { this.smsHostType = value; } + } + + private RongCloud(String appKey, String appSecret) + { + user = new User(appKey, appSecret); + user.RongCloud = this; + message = new Message(appKey, appSecret); + message.RongCloud = this; + conversation = new Conversation(appKey, appSecret); + conversation.RongCloud = this; + group = new Group(appKey, appSecret); + group.RongCloud = this; + wordfilter = new Wordfilter(appKey, appSecret); + wordfilter.RongCloud = this; + sensitiveword = new SensitiveWord(appKey, appSecret); + sensitiveword.RongCloud = this; + chatroom = new Chatroom(appKey, appSecret); + chatroom.RongCloud = this; + } + + public static RongCloud GetInstance(String appKey, String appSecret) + { + if (!rongCloud.ContainsKey(appKey)) + { + rongCloud.Add(appKey, new RongCloud(appKey, appSecret)); + } + return rongCloud[appKey]; + } + + public static RongCloud GetInstance(String appKey, String appSecret, String api) + { + if (null == rongCloud[appKey]) + { + RongCloud rc = new RongCloud(appKey, appSecret); + if (api != null && api.Trim().Length > 0) + { + rc.apiHostType.Add(new HostType(api)); + } + rongCloud.Add(appKey, rc); + } + return rongCloud[appKey]; + } + } +} diff --git a/bin/Debug/Newtonsoft.Json.dll b/bin/Debug/Newtonsoft.Json.dll new file mode 100644 index 0000000000000000000000000000000000000000..20dae627a5338a8b707f983990019ea9dabd680e GIT binary patch literal 489472 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 z

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⁢piGYQ-44>I?-P{BwRjG3#)?@ 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

Y+D7N$wjm_ZJo}KV5+PdjHU%i ziqKOmU9mA0CFmwc7x^v8=uScbT)d!r-A-rlF|2Q$Up`Et=Z5m1{lB8peZ`u{TscFaov zTpT}{zrEA9mE%)z^yzZksW^P%=Tk2Ro7%XtE+oxqq)EA_B!|(1W8j|LpJXu<+OT{U z@JywOOqAnCQR3E{4IyNiXCG5KnKt5erMG*P@Z$iW(cyJ(KvoHjOL*O~y^@5c_5Xi7 zuWECi_j&o~2O%B~7ooLtuK~Z|a);zA70?VHz`Pxax9lPU4ZD=Z#q}JZ1RH)G)3ZEO zs|aug+s%deXXI#*d7A4Ra>IS15WvZT6nvb;)dQ++VDH|@Swo)70_p5c)a_tMvkZHp z!L{`gXKS%4Lr6k?4{V4ah4dqL3L+fmYo+;c$&o8II{kfj?k!iRJZ_jfQAzoipr}L~ zBeRKgBMJMy!d#v)icL4{Mc8&%MoyCpdBb`g!(}I0FVWx8U53uJc;(iyT6Z$(0C1_d4^DT z27}_5xwpK6rWWdBt~cmRx{EXIhWfK$IP>*G;SQxzUQcXnCEiRr?TY6m1Wt?}aT}^F z3l8Qb3Z7;AYFc38`#r5IEO8*L?JFy;U0SwkX`tCd(wg*1VE80pm~Y=pGM+;wRrbqs zI0aJE7t={yX4xB^^m{yubI1(xaydRixX)`&VHtRq!~210#Z{6JprfoVl_W0}lLfXP z1PNrzn<>LfVD1L9ZORnMAmt@yV}=hZ`8-7DwKP<-y|1yJtHtUR%pfeYvg905UCtzx zCaAW~-RYRWDcNHtn(}>n>s)CwM&-^TN`H(Y+Ng;*P+6izwclN4DHU}1KJ&-9n=Vf0 z;C;F8-odSCn=`IQ@MO&ymjiBlyAX8ybC{GoUnYV2#Mn$VagEQOkiT~m3w0P@1Hq2o z3Q{0_9X>C569duWvP*R%GJ_`(hgm-R8!H_eT5g1JDk*4fyU2C3n->+3zZb5Q8kUrT za$r(Qf1Zn-R%f(1NabRuzwWN*g2_O2Y5~@fnl?;GvWUa_?$Fb@1AzOay^`SU-NM4 z#m>qg#3GDKG#TU1iLWdlGEK$BD3xWRs@W*nDedIy&qiV5C=<0R8zmusyL7IEWzwzB zMoo4_VWOjx3o~AsTw~d&@vf+~*{F%GsDrXmBVAFW*{IcBQN!7&T36ISHcHmkI-of; z8#UM!HI$9o&=qxXHmav93Z1qNG-ThjQx_Dy6E)QpHJy#BcSSX_Q7DXO3Pe@BQy{1L znJ6w}bfS*xih4vgYI9fAY&Htry-b0}WTWP~qPAqCwsu8v&#=>sTybi73ioB zvJs4#sbXwN>y1!*BQVGzLeE_z{<%6mXb**Qs!|V1yybTjy{snI#2eqkN(l0%Aa_0K zkvH;w@Y9GNn=J*=nJO&U9z&+FTq7S3r=O0|1QOIwEXE%~W3P9b$Bm=&39)p2m7!=e zi)?+RsldQkRyIK(Q@UrOQKDnz?<)zzbiIf#h_}fvA>TxIc%>bk3M%* zdKp#!dT4ubK~oq&o1u$u`M2(95*Yki3Ydo7eP&N;bw7X7~&S6^Z2vA;~Z-N2M-km={&I&dv^47P4D8)AFP1F zM!c|AoO&0pPW~IAttXJNbs>LtX-*URWrbd(PmP zW)$CxtpFN)OJbiWms`0qy>smE8hsMJGAT1c0K!RY)YII0%0A01d6`B#((~4|+|5Dj z^UUSwa`o!GAo>{)3FZ&CHpf>eP&gLmw$Y!%Rd*Qulq6^rJ;2Ovok-qW2>Ur<)twR9 zI8nZmY>m}uRbak5`XMn;Uml0}B`zL8i>@NttKfc*RTW>Yitdu0(zA|g>nT|jA~kPK z{3NBZeWu#8f%afa8Ca;TIt)r%;UPTX9Y0w)u1Qj?3aojpYY1FWo~g~@_V+@F<1b5B zuH}dzE8@l7Kh?knYx2+ zN`lnks{d6-o zV~@b>(yY;g9aH+=7!GgFha;PMnk!_19!jnGwP10inchbliz7|FlV;80ax9KCjZT^+ zby=KVGWeM$2J>p7FZ!vRvIYN0+Ra&V%}AJS*{j9YA)IRUlmfHZ?t5%A)7{HE8FhrF zCIMV*8y#K1fC~_-4|Ch-L9Qn^xyjw@gH}OSz9;pH$PNGsbj+gd)EQw^B_@b(Ce#e3 zrt?Ez?!F>-dJhHjGD7RWXtMOoQJKrzwF!0RYdW!>3s zRT5=ez_F*elfOwe#q2fPZE3b$mhJXVHpT2U+q2Vb&#`RJ?POETUb8&_r)Z7*7LGl| z--%;}_p884m>tncb|3^}+ zaqjf6Ow>oaqk6rFdzCjW?)~5&Tc4@s%jmlE1Xho6*Y}IXvs&!Ly*1DF2UE;dUK00q z^t#7O>{N{TXjEVj{(5w_7iD|5GRfywrp<<;7s2SDMKR4wM5b-KgI(J=i^O()r-Bv+ zNve0SqZ${fI!5FJd5^wr@@?ys#P?|7W0#6MYdUjY0TFJ15B1)_9nlOvEkmytmQdKy zDhzB{Fh_L_>xJ%G^q+-Rn_`&c|2DzbBj13ez(8 z5h2@KMO;HOgxpxw{47BpjzHLmuC<5$h{u*DceY>kac_9iC!%0YSjfIm+qf z&qHIIY(9lM9wGtH2(7$5!6_c510PJ&F=f~8Rhsx>HSm|q<^A;j^5)}9l= zm}JZ5SMXrGi)n`EkZ=2g^rEG)-WVi?p8pxxZ3HoHPy=|te16Ul^oKxpJNUR_LHEw8aa>#EvJi>BxM{Mon_($cC-*R|_<>*8(&Cb+90!*||5NIhnLxGiz3j^sHFI_Ly6~k2I2)u;@9v_ zplVREmyryO|6vRGR`Nb=Ems|P9se{x_gly>=q$>QzV*KHA0Nag)BX4_NH)Aj?^lO8 zw*EPuj$m#Xzi0`7oYL{^ol=(Uued=pBgQ#576)GPk27yXxu%4r-25#a2x`uw?4tWo z$OBXyY^GJL=b2?Ool-1am|IUeo~h_g*Hf~GoQr7ad)m!jOzRc2iB-(Xj9w>-doVAT zpHB@qM%Yyub_4+#X)wF@^lp-QkYg8RGi7(Ck+Q?8e|Hmay1Ae8VOskq&e~Fs@pIK z9gN|8*t$!hXAr76pnkB<=6GJD-H+iTk}h1_?n2VU%}K=b+Y#Qkq~Se_de)m{8@Xsk zJ-#sQU7wm=u@0biR4IGkhODQhq131TQ7~L|r&FWLb!w#4-6`SY2z^3^$=)cwfUZ`H z!<#ECsu$wc3GC61Qx0#3L&4sP{6B?53ISd=xq>?Mu4FRm!^x;)8_!1cKw*@QyhFza z+D5(uxX#Ga)hdt^s&oUejSgc=A-6IZ%>%kuW${6DhmB^Adkf&b;cYsjox+Yeh27|t z@e%S3*;poYc6XM}7UL7M<2Sr|2~ze3W35-Wo8UBgC^wnVWYI0r42@-|H+nQZgBie^ z3@qG{FR)xmw4q+TXN6`qd9-G*DYP|1jLcj;Wn}U~@vniz&7Ze1nWMSa&pjgw zpO-S&LG)*gr^n?lVvqRxb`%;<2AgE<;h8d9dqS*fT^PTXvNDU$Ls_8EIPd3Gxed?p zwMRJ1zAAUS;J!oLF7%!YO?rc5qH3BNZ07Bvx&$WQ2%CTV{ABfmf|F=$c0=>63evLW zLNb2}&{<*=J|VP9S}a1v1vIUYivmYHa4Hy1;|-3Islb&;rt&!9_X&ReDXf~BqbIIEU7XFvqc64n~Z3;TDu!T#MV}soWb3X|LAzf!QF|P1DAi+y(Wp z_XtjC)FOJrfUH0?jSuG&$xtizOdr&|J;fOx+YZz2T&APr)`z(74y}+Z>1bLe-ggnr zS(VTnST%`Uu1tB|A7;so7J8>Q{kgSMPH)C`B5^}zAH)}sZ^yeyA=^PiQ}I8<*<{v99;MSp`FVbWu?o@gFFo$qrQht}($py-{&kEU?sc=*^zPQ0*- z6!=E6$Wi1ip2S(uiRMC@uJhvWlC&m_!yc~zp~Sx9i;`++eHIDePBYVwy#lPwsd*YD zdT>MYa%p&;mYTxwgikZB!BB8m-#C64|#zPNaoHgf)Pnx1=A|@83g6NST zN9zrA4kF}5O=OEIN@?+KqS?>m5(XrNe*J+z(vW2fHENv}*VQr^K+G2M&;#$>OCd7+ z>Fs%{w`Z_i4q~m;N1PdyO?f&#Ux>~2GcXH^GDioid_75~kF1sJb+kTh36gC#Uu9=T zldOb1j?7%mPUf$+JW0o1y8F=Ode!_BL)u*VqLk+szN|Qk$~n^n*DY<*OtroW4gHg0P?-i>N~N!z7KhQ3Z*_)!lm^s&S&-QEg!Jw}M4AvIC7aNe!1&x3(e7}^KNzmk7`nb!Br{WVdg z_(sa$dSPJ4P?45Zp359g0|?hiRP<@Wr=OYl>T$)+pM2uOtTZ^svvesd-J7qUnU4Z8 zjm(}@Nh80i`92F_6e&mp<(^sDon~b%pF}$`Np2@TR@$T0&Jm8yf0I29k(Z*Kjw1Phi5Rg2LF)KIObTlQJTL;ENrAKB3q`89VY z_}*c-{_GdG$)}+Vjgb_}u)=w9q=A-}X(^n7{}2l&4A8Dpuw)*!et_Q@kkCenX*?AD zv$s1VtL?n=yi{!adNpOK*mgu>+aD`Vlf<)iI6%)}%=YrKTD9XNYKP{~3H0So`puyO z{9Fq@j{bz!&Y~MYSzWa4!}v^ZvH8k7(gyYHrrR(swi#=mxAx`^n{`~>3_U}H9(_y| z8H_`_!)|-AFnR~Tp@74EgE}&EP_ysOq(2^X$NRwXj3C{g*>w1em!;jv*JNd6*sK)@ zV~g?MfNH5&AHgj%L*en?61@4FiJ=h~%dzN_Y5$*0S@b-??e>6jw6A^CRDNvcw4{*x zD5PhaN7A%OH>^iDOZ15y-CyZQ0y&iO^z9x_1Q}n-PUxYj_Iuzu;W+XM4yTg};EFZp z+`>5s72#5|xYME5KM}P~re^$Gc?@q?(|+M?8y7|Ni}58iB)MzhveoW1nB(V0J^)jL zxuG!D`a61e%XPuZ6-F!hh%|O^7~&9J>$vN31}iT~-JT|@StTafB}I`8g{3`*eLb^{ zvp*TiORn9E0EPQ=OQa`0x;`*$b~^)u^_&ZRaC}T!Z=ri{emToVMx^qE?C^Bx?GtlH zzud>>MrQM647RPKNnhi)Qqtsz;Gr{^sjb7U2^Sv!Nm669HN=h72mFf&;ccXk|DHdJ z6X&2feTjR!;{HK#%*mMDc-7ARw*jx00|yzb&a*&X`h|%(r0TJw8rVdNbBA5!grlS+dl=qs+NkjOy#$Lk>dGz}Sj(Jl{##o4(uFv@ z_aT<+eVlH#{yb^;-ts2GSC~?@X6gC%UkLW0$qaci!4OC0or>Z1+nrH>iA>M8B_CJ` zu3)*7vk0B}YJ;OQU!nDBlrLREI9im&KZ=d6bdz+lVsw^WBukKAI7NQS5npf--&d-< z2o1O*Z`fNo&RMHO;}bz;Hda`$$ropY)4h~~YOy7ac*(>(s%1f0(ujT{+BEu7>MpLah`T^(kLaT&Av*Fc4-f7>@3t zH*S+9%t7OFchN@|1S56s7*?yQS^U^5=cW&y=xe=C(46Q`zAOE!hi_5l9WPBaSLF2M zg&1F3!JE~W0_O;6b>h69@PAthsA3rUnQmHtW-`V`GCbo5+)a}c5&CyD~=R4|%+*MvF=4@`GLJOWW;zArMyAqg4} zx4&Phq;8S~ty>zjereD|Wtp(*GGRT-g!L{HwrXkE+ND7gwPnIE^pNSrN`}b0k_kml z{Yd6)eJGfyl(x$mW7(>jba{fSc2OrEY4%d$5)?bBjbhRsLn`PO$u#CGa_bnRX`SQQ z{O!zJW)wUg+^aN5NVEU6YaT{grc1lrFn2BGYo8NDNMK}zLj`m0Wf)a#WnSBtk1x#_24esO=fLEHD#_Z;mkUiqUh(g3&an-5CT**zzd8 zDnwtl+o$XEY=8l^51Tg$aym+2-Y5Z|M=Jr$jS}el41G~56{j88rXm_=aHrl8%qwYw zQL?Ogo~1l%?eiC$Dy&4NlqsF34UF5cck%%ssG)(-C=+}J2i+Nr{VMu-&pIPjhw z`U}0Qf_2d+)Z=hnv_TD_eeYHKP70!zDtu_7$6H9i%RHdh11=!x%Pp(vimvU1zRyDK zuw&dqPb2LsEOesc^(gl%EyU!aN$m=~%R_(9RL+FH%0qwE9r|hy{X=)?YdrLigs$(@ z_F519Sts;jYI~iB{({hnYA5mQJ@~iX1;4>Vf7c1s91n8`F={p!!{~033{~Ol-^5Ic zKnls@vz`7+FXKNtWvJ6{^w9t64t5I58j#yR{r;R{v@I97-{i(jn=;%?_#~- z?#iApe|h2Z{`}=z00C@;jtLtT=W9)wumGN!&I*?Ygx_^G!}_|EJw@c@@%)T5x{c=n z2r3MoJ|ZY3^Fmaoagd{XV>BokJLR;fWT)6RABtv5*rbyfR(Kvoa0Bd2Wv#YGn6|s* zwg8d7$Ka97bio{SET!$v$Ei8+9hHF1s=J+y`h{*7hBK=IOun)+2~A&##X)<$`Lok9 z%|XCfX@EH#x86csuN7^HRBof_M`SI`##F0AJwfmEGt0&q^;JeMg1N!)Uh)h0PM=qH zRrq{yfJ;e;{`ewKl!Rg7P|hhiRKeIvb$Y5)Kdii+z0`O~7vnHgLBi2ALvi7dPTF!0 zs#oOiEjONrCN^ABaiFwkHTXZyg?Nf^IqxQ_mpsKmhoZxCSr_~u(StbT1IjF1f+#!a za5%P;fAVRMCVAMy$e-qxD%Lr)jo^S67A6MwJs#Mf!eLObsdJ7y;!V2AA~ z?8qbfE0UO=u8#f$mSw@_Cx`n;5yqDSS(ccQ;X5apl+opa18vgYQ#|kMX`A(|TmPSB zR?{10E>~fNKdts=MRH{d@iW_=+(dF_dtX2!?W)6DNq$RUY6G0m7~YxSW>wC0M_jh_ z2Xav`X~%<^#+d%BFEk%r+!*!@ z)fQZBq8lIPUP_yI7O57XP!1BpvVeraBA|>sJfMs(3lzK7m$Wxq*@50Si9FT`uz(S=%y=|Zh!NEe}2tJUd< zBU~H5Jj&btV%q+uPTLW4EW$AjY8$TGUjDEr-mMI3EAF(#yXW;}fr{K9NoO>Go8UPb zoZ|lD_T8>s2h=Xq;5x|0VRZHS*7b`U<`rcdHlc=DI^m(<#ST7g*Y!)<^@J?EK6F6s z>LOGhgDkW@w76MbPqtYfZ>KYOX&@A@>f?KSAYhPJDJOX|}Y9%%pG_VD}n>BaryD$xPg z_rr%@-)9!r_b;9PY2IMRKb<#Qmdu+jI&)yi+BI*4tgUT}=Z)8soj1Z^PiON+?Yg(q zuIu*Qt^-5ru67BjTOVHBF0UusF5$YTYq#sKJMDVfzT0(R$luj2qca~_+%B&t+b+$C zmZfXA>wk6Hb;G{fbzn%_)h;1z>!XX?<@IFSC0zD&?RNc5r(GP7?Q0!7Fy!uPmyo;l z&x_mT^<>*6ocDCrE}bj?t=g4g+q(G517lT&yb80kr3-9gRk}zQYo(@k8y5F0VD37UJJLowZAA`rmchb@9I2b?7S&WC7_~(-&yh(^{Wg z+%T^w+py1SkSyH+@v;ZT_H@yDu{~V_B>pC$^`bd%>A->Q&c4Ryssn;U*Z6!+-TT;L zFnB##Fnqq9u8lWu?X(MV^}gEm#)sdoox+<>EN++AlWo`U+UcxaR|Bto@-_#?{tb8) zzSl7JuWNwB=lNc6zx5p$YIfCUsM%GYaM0^}75#gg!JSi!ETK3*%S-Ow54>GFNer%C zOsgm8xE*bX@#qVx%=_pT5(66gLph!n3449qKJR1{Yqn%3jnbNuNk9*LA>>Cgq)w(Q;yATo4FXS+*5(z?Hc>~{PMNQ}-SJ6=NP&&!U% z@Ll_!e$h?=+sZ;}lluq3H^XUPw7`Xm>~9e~>iZjg4-Rf@ z{alXC!5v~%{bJd{!FBCWF^V2alIgaG0@8evGqqDl$kX;nSkm@LK+*PSd*dDo`gPI( z@nP*07q>m6_>UyTb?rbJBbL9NTs%VCqlLL$`Y)B2GJchOf0ulJk$h$PMe%<~zJJu0 z;)Rs$LVlkFYDTAlcIy$^u~(fPj&MvSuhONNWBRJ}Ja@dtH=~o@e4_9}=h&?g()EOx z$B}i#QoI^(HLK=lvUQh>ug%pOuIHEPs!AzU2S=uzinu>x7UW$--K*08;jDBTOJOee z4%!j%r?~a!0e59kM0pl?*i)=8xO{v4?CBI{YOwDifA0fdB3WM;VJ8W_m(VPPOs@zB z^UYg22!0zWIrjO!G}E6*!b zhZ2oZq z?q7&XV!Kjq$-QvLa(~amZumW1!b{j@v&=n>Z`Leraw1>D!)@iULORuPPfB5slUNDqIC+#(x50CNQhg1{=MDm={>kXV53uFsN-ch#eHf>?p_-vZ#Yas)s z`OnvsTlt#Z7QR1GCjxt=)F|UdK%mRCNm%DHYCFR8L^?iQH*NcZX7N?&T4~*1d@n$7 z`#=J>RKN9|f?KzK>jz2lf2H3lGHTpU_+%;ii!d$|xt$=ovug*Wj`n zdBy0%O1xEC@ROYJMxT=x)Vr5sMCr!^Tdf(o*ZnTF+am1PcK&~)fsHoT-r}Kxil5Ze zsh?1>lpz?L#P{8l6}CC&Oz+8dUCUR2j;E`08;*87 zwaPwaUGn0S!cFh`Utx$wTK^`tNQ>R4l?;8Q&-&LCFTB702IhOzMviblpk_d!Srz6V z3vbg{8<dlyJ`So@Z(F;)p9%(~CU z@t1&c{V?}T(S~7f!|Jf?Q9-#=G4_;YwCu}d!6wXCG&)jDc$8}#tOJR#5wljfM0=$F zz~Ym8e+LFnTGWQbYaM(v8n`wp!+JYtoK|4dV60-0Xq1cPjk+j$PdW;lzg@1coKAv= z?kSfx|9UDdAgTK~N!|N^$u-^W8Sa9~>1lb^ptath@vvfGS*At1_t7H3g5y#9xAxBW zK|D7Ouf2QY$hx~Xj;_CZ2aqUF^-Mhr& zPxK^7Cwi%snn$U54KJhR6sW7FHXLf=)2kd^9N<{6gI(huiY+7N9Pd59_6*P*y$d|;?fhOm4eH! zy6+5HmxBEZN(Eg{EW(*)l2vw6STD8;Y>+Tjr29Wc8^YZAjtaR&u^9_DQcjY6Bz?{L zK@k5FHDhKdl34(cSd`!&)wG?>e@oZ7``-(qX$h}puE2AjK#j%V0PUXoWA`OjH<2;X zT>I)|sa&=Q8Zqp5VOf3Dt5EluMDvcIUw4QOnKBGSRVp7!QRhfr-&D^e z4o~;E(=AT0@(no?WVE!E;LOtdK9^~X#ndKK3KaufkpM?IWnTch*lWLSw4E@APkGU)eSrfj>>ea|kRHp+}OD%`e ziL*zs)cn9(bQ_*M_W`Y8Y-9JVMjL6ITc9QFDLs|&Ui`1*@nK?L$gUc?Ex2OTPugVO z-$uF*l5S-V4Qh78(bs4N=z-~-aEAa@pA7HSw`b=(h=B?YcGAC2nrKe5_#1M4lRu;u zq}VF&5Qysa(4~5k*!RKY_`kvYK)zCmMhLtp8dU+`QeK;Hh1?He;L)mpZz`DO>aeb_ z9waE_>%r=&VEm#}`zYuq{0jWulejCaV>gmlzbV{`=d3OFHGT!cPUJUtEq@a2?7q;> z7xK{_O}@NKd;9Yi7+T5lNAF`D=9DhCGB&4F@I(!Cq$!(h)qk6o9pM)IcM5Ezu- zzT|iCZ72YQoo=@4$+3^lh(ETh#j2(4Hh3?901q)1W^fG`MnLrJZaJ_D}aE#p_&iuz#Sh)*pSx zO0Xl)!Bt7lYLc@yJupzqWQoAs>cFa6EqYM7@+MS=Wxnz?Fp4Jz%|V-5f0C{acP6 zA|aMZUJuiXK@ff7?|EL$L@KJiw%xpY6*O4M`?oq!sa2!zD{=FD5(R#%>M1x4=I*zJ z&u>|2p4P!tgdnV|Z=$M5(*>i?+4W^@KWFU z;X%C+Oq?*gf#=@r>Yeo;;?zh=e-6Q|Bh z1rw*wte!(kmSd+9{W}0Mxdhe7|AR&TA1?C$DC19N<#;kH2a{PzCq$yQu+!-7guzjh zGM!j*_bt;Mo`K1BXN!5eyR)&oJG@wwE0inIkJUWYuI}I$SvMBzi8NbuY2Hi0t zL3fNu&>elZu!~!!J3PxKaJ}ulKfm`G1aEAnJjZ4BEzt#8raEAnU zjWfd?5(G9*4tId_D;me<-74>F-t$f8J>MaD&j(;E-(cSJ0T|`m^4etqV>FcerEk(i zGEYf>85iPKgZhy|+{aH}DXiTls5GV@FOc*KWe0__bJM2?Uk?#HR!z@AHfp5{jd?I& z;Jc{HcX5~RlD1Fx^^t>{nfQZ)@s_R12M6ojF*!6*ZM%Bh<@_43vwuw82^Q3ycOW62 zHK$K*E{~RN&2T8qB~U*yfpU~U_n>s`N=AdV$Dqj4Ea=sPwM_n@w#(KR3p3;+wIL&^ zZTSz@k=j;-aH1Ed>AAX7RJk5b^b;yR2WJJR=rPWfI7Mx7uEHrwiL*At&m%#=p3eu|eqevY$R9LH+v`k6v;qHngG1Wv8jZpxTHzTyQFzUB3ru@t;qqhyWV`U_LfC0oC^i_7n__*CYeg1o#|!qh)l*718gVmc@%ui% ziXz1I zlcU{E`C{D|>&_*1Db{VXG}w;FW8EQ3L;RuDnE6#s@%CQ%;&*l@;<;6w0#w?GBe;uOM1KOiP(72GGur(*T5C^OO>h=Pl>cOg6tA56 zBv-JeJv20Yo@Ik9y!Kq7BmMutWV`w0k*TA(^lLBD*bYQ>PJr3APfNrkc9lz?)AYSQ z`Rce#ejShLtK%^C`+oc-haGn*M#o$F>NrcX@aSD0F#mLhUI7c{xEVR@l`e;!bUExs zeew%noLyVKKm!BSZl>AHp=?j{Y@0kAw;`47D9<+EN|T#|{M*w2a}cm24KRla+~EcC z0EFbh$9aJ#tH7fR^+K56lb_;Gpw`@+W;Ta1@AS-Pdge1c^I6JF@@J&U&7tHk_T(3N z@(VpVr^A-~S!r@}+?T$V6~3+`8+s;5g4Qp=t>|PR6hx;APTKc>9vov80B3I@4MLjJ z6+f>G@tq96hs!jag}FE81im_P=Q?baM|XmbtS@_M-2NCkT9xxqJjBdztr8OQN_?t?65 zXsgzSs}gPx_swbJo^7KQAd{67hd*K+e-AqL!+--vG&8NhWADRj#%%G;q>-1*^y9ts zSiqB;yPQ?i+nnEYo|m0;Eq_sb3?xowVw*Q;EOyY!dN{;=&Bn^sBkAo%wA7B}JKfj1 zA@M$q?_h~HisN4~Si{vYs1>3|5orG9Ah;?Rp>uPRQH=D>9nx-&x5dWrxIT|8wj=k} zR*cbhx3%19Yq`6v<=EO<32T+4t?BS)YCeJ^7sI_|<~ys8$y?bo(r7RWRH$ z(mQ>Ap&kM6N6xJ0?{PDu{M|4!z~AF%dii_n3~xtGOwQ&<`lh2&eWdwxV9i_7i*RC5 zbyh*Pp~cFU?_w?2n~{mwvjTgkmO8)bQV&o4KEA_uO4b+un&BG66lgd2Af)L~SG&Pi zb@26swH^cC^ia88!<6+EoN9fH9yliRSRzQKwcrN6$7mhx0#rD0$xMFYaHM;eR)c2c z^NTk;UlI`X+T_iy-%j4vo;A#4YdyLrf{1 z(aAkfNWQ$6DF58=mz`=@J)Ssdc64Bc_afTHl<>yReTodVQn*bTCZ)m3KqdMj6B_d{ z2K?y~0bd}XcoCLb>&Ms1NKHgYhc|IZA`mT;uctCH+k=p&$C@}@87L;s))tk6g3f097UHAqTa1rZ!3Wx`-d5eR z_1cY;c*^pYChFU6-*4~xYJFW@FE@&OSU;3Qv^p_Exy$Og#0))Y!8+TG9F}k0Q z=^P`%FicF%p0gV0I=b}D{Nh>$xw`+qG>?i#Fy|GbPnC#+7Ol#<_1MfGMq^k zY};n0nqOv6mh^0}I8fYo*Nh?R4H6PFVjKwM_YrSslNGPiLX5BuX)#z#RS!oRxg_w` znbk`JS*6zWO>g2AV0zk@^r%yM5Iu%)s#siY>&XI8Ile-lN_?Sx*32S+DAoM&z4$8S zEG(_^@Y&U+`pQy#3GrBv_#LzWGF4cn#gns-37R+1_vmcW)=wzaE0|QoxqfD{bt&JC z>#gR&QmNjT6j-tXYbBnG3`*$4WNKO3lv`)d4w|iY1t*s3gltg{^|KsdE;H0X~_whUT-krL;?6S+u?oyVvaM>x8 zRa}ZxLBuFxK|rO61r#sNfI-H=#R7`#VnI|a6hWnlT`Y;QMH4l_Bx-Dk#>ChXyG9Xz z&-0#pXYMYTeESpsHF}3f~UwbAU*5n;JMqP*V8rtdUjd=&`5%@tG2cohir==?^M>rk2-*V?WuG>)p75W zz84ZbfQU!`|7+D3?-xKoZN@F?&CUAO5yVzwr6mW{{62_1{XsrMQMc*ZaY*3rMIWUx zGPo6}KVQj$7L<4gUwxfA1Q*r7DbygZk;O4qmnXCWlCcARi%nS~M2zQj4bhN4SAHJB z4ro=irF-Az>Hx<2dOGQX$r3%?-~xQET~7}xfY=3^9$o-z0FEwzodF(I06W#Ej{&3_ zJ=KqW3$c4a>h;D4U{z%g8v1kEk=D5+&)1Rn>oZF#PW=66)!Xxu6w`wSbyKo2` zkjb@)hBjqag@x;RGSFGf)GC(opJ}cRrX&Ys@<3)Xd*3RhxahS_#WVoVB>Az$aWOVF z%6Jz`wI?vXvX^`q1o0wd5^KilGxkgw8?g)ZKPd2#csn%D-?Pp(?Gr(d`#`K804D#5 zS8sj$qgat~UcF_*>F$y3lu~crvK{4m&r8%bb?2%sPeo#jdVjyXc3}4FYT&)PtC(l( zESj?G*|U)bH(#6fH{5a)NDK^k{k-{K`~(yqwSC`6^hzJLu2ledVh6G>Y;sq^spRCx zGSmk$;Ug9xmb(bCjMuHH5QLuD2QgTuIx?MpLL`eW+vqDCwJyh+_jQ)kk)yh8r<1f*mU- zVVNV01O{!9qD4s*2XUKc03eqGI^u`jj(Aia>i}pVes5z}r14aThsTHbk3aHVoQ2jar)epaf%Ch2MRmu!j za~!`1hZOrFHG_N0rTB$=#-rXlv@5i|U#dN}9Wk5tPsDXMJFIEPt6UeZZMiPbz$GNh1zxl@)4mY@}``iO;FSFcyohi9tk!!w+D!>e36v5;<^ zqB~E~%_AM#lo|-)Wysb{2Aq9e*ePZsv@qW1lO+aKx1R;NKQRxabf;~W`3t$xpa=F) zvA|pN;YrW7AYdcC4$k(e5RS+I^V`oNrHOXNW`23UtL8^K(>vXo!@IQS!`j2*FBGR_ z19m#an!CeSU353s4`nmpM*9UEp@}uWD|iWQqcsD;lC-KJj4A3gB@iE`P_?0k3eWpaa`H1A$Ln4bT}EwR zYO;i-DK7{o4HLWVUy%OHS!@X7lT-|`fS5Wu&^Z+d)Rv}d;`-q?L1>S0f^ zK*bes3nz%!*6|G1C5S&(FY$)_b4Y8E-3xiNa0TkDaApbe22Tzx0>;)M4cmZG93K!= z?->0S^d$y%I)-c$4)J1?P+IIMet6)mp8+FOB+IHnb+!6$_f!Vu4LUwxh8K=Z_40x9 zrU2NLv5xPf4LeJ{$y3qKud!Bn)vI6VI-9#0*Fw6I*zkm-qG3rwyeLzISmdLBH_{qE zN~J*Mf>dF)pNR?LG(^DQW7LXWuoMr}!NUS#ijz1<%!CK+08GOsE0sSrsk{C4V++wR z><&CNhPbkw`4_&giA>4HD^tT>OlbzePNW%WybZJgCD7*?rjmEi4v{46(v`$da-Mv` zS{7zgF^I7vaI7dQvO9uftf2&NM)fZ*lD!Ej3)zC5SavZ;;w3x^M_VCdiVO^6dAiSe zPwDnOmCk!gm}p1FI8RcjjBy@UIhpN9rFuh<^YLCXx%V6qlQ#NjZRU3OO{E^%J%4ud z($v^l#oj;EZBAW*yewKs8DWmM&Mahu98JjQDhZIQB}f7?fnIAGdN?IYCm3lL1jw>{QepUOcfT zk@tpGGvxODKmFvlqws7^{jXEsrTh`tTR*ZafdmmEWL zzahZ<9gHU4sN0tzlJ&dU?nyO+gJjGD6%b~%3z>!PEi=}xVzl&h-;GW^E(ZruI2);fAS{7BnfY8nb_W0#y? zSy3sGP9mMJl-U0`7QFdq>}J2pQ+J}3nB@9UM}nj+8E^pA}s&Stmqfe0w_UmBHfv-=sRKCPsPF5AOX6) z1qA*~M+hW`1Hk6b2gv2TEnpuAt}V%IgD*BYR%b8{N%*pdCbs}QfbN(_OLdZ4sL;?| ze<&&^y;MprLTj44Ksk2s#xdk1m2u4dQW3;{mS7PG{8`2y<+T&iqGlpm=E(dK8fLb8 zG05aC%49ob;%P%7ORh!VOKq33k3*>|UUCf(LAx_Jl^}U{!GqhuF*n-9h=)oox{+o` z!u9X>?*LV%3%po&A!{md%7g8^5l9BoL!n`DbfNeyv>A9KHcP?S+-?Iq<&Zevv9u)4 zf{iI}6SCyKa2@M#<=4Yi8pMjCXoWu>EyvEjwG{!hP6271%5hCDo0{^XmN^67Q_pL- zodwp%pF&1&Q$}}FM&4GXGUBhyEk<-IQPZ;IHoimMm%2yB23)X~1maOW^uQAH6q$(9 z6j3@2j8F?JCAn-CT1L7&pe!}a7CXf1dUid7u1GSdHad16Vs&=vJEs2S1$Ep;H-(MTV+ z$%%lZ)I%ST+-sR5x?SQxi7sfSjP%C5Cq~iZDVUh+`U}b&MyivM{?4U7AdS(AK)i1d zImw9+Oh!wP<$<*op-?%VWW|a%junK_-{QIEjpaD5$M;+n=K;^TY82X7VFt1+G3>-Z zl~tYL*DgSQ?m^z~Ug}mn%)^6{<5smGRBoQCa^`<$nJasP;3pC_$O7Fq&8hfn84Q z6co$MR2WSxtLQrza_IjZ#8(wu>l%=G3UzqN4J_2@iaXr#+`9-S;$SwO_uT;uorvet@u5@+o*>u=FCq=b1V_ zpe>>HrZu0h4Te!Sh_`qLiy=y< z+BnG0FAs<8rR+p(A`}_MIdwCKaA8BzZmoh`ouW*MDv5Z?y?q+;)DS6nXgvhhC*T$_ zB+(uU2~>#!&2B&r*ehOAz4+_z5Q=0s91UjH)kP&fI2kOQHd;_fe-oorKfp+z&ZKfw zFWa=%AkIjqsm+B>vp-|V*{mcgf}2UGDgvjE6HEF1RjF{i41?zz=@H)>_*K=P1vcoK zs{~Ky69tkoX}Ufun*JR;^O&gjnLo;Ic>SAn*1D zIo8;X?eU)OjOfc)!~v^8=ojKu-f&&i?#Z~s>&Vtqik-o-GDE9Gg>#Is#piQY0 zk5Ujh+vAkUf=By8ct_fcG_DQ2k9g)=LmUGg%=s9|cgmfvHdWShO;{C_17=T(C5=Hz zUP;{cZq2Q<=2Ogvkhs%y0_*a@Ee6T2I8|9}BLRhY;H4kG zb(g9D{6*Fl+Stxq3Hm;ei`>9qAyF~wPPpN6_4Egf(|W{-mow0*D)01hTPK`!biJ(@ z?RxX4|J|0ZCQtTd-U-vkw;&Y19bn23A9wH72S|sfxIi}f2JBn-W?RFrr+HGG3Qbbr zE=9&~feaf(B|R%&fQY2$=(Ib(Rnm`fsu3gm?G%!eNg?diGOTTaNyorWRkMhzx+mhF zQieEIl`%nGZC|?&L>8`#;b||~P!mD#)NX`oMT<+K7?>Z$85gcG%4W!UhjN4CoD@2> zwewQZcpbi(R3*$ssSfd2FgBw&ULLH1841>w;bR7CW)zoW8JC4Dq?RRj1cI4*gep2| zXuBcH4-v0QxzZj()Q*i?fl?_d4%Vc~gB^$52uu*Q>{&AR?kT+JFSr%$%zS!7B5|jT zmO5(51}q#uK9r`I9k;UfK8z6%T-=HyMy$eFX5$H|S? zn*vdM#Ilp0b2s_s2WFenzAaE7tWsffLR2!%!hI;=qzlz18*ma-oq+I5Wsh~2o#1SJ ziR!l)y&O4o0RCJz;knk2MPHnGEzE&So%{21;EDj#UY<$oyk=H;at#OZQ0L*^t1A$Q zqUhYvs9X0UGD&p6i;xhfqM@>S`s<2`xCN|B$z#uvdwP}_>2Jk0DsW|z3e}e?C0LN-TrJPSoUuvk8G}rx9Z(U=6EqM(>Ea~ zRVj)r=YuOI{0i+C<_PnG>F-g{ObTih-ZKV$wO0zU&C4L*CZ&37KDGIzIHJMkZ)Yyw zFKa=X7S$^HXkC~d=ps=KT%P2j&0SG=jrCzDQF?aRw7!DZtDsyzi!&2Fe z4v`#t5S1pz(b1=o-cP8b>MYkdQ%?8ddxpDOA zG-iIMG_VibjDg0dOpla+gDSYJ5&e(y;beJP!<@kG)>Balr~`9Z))A9Y1&Gk({SS3t zm%@4}6V(nSxpBYy2}qZ^^eay+r8mU+;uE$Vs5A!@EotS7gOcU`=?N(60dXCzWU92H z3pUA7CsanM9I-IG39C20FrW6uf8>lhCF_}-n9vOmZJ{f0X^1`>_eRm z+`kIC7j<;c(J7RCje$4Zh@Biz1VReJIT9hEvGH$ZBk^b=@`K7W|>NR%=#rCh4Q;9O0mu>$) zWb@`PSr0r!VW{@Y;ZWO-EWZEmEDq>gx7B8>G-5RBsDN_|9aiWhk8sU|^$%ng8o}FH zV~p3c{2KNl$bbx83aCR5L=8L;b=ZNZ#yko~FND2WWDg?p4F)hNkF2x@6T6q#V_mF0 zB=0>RyP-tA+M4X}JPtQ0sYDEOeb$-wzezne&vba+sYp3pqMYmzaF7dDg@=GDB#)>z zQB*RnM}l21J`YX@JXQvfm;Mm4M-%X{-AuM{ zpPin6 zprZ}-xRadFK*<-8 z^tv1mWH{d0uU0EZL4atcNEEO>hDhxb;I1~EB;VXq?w6I`;$Q-^233gVTZ)!(Q0u&h zXnju8$^lAVft~g_<0R3>`?;xNKVG@2_1BiCO5;8C1uwy$%4>bWA7~f#)EE4bc2P=Q z6$zEb%fRmoNuwm~M8r)g&X!h5Cf+^?hDtIWog|CPB)AlkOr1fJN%VhBGHIQCCZn}J z=ep_j@f?cwWj=lj$r_smRX&`IP%*(HfKt@Sj0Ywqv6D<>O+}P+VP-*ekAPuMC8Xqu zF<@)mCxu^mIt64nc&ReDGRHU?d5))&2UKY*W6u7!Scc((q45#vU`O$(FU5&*T>07o zcKbB?aDizA1}YcBp6+#;(aLEiAr=P3Hn)x8AzA#|vy?vtobCl?dx0|)U>%KUEEoe3 zGQ!pvMv!ApZ2Qr^qKvJvK;e)~Pe%7lcuMrf{ak0kVn=|2ipBgtQ!n5IyYj};! z99S}pCV{zL;G8@#*f5JS=Mtpf`cVK&&CEO^x)3oCcQKwvXau3LhGi3&Ph%P}=szc< zAAWvo{CGuaX41r;Oww6i(jt$;B~B7DAQfd-2_~olfjrpm*Wvp$!Yhw{ zTk>-O=w)8o6~sXH;=LgIJlI;XC|0LF?TTFZmStwahtij@PD7Y}o2uj{b0?$DJymt+ z<9;XlMAYC4fR0KL*2SxRB_p^3MkHPpu&;szgEYDaMaZI3YU@oBDiugzkF{z>?Gq6u zW;rLI+c@}PL<`#zjsvPLY4)m&7uglCTezwtEZ4E%tm2tOka`d&2cu|Z7>vCVL1Nl! z2xe%SX~l}DT@2E6Gx`>4fvgrNVMpIMT3KY5fxxdE^%zbrS}pLJd>p%e&Hd38`CY#u zEQClXQN@jw9Xh%&RpMB+Dgr4Rogg5sx7PD$RW@{OlQ!-XwYQfo1nVKF5o67)r{wKb z;J~aWfVCz<$a-efHO|aUUVqMUrp(aX^7vpl<-yFUnCIzo5M?x?$Qk0&ACoR9s5pqcQvw zt>L;XRV4lAyw>yvs-Q^J#6+bm-+~NIR3ZB&@B<6co(G^khF5zKsyHl#gYI>JvZy^~ zleFXRQ2L>3L$ynvPk5Zh}JDNNirWh)u; zr`z4F%~u?(o8c&L!(&!~sS^ap8K#DtpQP_DZTf@Y`VLc^;SUCfFP0>MSMU3PeT~z4G)~g@~<3p5qP?Ab4-(`HY%E*+A8&n`t^} z{%;&y&-Lkb2eSHc*a6&c7w$X6d|S*9#q{l@$k?q~32pRQW0C*)`8{3EVE@2+RJ18E zQ+-9N!tue_u}rOs1XQlg1TU51u7S2PD8=47ru7!k7w_o^pQ1Crg3jO#-9lA_gFaHn zV7^kv*03W_QM$r;+j8XFKEx$+D|q03gZSa5T>_o~=^EltW092xh)p%^P5U;`B+I1m zRG5Cw^{)e_92;+>9K|L_@Q^Tl+v|ZJ@F3pX#Zo9v3B;-@@}B?TO+cLE&nw%SL77;Og8;91<(S&F0Q(UtkyyCARAw9UG&6bX>I z*+1h9`;U+p_MRf9c|E7DQRa#f$5=lFG^S)=nq?m)dE_0kso0Bc28&jbrttP_oe+s;a8O zkA@LDV!bui`nEL|a--DHO{FjDK35eX>vBXsIm{FJSVKPrc?KZW4V^G4PUUfsQb%%$ zq45$3&*MAU*WruGBA)1OF4zmP*C<@&Xr$ig6Ky~ z>4&rP#u1<>?<*8&QDA#nMw(;Tch%^!f z6o{maC=_uYxVM#}8<4EFm<#qGv60qtR_P1aKVb$!O|xRrWghAcRWg)=$Rc2C5L2G! zVh;@+92(tAbDf8V4npIsEt(6krA#kASZso}>E*I5&qX;1m!R$U(md>;p@TzHCByoxeS>if#TiLaq@8MZ|)x5 z*6-ee-@D+quF~E@7SBV;z#@<^g30pqiT6UBp7u>mEXPuj^m@3cHcz+C&Sy`1-3VZY zo(R8nA8td$>h)R7xFlw);0U7eI)J(G_ zmKHOa0K^`Ef*Jv_eOAyBfY@>?=(zaVrA6oiaaBduH0&=KVtYgfCBC)GS3m3W_0PI| z<8d)n`KvB9)v_zDL@hyOQ_6b32?3%GNcX-kzv|3-zO=|%N*5*Gs)kbHfGx6eL_5BV zM52^OP!oCRS~+;izy(`h27#wq1;9>#BI{!K#NI*vKSqyZP2Jl{7fwTY=@10dQZ=Qjs~{SKcb?!E7-`r_i=@p2 zcpsB=KMamFq|ewz%Ut8uSEh!F2M6o1k42<|lM(q+6M~TKSB~agzXz%HP{CEP#^@((JzQX2 z8+PNb+!J))<#8`-80Cb`wb(p&S>}DDE%%M^9SJ~Zjw74xScS75_3)DR!brc!;?0z+ z)V1BO06BNW82vtcvF#CgM`aG{MW$OAPzMB5g@+x(*jkB9D+*YPpds9wuWD&*b5*KW z+OS8r=E4ovAqH?0vrsjh;^0mQ6k5xYIIg#p5zWHAP#YGXM2*wSERxDM5s~9O}oEsxs7Z2o6(fq1uumxNJmg#4QJ4nlEDc`e*PR za42`$5ZQ0lGj%lfR*e{Or8u~CWxjoNY6{Fhpqh9b$%5E%$sP+sk?CjeY#a zjBrR7DtC++Je7MAP@!_K1yrcqars!Gavy}^qG7uv<<6M}8Pv^fA5xcl#mn0BelASY zV0NyFI2|--)X-EWO zk;b)%4>p)d1IGg&p4D*KHq7lrX|VN{p|LD=&IV*=gIs9q%@IE?{*q}D?Dzlyj(&-F zv6REC88)l^aea zW9gNq^ujUknm+UaNY7Iuq{r;&t%@slwnsuGBHt#>n&9)^!C;8?#{_S|Mn#UdFR5| zJ9MKHKhvW@#qnag;rO#e)rsa2js~}DcrT6tgfm1~@Ge?y`wNIyWmX&)k*C)@`1AD! zn~s_x7vm(S;yZW&tnB-!{?!B8@GlE(8ir!>XUM`qjXeN$N}``3`(ZmagiPtD;o5hj zqiox(9o&Gb4ExZVQIU318*|}m@~U^V`MSJI$1$woOfhzHhp&bC2sL_*c}A~qwjI6V z(ujN;9MJmoQ}Nwe7@4|2OVNZ`FcmIK05@ogLhi?QHyXed@Z8MlD_C<3ydK%@fp6R;M?PYl|>0f>bq z5`^qGNWkdWPXeun?7!0fJPgqt2mU=^_v%YD9;*O?lzt_F&Yc09_JqA#NEkrWeu@$? z7JR`z74B;z5@jMEujpJkiTn&$VczQ)%y&Hv4;9#cCzL@?+%TWIfgR>&K!C%0c$n^h zIH8rLz;PIHE>9ymYjRun6qg5Z2Hstj6V~~deaV=GobW=DbQR7lsI$lp(H9~tgGr>q z9wK(u?PpaQg~$;-t~sR;6(@GP?cXXQ)MR=^v0h$W5Hjo(Fg_GZ%@nyLQ-th>>||GY ziFlH8ZT54XKuaOUcIBnwsy3&Na3J*nO&Ojt1#8~%SteUjE6U;+@ex{wDUo&a#%iF7zoeZU~sBma1 zTIPr-9k9LqM+7ap;S$)-7t-TlQ0cf=y6)dFkPdoz2m4QCk=IlgaWGYd+h5ue3*sQe z_35XFqpSTDDoM#aLo|?&;HneinSIc~#r0}!E33_T(_IIx_D#+Bicx;Gr`j17T8D6= zy^1_Q_8pY~uu5|yMa4C7 zK8g@Nu%7x9(L+R}o;nxbafsOw_|3y_6n^M`3Opa*d)oZ45HC1xzi-?IN2i{uDOMFz zN&JwIR7@3Sj9nyj`K2b3dUUdjkqU=3D=!3ELO4Nj`-d zC4?F!q}KTz7OZd>EJ9&HuCL+C8i;}v`G`{^NVQr~TplSe=AnyX$r}{?7m*+K3-pa) zW<*s85&K0TtZQK?#u3F>u7&|)7PvZ3VJWHWSYFaHXR;70Qoc8`K*~&M6jcOnq$rhw z<0Q<%urTB?rRD8ZXr+q9|EWNz@^G#;V!K-&-qc2QR^?$pH1iTt*F>FV>x#80wQ4UG zApYbc!~(=$T!dIKZy2qzZbcmNFfOgP(TagRRt|AM^oWO0RB@skEpz4%2q*UfeCwG% z()uE;W{!OIqMUI1z3UH0oLqnZ!^^Qcj;tWe+#kuu+REUe$Sf!j-i27I74Jpuu>$jipw{_d7&nn+DJ0Bj$k*NtS#dsA z?L{cgrzecoXbk%${MF#sh~I_yt)_iF48113gi*bn%sb{7S6(A`FVcZGkwUt)4L0T4 zDerndh`V5NxF)^A^$SliNsr!H$f`5<;J|(a_d(qO2H1T;j=AMHTu$~BTpixYbVhBs z)3l5D!ZTSVic8c9Ox;SS=I&U5^~V?m4>}+MxPv6s-Cr&5;mmD(M5RS$3nVR7ZfqrE zs~XB$rv|YQhiWVe*Oud1BRsyh;%6em2)ySmz-1BDqOQ!qh=~3wCYx&RX2cR zn}qyVo+>;^*2 zky2z6MpfJwL*InOD`C{cebstM#4nkLi+#~oWcHP#(0K9>?~mwN7A5O0I8u@?1HeTL zyznh6c|4^!ki7z#9qgM7WS7BG1A$rVK+fAOy?$#HT2u@RSISqzQMz>}h_OE|{S8%2 ziQd`_oC*ytDk$p#;8YmZxLdvycgvTcql$?~mM-Syh=*MUN||_-3S?^L=k)ZfR5N1Q zFQX{o)Zw4-QFy`NUiZozQ^}+sNd0HlRpNZSayIP0kb$9)$D(X7noenb1x{`pcyDwm z+iGlN;b4MUIs(55_$|PX8&jUZ?|J;*#*Y(S)P-a5TY_IRej|Xp1z)zyPdLBEmtfJY zdk`wp@iJz|VwlD6;$MkEK9PNW-jNE8g6J*#ZsAs?x`Hj7QViUL znpcc^y-H+WqqK*8WJQG6F+4<=U*3XP6$fe>N`jfo&~cS_K;yn39;GV}IgvquWd0!@ zs$@bLYcb{LxQcREuR@M|_zf2$$=$!M<9%Q+he#?=U)}_u0+-OEwJ)i{_V!pg-tKsu z-Q@soEA^|Mb0Chn$_hM{R#qO6<2`OHB2Fx%&A_NeeM9MCn@U_)VMhDC9tuvWC<>rE7jZ}q^Cu6nUZegC102iMvwwh}sQp*w zm|sVa%_$FpF85~+M_TIjP;82|15v05wDJz}Rt)gSM@0J3nH!fBH_q&PBrEF8(YI7{l8`zK%GR90x*8B3mn=h!v< zc!SoG=Nb4l1B#W6*eYOum&ejZY&EdI&tqvLwgxvfvi$H2gOneM7zb}nz^K6+qpF0H z>?A@HH~TH*3JR0lnx3Qdaa^m5x2}I11i;mJaeEZ572P`u*Q%Y^OB@;$HY|10FdCC{ zY*m3YJPZx{T~bP$HVZN4UzJ3=E>?T-Elre^14p|)1;<}x<|-a`J?8PUui@U>qjVA^le{vM)j z>h>eBV@I(N+kXRY<@H#oMgSJ)ym0O=^FEL{^3tuxiGoo63dpek4hN&afk^uw~O%GAUPrKuM=tJ-oS@xBFL``ze$*B6bl^QauH&|Tw#^<966cROAHGX zZ@Uy?0YyibVz)!F$E6Spyu9Ng#InqdoRXRKXW{PvuaHM+ZG<81b-jrNh<9CtSO)0X zZ-KBmPlOHJ0vI+YLGjYLbw0NKD5-4{(EpGeRpkyWFoLzuTaZ zSAn5!eF9Loroo;>TR}#8_B+O+nREm7bp0-Eex-$lc>iKR^IJi`EigIZk2(I8G8ltRxqD`4=qk@*jE`kD7=U zdl!%jg$L8k40BZo-M$*P^z%=VCx)pn-~H4RwF;2gTRqFD81}CiNTrIG@e1@A!>my{dL8bk{pu&x%O$8x{VD z4oWohay~(j0I!b1Ot*D4De)Yu^(iAYOt<(Jre4`e!7D(?4S_}yhf7={-H1t9R>GMI z5t zx`74%gw4=Ly=-n&^#AeDPXe2p6dK)RUrcc!cCEs)@9V+x)k*}3{PT5Dw2a6t3X3_H zR`I)4p)q>OquCzygg$T&JUre8ipp?1r+1CTakdO?CAChmK^2>4!$8+7^ba01OBXXr<{99sE_o zptFknZCL8t?Y$<-R1?Ce*TY!(*5cCN{Gh9md6oa){UE zu+2{(|H|3-P4w>i?5&-avTIVQ2V}v^KeOv~xbbQ#x+K_fuFG8QfWJuEUkfQt|d5J49q79c_{LM%YwCNRZAEI^n<;9KN;4So?%u20{GFaPq#k?Dx$i+*%d z-|z2)lx03dMa~OGJ($N7dy-EH5)8_UONH z5B2BB_oUz22`{J)2`y=E&HW*A|3uN`!=(9CXy{_yOLnPD7X;cAq3FQd zXP|8EH|o0>_D=|=J_Tj}7rgLM*6y(X8}|BHdKUMPqPfEG04A;~G_AKd2pz9yKLdfD z{T!x+EQph~r%=_2*^9IvlNJuW1qDffNgq0VPKWM#GkgBmEAc->4BqB1a)XUrKxr2NEfSE)AnI z6;&)i40jP?x!Wx}Lwh+z&rEMDwEEWJ2m(Ev;rP^#H|(JVvm?MluCYZ2*Ra1rh=%<& zC3H9Le&oFcL-0lXVH)-~Oy`+;_6Wg^7ITcad`lNl|3Yv_3+_7ycf8;x3hqA+hm!?2 zNzBRO@;zP9C!`BrE+(?l{=p%iC4@7@Je>sgKF8&3!C{*fA~{D~eso;U6Wly8ZE@L8 z7esP_;4*^y$)Uy(GH_TVCb}#LK?{I-iJrw$FkH|-f!QSHQgQdu9l}^HxMgBqAuc*y zQW*oErj@|dPnDwv;oUt@`>H+H*AUJ5tJzLjS~3qAkvug$57k`MT8_DmN_D$%O?vj@ zPKQDq)kQMO21*FUCT)s zUbh~y*P_3|JsctM9Pj`S6>(hs0>a1BYAXDgBs82p{|RlrvPUG1%3i$tFgG;!sRcYh z&!OZ4>SFrFx+(*)Si%f)u01{jB(5)V_%FVg zg#+<%P0WB8CqQ_MG?W}b234ob4;9H2b0z09qH7mmd8FeK zKfFtO5`bmDKL|4uBCd%p*8LC?xP)PM@0N96e@JB_z&6oe{qd-#{)X`Ic^{ulF_Gzf z!?p;KK*M$+KSjC4_^38e*V;i3Ixs#6Bn!OXE}_@KdKNDenApEeP2zZ`6lm=5p(BcJ zJA93mOt7gaAc!*HJc1anXUl=96hBHf@Yp`@vCW@yZk)!@S>`Ja=7vGDxao3` zGe&<|vbL)o&o%h2+=20Z8+=FN?*=~8i8hG=q%D3?ZbkG0psUO}wlk=j{>ji5Lj@Tn z$#K{jh0U)+Q8E~xlXN4i$?GU|w9Z}NkKYfO@2N~J*>oi?W!UJ5hNE-QE|Z; z8D`i|g4TKf<$@g!`29Qm;`_4m?N0yG6du>_F&jxDyUyx=dvJUrX4t<5kwZ_bn`4x_ zu1$pe`S&y455py%SanVGH7vX`?yt0lLU9t^6y)J7t^%uwnQv^aYryyxt+16CC zjxN4%6+hRc9!_%@TVyM*0utVo5Uc0Cfxa%IGfY zT#uFUV*})3!#V=gyT`gs4c0`40l^o`#vmHewdxyNTU=;0)p@MS;O<>+@Ct(o(Ddjh z{||wVH+C1hUSkq-X;*!+Fg$|u2R7ER@MfDPyI+!ehk97K^Tla@e+ilVj>DzwgAi)= z9vFt)@Q>?qP?us;k(sPZN1t-y;*i}7v{L56HFkOy7oMp)5cyA!xV`K+lpQ^b{Y$3b z?HZWqHx#KhtQY4ui!_X9oj5!U!q#!X5e_|z%fs>)<2$X+f(RQqvwAx}N5E*~GSXCD)?39J%6XQjq!7ga2)-CyBT|EQiN$ju;_W}?-pf$8dCX)RR7 zqYITWt=6BN%9wr);h@SCDr0&y#8g#5wEhA;`)eZI%Gg|4jaaGPQ?L4EdiDvr<^`x+ zMT%?{dtrzmBLc&!XCWDHWS<4Sp8Y+{{XQ0uROTI)n-_pUzVm*Ary=udmW9N8W67U^ zm$v^;^x^*}XftsZzb3j^5283(lT-&_HxPb#)+$mNuns}+iAw1L;qgOsE)01Ps(84Q*)G65Dl&%TOHo3zd`2riZR zfT?9-SRbE?QVj_tkf5d{1vEhQ80=$lb3PnWbm;4Kn4lc+v_`n8zt>?RA0bR-2GF6w z>u|hs_=e%W<%Ih%ahPxY2TB|C>k!c6Y9E;PKp45h=pT8Z%et^yqaY3HrF~Pz1d%^j za*|&ceBGamP?vUWH(1U9|) zM69MJHo{a3`p}SQWVdRF>PwhVO6i;DH3|QVJEWtjAhx1&kT&^pGtD<+P*|A7I ztE7p!UUG;ZrovKjmp3KlG*VY?rzmi(cDU|2%#A4gt2B!s$a(NTun4L02#!QY!+WrX zI|8=1xFn{HM7}XA_=j7He-aqo3_aN2P;~l6rAO50m0#UzOjL z>*0NUkM-0awH66$RbC4gPRK3TdK0Ts$7Z8stnU^Kv*qh7x9WJlt9-GZ9LekA{u% zBw@Uto+T`bjC(CamsPg^f@CqFiiP(iT^|m;XwuUvqR4FWP?>!UY?9fGJM;Sb>s8#D zzbbAdW)@1oZWb~)W+A_B7D~Sm6S-RFe0o(LQjTr%P*_VI9t%h2+XQ@bOt$3Paj;m=DsBXu(%VMR$7G(;t2(|;hkO+7_in|i7{SRAyTGBnmx zT}4*(cVIn5EOhQie6qv2pt+Te+BrX|hNQ=# zK?HIE81W<|NJ~zK0V&WIb`j>i(@neyxuQ+J071|}4j<8@tSwQuyGeeLiPCLGwT*5| zyhOKqLxR+8i46_di}1-Y&Z65%PT@(_Q31&q@xAX&X5R zXOTl+M-Gf*j)tWD(AH@$0p6STc7RoQ=t4SaCykT#fs%IdglRwECGqworWpJ8RElZI zmBK)ZNh&FJ{LoFMm^Mrlib+ll&m#K?O1kO2knSFmZn9A6W-QyJTlh=54|CE@ra2mt z?!#NB`vg=q-gKYHst0*)Xc(SqJtaKSg#BX-AawlDTMr zg2Gv;iOBBG3|4Eyi}fsyv6$Y>$-^phy1-e_(oD=m=G4LxAFB{p!34AxZNnH{_y_F2 zph`!!1aj5%7Rxbg$rcp}(xVYTrqHJRD_+Qyt;`fg(-S9Q=x9woVv2cHYvz(M4AsdC z)`z|GvQc?K$+gJ~iI?QXkxqGFFgY5?mrk@ZN|Gp=o&DGAX zM07{-6bll=uYp;P@yePA8AuzE8#!Gst_>lFp2u{cQbaPnF-{r@MG8}6QB3z@JFTfW zi`@xjfWh|(6sgQ5&P2L@hj}y8J_TyDTgI%MK9t$oWXwUcKcW`+I7^x+Dl&NVR$gvL zH>F)s?cy#)9Z{2FoF2z=EH!OjYNd!$Zj ztP$JrejNg}^+P@aO`vx8koQQ-$%#Pi$RX^42WrO*A(KGuQA3`kBbFj@6k9!XuTt!{ zenQ2J=_uKqgQOkYS#93=S!eyf`!@e4fAhaH&^-*4RGrx4Y_|`Gwi6||lEyqvI+zkk z9+ifAp4PfH=>`S!)+RjwqsT~K@o0QiJ5DM!-@`sQ#QC%HJqOP9oPqLyk<@H{+_|2? znm*JWN2Rn5qup_opXOi)7Z5lanC_&C zNf;QV{hdfR$Snkf*+NW3>g?!|^TK-pBxWHpgj7`H91Ym(Xs2GlZqZJ;NS!?g)Sk990lZiHQ-IYtsR8j& zx=$MFJ`Q_1lREBfK`cL8U{gf8bsj&ij(6Aep018ZwGQ!uj`JK%T+&G1XfI0xu_4z0 z3Ekd{4|H21rf2)YT`A0=uu;+I(0Cn*^ek~ow+GNw&-N!G33aunp_Jza5(_1xpZHMy zBEr^mxZqfV_{idgA2aAEc%lZ{ourqT_`vXMlIz>?I|F``5938Hq*I~xclb3ILo0KN zpTtOX=`ZE}T!2L`$luBEm~lWUiZVC(J0rRKtDD7Bb4J z&r97&JH_WqXBzA+9`L~522kh65Yvw+M_#%0q@nFL4ezi zu}RZrjJ=2wIM`fZk+uzWT~gvte~w;ELnj(~aShxcA_+7*7|!;gti+RIBH8XZAbY?H!AYOvhlL}Y0W+JSh$ ztq`EqWy3dh}`5|;n>yrMIuxcYsp}>(+^^?G=9A3elmLjc z8zH*Hd6?_ZVM*7Fk8t9TsdT#Xh2~r%{l-L*(0&bOD~W1F^h%Mb_)iuNN=7ceO+d*F zjqE{TdL1kWJqm037-*d=Ks&;1r38WWyqoc?W7jrr)Ly#;>a) z2l(}@bE|lvHQZK+6g6AD=_)%MPQhxdQ%EY6u2<%y45%_871^8nI8(_|i;9dzMO9=M zuo$Bv^R|f_QJ(nowu!31(jV(IDQa%B$DEM48rEB>e7RTk7Hg9>^_H-bdTSv9XT8OO zmZJgtP}*70VINI9b4BW{i$LwEx5fhRt+&PjR`ph)zek$?zx};SC>h;a%8%O?{#<|0 z)SiU`_La0VOizFBdI+T*98ve(P9^P-lZfltqd=!Bv*Tc+^3tIZ@7J+@B2HCi6X=R{ z1AG=f0Jq$+L}Y0WdPDT~XjtvREHY;)JQgurluX@Xo}s%Q%pFOOF$o4mrUL_VL;aI5 z`UQDD2W$G%g0AIRd6$$`IQAAP@2h7C+vl+~=qL_Y^bV_#tK5)pW?+s7 zhg|xB&*&C~4*evH_(&|f;F}nf9{Fs(IOb!+TRWv7D$#gK1D{FEmj)45Wln^sges+B zt#lEYw+M~0R;A%$W;UDkR^{PwNQysid5}yLhAa<~TT&jRkEk4(2s(;9+`_^<@b(eW zRYV_=9#nau7Pl!c!cEG{5=4*Xg+j>DfPFme)Fs%Dp`9|5^0Exnm`}eFpQhu1tRI`c z6oNFwR8IpG)&x%kfwweGq6f%3V;W0eL%p z1*kd8%LZy_hnz$WGhJ|3=05dX{##ICVyGI*D#E@rB~_6^ek#* zGttpojOg22f+`hn71rtOkmAG|Wv7DQ-vOu4JI2p(Se>3;?v{b{JcIWtxBC5)qh){`CO3N)$T9~6KEtIq>Ei0MD zZQ73ekRAMa%Zg;6uw!wMoRZ=o{b6wwDeR9j$@%^;#arkP56J6?Dks#>HswS(NjbR+ z5o0-_jB+$!pG-S-2zJyEW{z1T<>We0d)k$mz44jgrAYI?%E3*Pj&9w^&;Ke1 zy7ns6r$N$4-Y5rLKfeft;0fwghn&Pp&(4OUDgR zQxt>rEMcL*c>YY<&qN6b*;CkXaLhD|^f4jFm}xwfSwdAFrG|bKcL5+h&;ntu0u>d> z$~cLMg(KslRAdcP?;R(-^ipA*q_~rqdLaoY)S-o-=_qk`>rh72twT8zkEv5`ze{QuH6G-TtSOAfjm9y@3X;V6dXBe1hv?O57a^; zr)SRvt;+QCVWV2mq469N=~?1b-DuM_dmiDr$o3=;kQ0}iONW^FLS1$W{W(lriuvM| z#OO`*4%$axZV@LogKG7MuJLn0ON(0CQyyq0dMUgLD^=w}d0P8qFiSnD@PqC|N?j6$ zH)IVF3ZoW}3al4${k0^N7!;BfSWnv2_P=9rMIYCYRRXJ=1n$YXsf#B(UXry=D2lq; zrJmqYt2n5w294jaQmo8LTq<))vLb0I50^`o$$SP4(W*SGXU4NUc>CM0K-~O!>rBa5 z$vLXO@O9Ond6i!q9hlb@rTf&*Ho7mYMEBPrbm~48AV&lCd9+i1MECCi1!h;X86afx zUo69n>;fS4?1eBn@o!`o3cMJm+EiIsqhAIbx*hj{Q`42S55#Wp?@=Myukq9vPl|m9 z$g`?H8?B$)*C^~iB9>*!v;XJ}pbk3cU}&46BZrAB=+CJ?&qhIMq4IRd5sTdA?&d6a zJlh{*D`oCXVxj1CjgLa5K$o*%6zdqV@nD6lgTcG(=K`Vnm+t!hEw>cv!vY89xx~fIbB4!t6nnLGt zl;HjYk4Ud4n)8rHBKfM0BFb6E?I#OpMCjQYV9JV&Y~aa5xixf+pyMcTPAKf(FP9!oTBGH&mz+^=apPFRqhbKY58 zTGr0}Lf2lzu)D`eCuohk3=P||v>r#Ebkq^}jsyJNdcdR3wPyk5A7*WQC$D=b9;yZK zy{`dJpG)W*F8vZeL|l6go65K0_Y_DVX>Bp^IMspJh;GO?2s@`8v8_d$0=FMv{|)Fc z#U%Xb4p6%YKaNvSzi8d@!_Li1h==BC`)16>o$go6qWSshG~?5!K2o7QjkyEAwsU&7 zRetTRSu=2W?(CU#J$fcF2{C_jI_*EqqS;OC(`V3r^Yk&G{A?P{c0xJy^q$N7+Ts~4 z7x=Z*a@zm$GR=zVG<&Y0`Q43iydrhZCp0_GCg$pC3~}xWw6ELn0*;_ImyN6OYhRT1 zT$a^}FrV+&E}TWzx~Vi9-lDli!n$tEr@Q^yCpSjHZKe2n?9TgeC*Q~L>(?f3WGGLz zqx~bqp;TMgj+{pb<$?;@PrsP1=S-k^{o6g4J?w;d^_I6|e(gojwAXIfH2x9477@R` z3Q|71j;=R#r+w&F+SekzrP>QQVjgJM5AQO5JDT=fyGmU7+2P{K=c3xbhJSxaRQqA? z_m|XYGhSb`wnqEg-bHKS7ooi7gnL8<{caZyr#(v!J5Hr}%sVvqfPblW!psRv!`dMm zYih#UZZZG0f%ZLOUnJ&dVqPVtA?6uk{v_tjV%Cbe@OAnl}pQ*LHo$m|S#Yw^d=SY~$=l!`hf#^mP{KA;Uqpa> zkl068_FUFQ`^~6haBc44lH(VCL``T|Mf2s+G}HIfybXS%T4&^iU)$Hnv|REX@!vl{ z^Rn-0c7m>U*B+cn{ds0JX+FH3>Fr)|1@h~V^^D2oV`z@wK-Y(mN2S`iOQ$|ks_mOh zbIlN%PmiSe&}N!55$<%I`W)6KwWH3TP{~w>MgM~x$miYd3~}i&hW_%bcuRL}1L6Rl z)0xKclCJk>OocZ7RZ7!!GgxMukD#w5_tQN8dodx6Qf<|)2}?`08$Y6X`qeaF5&MbH z(mv`MnvZr)b}Q9>+C=;M%{1TKM9hcJ(Ej{0$!=lo5|o!x?PTG0_bTF-i2W$xd0`h~ zw#=g$6Ale9{o4FdOwlNb?XyxAPDg(EwI5M7!`hCM!Y_8w=6!d}6J50AsGikbw5#5t zIrU#Ouf4Kob*XmFXQN&$)%w0P3OO?B*U^@!HUVWPs=d9E=H|&Xzne(&-We=YYge*N z&6`Z~wU23Df$~+OZMlZ#A2-uHdpONr(`eShHL8u7IBg%XNqA zX3Tmx#X&c@fq+ONq`&89!OfSET%2B6ZqhkFuObhtmw)PCdVG zljy%twiCbCiv5~)EVBc5F}+WAr1`mo6@Y%0YN0_i!=F+gQkSrV9#hU7-&INTsO2=@ z`z6il2`stKiS*vNk@1`=@;pt-e&#{)slJ+;-+l%)eA_gdeZ>A(u|HMu@ZX__JE(^< zq)vEp8q3jTQi8Hl=U?_Hef>vD+2ztAOoJx-wFOtrL@NGpF3l^iVwt*4Fdqo!jMIqU zvYNH@wO4D}YuZz*uysM3C#4`gks&_clI#X8MVw2u{Ze*fC}ju>(&(byu!>s!<5ZeW zSJO0MhP8{{tU+D$qG)ye6KZn#Dw<=4(9DVX%{8>&{t?Y>;`+)>)b@VW)ZwjTXtoTd zCjVj-X$}+f`VYm|PU?17=r;QSz0m_{YNO)EWmk4S&hH&kCazXwJwAm)q-hqZJ zCKMB>Oq(%l$C^1fkp@citAmU5u&lJ*8bOy9LPGJTEWR;KNc^flsK!BT`$Dlr?Rbrqf^ zX>u8(4VKUw#cjL;eE{fG+%7qsk=BlWX2+UlY^WJ4DcX12jy3DGOSQ{{%eoeFS)n~F z&_dza0*D@GOr+bjbVKM*uA{$OgtAO)H=A5=dPY0N#}r+%oiTe(n2(hlF0m z>==0-Azb#LW6SU!zK3pm@M;Dn|3-$f{!yDM&`!}FT%jURTHFi=N{AK&9O%+3=&uCO zQpn6e8k)7Pj@!7?=$7<7uQM(`y)e3}SvwRE2|!Y!eAQSxSP-vU!Ayxwh)@?>tirQ6VDr6HBmd& z*H0+>KRddrk8cJcxTQCbu1fl5`VJAd`>W`0rVrP4fM>IWzRY)}(S%r+{E2Q?`EC}< z+6M`3_uV2~{&gHfxYu_d3X-P1H(~l?6EU}ZpAiIf!CliIJ0HD#xPj;DvgwaCYj64< z6R7{~3c^io2w@i7=K0?By(HoFc%E+W`#uoL#I4gGJIVLH52u~MWi+5Oe1G?SB+#&3 z(;vIZ_YdDE0)6zK>5u)w_kr)<0;Rqu^iSVU0$p(pd4A}Nm`u^F62iy65`n&Yfo}VJ zmO#_QZJ#fNQ3@^lrJB@HF(;^arrjKHUqopdQKbG|Q^k0ZuN5r#P z^XbP4H0Di0rhc-?(qD5p<>J?8N_a0w=pp?qp)3QJX1vsZ3lI>(T>=&BINys9CJ&=@ z%k+%6tyoFQA%x&I^&Pq$t}havf0Z~v>w`qEbK;s>#Gb&z98wf2(`ljhU#O*=Htv4V|%Q;YAaT_Mkbo~^8 z{w@-ntIIMBrc9l2#(OS3jxUnj|BqFDu#r znSH%(9A+@i)~^((29$)Z63SOz8`pB8ezx8$&@|z4o_B zr$BKDJ)>{Mz!JRQwrDr%rwH`fCv;n@ z&+t=%JHb=a*6Z^Gx(IP0be>S2`d6lJy*}U1e1G@kaV-|DLn!0ACiw<5;~VfF~nhd+*M z*^XnzD}+lFaVgd-jo$^R^EW<7E|tdb1?o~psH^d|P`)L3)XjJ&z@ET_S>syfXx)wX z0AV95D3iYK#@_^bc;V``6XEuOK)*^8ssqH(&sep3?I_Kn8zAeM)oYuzdgBLy1__if z(D4AzFNI6WC=%$x^U0-w5d8h})75J~(FZzE%dXXHw*U$SDW&RmtJk808kIs>dKW_& zXmkjwR!u=w;q^|~C&esk%ZWYSOuak1Pv00!Y zpA#Bo{9T~by47pfYom>#5M%a_Evwf)gU4nnL*)7Oa)x)bak#jx`+@$Z8h;5feTz?G zicU2?QEsytx($d@`hIImHfWr0VEZPZcLhr0c0fXl1j-oLaRTUEfi5rx3v{JGzcjFN z3AdB7E!k#mkufUV1ZW%FnzgKPB0GKB84tE(CjvTI+$LW|w`G9nZ}f_mY?-m#I7Og| za4R#eFs2I>*~XZyFwPX{RSEAZV=m4Xmuc_pSibv4ZKZLZKsO4s%2+7SW!vbs%D6C0 zxtL`Nx>%s9QxtT$P#(WsLCXc&CD3(7i$LRq=Z(f{fr=gI7J5Rzw9^-5dQncSpX+h8NQ3DsC z!tI2uE$CG~1&EaPx)$`Pe`{PHX##ZN6?A*Wz@40c&VI9H&2Nm?4BX%e=sr2N4M7L&3c#%kzU8IfYcS0?wqH*30CT+Dgr+;Mcn z6Pm?Fw=(VVYC;jSb1^C{?UmEe3&Ej-p5hOeUBIo@fzBx<)ZOeQZjGRB)_R(jKz-2H zYu0+3^~Go^9WM1Io?}Dk7YpT~4#bIV)L>@H6Z&ChKcQ@q@CKWQc-)4Vhl$&d;_q;C zu%uxb)(M)mVdhYe+X!ql(1#MjNb@Lx-b5?ktc^C0 z7RZlQw^M^5Hyl zu1I3rU39a}bH(jMaZ8)?1iD$$kTK^A^gw%3E;Q2;!dn7eU@j0YEm*HY-D>_)C{LGI zXU#Gb>Opfi5GJ%vGXUcfUjZTwz`>lq!!_0g8a~(h5>uZQkIK z;5FuL9_TuAgFsJ9%x*C6@VMP%ZV{fxNdDbs?i8p(B(cuCUqbIKrDKEnptyaDm6vAi z4nRdHRg(~Uvv!xc%foYv`Iu0CCVF;{`LsaY{~u$29oJRz{{Q21(kC_wh>C&TiXEtk z9V=Lfba#hhgDBX-qFC5iYk`W`q9V3p7b@=BYscF9y{`3+^Ev(EwcR5ZaDs0Qf^DySiWAOP=dpeA8BXx0%s~6)bDXsCcR;?t zTj~9KtouQ^klVD;cv!y532rVyyd&~;exw`n{*ou(8l9EzaT~rdF^?6>4@=oD%a1u_^VYp8KjXBY({=d;C#~gg%C9+{{?cR2C~>$=+~!E-Rb@O|UF)~`%3tbf@T*}THP zXSXl11rJ$diXp$rb$H0nu%MjBe#wovZ3;gQg3_2%GoGeFY0YUWrwU3ZPS<#;t0+A= zZQ*H}EB$$zpPplybrm~K$Dl0f%u;dVAwTd`EEUgE)Itg7WXyB#q{No8^;4#ls>5() zW+~f9WlkybR2G$@KxI`0?2%VzVOgS-O`L+Akz$lBJfwE68?S8Tq>ZBq%61^eVtFs0 zq-60rq`km+NkCP>mJGFp6^fG02|P;Chsvet$bUlq4)xRG{d-g}6+D`&`O#dU>@8K> zH021l-Qie!uf5hj`!I&ZA0vW{$T8AM-?14}WXj|3e=e@bR8% zqx!2EU8KPV7+S!B8@VfS+1opX} zuZh6!f&QE3NU*jmLf!iw^=a! z%?1sN+6=lrCIGZkOlQ!B;oCq*j&%Xuer@NdcFgi+F1XuIum?4c?E|_pd&@ zQ_$8CZ$K|VT#3zijIEI{`7`LwB3}~-&(m4K-RG|T0{?nZ1_z0qjHwKIG}0V&Zj>eH zo9L#XGkF_&y=)8a;W1r7yF+_QEM}}N+}PjJeh_GA>ye;^EysWkYv~61u4Mq|q?Vze zds;_1ShBmTCV|eLk^nwstIq-TO-KRVYQG3HYW*??D>n7{Duyfhq~Y{>Z?AeQOTPfhQ$YF zYy(|4X^R0%m<1*Iblwqqi%s1vu(otNkLu6$x0UF&>x=#H$hsT|*{u71(0++WpiPF@ z7JzE4r?scnZdyxfEvEHMuXT7VYS;Z8^#AtK(*465z-_f$%{cu?%lI_?j5A z>1|&-bYz1AV#{`9NzSORrlGE?gWBgCY7?%vs$t*m4x>h5=U}{GZwvsP2_p{s;VRI% zFv_rnGePUYxWnGq88ik)nZzCxeunmMmNgPIVsikf^QJMN4cCQ&dco)unA46QP(mC* z0v|zGuR<(8j36jKj35~GFoFa=f=cSH)f&f+z(-R_eQ^Xqzs-))d#tC^D(I6@*{k$E z>1LA&KAujQx=&R0GVX&~D|ngif7fms_?)|hTImYv<^Y#qUh3fbg)oTw|7t}^aZ^1~6c`J@? z$KJSzqf3sg)*sHh8i7wgIFAV|i686ca5gLHA+6!ug)M0fs`U!&KP4kND!bxnhxoyD zQQH-v?tPE?G#54N2kM8X6(Rlq+e?qu$JVxLR28iL&9EOPaW(E_4nFIfp%!yJ+zdm0 z;aayHhU~$0ce^?mvh6D91146D!JWXhjTN4SZnZ^S(j4PDSfPGxi+Yf2&E{<}{f?M> z)dSX`Pfzv&b+j1@s$G?qw;2I$6DwEH1g`7b27tSb6^6Oh7Ik-<$k8~8CxS*~#g8s& znY(r~pzb&Op?>N+1FSn=&4%!$uXji5M?zh$bV9Xij(VsAs&*Z;YP0~t+wg1R|7stM z^`#kV>GoOQHWE_MTHsb&JU^Fi0TZhwU~OZC{t4WzwbEZ!IQC202g{JzA)uSUzCld| z_NqNvr!>cNmupRQuWo=^rGc-BC7dy^HLx8lS@nIG{%dng|EKvnXb1bjv1Oq*{)T#( z>ol&$+`kTY{~UtW?%eIb-O*fs;~KoGU+0RA1>rm>r#M%SCn0LAkX{4E2o>Fg=HsHXoO z{i;yknd4C_T}RE#M2$;EZC8Z4_dV*XX{ZA~SJiutTIUe>JgI?tk!v2P%62W=Vo+J_ z$*Aq#q8{0c+QSFcsSE1k`KSlDe^>7R%kB`A?Y9?>&^H!z-eRzVZ!8`gZ3PdMqPq>u zX06!aYN#gMeboZpKe-R%T9Ny=Nkad|+&%dcx;t}sIY?(%{G&?+qld+>4MO+lJiPMm zwsRa+a&&wuK;;mO!w`7+yZ-CFKDJ!cRGXZ9~#w>DK@n~Z<#NlBLW45EyBXAFFegpJ}73$#@ zs86|uw?X%uM$bVr8lq-5LA?V04)MGDV?Qb2`WvVfdys|K(_c_pIBy(y4<)ZL73&*s z{RP}V8{tgye5>c+F5CJi==s*n0L~8c=I%IS^jXN=vw8R$JiImcPvibKOfbwk?%v4VYq@(sU-bXN-5>g(`#E<9+o9XQ z(^+&E-6`DdJr&)JxqE3nbl>ISm+><9=l+W`(choD&rU}7%<-s=j-s}jR>cvo1=zMi z!zzv?t#Q|`8d&o$p+>(#olviuqZK>7)B<$V{-&Up3tL0WD}Rr#W663hh^Qkl@24xP zw`1`IHjcyM`&^4HJ1l-Y%=d=H&*Hk2>sA;|!{VF2wSg3>o8pLw1GQx9zWh@cj@{?i z@b~JNjuji_&>Pa<2ImJ@M+9uE-;ND|`B*z<#nm5lSp0oB*2Cf-|BYutn@k*QX0W#E z$W9;W-q0bwZ7u9$OJQE*5MOukHn<|&*FxP|9p`v$TaASDO_z>=7C5>c`_<{~*so%4 zxPgx+*LkhH!Cl+{&+uiM#eoiNngHXg`GElN#}ov1vOQki4#1Vpk_E2DQIpQ+=l%bP zfb`eAiUqCCuT%f};MHvc#O>dDDwg5WOwdM`R)OAKl?(di=0VWn6-OaVr8d~l@#t8w zM@tL9|NoZRw*&U}V;wI;_&$8RTf@rBlDz{}Sx&DTjw+v5<7gV`V8!wZA3|!mFh;Cc zIoIcqra9LRy|6B0+6FZi*pqhX9t_tPxYjgAUC=26R#M}vUqg7?ULPPYdp?)g(^?oK zu)e$u;VrNv+I)Bux8CNx>$gtWK4(W^Pdg1~4}q=QiS>%usX*MZV1*S>OVrdR81h}t zM6kZj#xN~;$j7b!T`AwSt1t#fE9&0&sAB?9XO2f*@&(nV2I~AisF}+ujFH%c-Z9$y&<0q;>30oA@1Wh@C`iZM^K|^rw z8isY*&+B-c_Y*tbXM(tPXoIz@%G+T99BYAf=PQx^JiOY$&GG+No7C8av9L8t+Cggp ztu?S6N>)8R{jr3h{@CU({m{J%#*4)4?9pxEgk`G_xd<$T=eV#X&f+HVRe#%-ts$36 zE!%@?W!}om{DqgcW=l7-t(Bh^zBK9`51b1T?7jV66(gjir z;~G#O-81Xsm?}Mva0F?i$&$5#65=_e7lbTsJ|Fz=)c+k+8y)pp4+8&3t?b~qJci>X zu&D=eB=*^ZePa#R(k(OZB95sS!?D&+U*K4%oj-C+eRd|x71RgTGBV4|@`5zW@g0nD z33$DjFvWiioPYSZYxGALxUWHYV^(!ufpPdpMt~B)`Ek zOfjexo6{?Lj1^nbYX+oXa_4t&JN7!*UK_I|XID?B#n2~D)m%L0U!M%_lL6swE@R04FHjep!}E{V zkq=PoG_I?-cIK*Z4d>d2>twE#xE=df(|amlE!rlGE?gX-miI_o8Bqob%x>!F^VjJgcM!&F_S}tYSW8ys!EewGQ;Ua# zzL+~2G{?~e)X~NhLY6t;2YMh6^?37eZjB*-EB0x>ANV}EJ)Xi0i(kRZ)0peAzF3le zy!_p`mg8m1o{S|q#*e~Vem0v9`zqM-Q=kneeog?LpNhJr9_l)-E4g+vMIYZf3D7=0 zLX#kOpFie6?u*vp>{@7=0xj?gX5dzAbLG=8pSfQZ)yV|4lIiKucuijfv1U(M2C+8q zSWWp{WsKuG@R{Md3AD}2ZJ_b*@htZXMxwx0gr$Jb%?>+3TQ*7pL`#ed~G(3#^=+ZCbieUCcv zGwP~3sA2U`2z}+8EkAh;mU4oK? zKE)ahcz}vmD=gdT(d~q2Ayp72(%G<4r*ui+(~5}0)9AHvb0gZ zVAOZtw+h_C!Pk&Z`9_#dJKheh_*}xJ9quz!YW3NvBdc%r!wH^R;TaT@kupbNAl&=pI}bb+13_dG7x-7u`|WsM)pe zIbdm5R##bn*x^yx+I*Yx=mTe}|F~Pj74W}4kBcxC4^MYJK0Gyo6;sv^)W5j9T@kup zbNAl&=swTgPjk^dxGri`wh^peC&8*sWt}e78IA4G9P0ar&<1owxv4NGywe@m*Y(Z1 zflr=dCyKBzIvdxvY@BCekja3!lwLp^y9+jAn!xK!3SU@)}UL|c1McUW1M zw3R7@g!h1KQCGV#3(WUpU&yyyQQ!IyE4FNXCild9Km~t~g1FCWOteth?Ji?MOS`p} z|7|H+W0tN34O+58SIy^Jt}+JRG~qd-TC$rkr?q5l9HC!P|H;4PB--|S37eUcKp`IBVFGklx_XO~_V^cwE zsQemyG{?2jw-7G3fHWU*n7W!z1cV455c;}a1A+uv%y5l8>*!@2(_Ph{QoV9z{1Oq1s|=Zy-l#b54kom#Zr|{d7UYyqox19YBv$m zEFCwoJRarXD*vYNPt|zd=Tmqe#+CB_N^=pUsijjo^DN;1jlH^F=<^(m@F2x{k=sH?e8>mKNyWshol8?|TWO-_wiLzoA`d#tbC{6~*d(3$!hf13aY|!}F6CT}*b?0a{fVvC$lzVw8E6wxWOY-ZY@&f+tHAaVIe@JK zJEjpYXGL~XClgnATb5HIYdC4RREgPJGWaF3A&YCcR$|XMrLpwabzLj7&qSdU8@U>@ zz4b6;8hq-aqia>>S|2IZJTYfoO|$=$8XnE$zXIj(5@&p^U!w}GR}Po{rO-5_Se{Cf zVgG3iIhpAEX;YxmZC#BeX*Q^lDZI~Cy5-H;B8vBSjjCdGwu0zgjmoS#+d$;gx2jl! zZ6^xr3r`)gT%ykDRmGa@2+@G_%J6pEDI#ICM_CJo|1=B7-B4|G4_6Czi>Ud{ z1ET&H2LU}N@)+Y$wl;f5G;T}}*V_2qRi4Txh*yV|B{C@-1XP1lqM@a=y=z@ok7$6k z15gVJIjXxevt+}Ge7lz- z_)ni`$+l9w;wV?wR_rp-*C=nGVxm>i>8`Dr+DNO>zUT}f6Qa&h>s;Hgu0$iEHUSMF zY8AQN)ry4?^@-dKG>PbHVY%S5t$ULAdqP2wuuI<=fqU^#;K>0-eF?U_tv*$!f zF@FMmCfWtZr~|9rSS#l#I7S^<3!)lhpSpHr!-+bLeF@}26nE{tYbTaOly>b4&_bdz zG0d$q+fP&{MgclSbaY2Kw=S%Z==u(0pj$-eH=4V3Wea;sNsa=KpsSY#jJ7b!;*-;#%usuNMskj)vYhvPZSWI4RngA zZ$z$JKlX~qIpQGDccPxL$K3j}dd;-lN5`H7YD1J8ao%kJb0E49aT&;m=t1~Rw}EUn z(bw?1Kud_io&Itg#5NO6bb1D~o5)~J$~F<5TmH#yD9hn=!f<=} zC!?V(muxdeeRH#8`9zzBdz7_fmpCP`?h^%fJNB5U`H6*QS2P2 z1Xj(`7N|iREzQgJ1Kk~17N-IhWjw>pfgLBRb~MG{z^)UyP8|UupAo(4;|lb>Bwn&F zP$er&vw&Gc-*sU1h1Lf>Q!}J`?st;du+KWUez4AmoQm z8a=pW>pq$-?5vUPTU&QWHl~Y4gQnTKk6}?nU6O6xo!DHWm~po5&g@)QEu>GTt-A|* zXsuDQA3Sx&_IB5(%ynCLS2hbiTm*9lR&ia$hHh*zQPR@GLOyDvLOWI86p-H(;;h4CH;t6}C5z}jeJWDGNp05+1y z4rU$!ERK`buLIb0PI%lmxCgLJ8X1};ZgUT0Swx)^bAV2AN?^0U!SieE1<_eM1xU8V z+!I*9xWn$jY)x;ZRQB}z3HMO8n^OXl;qGq~>()mL=~Vq$w9kJ8=HG zdn|iFlnpeFweN?v0*1$SJZslqBkWn@SuY~&6XTg35%!ny%!3Gf-FTKaP|Ly3w+KSI z{H9ULqCedyut}Vtw?eO*$Rh1ETNPLdPGp%xUHpo`mOMhs9edp*wulIO@+7v72z&A* zwwqG|>o5)O%rT3RTAFKWBh4dvzuXzaRCoN?4@krK0yZoJj^5HpgJVs+~BW1a0)ayIaXLvFkZOt>@xW}`~ zZW=vYm8rgBW~8B9-lPW**a73J~U=QEbYRSnm*xQi}~9$;^Xjk#CC0Y<7>R->wvsIjnA| z7SeCm8~3>^pQu{^+>>N4iEN>?Tncp!sZM zxEAkJwIcTgtdLUyTLSS?;OR%SJr;1TpTgQ|WQ2456gG+o=lUtkhf|UPXVfVyga~KU zDJ+%4L{ha>~e))ukKL^yLyXB~-f=9td<5aH}_F$*HX+2LXqM})JrC2S=T&eoQ& ztwcD3U&<~M;S7E$D<&GcZn(6JsZm;49M>sq88ac;40GY-tSiwTme^`E|DN*u=WTYH2PQ zTp7Ma;-XVm^FP>mPRGSDaMsw$u5n6WHIE~`;grw*zK`TF7E=M*gcMFRxhv8XP6_PI z)cPJ<*<4Nqtb?yR+s@7sdBJ$!!Tuy#2IGAP`$9DRWo4iW?ih<3 zuT$;g?5a-vJ@Q%Bgc93Oj}y!=v4lo>6tFQmxpqOr$mV7?Qxks<%Ii7!5-JxC!NN5++^h@V_A|6c)q^Fs&Yy& z^jN8|JIsP?c=j%04ahbHK2TZ2T9OS*eV2708_j-KLY4x*!nx9!7 zk5?dEf%*Iwx^fj5t%kYOzf{!?={OIm?SOoN?-pW0+OFRhc15!p4!Rb2d|`Jqn<3Ig8|pRzt}V)T>JiFbBJ*5%Y=nQ zxb|hjWljY~xB?S|+eEmk6NEpBa6Kjn--&RICkQrEF~0&M>>+}%kyDZZSD%8gmk3v% zf^d{mBKwkd&O;PlaMD^{63pW<6z&u$MLXtJxi*e69RN*G40s-g3WrVpiHQS+a?>x!~-#HZsI7>GOS+g`- zuW>&-3_`$cqyhnF)J6hK?ckTl&c_)%jfCAqzR%$4VBrK&#KNkcWreFm&2OX4V=l%^ zVzrkct>rYG<;=8zgS1Vj>Yn9fjxsI~Z01=-xXLKsjwh{i&LoWBU63$V`QC%}VI|$`}#~f1G zsIJk*orFf5uqFQR>@0N9X@_SQp^r{iY`Y4MI_>uCCirl|vK;WV7MAF?3><+(&q-(*w`G!aJRwc=i{}(@NUqwdWw=(?X3>Zol>% zEC`EA=!54Fp}bDtJckOMb&|d81z(*id5sVvbTacACCt^Su9u^*M5m@+&cZ=XsVptN zgO|Htk*?)8y@rjKm(WP3L0;ZM8=V}ye1$Ng)wg}T0)#l70=)u-X*xxC1q*X^it`E; z77?8qJ=H5rSfSHQuLxm-9x}}cG@A8@;_z*3vamZ`3 z5TVm)uPMStoo;x=3%hlC;FTb}BTBga#%sFpU8jG%k_49}S`HC4etOLkmJwade-y)UHGn3Q|~mvuvAO)ubx)ki-ZA0Lwk1hULp+Bsh9Us z!9}M*-phq#BG;ZHy;lk;Iyrl<5;Ao1_Ff|tang2wGKJFftW2TwJS$TuJ3!WoXUyivK7~$^u9>J0bchC0-&4_TfK38Z#dkn{gVj{f9 za9nsnWCr&N@`WlZv^wCuf_$Ma5#B2}A@n1{dj%(ikwiG>D-b3S;he8Pm`Q|lzLUas zBAoM`6b=&MobQzIClSv1P6=;_@IJz6!EB{g7QByeT4+Fo_X^GkgNX26!5P7k23qA z!W&MMhjOkB-rhQVqX% z;dqe5;Y8SXWznf59`s#V)b1Z0mvE0o5hsxiM}Q(uC&Ce+h^vXPm#g9?BJAa=m`#Me zyo`8^2zz-M@hm58g<=q2b4uj%WP?~S3u~mUR}7*(5w2H^#A8IbUNI6e9IjVz@5xBK z$ZgtO*hsuVgnLg$;sc`hw~(F_;ZBs1_QvpcvKY4ubHI=m9#zEYoQ_Mb zGn0I(itTr!ErD6OG;yyc783b&HgPo<>*Q#*v;=`w7uym!j85^XE`|`zbvALWK}R!R zz`eDaI^iCf#lHl5Wd9QGky(gy_h1f*?1!s`hlS{pi&P-su2?P6j|g|gYKajXk3bHJ(`p%%O|6zrEFVzH!DROdN(hXgL~~3Vve3eY`K=DsJ}<6QfUtLXkCg% zd9)Fa=<(*cS&8>_TH@1I{GrntpLU|fUafUI`2OM3UhJk*bB_+9lTPhDI*Q|U+U3(p zT%yxKpUz^gPA7c2h}U(x;L}z7sM8IfZlcM)lKhH&ti^UZJ@e@<4%g{}PY*Ftr(Zrj z#T1>&`r3#)bTakrC0@`ewzjSKr%o;&y~Xc3xwAfEv;A7`xa-$fY)jMucK!N^-8gBh z-TvYrPTFd>zv#m$4fbj4`VJ7k9>!EsS@FW=zJo>cBS_O(U)SoMzlncyN`%KVOkC~6 z4@Ai@ZtbbhC$dQ|;jI(VC=cT$vaF{ae20m3h+6tuc#IHRl@OF{q&R>mw;0}}5l3=L zXHoTf_>K~1>NLQ2w0M?ig3B0RC-J6E-o7rP^-%^tZMV=}?88ahEp!)uBOC4(dWfUQ zhP#Cxq8r(8FUV8$BOC4(dWxmz-d0Orab$*KuYc z;u4}gbxeWQ5aroN_=bv`iB8*(1=>mU+oTz8Vd8!w_et}BjuTA3ns;#Hz= zZ(Q9Y#3G_{Z`*rBh>uF*CAqpsiZ6-gB(?X56#pSQ3brWmC((JZMTupOX|20B$r--h zTZw3Ek|~fm(JipWh;@lxfh|UCO7!OR47XU(ibyy!52!0ql`}Kk#)`H?^}#k)98A>b z{AAy8;s~N)=aYb3h(4XF=pHBf5DBLffI^AJA4u^XFUAthJdgo2g=o&96yFJA649DN z89)n&_8i>oJ5gLrbn&3A`$TayQODDpeJ6>Vhz6aub)O_=6Ahm04Bsl=M-({M6zCX{ z#UW=lMLa{)^^hsh6{4A^o!M0J4$&HTws5NWkjM;d@!|`jMqrB#1_{GS z{JzCzxr7P?Q`;|od&pKGsJ4RtUY)M=s^ouAY)z?PFE}K2BEnv9NVFls=V=d%1Bmc> z+QZ^7qRn-D-H(W4i1yUk<#R;zB6{}G*F8@RBKqg!E}uLxnrI#DrNf^F5^Yc3<#SY= zPW0)%ulq4^E|F5a%jcN5hzOtGJua>w!smC7iyMgY;2ErZaXZmzdo%xhF_-8I#5*A# zAyO7sW+%i`M0iCg5DSU$iclclBEl=eN$~*@UJ*`;&x!Dga7uhfgja-9;CqyI&IL5DkKUeMwwMglFN)Vg?bOg)fWiiSR6ZMchV&XW=X29-{FFEd8&Fhlyq$ zXbE(ZXwSjc?$^YNL>CWs0J=#u=a8lUb+MRe&7qb+&xr79aYKAdgjb6j;#Z=pN2-c9 zMe(|Jj2;}R%x;S1i13PVORP$SSA<)l1<|Be1Kn?n4TxsFGV{MJwj?UP*VX@y*n#N9 zJsY4NM3?q$@GBDg5#8OF4P;03=T*47Dvl<4c@^%iiXNO24OVljiuc3-q8@WAvwLDB z(a@Sz#rxuTqV?8D2}B31;mhCRY@%m%omsK?I}x)q18g6`n{w^;8c=8(WzE^F=nLL8xy;V#_2eIdGVN`#V4^nW4FqmY-Z_mz7o z?j}m#Ki&V8IO&d-$^`Ry{;x%kB8?UwNcVpuwt1-0vwb%HZ^hk2jgxKs--$yWX*PDq z#{a!Ii74{4jsFL6E77S#EBrr-A&<3?J!(O*tdGM!|IcEC zPI>-c#7&&E{gQ3GD1tivT0(#cPcojcgK7UiwV*Go)QWMfg;oW;<-& zEugYw@>V0~>wN>NNDVlpv7aG!0VYyD+5Wb74KR})y~B`N|1_6AbJAMST)Ow3+n`4V z1ei+}AG9u3GC$gdqyK9 z;Vas3R`Pde2dM$41bE*233HOHG-BtHQ%syBdrk!`XvHEEXDN$l@rsuwE>eqcm`VYA zl+ni2O`1zI{+Ye0yYzx+M@GD$q$Y0_IhpVBh4g=nOD`!Pm+IX zw$Af9ngvKcMB83Fm<38ViEg}}U=}R7{L(_gHlA6SbdFOh%gg^_5+Qvidi(Z^Nu&h- zngu~q+1t0X&7vfGqPzFKs>Mi?I3=*)`#C1D(rzNZ`x&Maq(TAX!TIdDY&uoS6E#|J zUp7sY!X%BJpPN`M8UD8bseoNPY-OG-?ct>L>tyLTr*yDY4NR751-#LSbq^?76u3&-$|-@FRm%)qEqy0jTG95vweTMX z7&48uu68I8{^@~J0ZS`78Mt0*UtY7Vt#&*brIS)8=`ZITvgAq^SbiUT)E z8Jx8GZIa{)T3N7uo25yd64+H{gyZ%$o9H~BjhMIQdbEMXsunuxij?`BpW@>A&$d$%$N;ho! zSUG5~-pVB4T0(rK~{9%v18iEL9s+6KWtO^_`;#2ToWY^nQd1s#>1kZtR}#z1d08+&bO z7IaLCH|6cg22SZ8bX?j^v@Ky|P=Qq03~lMmf0 zX}#yH^qy>wx+R0nvYM7kP3zR4^HM(|^IFM4g;F3<1E9;&T%w#V%Yv>-xkODCX9iuD z@;RlkN;9_v-H?h)Xx5gXo6V3_-BX*Ln&{zlrR)1tt)QV|j6{!UWhP7%h#bIAMu zjK&XAD{j+{`v+dmlJ#^6;d**p&40*->**&!pLM#@>toP&sVh$<$uJ$>nfxKy5~Vrx zaQz_-CMvi6N6=4c1d-YHGQmG37b3syRf2y>K17k*Er3d2!) zQ%<RtteX)ReCdAswnp%x-b!Gh(=JB zdqx#yZ%*18!C0QeDV-UGj1M-JvxvmWiNU5av&8(;*_TO)!PR7UPBr|H)Y6Rn< zNu?U{K~4$mPoE~0YRW$KcsY69E#$E}9j;{|&(^81R&Dv9M(jqBzoDM&Tc5{c{r~<) zX&}cC4e#>9vXPvqks;6Cqihp-4$*1*9CePg(+)^Guw6{-Aa4Xq~Xi@UP;MQ^gr&M-u+wtHw@*7TR zY*A)mu$5fgP)j8#^G0x6`CKE7_CI?N++KERjFif9pS=j~BrhR49RDS_o9xm|3)$%T zgW#U>CQhj=tG6M*UqOY-3nJnFXg;>Xc-SWfggD9#+Lw@B$QZc?rvjnSB2sXY{fRP`!?(-jnM9k; zjuV{aETS<>CJQd|HI0nAJ{c~#$^Q_&`{c~r;e2u7UPw$X0 z+0Yr&Ok>Z7hJ=L69-QFaAG>iOk#Z){uA$>XqU6U!TMFVsqGdxDtt?v#l0#zT2u^A2 zAkbKOicaw%adNUwsUhR#)tpk<-GZed6Xh(j^|4zSGD$u~G;itpkjb)3H?3rAmhKFR zm#wX}{L0!L3YjKnaY|!fh8Bb*%JJQ`kY9%02$?B|^w7xX?&FYoa{Hbo^f4q=u4|*E zGR#E`T_kTM%DKBfWT{-Ymu9PS>qbb1>_T+$?#_@k@@}Gzw?2lflOGZ}+^rhAQI4_I zau_+TPUs)XBBmt<*x7VqcuCY3J9ZHN}k z@HbqR-8F*zW`J`L$Avb1GO}9+}@N^iE!NBly_?c zC0i7FQ|>&7hZJ7yo@{wbp2tZWx3}a)MA;TI*ey9` z|3JGth24_}6U~AVeov0p$jBeY?R|MR(fcduKv|p~Ls{H`ZjsG!ES(k0zcdnX+!o7C zhwvQuxcyVMA;NL{r|iY)u@N4>KjlfBQkmPR>`(~#8^%j#$BrEi{Y#D*s!`ixXG0&# z({;KHG}BJAT{`wM^pV`cUZb~%zl1)P&k_AKKnZ&yj~qs}0TsiZ%cnS{vdaUig}s!Y zXvEJ9ujOByk_=gJAK|rJW;n)6;=2d0GKkTjCnW%VOtFZTS zU!uD~UBW)fKAg1K+Gn|NgjSY`$NPnSmR}HgjUO8JRcW>`gK9#O{f9QP{9ZcYg-J18css`87IHt#W2DmrSZw2N!r&{V0Vk>UJ0 zL)mIdLr&=|;@hIIYD#A!vtDb$%$0>ix5wlJ*HF$8)ymx+R#W+|Q(jmtW!4y~d(p+P zx(a@amA6FE-LQH}7SVV=%Q6iW3n$Gsvgln{6D5SmD5QLNb0wc>)7iS=Efx4HZJvrz z_cq~el+K(|*`c%D!`mv;iMqZU6y9Djalw$OY@we+cqe5fCpZr8+{3#lONg#b3JJGX zmb+?cZhqC-sJoIyrHE}YU>qbILD9hD?bT2CIMEToWc<4=Z< zQ63Uq`~5<=lhWK%OVhZ<$#7>SfQUKX2zOE9h&J`V7w)PQa!O?%PDUGhC}X^|c&l>% z4);_h6XoQ-5BFAP>hwL_M>$J0p?6NOpYoKb{_vb&f5pUGOQr2_Q|Tb)s+CUMFDUoBp(BPJ2! zm8(PxM%Is*qzv)XY`?y>h?uNQ(&=RQ6lEb%dB1iMQx$7}Eo5!KZV?Ge7SR{qJ`vNE z@&THyrr(f=Bqg56^x&w7S<3D}w57824Bv=3O5-3cq=|QU#5|>qPGckHD~?3l@}@+j zC@DH6NBpj21#9ur`W+5mq*M;k(wy}A_lPA*04Ep$qn1Z3Rh|)@+_y1exl%b)3mLj^ zZ^Q~Ej#D~Q51)xxtyqR>X>Jd>6R}ol!zq<@KlmgfQ)v>e+4d!WiP)(45Y_Ro(c}+h zQG{lzFjwH4QOyxK!9_|uQLX-yBkw8?b($4ftb8Z3?fO;vQ;Cb! zYP)}0YUD#@Iwzc;EslJwEYk_T6|Su1l+Vr%-dFCa@<%Cp_Mec?m2KSi*l5omD`+ZFjjDZPe$t?V9)CBw2DihQjUa(XQ6_M5@p zD1FAE4dym}bJ#n6-i6hYvMnz^@_i|~82O=uDqvauDIo>(`$yT!Q%N*5y>U14i;_pw z^~PU7Ux@~T?W-cj@v<0dY<&(?mZ-(nH$YX1W_I^=|EAO=%ILn!=bO@i$Rzqxbuf`=x$i~s2@sqqJP57fCg~FJ0m?@e=0jTY3=z-$)%9kp1+hljUXhHP%Y9z z^7dqE^mtxsR^xz`xuj0wq|FN?^@V0L)V%7LjS-TknyTp1M(3H>&nKJDS=qoRQi|O9jg5&WzMyoE{5!#LB83 zI$ew`r>tXdG^6E?D%8J&ve?-+f*$(MQhIvzBhc#)aE*UGODHy(J8jJxf=Q}m8-7K*Qvip4Rwc3)eJS& zLLz*s+CqIrgil;ssO6`Y)*bP@NQ3TMgIAuXY_ZMJIPwSAD3{hTfK{ z5?_*LcaM5%Bb_R<`f7ijMtL+)19S?m-B6vSQ$+1X>K{6}cr;ee>I6?*t1n6jo}g{2 zR!GqD!{>gRsjZ0cDg5T@5F&gEzquMjgiql&SLYDnQ}`{^%|!SVehc-CPF>AgsxOJ~ zssGk$IcPcT^Z3+%Yqcp6K9}BF9ZZDJthZ4^i10mHD|I#zzE@zSuH}?u7=NH~l$H7i zrvw8$MFX^pY@s{aN3~TC5GC#C0hG@vl?~fIFshyUh-m9}m#FrtArVW4eXxgX2i1pD zBAdM;BC4ahi70o)gs3j+BRyndl(lL;9pfdiLf@3Ap6U=zkA?lu7Dw5ri*;HRWviYb z3P`qRebfs?GkrEj^;K^WHOSZ+)lV%Zag>aRW{8ZmWm)ByDz(W5>`q6Vtph$2k$ zqXwz+3@poIA;@?z8?06!x@K}ZYKUq^Nm9xQNO-dqK2wXh}y;NXltih5sfgt z8D+0_CF*K?H)@#Ln`phspHairA)Jy7J$5z@9-)pT8ojd(kgG<#Jx8jcrD&8onNy+x z_lzCX8AP~e?4YKU3OQOW;-sw@9M#K7CCBJcq@((RlXmqTqk1H3b;ql(vwD?Nl416p zNamszaY`^`+;InbM7GQqPoiAamt@O%@e=4C%?73Z5ap(ppQ#<&D*4}|Jk*h#9t)qX zM+AGSF+>--mx=aP4-zf09uw@Vo+J8Xv8O=*U30K!!MC;4r`%RTWoMPts6up*T7y#o z6M7DpLezFd4^G;%5Opx8$HIe?)uKbyXgwbMYm1u13GXJ=jt*1jX*Rd-Ze@sCNlr%0Q5{F-V)Jjx!EOkhiAdn8k`c@E?2AQ7_|+j0^#2EPC&(+@&&I8 zHqo)_skz!w$zSnX^jOto9#X#W|tQZ>4s6A?X0_285*?7uiZdb0YWgf`8No~kZO({gCN&CVx5UCSwf8Fr;dPgApq zUS0nyGEq%gsHORN-`eQu>UW}9qqjyUsV~yemdb8g<^<1Gdo9*z$%LHXd1?r!1h#JU zo#^@MZch2a{F_gs7pUczYPk=%`8GO5Eh5Ug{xv#P{Y

h7|L=YO+iV+4Fk&m^5_~ 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ℜq%CV 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 + + + Newtonsoft.Json + + + +

+ Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data. + + + + + Gets or sets a value indicating whether binary data reading should compatible with incorrect Json.NET 3.5 written binary. + + + true if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, false. + + + + + Gets or sets a value indicating whether the root object will be read as a JSON array. + + + true if the root object will be read as a JSON array; otherwise, false. + + + + + Gets or sets the used when reading values from BSON. + + The used when reading values from BSON. + + + + Initializes a new instance of the class. + + The stream. + + + + Initializes a new instance of the class. + + The reader. + + + + Initializes a new instance of the class. + + The stream. + if set to true the root object will be read as a JSON array. + The used when reading values from BSON. + + + + Initializes a new instance of the class. + + The reader. + if set to true the root object will be read as a JSON array. + The used when reading values from BSON. + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Changes the to Closed. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data. + + + + + Gets or sets the used when writing values to BSON. + When set to no conversion will occur. + + The used when writing values to BSON. + + + + Initializes a new instance of the class. + + The stream. + + + + Initializes a new instance of the class. + + The writer. + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Writes the end. + + The token. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes raw JSON where a value is expected and updates the writer's state. + + The raw JSON to write. + + + + Writes the beginning of a JSON array. + + + + + Writes the beginning of a JSON object. + + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + + + + Closes this stream and the underlying stream. + + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a [] value. + + The [] value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a [] value that represents a BSON object id. + + The Object ID value to write. + + + + Writes a BSON regex. + + The regex pattern. + The regex options. + + + + Represents a BSON Oid (object id). + + + + + Gets or sets the value of the Oid. + + The value of the Oid. + + + + Initializes a new instance of the class. + + The Oid value. + + + + Converts a binary value to and from a base 64 string value. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Create a custom object + + The object type to convert. + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Creates an object which will then be populated by the serializer. + + Type of the object. + The created object. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Gets a value indicating whether this can write JSON. + + + true if this can write JSON; otherwise, false. + + + + + Provides a base class for converting a to and from JSON. + + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a F# discriminated union type to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts an Entity Framework EntityKey to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts an ExpandoObject to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Gets a value indicating whether this can write JSON. + + + true if this can write JSON; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from JSON and BSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from JSON and BSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts an to and from its name string value. + + + + + Gets or sets a value indicating whether the written enum text should be camel case. + + true if the written enum text will be camel case; otherwise, false. + + + + Gets or sets a value indicating whether integer values are allowed. + + true if integers are allowed; otherwise, false. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + true if the written enum text will be camel case; otherwise, false. + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from a string (e.g. "1.2.3.4"). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing property value of the JSON that is being converted. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). + + + + + Gets or sets the date time styles used when converting a date to and from JSON. + + The date time styles used when converting a date to and from JSON. + + + + Gets or sets the date time format used when converting a date to and from JSON. + + The date time format used when converting a date to and from JSON. + + + + Gets or sets the culture used when converting a date to and from JSON. + + The culture used when converting a date to and from JSON. + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing property value of the JSON that is being converted. + The calling serializer. + The object value. + + + + Converts XML to and from JSON. + + + + + Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements. + + The name of the deserialize root element. + + + + Gets or sets a flag to indicate whether to write the Json.NET array attribute. + This attribute helps preserve arrays when converting the written XML back to JSON. + + true if the array attibute is written to the XML; otherwise, false. + + + + Gets or sets a value indicating whether to write the root JSON object. + + true if the JSON root object is omitted; otherwise, false. + + + + Writes the JSON representation of the object. + + The to write to. + The calling serializer. + The value. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Checks if the attributeName is a namespace attribute. + + Attribute name to test. + The attribute name prefix if it has one, otherwise an empty string. + true if attribute name is for a namespace attribute, otherwise false. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Specifies how constructors are used when initializing objects during deserialization by the . + + + + + First attempt to use the public default constructor, then fall back to single parameterized constructor, then the non-public default constructor. + + + + + Json.NET will use a non-public default constructor before falling back to a parameterized constructor. + + + + + Specifies float format handling options when writing special floating point numbers, e.g. , + and with . + + + + + Write special floating point values as strings in JSON, e.g. "NaN", "Infinity", "-Infinity". + + + + + Write special floating point values as symbols in JSON, e.g. NaN, Infinity, -Infinity. + Note that this will produce non-valid JSON. + + + + + Write special floating point values as the property's default value in JSON, e.g. 0.0 for a property, null for a property. + + + + + Specifies how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + + + + + Floating point numbers are parsed to . + + + + + Floating point numbers are parsed to . + + + + + Provides an interface for using pooled arrays. + + The array type content. + + + + Rent a array from the pool. This array must be returned when it is no longer needed. + + The minimum required length of the array. The returned array may be longer. + The rented array from the pool. This array must be returned when it is no longer needed. + + + + Return an array to the pool. + + The array that is being returned. + + + + Instructs the how to serialize the collection. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + The exception thrown when an error occurs during JSON serialization or deserialization. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + Specifies how dates are formatted when writing JSON text. + + + + + Dates are written in the ISO 8601 format, e.g. "2012-03-21T05:40Z". + + + + + Dates are written in the Microsoft JSON format, e.g. "\/Date(1198908717056)\/". + + + + + Specifies how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON text. + + + + + Date formatted strings are not parsed to a date type and are read as strings. + + + + + Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . + + + + + Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . + + + + + Specifies how to treat the time value when converting between string and . + + + + + Treat as local time. If the object represents a Coordinated Universal Time (UTC), it is converted to the local time. + + + + + Treat as a UTC. If the object represents a local time, it is converted to a UTC. + + + + + Treat as a local time if a is being converted to a string. + If a string is being converted to , convert to a local time if a time zone is specified. + + + + + Time zone information should be preserved when converting. + + + + + Specifies formatting options for the . + + + + + No special formatting is applied. This is the default. + + + + + Causes child objects to be indented according to the and settings. + + + + + Instructs the to use the specified constructor when deserializing that object. + + + + + Instructs the to deserialize properties with no matching class member into the specified collection + and write values during serialization. + + + + + Gets or sets a value that indicates whether to write extension data when serializing the object. + + + true to write extension data when serializing the object; otherwise, false. The default is true. + + + + + Gets or sets a value that indicates whether to read extension data when deserializing the object. + + + true to read extension data when deserializing the object; otherwise, false. The default is true. + + + + + Initializes a new instance of the class. + + + + + Instructs the to always serialize the member, and require the member has a value. + + + + + Specifies how JSON comments are handled when loading JSON. + + + + + Ignore comments. + + + + + Load comments as a with type . + + + + + Specifies how line information is handled when loading JSON. + + + + + Ignore line information. + + + + + Load line information. + + + + + Specifies the settings used when loading JSON. + + + + + Gets or sets how JSON comments are handled when loading JSON. + + The JSON comment handling. + + + + Gets or sets how JSON line info is handled when loading JSON. + + The JSON line info handling. + + + + Specifies the settings used when merging JSON. + + + + + Gets or sets the method used when merging JSON arrays. + + The method used when merging JSON arrays. + + + + Gets or sets how how null value properties are merged. + + How null value properties are merged. + + + + Specifies how JSON arrays are merged together. + + + + Concatenate arrays. + + + Union arrays, skipping items that already exist. + + + Replace all array items. + + + Merge array items together, matched by index. + + + + Specifies how null value properties are merged. + + + + + The content's null value properties will be ignored during merging. + + + + + The content's null value properties will be merged. + + + + + Represents a raw JSON string. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class. + + The raw json. + + + + Creates an instance of with the content of the reader's current token. + + The reader. + An instance of with the content of the reader's current token. + + + + Represents a view of a . + + + + + Initializes a new instance of the class. + + The name. + + + + When overridden in a derived class, returns whether resetting an object changes its value. + + + true if resetting the component changes its value; otherwise, false. + + The component to test for reset capability. + + + + When overridden in a derived class, gets the current value of the property on a component. + + + The value of a property for a given component. + + The component with the property for which to retrieve the value. + + + + + When overridden in a derived class, resets the value for this property of the component to the default value. + + The component with the property value that is to be reset to the default value. + + + + + When overridden in a derived class, sets the value of the component to a different value. + + The component with the property value that is to be set. + The new value. + + + + + When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted. + + + true if the property should be persisted; otherwise, false. + + The component with the property to be examined for persistence. + + + + When overridden in a derived class, gets the type of the component this property is bound to. + + + A that represents the type of component this property is bound to. When the or methods are invoked, the object specified might be an instance of this type. + + + + + When overridden in a derived class, gets a value indicating whether this property is read-only. + + + true if the property is read-only; otherwise, false. + + + + + When overridden in a derived class, gets the type of the property. + + + A that represents the type of the property. + + + + + Gets the hash code for the name of the member. + + + + The hash code for the name of the member. + + + + + Represents a collection of objects. + + The type of token + + + + Gets the with the specified key. + + + + + + Compares tokens to determine whether they are equal. + + + + + Determines whether the specified objects are equal. + + The first object of type to compare. + The second object of type to compare. + + true if the specified objects are equal; otherwise, false. + + + + + Returns a hash code for the specified object. + + The for which a hash code is to be returned. + A hash code for the specified object. + The type of is a reference type and is null. + + + + Contains the LINQ to JSON extension methods. + + + + + Returns a collection of tokens that contains the ancestors of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains the ancestors of every token in the source collection. + + + + Returns a collection of tokens that contains every token in the source collection, and the ancestors of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains every token in the source collection, the ancestors of every token in the source collection. + + + + Returns a collection of tokens that contains the descendants of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains the descendants of every token in the source collection. + + + + Returns a collection of tokens that contains every token in the source collection, and the descendants of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains every token in the source collection, and the descendants of every token in the source collection. + + + + Returns a collection of child properties of every object in the source collection. + + An of that contains the source collection. + An of that contains the properties of every object in the source collection. + + + + Returns a collection of child values of every object in the source collection with the given key. + + An of that contains the source collection. + The token key. + An of that contains the values of every token in the source collection with the given key. + + + + Returns a collection of child values of every object in the source collection. + + An of that contains the source collection. + An of that contains the values of every token in the source collection. + + + + Returns a collection of converted child values of every object in the source collection with the given key. + + The type to convert the values to. + An of that contains the source collection. + The token key. + An that contains the converted values of every token in the source collection with the given key. + + + + Returns a collection of converted child values of every object in the source collection. + + The type to convert the values to. + An of that contains the source collection. + An that contains the converted values of every token in the source collection. + + + + Converts the value. + + The type to convert the value to. + A cast as a of . + A converted value. + + + + Converts the value. + + The source collection type. + The type to convert the value to. + A cast as a of . + A converted value. + + + + Returns a collection of child tokens of every array in the source collection. + + The source collection type. + An of that contains the source collection. + An of that contains the values of every token in the source collection. + + + + Returns a collection of converted child tokens of every array in the source collection. + + An of that contains the source collection. + The type to convert the values to. + The source collection type. + An that contains the converted values of every token in the source collection. + + + + Returns the input typed as . + + An of that contains the source collection. + The input typed as . + + + + Returns the input typed as . + + The source collection type. + An of that contains the source collection. + The input typed as . + + + + Represents a JSON constructor. + + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Gets or sets the name of this constructor. + + The constructor name. + + + + Gets the node type for this . + + The type. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified name and content. + + The constructor name. + The contents of the constructor. + + + + Initializes a new instance of the class with the specified name and content. + + The constructor name. + The contents of the constructor. + + + + Initializes a new instance of the class with the specified name. + + The constructor name. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Gets the with the specified key. + + The with the specified key. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Loads an from a . + + A that will be read for the content of the . + The used to load the JSON. + If this is null, default load settings will be used. + A that contains the JSON that was read from the specified . + + + + Represents a token that can contain other tokens. + + + + + Occurs when the list changes or an item in the list changes. + + + + + Occurs before an item is added to the collection. + + + + + Occurs when the items list of the collection has changed, or the collection is reset. + + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Raises the event. + + The instance containing the event data. + + + + Raises the event. + + The instance containing the event data. + + + + Raises the event. + + The instance containing the event data. + + + + Gets a value indicating whether this token has child tokens. + + + true if this token has child values; otherwise, false. + + + + + Get the first child token of this token. + + + A containing the first child token of the . + + + + + Get the last child token of this token. + + + A containing the last child token of the . + + + + + Returns a collection of the child tokens of this token, in document order. + + + An of containing the child tokens of this , in document order. + + + + + Returns a collection of the child values of this token, in document order. + + The type to convert the values to. + + A containing the child values of this , in document order. + + + + + Returns a collection of the descendant tokens for this token in document order. + + An containing the descendant tokens of the . + + + + Returns a collection of the tokens that contain this token, and all descendant tokens of this token, in document order. + + An containing this token, and all the descendant tokens of the . + + + + Adds the specified content as children of this . + + The content to be added. + + + + Adds the specified content as the first children of this . + + The content to be added. + + + + Creates an that can be used to add tokens to the . + + An that is ready to have content written to it. + + + + Replaces the children nodes of this token with the specified content. + + The content. + + + + Removes the child nodes from this token. + + + + + Merge the specified content into this . + + The content to be merged. + + + + Merge the specified content into this using . + + The content to be merged. + The used to merge the content. + + + + Gets the count of child JSON tokens. + + The count of child JSON tokens + + + + Represents a collection of objects. + + The type of token + + + + An empty collection of objects. + + + + + Initializes a new instance of the struct. + + The enumerable. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Gets the with the specified key. + + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; otherwise, false. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + + + + + Represents a JSON object. + + + + + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Occurs when a property value changes. + + + + + Occurs when a property value is changing. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified content. + + The contents of the object. + + + + Initializes a new instance of the class with the specified content. + + The contents of the object. + + + + Gets the node type for this . + + The type. + + + + Gets an of this object's properties. + + An of this object's properties. + + + + Gets a the specified name. + + The property name. + A with the specified name or null. + + + + Gets an of this object's property values. + + An of this object's property values. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets or sets the with the specified property name. + + + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Loads an from a . + + A that will be read for the content of the . + The used to load the JSON. + If this is null, default load settings will be used. + A that contains the JSON that was read from the specified . + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + + + + Load a from a string that contains JSON. + + A that contains JSON. + The used to load the JSON. + If this is null, default load settings will be used. + A populated from the string that contains JSON. + + + + + + + Creates a from an object. + + The object that will be used to create . + A with the values of the specified object + + + + Creates a from an object. + + The object that will be used to create . + The that will be used to read the object. + A with the values of the specified object + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Gets the with the specified property name. + + Name of the property. + The with the specified property name. + + + + Gets the with the specified property name. + The exact property name will be searched for first and if no matching property is found then + the will be used to match a property. + + Name of the property. + One of the enumeration values that specifies how the strings will be compared. + The with the specified property name. + + + + Tries to get the with the specified property name. + The exact property name will be searched for first and if no matching property is found then + the will be used to match a property. + + Name of the property. + The value. + One of the enumeration values that specifies how the strings will be compared. + true if a value was successfully retrieved; otherwise, false. + + + + Adds the specified property name. + + Name of the property. + The value. + + + + Removes the property with the specified name. + + Name of the property. + true if item was successfully removed; otherwise, false. + + + + Tries the get value. + + Name of the property. + The value. + true if a value was successfully retrieved; otherwise, false. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Raises the event with the provided arguments. + + Name of the property. + + + + Raises the event with the provided arguments. + + Name of the property. + + + + Returns the properties for this instance of a component. + + + A that represents the properties for this component instance. + + + + + Returns the properties for this instance of a component using the attribute array as a filter. + + An array of type that is used as a filter. + + A that represents the filtered properties for this component instance. + + + + + Returns a collection of custom attributes for this instance of a component. + + + An containing the attributes for this object. + + + + + Returns the class name of this instance of a component. + + + The class name of the object, or null if the class does not have a name. + + + + + Returns the name of this instance of a component. + + + The name of the object, or null if the object does not have a name. + + + + + Returns a type converter for this instance of a component. + + + A that is the converter for this object, or null if there is no for this object. + + + + + Returns the default event for this instance of a component. + + + An that represents the default event for this object, or null if this object does not have events. + + + + + Returns the default property for this instance of a component. + + + A that represents the default property for this object, or null if this object does not have properties. + + + + + Returns an editor of the specified type for this instance of a component. + + A that represents the editor for this object. + + An of the specified type that is the editor for this object, or null if the editor cannot be found. + + + + + Returns the events for this instance of a component using the specified attribute array as a filter. + + An array of type that is used as a filter. + + An that represents the filtered events for this component instance. + + + + + Returns the events for this instance of a component. + + + An that represents the events for this component instance. + + + + + Returns an object that contains the property described by the specified property descriptor. + + A that represents the property whose owner is to be found. + + An that represents the owner of the specified property. + + + + + Returns the responsible for binding operations performed on this object. + + The expression tree representation of the runtime value. + + The to bind this object. + + + + + Represents a JSON array. + + + + + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Gets the node type for this . + + The type. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified content. + + The contents of the array. + + + + Initializes a new instance of the class with the specified content. + + The contents of the array. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Loads an from a . + + A that will be read for the content of the . + The used to load the JSON. + If this is null, default load settings will be used. + A that contains the JSON that was read from the specified . + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + + + + Load a from a string that contains JSON. + + A that contains JSON. + The used to load the JSON. + If this is null, default load settings will be used. + A populated from the string that contains JSON. + + + + + + + Creates a from an object. + + The object that will be used to create . + A with the values of the specified object + + + + Creates a from an object. + + The object that will be used to create . + The that will be used to read the object. + A with the values of the specified object + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets or sets the at the specified index. + + + + + + Determines the index of a specific item in the . + + The object to locate in the . + + The index of if found in the list; otherwise, -1. + + + + + Inserts an item to the at the specified index. + + The zero-based index at which should be inserted. + The object to insert into the . + + is not a valid index in the . + The is read-only. + + + + Removes the item at the specified index. + + The zero-based index of the item to remove. + + is not a valid index in the . + The is read-only. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Adds an item to the . + + The object to add to the . + The is read-only. + + + + Removes all items from the . + + The is read-only. + + + + Determines whether the contains a specific value. + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Copies to. + + The array. + Index of the array. + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + Removes the first occurrence of a specific object from the . + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + The is read-only. + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data. + + + + + Gets the at the reader's current position. + + + + + Initializes a new instance of the class. + + The token to read from. + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Gets the path of the current JSON token. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data. + + + + + Gets the at the writer's current position. + + + + + Gets the token being writen. + + The token being writen. + + + + Initializes a new instance of the class writing to the given . + + The container being written to. + + + + Initializes a new instance of the class. + + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a JSON object. + + + + + Writes the beginning of a JSON array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the end. + + The token. + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a [] value. + + The [] value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Represents an abstract JSON token. + + + + + Gets a comparer that can compare two tokens for value equality. + + A that can compare two nodes for value equality. + + + + Gets or sets the parent. + + The parent. + + + + Gets the root of this . + + The root of this . + + + + Gets the node type for this . + + The type. + + + + Gets a value indicating whether this token has child tokens. + + + true if this token has child values; otherwise, false. + + + + + Compares the values of two tokens, including the values of all descendant tokens. + + The first to compare. + The second to compare. + true if the tokens are equal; otherwise false. + + + + Gets the next sibling token of this node. + + The that contains the next sibling token. + + + + Gets the previous sibling token of this node. + + The that contains the previous sibling token. + + + + Gets the path of the JSON token. + + + + + Adds the specified content immediately after this token. + + A content object that contains simple content or a collection of content objects to be added after this token. + + + + Adds the specified content immediately before this token. + + A content object that contains simple content or a collection of content objects to be added before this token. + + + + Returns a collection of the ancestor tokens of this token. + + A collection of the ancestor tokens of this token. + + + + Returns a collection of tokens that contain this token, and the ancestors of this token. + + A collection of tokens that contain this token, and the ancestors of this token. + + + + Returns a collection of the sibling tokens after this token, in document order. + + A collection of the sibling tokens after this tokens, in document order. + + + + Returns a collection of the sibling tokens before this token, in document order. + + A collection of the sibling tokens before this token, in document order. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets the with the specified key converted to the specified type. + + The type to convert the token to. + The token key. + The converted token value. + + + + Get the first child token of this token. + + A containing the first child token of the . + + + + Get the last child token of this token. + + A containing the last child token of the . + + + + Returns a collection of the child tokens of this token, in document order. + + An of containing the child tokens of this , in document order. + + + + Returns a collection of the child tokens of this token, in document order, filtered by the specified type. + + The type to filter the child tokens on. + A containing the child tokens of this , in document order. + + + + Returns a collection of the child values of this token, in document order. + + The type to convert the values to. + A containing the child values of this , in document order. + + + + Removes this token from its parent. + + + + + Replaces this token with the specified token. + + The value. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Returns the indented JSON for this token. + + + The indented JSON for this token. + + + + + Returns the JSON for this token using the given formatting and converters. + + Indicates how the output is formatted. + A collection of which will be used when writing the token. + The JSON for this token using the given formatting and converters. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to []. + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from [] to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Creates an for this token. + + An that can be used to read this token and its descendants. + + + + Creates a from an object. + + The object that will be used to create . + A with the value of the specified object + + + + Creates a from an object using the specified . + + The object that will be used to create . + The that will be used when reading the object. + A with the value of the specified object + + + + Creates the specified .NET type from the . + + The object type that the token will be deserialized to. + The new object created from the JSON value. + + + + Creates the specified .NET type from the . + + The object type that the token will be deserialized to. + The new object created from the JSON value. + + + + Creates the specified .NET type from the using the specified . + + The object type that the token will be deserialized to. + The that will be used when creating the object. + The new object created from the JSON value. + + + + Creates the specified .NET type from the using the specified . + + The object type that the token will be deserialized to. + The that will be used when creating the object. + The new object created from the JSON value. + + + + Creates a from a . + + An positioned at the token to read into this . + + An that contains the token and its descendant tokens + that were read from the reader. The runtime type of the token is determined + by the token type of the first token encountered in the reader. + + + + + Creates a from a . + + An positioned at the token to read into this . + The used to load the JSON. + If this is null, default load settings will be used. + + An that contains the token and its descendant tokens + that were read from the reader. The runtime type of the token is determined + by the token type of the first token encountered in the reader. + + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Load a from a string that contains JSON. + + A that contains JSON. + The used to load the JSON. + If this is null, default load settings will be used. + A populated from the string that contains JSON. + + + + Creates a from a . + + An positioned at the token to read into this . + The used to load the JSON. + If this is null, default load settings will be used. + + An that contains the token and its descendant tokens + that were read from the reader. The runtime type of the token is determined + by the token type of the first token encountered in the reader. + + + + + Creates a from a . + + An positioned at the token to read into this . + + An that contains the token and its descendant tokens + that were read from the reader. The runtime type of the token is determined + by the token type of the first token encountered in the reader. + + + + + Selects a using a JPath expression. Selects the token that matches the object path. + + + A that contains a JPath expression. + + A , or null. + + + + Selects a using a JPath expression. Selects the token that matches the object path. + + + A that contains a JPath expression. + + A flag to indicate whether an error should be thrown if no tokens are found when evaluating part of the expression. + A . + + + + Selects a collection of elements using a JPath expression. + + + A that contains a JPath expression. + + An that contains the selected elements. + + + + Selects a collection of elements using a JPath expression. + + + A that contains a JPath expression. + + A flag to indicate whether an error should be thrown if no tokens are found when evaluating part of the expression. + An that contains the selected elements. + + + + Returns the responsible for binding operations performed on this object. + + The expression tree representation of the runtime value. + + The to bind this object. + + + + + Returns the responsible for binding operations performed on this object. + + The expression tree representation of the runtime value. + + The to bind this object. + + + + + Creates a new instance of the . All child tokens are recursively cloned. + + A new instance of the . + + + + Adds an object to the annotation list of this . + + The annotation to add. + + + + Get the first annotation object of the specified type from this . + + The type of the annotation to retrieve. + The first annotation object that matches the specified type, or null if no annotation is of the specified type. + + + + Gets the first annotation object of the specified type from this . + + The of the annotation to retrieve. + The first annotation object that matches the specified type, or null if no annotation is of the specified type. + + + + Gets a collection of annotations of the specified type for this . + + The type of the annotations to retrieve. + An that contains the annotations for this . + + + + Gets a collection of annotations of the specified type for this . + + The of the annotations to retrieve. + An of that contains the annotations that match the specified type for this . + + + + Removes the annotations of the specified type from this . + + The type of annotations to remove. + + + + Removes the annotations of the specified type from this . + + The of annotations to remove. + + + + Represents a JSON property. + + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Gets the property name. + + The property name. + + + + Gets or sets the property value. + + The property value. + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Gets the node type for this . + + The type. + + + + Initializes a new instance of the class. + + The property name. + The property content. + + + + Initializes a new instance of the class. + + The property name. + The property content. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Loads an from a . + + A that will be read for the content of the . + The used to load the JSON. + If this is null, default load settings will be used. + A that contains the JSON that was read from the specified . + + + + Specifies the type of token. + + + + + No token type has been set. + + + + + A JSON object. + + + + + A JSON array. + + + + + A JSON constructor. + + + + + A JSON object property. + + + + + A comment. + + + + + An integer value. + + + + + A float value. + + + + + A string value. + + + + + A boolean value. + + + + + A null value. + + + + + An undefined value. + + + + + A date value. + + + + + A raw JSON value. + + + + + A collection of bytes value. + + + + + A Guid value. + + + + + A Uri value. + + + + + A TimeSpan value. + + + + + Represents a value in JSON (string, integer, date, etc). + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Gets a value indicating whether this token has child tokens. + + + true if this token has child values; otherwise, false. + + + + + Creates a comment with the given value. + + The value. + A comment with the given value. + + + + Creates a string with the given value. + + The value. + A string with the given value. + + + + Creates a null value. + + A null value. + + + + Creates a undefined value. + + A undefined value. + + + + Gets the node type for this . + + The type. + + + + Gets or sets the underlying token value. + + The underlying token value. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Indicates whether the current object is equal to another object of the same type. + + + true if the current object is equal to the parameter; otherwise, false. + + An object to compare with this object. + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Returns a that represents this instance. + + The format. + + A that represents this instance. + + + + + Returns a that represents this instance. + + The format provider. + + A that represents this instance. + + + + + Returns a that represents this instance. + + The format. + The format provider. + + A that represents this instance. + + + + + Returns the responsible for binding operations performed on this object. + + The expression tree representation of the runtime value. + + The to bind this object. + + + + + Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. + + An object to compare with this instance. + + A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: + Value + Meaning + Less than zero + This instance is less than . + Zero + This instance is equal to . + Greater than zero + This instance is greater than . + + + is not the same type as this instance. + + + + + Specifies metadata property handling options for the . + + + + + Read metadata properties located at the start of a JSON object. + + + + + Read metadata properties located anywhere in a JSON object. Note that this setting will impact performance. + + + + + Do not try to read metadata properties. + + + + + A camel case naming strategy. + + + + + Initializes a new instance of the class. + + + A flag indicating whether dictionary keys should be processed. + + + A flag indicating whether explicitly specified property names should be processed, + e.g. a property name customized with a . + + + + + Initializes a new instance of the class. + + + + + Resolves the specified property name. + + The property name to resolve. + The resolved property name. + + + + The default naming strategy. Property names and dictionary keys are unchanged. + + + + + Resolves the specified property name. + + The property name to resolve. + The resolved property name. + + + + Represents a trace writer that writes to the application's instances. + + + + + Gets the that will be used to filter the trace messages passed to the writer. + For example a filter level of Info will exclude Verbose messages and include Info, + Warning and Error messages. + + + The that will be used to filter the trace messages passed to the writer. + + + + + Writes the specified trace level, message and optional exception. + + The at which to write this trace. + The trace message. + The trace exception. This parameter is optional. + + + + Get and set values for a using dynamic methods. + + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Provides methods to get attributes. + + + + + Returns a collection of all of the attributes, or an empty collection if there are no attributes. + + When true, look up the hierarchy chain for the inherited custom attribute. + A collection of s, or an empty collection. + + + + Returns a collection of attributes, identified by type, or an empty collection if there are no attributes. + + The type of the attributes. + When true, look up the hierarchy chain for the inherited custom attribute. + A collection of s, or an empty collection. + + + + Represents a trace writer. + + + + + Gets the that will be used to filter the trace messages passed to the writer. + For example a filter level of Info will exclude Verbose messages and include Info, + Warning and Error messages. + + The that will be used to filter the trace messages passed to the writer. + + + + Writes the specified trace level, message and optional exception. + + The at which to write this trace. + The trace message. + The trace exception. This parameter is optional. + + + + Contract details for a used by the . + + + + + Gets or sets the default collection items . + + The converter. + + + + Gets or sets a value indicating whether the collection items preserve object references. + + true if collection items preserve object references; otherwise, false. + + + + Gets or sets the collection item reference loop handling. + + The reference loop handling. + + + + Gets or sets the collection item type name handling. + + The type name handling. + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Represents a trace writer that writes to memory. When the trace message limit is + reached then old trace messages will be removed as new messages are added. + + + + + Gets the that will be used to filter the trace messages passed to the writer. + For example a filter level of Info will exclude Verbose messages and include Info, + Warning and Error messages. + + + The that will be used to filter the trace messages passed to the writer. + + + + + Initializes a new instance of the class. + + + + + Writes the specified trace level, message and optional exception. + + The at which to write this trace. + The trace message. + The trace exception. This parameter is optional. + + + + Returns an enumeration of the most recent trace messages. + + An enumeration of the most recent trace messages. + + + + Returns a of the most recent trace messages. + + + A of the most recent trace messages. + + + + + A base class for resolving how property names and dictionary keys are serialized. + + + + + A flag indicating whether dictionary keys should be processed. + Defaults to false. + + + + + A flag indicating whether explicitly specified property names, + e.g. a property name customized with a , should be processed. + Defaults to false. + + + + + Gets the serialized name for a given property name. + + The initial property name. + A flag indicating whether the property has had a name explicitly specfied. + The serialized property name. + + + + Gets the serialized key for a given dictionary key. + + The initial dictionary key. + The serialized dictionary key. + + + + Resolves the specified property name. + + The property name to resolve. + The resolved property name. + + + + Provides methods to get attributes from a , , or . + + + + + Initializes a new instance of the class. + + The instance to get attributes for. This parameter should be a , , or . + + + + Returns a collection of all of the attributes, or an empty collection if there are no attributes. + + When true, look up the hierarchy chain for the inherited custom attribute. + A collection of s, or an empty collection. + + + + Returns a collection of attributes, identified by type, or an empty collection if there are no attributes. + + The type of the attributes. + When true, look up the hierarchy chain for the inherited custom attribute. + A collection of s, or an empty collection. + + + + A snake case naming strategy. + + + + + Initializes a new instance of the class. + + + A flag indicating whether dictionary keys should be processed. + + + A flag indicating whether explicitly specified property names should be processed, + e.g. a property name customized with a . + + + + + Initializes a new instance of the class. + + + + + Resolves the specified property name. + + The property name to resolve. + The resolved property name. + + + + Contract details for a used by the . + + + + + Gets the object's properties. + + The object's properties. + + + + Gets or sets the property name resolver. + + The property name resolver. + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Gets or sets the ISerializable object constructor. + + The ISerializable object constructor. + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Get and set values for a using dynamic methods. + + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Provides data for the Error event. + + + + + Gets the current object the error event is being raised against. + + The current object the error event is being raised against. + + + + Gets the error context. + + The error context. + + + + Initializes a new instance of the class. + + The current object. + The error context. + + + + Resolves member mappings for a type, camel casing property names. + + + + + Initializes a new instance of the class. + + + + + Used by to resolves a for a given . + + + + + Gets a value indicating whether members are being get and set using dynamic code generation. + This value is determined by the runtime permissions available. + + + true if using dynamic code generation; otherwise, false. + + + + + Gets or sets the default members search flags. + + The default members search flags. + + + + Gets or sets a value indicating whether compiler generated members should be serialized. + + + true if serialized compiler generated members; otherwise, false. + + + + + Gets or sets a value indicating whether to ignore the interface when serializing and deserializing types. + + + true if the interface will be ignored when serializing and deserializing types; otherwise, false. + + + + + Gets or sets a value indicating whether to ignore the attribute when serializing and deserializing types. + + + true if the attribute will be ignored when serializing and deserializing types; otherwise, false. + + + + + Gets or sets the naming strategy used to resolve how property names and dictionary keys are serialized. + + The naming strategy used to resolve how property names and dictionary keys are serialized. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + + If set to true the will use a cached shared with other resolvers of the same type. + Sharing the cache will significantly improve performance with multiple resolver instances because expensive reflection will only + happen once. This setting can cause unexpected behavior if different instances of the resolver are suppose to produce different + results. When set to false it is highly recommended to reuse instances with the . + + + + + Resolves the contract for a given type. + + The type to resolve a contract for. + The contract for a given type. + + + + Gets the serializable members for the type. + + The type to get serializable members for. + The serializable members for the type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates the constructor parameters. + + The constructor to create properties for. + The type's member properties. + Properties for the given . + + + + Creates a for the given . + + The matching member property. + The constructor parameter. + A created for the given . + + + + Resolves the default for the contract. + + Type of the object. + The contract's default . + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Determines which contract type is created for the given type. + + Type of the object. + A for the given type. + + + + Creates properties for the given . + + The type to create properties for. + /// The member serialization mode for the type. + Properties for the given . + + + + Creates the used by the serializer to get and set values from a member. + + The member. + The used by the serializer to get and set values from a member. + + + + Creates a for the given . + + The member's parent . + The member to create a for. + A created for the given . + + + + Resolves the name of the property. + + Name of the property. + Resolved name of the property. + + + + Resolves the key of the dictionary. By default is used to resolve dictionary keys. + + Key of the dictionary. + Resolved key of the dictionary. + + + + Gets the resolved name of the property. + + Name of the property. + Name of the property. + + + + The default serialization binder used when resolving and loading classes from type names. + + + + + When overridden in a derived class, controls the binding of a serialized object to a type. + + Specifies the name of the serialized object. + Specifies the name of the serialized object. + + The type of the object the formatter creates a new instance of. + + + + + When overridden in a derived class, controls the binding of a serialized object to a type. + + The type of the object the formatter creates a new instance of. + Specifies the name of the serialized object. + Specifies the name of the serialized object. + + + + Provides information surrounding an error. + + + + + Gets the error. + + The error. + + + + Gets the original object that caused the error. + + The original object that caused the error. + + + + Gets the member that caused the error. + + The member that caused the error. + + + + Gets the path of the JSON location where the error occurred. + + The path of the JSON location where the error occurred. + + + + Gets or sets a value indicating whether this is handled. + + true if handled; otherwise, false. + + + + Used by to resolves a for a given . + + + + + + + + + Resolves the contract for a given type. + + The type to resolve a contract for. + The contract for a given type. + + + + Provides methods to get and set values. + + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Contract details for a used by the . + + + + + Gets the of the collection items. + + The of the collection items. + + + + Gets a value indicating whether the collection type is a multidimensional array. + + true if the collection type is a multidimensional array; otherwise, false. + + + + Gets or sets the function used to create the object. When set this function will override . + + The function used to create the object. + + + + Gets a value indicating whether the creator has a parameter with the collection values. + + true if the creator has a parameter with the collection values; otherwise, false. + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Handles serialization callback events. + + The object that raised the callback event. + The streaming context. + + + + Handles serialization error callback events. + + The object that raised the callback event. + The streaming context. + The error context. + + + + Sets extension data for an object during deserialization. + + The object to set extension data on. + The extension data key. + The extension data value. + + + + Gets extension data for an object during serialization. + + The object to set extension data on. + + + + Contract details for a used by the . + + + + + Gets the underlying type for the contract. + + The underlying type for the contract. + + + + Gets or sets the type created during deserialization. + + The type created during deserialization. + + + + Gets or sets whether this type contract is serialized as a reference. + + Whether this type contract is serialized as a reference. + + + + Gets or sets the default for this contract. + + The converter. + + + + Gets or sets all methods called immediately after deserialization of the object. + + The methods called immediately after deserialization of the object. + + + + Gets or sets all methods called during deserialization of the object. + + The methods called during deserialization of the object. + + + + Gets or sets all methods called after serialization of the object graph. + + The methods called after serialization of the object graph. + + + + Gets or sets all methods called before serialization of the object. + + The methods called before serialization of the object. + + + + Gets or sets all method called when an error is thrown during the serialization of the object. + + The methods called when an error is thrown during the serialization of the object. + + + + Gets or sets the method called immediately after deserialization of the object. + + The method called immediately after deserialization of the object. + + + + Gets or sets the method called during deserialization of the object. + + The method called during deserialization of the object. + + + + Gets or sets the method called after serialization of the object graph. + + The method called after serialization of the object graph. + + + + Gets or sets the method called before serialization of the object. + + The method called before serialization of the object. + + + + Gets or sets the method called when an error is thrown during the serialization of the object. + + The method called when an error is thrown during the serialization of the object. + + + + Gets or sets the default creator method used to create the object. + + The default creator method used to create the object. + + + + Gets or sets a value indicating whether the default creator is non public. + + true if the default object creator is non-public; otherwise, false. + + + + Contract details for a used by the . + + + + + Gets or sets the property name resolver. + + The property name resolver. + + + + Gets or sets the dictionary key resolver. + + The dictionary key resolver. + + + + Gets the of the dictionary keys. + + The of the dictionary keys. + + + + Gets the of the dictionary values. + + The of the dictionary values. + + + + Gets or sets the function used to create the object. When set this function will override . + + The function used to create the object. + + + + Gets a value indicating whether the creator has a parameter with the dictionary values. + + true if the creator has a parameter with the dictionary values; otherwise, false. + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Maps a JSON property to a .NET member or constructor parameter. + + + + + Gets or sets the name of the property. + + The name of the property. + + + + Gets or sets the type that declared this property. + + The type that declared this property. + + + + Gets or sets the order of serialization of a member. + + The numeric order of serialization. + + + + Gets or sets the name of the underlying member or parameter. + + The name of the underlying member or parameter. + + + + Gets the that will get and set the during serialization. + + The that will get and set the during serialization. + + + + Gets or sets the for this property. + + The for this property. + + + + Gets or sets the type of the property. + + The type of the property. + + + + Gets or sets the for the property. + If set this converter takes presidence over the contract converter for the property type. + + The converter. + + + + Gets or sets the member converter. + + The member converter. + + + + Gets or sets a value indicating whether this is ignored. + + true if ignored; otherwise, false. + + + + Gets or sets a value indicating whether this is readable. + + true if readable; otherwise, false. + + + + Gets or sets a value indicating whether this is writable. + + true if writable; otherwise, false. + + + + Gets or sets a value indicating whether this has a member attribute. + + true if has a member attribute; otherwise, false. + + + + Gets the default value. + + The default value. + + + + Gets or sets a value indicating whether this is required. + + A value indicating whether this is required. + + + + Gets or sets a value indicating whether this property preserves object references. + + + true if this instance is reference; otherwise, false. + + + + + Gets or sets the property null value handling. + + The null value handling. + + + + Gets or sets the property default value handling. + + The default value handling. + + + + Gets or sets the property reference loop handling. + + The reference loop handling. + + + + Gets or sets the property object creation handling. + + The object creation handling. + + + + Gets or sets or sets the type name handling. + + The type name handling. + + + + Gets or sets a predicate used to determine whether the property should be serialize. + + A predicate used to determine whether the property should be serialize. + + + + Gets or sets a predicate used to determine whether the property should be deserialized. + + A predicate used to determine whether the property should be deserialized. + + + + Gets or sets a predicate used to determine whether the property should be serialized. + + A predicate used to determine whether the property should be serialized. + + + + Gets or sets an action used to set whether the property has been deserialized. + + An action used to set whether the property has been deserialized. + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Gets or sets the converter used when serializing the property's collection items. + + The collection's items converter. + + + + Gets or sets whether this property's collection items are serialized as a reference. + + Whether this property's collection items are serialized as a reference. + + + + Gets or sets the the type name handling used when serializing the property's collection items. + + The collection's items type name handling. + + + + Gets or sets the the reference loop handling used when serializing the property's collection items. + + The collection's items reference loop handling. + + + + A collection of objects. + + + + + Initializes a new instance of the class. + + The type. + + + + When implemented in a derived class, extracts the key from the specified element. + + The element from which to extract the key. + The key for the specified element. + + + + Adds a object. + + The property to add to the collection. + + + + Gets the closest matching object. + First attempts to get an exact case match of propertyName and then + a case insensitive match. + + Name of the property. + A matching property if found. + + + + Gets a property by property name. + + The name of the property to get. + Type property name string comparison. + A matching property if found. + + + + Used to resolve references when serializing and deserializing JSON by the . + + + + + Resolves a reference to its object. + + The serialization context. + The reference to resolve. + The object that + + + + Gets the reference for the sepecified object. + + The serialization context. + The object to get a reference for. + The reference to the object. + + + + Determines whether the specified object is referenced. + + The serialization context. + The object to test for a reference. + + true if the specified object is referenced; otherwise, false. + + + + + Adds a reference to the specified object. + + The serialization context. + The reference. + The object to reference. + + + + Contract details for a used by the . + + + + + Gets or sets the object member serialization. + + The member object serialization. + + + + Gets or sets a value that indicates whether the object's properties are required. + + + A value indicating whether the object's properties are required. + + + + + Gets the object's properties. + + The object's properties. + + + + Gets the constructor parameters required for any non-default constructor + + + + + Gets a collection of instances that define the parameters used with . + + + + + Gets or sets the override constructor used to create the object. + This is set when a constructor is marked up using the + JsonConstructor attribute. + + The override constructor. + + + + Gets or sets the parametrized constructor used to create the object. + + The parametrized constructor. + + + + Gets or sets the function used to create the object. When set this function will override . + This function is called with a collection of arguments which are defined by the collection. + + The function used to create the object. + + + + Gets or sets the extension data setter. + + + + + Gets or sets the extension data getter. + + + + + Gets or sets the extension data value type. + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Lookup and create an instance of the JsonConverter type described by the argument. + + The JsonConverter type to create. + Optional arguments to pass to an initializing constructor of the JsonConverter. + If null, the default constructor is used. + + + + Get and set values for a using reflection. + + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + When applied to a method, specifies that the method is called when an error occurs serializing an object. + + + + + Represents a method that constructs an object. + + The object type to create. + + + + Specifies how strings are escaped when writing JSON text. + + + + + Only control characters (e.g. newline) are escaped. + + + + + All non-ASCII and control characters (e.g. newline) are escaped. + + + + + HTML (<, >, &, ', ") and control characters (e.g. newline) are escaped. + + + + + Helper method for generating a MetaObject which calls a + specific method on Dynamic that returns a result + + + + + Helper method for generating a MetaObject which calls a + specific method on Dynamic, but uses one of the arguments for + the result. + + + + + Helper method for generating a MetaObject which calls a + specific method on Dynamic, but uses one of the arguments for + the result. + + + + + Returns a Restrictions object which includes our current restrictions merged + with a restriction limiting our type + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert or cast the value to. + + The converted type. If conversion was unsuccessful, the initial value + is returned if assignable to the target type. + + + + + Gets a dictionary of the names and values of an Enum type. + + + + + + Gets a dictionary of the names and values of an Enum type. + + The enum type to get names and values for. + + + + + Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. + + + + + Determines whether the collection is null or empty. + + The collection. + + true if the collection is null or empty; otherwise, false. + + + + + Adds the elements of the specified collection to the specified generic IList. + + The list to add to. + The collection of elements to add. + + + + Gets the type of the typed collection's items. + + The type. + The type of the typed collection's items. + + + + Gets the member's underlying type. + + The member. + The underlying type of the member. + + + + Determines whether the member is an indexed property. + + The member. + + true if the member is an indexed property; otherwise, false. + + + + + Determines whether the property is an indexed property. + + The property. + + true if the property is an indexed property; otherwise, false. + + + + + Gets the member's value on the object. + + The member. + The target object. + The member's value on the object. + + + + Sets the member's value on the target object. + + The member. + The target. + The value. + + + + Determines whether the specified MemberInfo can be read. + + The MemberInfo to determine whether can be read. + /// if set to true then allow the member to be gotten non-publicly. + + true if the specified MemberInfo can be read; otherwise, false. + + + + + Determines whether the specified MemberInfo can be set. + + The MemberInfo to determine whether can be set. + if set to true then allow the member to be set non-publicly. + if set to true then allow the member to be set if read-only. + + true if the specified MemberInfo can be set; otherwise, false. + + + + + Determines whether the string is all white space. Empty string will return false. + + The string to test whether it is all white space. + + true if the string is all white space; otherwise, false. + + + + + Indicating whether a property is required. + + + + + The property is not required. The default state. + + + + + The property must be defined in JSON but can be a null value. + + + + + The property must be defined in JSON and cannot be a null value. + + + + + The property is not required but it cannot be a null value. + + + + + Specifies reference handling options for the . + Note that references cannot be preserved when a value is set via a non-default constructor such as types that implement ISerializable. + + + + + + + + Do not preserve references when serializing types. + + + + + Preserve references when serializing into a JSON object structure. + + + + + Preserve references when serializing into a JSON array structure. + + + + + Preserve references when serializing. + + + + + Provides an interface to enable a class to return line and position information. + + + + + Gets a value indicating whether the class can return line information. + + + true if LineNumber and LinePosition can be provided; otherwise, false. + + + + + Gets the current line number. + + The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + + + + Gets the current line position. + + The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + + + + Instructs the how to serialize the collection. + + + + + Gets or sets a value indicating whether null items are allowed in the collection. + + true if null items are allowed in the collection; otherwise, false. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with a flag indicating whether the array can contain null items + + A flag indicating whether the array can contain null items. + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Instructs the how to serialize the object. + + + + + Gets or sets the id. + + The id. + + + + Gets or sets the title. + + The title. + + + + Gets or sets the description. + + The description. + + + + Gets or sets the collection's items converter. + + The collection's items converter. + + + + The parameter list to use when constructing the described by ItemConverterType. + If null, the default constructor is used. + When non-null, there must be a constructor defined in the that exactly matches the number, + order, and type of these parameters. + + + [JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })] + + + + + Gets or sets the of the . + + The of the . + + + + The parameter list to use when constructing the described by NamingStrategyType. + If null, the default constructor is used. + When non-null, there must be a constructor defined in the that exactly matches the number, + order, and type of these parameters. + + + [JsonContainer(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })] + + + + + Gets or sets a value that indicates whether to preserve object references. + + + true to keep object reference; otherwise, false. The default is false. + + + + + Gets or sets a value that indicates whether to preserve collection's items references. + + + true to keep collection's items object references; otherwise, false. The default is false. + + + + + Gets or sets the reference loop handling used when serializing the collection's items. + + The reference loop handling. + + + + Gets or sets the type name handling used when serializing the collection's items. + + The type name handling. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Specifies default value handling options for the . + + + + + + + + + Include members where the member value is the same as the member's default value when serializing objects. + Included members are written to JSON. Has no effect when deserializing. + + + + + Ignore members where the member value is the same as the member's default value when serializing objects + so that is is not written to JSON. + This option will ignore all default values (e.g. null for objects and nullable types; 0 for integers, + decimals and floating point numbers; and false for booleans). The default value ignored can be changed by + placing the on the property. + + + + + Members with a default value but no JSON will be set to their default value when deserializing. + + + + + Ignore members where the member value is the same as the member's default value when serializing objects + and sets members to their default value when deserializing. + + + + + Instructs the to use the specified when serializing the member or class. + + + + + Gets the of the . + + The of the . + + + + The parameter list to use when constructing the described by ConverterType. + If null, the default constructor is used. + + + + + Initializes a new instance of the class. + + Type of the . + + + + Initializes a new instance of the class. + + Type of the . + Parameter list to use when constructing the . Can be null. + + + + Instructs the how to serialize the object. + + + + + Gets or sets the member serialization. + + The member serialization. + + + + Gets or sets a value that indicates whether the object's properties are required. + + + A value indicating whether the object's properties are required. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified member serialization. + + The member serialization. + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Specifies the settings on a object. + + + + + Gets or sets how reference loops (e.g. a class referencing itself) is handled. + + Reference loop handling. + + + + Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + + Missing member handling. + + + + Gets or sets how objects are created during deserialization. + + The object creation handling. + + + + Gets or sets how null values are handled during serialization and deserialization. + + Null value handling. + + + + Gets or sets how null default are handled during serialization and deserialization. + + The default value handling. + + + + Gets or sets a collection that will be used during serialization. + + The converters. + + + + Gets or sets how object references are preserved by the serializer. + + The preserve references handling. + + + + Gets or sets how type name writing and reading is handled by the serializer. + + + should be used with caution when your application deserializes JSON from an external source. + Incoming types should be validated with a custom + when deserializing with a value other than TypeNameHandling.None. + + The type name handling. + + + + Gets or sets how metadata properties are used during deserialization. + + The metadata properties handling. + + + + Gets or sets how a type name assembly is written and resolved by the serializer. + + The type name assembly format. + + + + Gets or sets how constructors are used during deserialization. + + The constructor handling. + + + + Gets or sets the contract resolver used by the serializer when + serializing .NET objects to JSON and vice versa. + + The contract resolver. + + + + Gets or sets the equality comparer used by the serializer when comparing references. + + The equality comparer. + + + + Gets or sets the used by the serializer when resolving references. + + The reference resolver. + + + + Gets or sets a function that creates the used by the serializer when resolving references. + + A function that creates the used by the serializer when resolving references. + + + + Gets or sets the used by the serializer when writing trace messages. + + The trace writer. + + + + Gets or sets the used by the serializer when resolving type names. + + The binder. + + + + Gets or sets the error handler called during serialization and deserialization. + + The error handler called during serialization and deserialization. + + + + Gets or sets the used by the serializer when invoking serialization callback methods. + + The context. + + + + Get or set how and values are formatted when writing JSON text, and the expected date format when reading JSON text. + + + + + Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + + + + + Indicates how JSON text output is formatted. + + + + + Get or set how dates are written to JSON text. + + + + + Get or set how time zones are handling during serialization and deserialization. + + + + + Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + + + + + Get or set how special floating point numbers, e.g. , + and , + are written as JSON. + + + + + Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + + + + + Get or set how strings are escaped when writing JSON text. + + + + + Gets or sets the culture used when reading JSON. Defaults to . + + + + + Gets a value indicating whether there will be a check for additional content after deserializing an object. + + + true if there will be a check for additional content after deserializing an object; otherwise, false. + + + + + Initializes a new instance of the class. + + + + + + Represents a reader that provides validation. + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + Sets an event handler for receiving schema validation errors. + + + + + Gets the text value of the current JSON token. + + + + + + Gets the depth of the current token in the JSON document. + + The depth of the current token in the JSON document. + + + + Gets the path of the current JSON token. + + + + + Gets the quotation mark character used to enclose the value of a string. + + + + + + Gets the type of the current JSON token. + + + + + + Gets the Common Language Runtime (CLR) type for the current JSON token. + + + + + + Initializes a new instance of the class that + validates the content returned from the given . + + The to read from while validating. + + + + Gets or sets the schema. + + The schema. + + + + Gets the used to construct this . + + The specified in the constructor. + + + + Reads the next JSON token from the stream as a . + + A . + + + + Reads the next JSON token from the stream as a []. + + + A [] or a null reference if the next JSON token is null. + + + + + Reads the next JSON token from the stream as a . + + A . + + + + Reads the next JSON token from the stream as a . + + A . + + + + Reads the next JSON token from the stream as a . + + A . + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Specifies the member serialization options for the . + + + + + All public members are serialized by default. Members can be excluded using or . + This is the default member serialization mode. + + + + + Only members marked with or are serialized. + This member serialization mode can also be set by marking the class with . + + + + + All public and private fields are serialized. Members can be excluded using or . + This member serialization mode can also be set by marking the class with + and setting IgnoreSerializableAttribute on to false. + + + + + Specifies how object creation is handled by the . + + + + + Reuse existing objects, create new objects when needed. + + + + + Only reuse existing objects. + + + + + Always create new objects. + + + + + Represents a reader that provides fast, non-cached, forward-only access to JSON text data. + + + + + Initializes a new instance of the class with the specified . + + The TextReader containing the XML data to read. + + + + Gets or sets the reader's character buffer pool. + + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a []. + + A [] or a null reference if the next JSON token is null. This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Changes the state to closed. + + + + + Gets a value indicating whether the class can return line information. + + + true if LineNumber and LinePosition can be provided; otherwise, false. + + + + + Gets the current line number. + + + The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + + + + + Gets the current line position. + + + The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + + + + + Instructs the to always serialize the member with the specified name. + + + + + Gets or sets the used when serializing the property's collection items. + + The collection's items . + + + + The parameter list to use when constructing the described by ItemConverterType. + If null, the default constructor is used. + When non-null, there must be a constructor defined in the that exactly matches the number, + order, and type of these parameters. + + + [JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })] + + + + + Gets or sets the of the . + + The of the . + + + + The parameter list to use when constructing the described by NamingStrategyType. + If null, the default constructor is used. + When non-null, there must be a constructor defined in the that exactly matches the number, + order, and type of these parameters. + + + [JsonProperty(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })] + + + + + Gets or sets the null value handling used when serializing this property. + + The null value handling. + + + + Gets or sets the default value handling used when serializing this property. + + The default value handling. + + + + Gets or sets the reference loop handling used when serializing this property. + + The reference loop handling. + + + + Gets or sets the object creation handling used when deserializing this property. + + The object creation handling. + + + + Gets or sets the type name handling used when serializing this property. + + The type name handling. + + + + Gets or sets whether this property's value is serialized as a reference. + + Whether this property's value is serialized as a reference. + + + + Gets or sets the order of serialization of a member. + + The numeric order of serialization. + + + + Gets or sets a value indicating whether this property is required. + + + A value indicating whether this property is required. + + + + + Gets or sets the name of the property. + + The name of the property. + + + + Gets or sets the the reference loop handling used when serializing the property's collection items. + + The collection's items reference loop handling. + + + + Gets or sets the the type name handling used when serializing the property's collection items. + + The collection's items type name handling. + + + + Gets or sets whether this property's collection items are serialized as a reference. + + Whether this property's collection items are serialized as a reference. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified name. + + Name of the property. + + + + Instructs the not to serialize the public field or public read/write property value. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data. + + + + + Gets or sets the writer's character array pool. + + + + + Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. + + + + + Gets or sets which character to use to quote attribute values. + + + + + Gets or sets which character to use for indenting when is set to Formatting.Indented. + + + + + Gets or sets a value indicating whether object names will be surrounded with quotes. + + + + + Creates an instance of the JsonWriter class using the specified . + + The TextWriter to write to. + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a JSON object. + + + + + Writes the beginning of a JSON array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the specified end token. + + The end token to write. + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + A flag to indicate whether the text should be escaped when it is written as a JSON property name. + + + + Writes indent characters. + + + + + Writes the JSON value delimiter. + + + + + Writes an indent space. + + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a [] value. + + The [] value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes out the given white space. + + The string of white space characters. + + + + The exception thrown when an error occurs while reading JSON text. + + + + + Gets the path to the JSON where the error occurred. + + The path to the JSON where the error occurred. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + The exception thrown when an error occurs while reading JSON text. + + + + + Gets the line number indicating where the error occurred. + + The line number indicating where the error occurred. + + + + Gets the line position indicating where the error occurred. + + The line position indicating where the error occurred. + + + + Gets the path to the JSON where the error occurred. + + The path to the JSON where the error occurred. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + Converts an object to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + + Gets the of the JSON produced by the JsonConverter. + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + The of the JSON produced by the JsonConverter. + + + + Gets a value indicating whether this can read JSON. + + true if this can read JSON; otherwise, false. + + + + Gets a value indicating whether this can write JSON. + + true if this can write JSON; otherwise, false. + + + + Represents a collection of . + + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data. + + + + + Specifies the state of the reader. + + + + + The Read method has not been called. + + + + + The end of the file has been reached successfully. + + + + + Reader is at a property. + + + + + Reader is at the start of an object. + + + + + Reader is in an object. + + + + + Reader is at the start of an array. + + + + + Reader is in an array. + + + + + The Close method has been called. + + + + + Reader has just read a value. + + + + + Reader is at the start of a constructor. + + + + + Reader in a constructor. + + + + + An error occurred that prevents the read operation from continuing. + + + + + The end of the file has been reached successfully. + + + + + Gets the current reader state. + + The current reader state. + + + + Gets or sets a value indicating whether the underlying stream or + should be closed when the reader is closed. + + + true to close the underlying stream or when + the reader is closed; otherwise false. The default is true. + + + + + Gets or sets a value indicating whether multiple pieces of JSON content can + be read from a continuous stream without erroring. + + + true to support reading multiple pieces of JSON content; otherwise false. The default is false. + + + + + Gets the quotation mark character used to enclose the value of a string. + + + + + Get or set how time zones are handling when reading JSON. + + + + + Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + + + + + Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + + + + + Get or set how custom date formatted strings are parsed when reading JSON. + + + + + Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + + + + + Gets the type of the current JSON token. + + + + + Gets the text value of the current JSON token. + + + + + Gets The Common Language Runtime (CLR) type for the current JSON token. + + + + + Gets the depth of the current token in the JSON document. + + The depth of the current token in the JSON document. + + + + Gets the path of the current JSON token. + + + + + Gets or sets the culture used when reading JSON. Defaults to . + + + + + Initializes a new instance of the class with the specified . + + + + + Reads the next JSON token from the stream. + + true if the next token was read successfully; false if there are no more tokens to read. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a []. + + A [] or a null reference if the next JSON token is null. This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Skips the children of the current token. + + + + + Sets the current token. + + The new token. + + + + Sets the current token and value. + + The new token. + The value. + + + + Sets the state based on current token type. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Releases unmanaged and - optionally - managed resources + + true to release both managed and unmanaged resources; false to release only unmanaged resources. + + + + Changes the to Closed. + + + + + Provides methods for converting between common language runtime types and JSON types. + + + + + + + + Gets or sets a function that creates default . + Default settings are automatically used by serialization methods on , + and and on . + To serialize without using any default settings create a with + . + + + + + Represents JavaScript's boolean value true as a string. This field is read-only. + + + + + Represents JavaScript's boolean value false as a string. This field is read-only. + + + + + Represents JavaScript's null as a string. This field is read-only. + + + + + Represents JavaScript's undefined as a string. This field is read-only. + + + + + Represents JavaScript's positive infinity as a string. This field is read-only. + + + + + Represents JavaScript's negative infinity as a string. This field is read-only. + + + + + Represents JavaScript's NaN as a string. This field is read-only. + + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation using the specified. + + The value to convert. + The format the date will be converted to. + The time zone handling when the date is converted to a string. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation using the specified. + + The value to convert. + The format the date will be converted to. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + The string delimiter character. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + The string delimiter character. + The string escape handling. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Serializes the specified object to a JSON string. + + The object to serialize. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using formatting. + + The object to serialize. + Indicates how the output is formatted. + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using a collection of . + + The object to serialize. + A collection converters used while serializing. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using formatting and a collection of . + + The object to serialize. + Indicates how the output is formatted. + A collection converters used while serializing. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using . + + The object to serialize. + The used to serialize the object. + If this is null, default serialization settings will be used. + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using a type, formatting and . + + The object to serialize. + The used to serialize the object. + If this is null, default serialization settings will be used. + + The type of the value being serialized. + This parameter is used when is Auto to write out the type name if the type of the value does not match. + Specifing the type is optional. + + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using formatting and . + + The object to serialize. + Indicates how the output is formatted. + The used to serialize the object. + If this is null, default serialization settings will be used. + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using a type, formatting and . + + The object to serialize. + Indicates how the output is formatted. + The used to serialize the object. + If this is null, default serialization settings will be used. + + The type of the value being serialized. + This parameter is used when is Auto to write out the type name if the type of the value does not match. + Specifing the type is optional. + + + A JSON string representation of the object. + + + + + Asynchronously serializes the specified object to a JSON string. + Serialization will happen on a new thread. + + The object to serialize. + + A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + + + + + Asynchronously serializes the specified object to a JSON string using formatting. + Serialization will happen on a new thread. + + The object to serialize. + Indicates how the output is formatted. + + A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + + + + + Asynchronously serializes the specified object to a JSON string using formatting and a collection of . + Serialization will happen on a new thread. + + The object to serialize. + Indicates how the output is formatted. + The used to serialize the object. + If this is null, default serialization settings will be used. + + A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + + + + + Deserializes the JSON to a .NET object. + + The JSON to deserialize. + The deserialized object from the JSON string. + + + + Deserializes the JSON to a .NET object using . + + The JSON to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type. + + The JSON to deserialize. + The of object being deserialized. + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type. + + The type of the object to deserialize to. + The JSON to deserialize. + The deserialized object from the JSON string. + + + + Deserializes the JSON to the given anonymous type. + + + The anonymous type to deserialize to. This can't be specified + traditionally and must be infered from the anonymous type passed + as a parameter. + + The JSON to deserialize. + The anonymous type object. + The deserialized anonymous type from the JSON string. + + + + Deserializes the JSON to the given anonymous type using . + + + The anonymous type to deserialize to. This can't be specified + traditionally and must be infered from the anonymous type passed + as a parameter. + + The JSON to deserialize. + The anonymous type object. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + The deserialized anonymous type from the JSON string. + + + + Deserializes the JSON to the specified .NET type using a collection of . + + The type of the object to deserialize to. + The JSON to deserialize. + Converters to use while deserializing. + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type using . + + The type of the object to deserialize to. + The object to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type using a collection of . + + The JSON to deserialize. + The type of the object to deserialize. + Converters to use while deserializing. + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type using . + + The JSON to deserialize. + The type of the object to deserialize to. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + The deserialized object from the JSON string. + + + + Asynchronously deserializes the JSON to the specified .NET type. + Deserialization will happen on a new thread. + + The type of the object to deserialize to. + The JSON to deserialize. + + A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + + + + + Asynchronously deserializes the JSON to the specified .NET type using . + Deserialization will happen on a new thread. + + The type of the object to deserialize to. + The JSON to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + + A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + + + + + Asynchronously deserializes the JSON to the specified .NET type. + Deserialization will happen on a new thread. + + The JSON to deserialize. + + A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + + + + + Asynchronously deserializes the JSON to the specified .NET type using . + Deserialization will happen on a new thread. + + The JSON to deserialize. + The type of the object to deserialize to. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + + A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + + + + + Populates the object with values from the JSON string. + + The JSON to populate values from. + The target object to populate values onto. + + + + Populates the object with values from the JSON string using . + + The JSON to populate values from. + The target object to populate values onto. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + + + + Asynchronously populates the object with values from the JSON string using . + + The JSON to populate values from. + The target object to populate values onto. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + + A task that represents the asynchronous populate operation. + + + + + Serializes the XML node to a JSON string. + + The node to serialize. + A JSON string of the XmlNode. + + + + Serializes the XML node to a JSON string using formatting. + + The node to serialize. + Indicates how the output is formatted. + A JSON string of the XmlNode. + + + + Serializes the XML node to a JSON string using formatting and omits the root object if is true. + + The node to serialize. + Indicates how the output is formatted. + Omits writing the root object. + A JSON string of the XmlNode. + + + + Deserializes the XmlNode from a JSON string. + + The JSON string. + The deserialized XmlNode + + + + Deserializes the XmlNode from a JSON string nested in a root elment specified by . + + The JSON string. + The name of the root element to append when deserializing. + The deserialized XmlNode + + + + Deserializes the XmlNode from a JSON string nested in a root elment specified by + and writes a .NET array attribute for collections. + + The JSON string. + The name of the root element to append when deserializing. + + A flag to indicate whether to write the Json.NET array attribute. + This attribute helps preserve arrays when converting the written XML back to JSON. + + The deserialized XmlNode + + + + Serializes the to a JSON string. + + The node to convert to JSON. + A JSON string of the XNode. + + + + Serializes the to a JSON string using formatting. + + The node to convert to JSON. + Indicates how the output is formatted. + A JSON string of the XNode. + + + + Serializes the to a JSON string using formatting and omits the root object if is true. + + The node to serialize. + Indicates how the output is formatted. + Omits writing the root object. + A JSON string of the XNode. + + + + Deserializes the from a JSON string. + + The JSON string. + The deserialized XNode + + + + Deserializes the from a JSON string nested in a root elment specified by . + + The JSON string. + The name of the root element to append when deserializing. + The deserialized XNode + + + + Deserializes the from a JSON string nested in a root elment specified by + and writes a .NET array attribute for collections. + + The JSON string. + The name of the root element to append when deserializing. + + A flag to indicate whether to write the Json.NET array attribute. + This attribute helps preserve arrays when converting the written XML back to JSON. + + The deserialized XNode + + + + The exception thrown when an error occurs during JSON serialization or deserialization. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + Serializes and deserializes objects into and from the JSON format. + The enables you to control how objects are encoded into JSON. + + + + + Occurs when the errors during serialization and deserialization. + + + + + Gets or sets the used by the serializer when resolving references. + + + + + Gets or sets the used by the serializer when resolving type names. + + + + + Gets or sets the used by the serializer when writing trace messages. + + The trace writer. + + + + Gets or sets the equality comparer used by the serializer when comparing references. + + The equality comparer. + + + + Gets or sets how type name writing and reading is handled by the serializer. + + + should be used with caution when your application deserializes JSON from an external source. + Incoming types should be validated with a custom + when deserializing with a value other than TypeNameHandling.None. + + + + + Gets or sets how a type name assembly is written and resolved by the serializer. + + The type name assembly format. + + + + Gets or sets how object references are preserved by the serializer. + + + + + Get or set how reference loops (e.g. a class referencing itself) is handled. + + + + + Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + + + + + Get or set how null values are handled during serialization and deserialization. + + + + + Get or set how null default are handled during serialization and deserialization. + + + + + Gets or sets how objects are created during deserialization. + + The object creation handling. + + + + Gets or sets how constructors are used during deserialization. + + The constructor handling. + + + + Gets or sets how metadata properties are used during deserialization. + + The metadata properties handling. + + + + Gets a collection that will be used during serialization. + + Collection that will be used during serialization. + + + + Gets or sets the contract resolver used by the serializer when + serializing .NET objects to JSON and vice versa. + + + + + Gets or sets the used by the serializer when invoking serialization callback methods. + + The context. + + + + Indicates how JSON text output is formatted. + + + + + Get or set how dates are written to JSON text. + + + + + Get or set how time zones are handling during serialization and deserialization. + + + + + Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + + + + + Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + + + + + Get or set how special floating point numbers, e.g. , + and , + are written as JSON text. + + + + + Get or set how strings are escaped when writing JSON text. + + + + + Get or set how and values are formatted when writing JSON text, and the expected date format when reading JSON text. + + + + + Gets or sets the culture used when reading JSON. Defaults to . + + + + + Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + + + + + Gets a value indicating whether there will be a check for additional JSON content after deserializing an object. + + + true if there will be a check for additional JSON content after deserializing an object; otherwise, false. + + + + + Initializes a new instance of the class. + + + + + Creates a new instance. + The will not use default settings + from . + + + A new instance. + The will not use default settings + from . + + + + + Creates a new instance using the specified . + The will not use default settings + from . + + The settings to be applied to the . + + A new instance using the specified . + The will not use default settings + from . + + + + + Creates a new instance. + The will use default settings + from . + + + A new instance. + The will use default settings + from . + + + + + Creates a new instance using the specified . + The will use default settings + from as well as the specified . + + The settings to be applied to the . + + A new instance using the specified . + The will use default settings + from as well as the specified . + + + + + Populates the JSON values onto the target object. + + The that contains the JSON structure to reader values from. + The target object to populate values onto. + + + + Populates the JSON values onto the target object. + + The that contains the JSON structure to reader values from. + The target object to populate values onto. + + + + Deserializes the JSON structure contained by the specified . + + The that contains the JSON structure to deserialize. + The being deserialized. + + + + Deserializes the JSON structure contained by the specified + into an instance of the specified type. + + The containing the object. + The of object being deserialized. + The instance of being deserialized. + + + + Deserializes the JSON structure contained by the specified + into an instance of the specified type. + + The containing the object. + The type of the object to deserialize. + The instance of being deserialized. + + + + Deserializes the JSON structure contained by the specified + into an instance of the specified type. + + The containing the object. + The of object being deserialized. + The instance of being deserialized. + + + + Serializes the specified and writes the JSON structure + to a Stream using the specified . + + The used to write the JSON structure. + The to serialize. + + + + Serializes the specified and writes the JSON structure + to a Stream using the specified . + + The used to write the JSON structure. + The to serialize. + + The type of the value being serialized. + This parameter is used when is Auto to write out the type name if the type of the value does not match. + Specifing the type is optional. + + + + + Serializes the specified and writes the JSON structure + to a Stream using the specified . + + The used to write the JSON structure. + The to serialize. + + The type of the value being serialized. + This parameter is used when is Auto to write out the type name if the type of the value does not match. + Specifing the type is optional. + + + + + Serializes the specified and writes the JSON structure + to a Stream using the specified . + + The used to write the JSON structure. + The to serialize. + + + + + Contains the JSON schema extension methods. + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + + Determines whether the is valid. + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + The source to test. + The schema to test with. + + true if the specified is valid; otherwise, false. + + + + + + Determines whether the is valid. + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + The source to test. + The schema to test with. + When this method returns, contains any error messages generated while validating. + + true if the specified is valid; otherwise, false. + + + + + + Validates the specified . + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + The source to test. + The schema to test with. + + + + + Validates the specified . + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + The source to test. + The schema to test with. + The validation event handler. + + + + + Returns detailed information about the schema exception. + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + Gets the line number indicating where the error occurred. + + The line number indicating where the error occurred. + + + + Gets the line position indicating where the error occurred. + + The line position indicating where the error occurred. + + + + Gets the path to the JSON where the error occurred. + + The path to the JSON where the error occurred. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + + Resolves from an id. + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + Gets or sets the loaded schemas. + + The loaded schemas. + + + + Initializes a new instance of the class. + + + + + Gets a for the specified reference. + + The id. + A for the specified reference. + + + + + Specifies undefined schema Id handling options for the . + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + Do not infer a schema Id. + + + + + Use the .NET type name as the schema Id. + + + + + Use the assembly qualified .NET type name as the schema Id. + + + + + + Returns detailed information related to the . + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + Gets the associated with the validation error. + + The JsonSchemaException associated with the validation error. + + + + Gets the path of the JSON location where the validation error occurred. + + The path of the JSON location where the validation error occurred. + + + + Gets the text description corresponding to the validation error. + + The text description. + + + + + Represents the callback method that will handle JSON schema validation events and the . + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + + An in-memory representation of a JSON Schema. + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + Gets or sets the id. + + + + + Gets or sets the title. + + + + + Gets or sets whether the object is required. + + + + + Gets or sets whether the object is read only. + + + + + Gets or sets whether the object is visible to users. + + + + + Gets or sets whether the object is transient. + + + + + Gets or sets the description of the object. + + + + + Gets or sets the types of values allowed by the object. + + The type. + + + + Gets or sets the pattern. + + The pattern. + + + + Gets or sets the minimum length. + + The minimum length. + + + + Gets or sets the maximum length. + + The maximum length. + + + + Gets or sets a number that the value should be divisble by. + + A number that the value should be divisble by. + + + + Gets or sets the minimum. + + The minimum. + + + + Gets or sets the maximum. + + The maximum. + + + + Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute. + + A flag indicating whether the value can not equal the number defined by the "minimum" attribute. + + + + Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute. + + A flag indicating whether the value can not equal the number defined by the "maximum" attribute. + + + + Gets or sets the minimum number of items. + + The minimum number of items. + + + + Gets or sets the maximum number of items. + + The maximum number of items. + + + + Gets or sets the of items. + + The of items. + + + + Gets or sets a value indicating whether items in an array are validated using the instance at their array position from . + + + true if items are validated using their array position; otherwise, false. + + + + + Gets or sets the of additional items. + + The of additional items. + + + + Gets or sets a value indicating whether additional items are allowed. + + + true if additional items are allowed; otherwise, false. + + + + + Gets or sets whether the array items must be unique. + + + + + Gets or sets the of properties. + + The of properties. + + + + Gets or sets the of additional properties. + + The of additional properties. + + + + Gets or sets the pattern properties. + + The pattern properties. + + + + Gets or sets a value indicating whether additional properties are allowed. + + + true if additional properties are allowed; otherwise, false. + + + + + Gets or sets the required property if this property is present. + + The required property if this property is present. + + + + Gets or sets the a collection of valid enum values allowed. + + A collection of valid enum values allowed. + + + + Gets or sets disallowed types. + + The disallow types. + + + + Gets or sets the default value. + + The default value. + + + + Gets or sets the collection of that this schema extends. + + The collection of that this schema extends. + + + + Gets or sets the format. + + The format. + + + + Initializes a new instance of the class. + + + + + Reads a from the specified . + + The containing the JSON Schema to read. + The object representing the JSON Schema. + + + + Reads a from the specified . + + The containing the JSON Schema to read. + The to use when resolving schema references. + The object representing the JSON Schema. + + + + Load a from a string that contains schema JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Parses the specified json. + + The json. + The resolver. + A populated from the string that contains JSON. + + + + Writes this schema to a . + + A into which this method will write. + + + + Writes this schema to a using the specified . + + A into which this method will write. + The resolver used. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + + Generates a from a specified . + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + Gets or sets how undefined schemas are handled by the serializer. + + + + + Gets or sets the contract resolver. + + The contract resolver. + + + + Generate a from the specified type. + + The type to generate a from. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + The used to resolve schema references. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + Specify whether the generated root will be nullable. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + The used to resolve schema references. + Specify whether the generated root will be nullable. + A generated from the specified type. + + + + + The value types allowed by the . + + + JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details. + + + + + + No type specified. + + + + + String type. + + + + + Float type. + + + + + Integer type. + + + + + Boolean type. + + + + + Object type. + + + + + Array type. + + + + + Null type. + + + + + Any type. + + + + + Specifies missing member handling options for the . + + + + + Ignore a missing member and do not attempt to deserialize it. + + + + + Throw a when a missing member is encountered during deserialization. + + + + + Specifies null value handling options for the . + + + + + + + + + Include null values when serializing and deserializing objects. + + + + + Ignore null values when serializing and deserializing objects. + + + + + Specifies reference loop handling options for the . + + + + + Throw a when a loop is encountered. + + + + + Ignore loop references and do not serialize. + + + + + Serialize loop references. + + + + + Specifies type name handling options for the . + + + should be used with caution when your application deserializes JSON from an external source. + Incoming types should be validated with a custom + when deserializing with a value other than TypeNameHandling.None. + + + + + Do not include the .NET type name when serializing types. + + + + + Include the .NET type name when serializing into a JSON object structure. + + + + + Include the .NET type name when serializing into a JSON array structure. + + + + + Always include the .NET type name when serializing. + + + + + Include the .NET type name when the type of the object being serialized is not the same as its declared type. + + + + + Specifies the type of JSON token. + + + + + This is returned by the if a method has not been called. + + + + + An object start token. + + + + + An array start token. + + + + + A constructor start token. + + + + + An object property name. + + + + + A comment. + + + + + Raw JSON. + + + + + An integer. + + + + + A float. + + + + + A string. + + + + + A boolean. + + + + + A null token. + + + + + An undefined token. + + + + + An object end token. + + + + + An array end token. + + + + + A constructor end token. + + + + + A Date. + + + + + Byte data. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data. + + + + + Gets or sets a value indicating whether the underlying stream or + should be closed when the writer is closed. + + + true to close the underlying stream or when + the writer is closed; otherwise false. The default is true. + + + + + Gets the top. + + The top. + + + + Gets the state of the writer. + + + + + Gets the path of the writer. + + + + + Indicates how JSON text output is formatted. + + + + + Get or set how dates are written to JSON text. + + + + + Get or set how time zones are handling when writing JSON text. + + + + + Get or set how strings are escaped when writing JSON text. + + + + + Get or set how special floating point numbers, e.g. , + and , + are written to JSON text. + + + + + Get or set how and values are formatting when writing JSON text. + + + + + Gets or sets the culture used when writing JSON. Defaults to . + + + + + Creates an instance of the JsonWriter class. + + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a JSON object. + + + + + Writes the end of a JSON object. + + + + + Writes the beginning of a JSON array. + + + + + Writes the end of an array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the end constructor. + + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + A flag to indicate whether the text should be escaped when it is written as a JSON property name. + + + + Writes the end of the current JSON object or array. + + + + + Writes the current token and its children. + + The to read the token from. + + + + Writes the current token. + + The to read the token from. + A flag indicating whether the current token's children should be written. + + + + Writes the token and its value. + + The to write. + + The value to write. + A value is only required for tokens that have an associated value, e.g. the property name for . + A null value can be passed to the method for token's that don't have a value, e.g. . + + + + Writes the token. + + The to write. + + + + Writes the specified end token. + + The end token to write. + + + + Writes indent characters. + + + + + Writes the JSON value delimiter. + + + + + Writes an indent space. + + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON without changing the writer's state. + + The raw JSON to write. + + + + Writes raw JSON where a value is expected and updates the writer's state. + + The raw JSON to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a [] value. + + The [] value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes out the given white space. + + The string of white space characters. + + + + Releases unmanaged and - optionally - managed resources + + true to release both managed and unmanaged resources; false to release only unmanaged resources. + + + + Sets the state of the JsonWriter, + + The JsonToken being written. + The value being written. + + + + Specifies the state of the . + + + + + An exception has been thrown, which has left the in an invalid state. + You may call the method to put the in the Closed state. + Any other method calls results in an being thrown. + + + + + The method has been called. + + + + + An object is being written. + + + + + A array is being written. + + + + + A constructor is being written. + + + + + A property is being written. + + + + + A write method has not been called. + + + + diff --git a/example/chatroom/BanExample.cs b/example/chatroom/BanExample.cs new file mode 100644 index 0000000..a2060ad --- /dev/null +++ b/example/chatroom/BanExample.cs @@ -0,0 +1,81 @@ +using io.rong.models.response; +using io.rong.methods.chatroom; +using io.rong.methods.chatroom.ban; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; +using io.rong.models.conversation; + +namespace io.rong.example.chatroom +{ + class BanExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "kj7swf8okyqt2"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "mFe3U1UClx4gx"; + /** + * 自定义api地址C:\Users\rc\Downloads\server-sdk-dotnet-master\example\chatroom\BanExample.cs + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Ban ban = rongCloud.chatroom.ban; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/ban.html#add + * 添加聊天室全局禁言 + * */ + ChatroomMember[] members = { + new ChatroomMember(){ + Id = "qawr34h" + }, new ChatroomMember() { + Id = "qawr35h" + } }; + ChatroomModel chatroom = new ChatroomModel() + { + Members = members, + Minute = 5 + }; + + ResponseResult result = ban.Add(chatroom); + Console.WriteLine("addGagUser: " + result.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/ban.html#getList + * 获取聊天时全局禁言列表 + */ + + ListGagChatroomUserResult chatroomListGagUserResult = ban.GetList(); + Console.WriteLine("ListGagUser: " + chatroomListGagUserResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/ban.html#remove + * 删除聊天时全局禁言 + */ + chatroom = new ChatroomModel() + { + Members = members + }; + ResponseResult removeResult = ban.Remove(chatroom); + Console.WriteLine("removeBanUser: " + removeResult.ToString()); + Console.ReadLine(); + } + } +} diff --git a/example/chatroom/BlockExample.cs b/example/chatroom/BlockExample.cs new file mode 100644 index 0000000..15c1ca2 --- /dev/null +++ b/example/chatroom/BlockExample.cs @@ -0,0 +1,86 @@ +using io.rong.models.response; +using io.rong.methods.chatroom; +using io.rong.methods.chatroom.block; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; +using io.rong.models.conversation; + +namespace io.rong.example.chatroom +{ + class BlockExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "kj7swf8okyqt2"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "mFe3U1UClx4gx"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + + static void Main(String[] args) + { + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Block block = rongCloud.chatroom.block; + + ChatroomMember[] members = { + new ChatroomMember(){ Id = "qawr34h"},new ChatroomMember(){ Id = "qawr35h"} + }; + /** + *API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/block.html#add + * + * 添加封禁聊天室成员方法 + */ + + + ChatroomModel chatroom = new ChatroomModel() + { + Id = "d7ec7a8b8d8546c98b0973417209a548", + Members = members, + Minute = 5 + }; + + ResponseResult result = block.Add(chatroom); + Console.WriteLine("addBlockUser: " + result.ToString()); + + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/block.html#remove + * + * 移除封禁聊天室成员方法 + */ + chatroom = new ChatroomModel() + { + Id = "d7ec7a8b8d8546c98b0973417209a548", + Members = members + }; + + //ResponseResult removeResult = block.remove(chatroom); + //Console.WriteLine("removeResult: " + removeResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/block.html#getList + * + * 查询被封禁聊天室成员方法 + */ + ListBlockChatroomUserResult getResult = block.GetList("d7ec7a8b8d8546c98b0973417209a548"); + Console.WriteLine("getListBlockUser: " + getResult.ToString()); + Console.ReadLine(); + } + + } +} diff --git a/example/chatroom/ChatroomExample.cs b/example/chatroom/ChatroomExample.cs new file mode 100644 index 0000000..d5cc9c2 --- /dev/null +++ b/example/chatroom/ChatroomExample.cs @@ -0,0 +1,98 @@ +using io.rong.methods.chatroom; +using io.rong.models.chatroom; +using io.rong.models.response; +using System; + +namespace io.rong.example.chatroom +{ + class ChatroomExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "n19jmcy59f1q9"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "CuhqdZMeuLsKj"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Chatroom chatroom = rongCloud.chatroom; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/chatroom.html#create + * + * 创建聊天室 + * + * */ + ChatroomModel[] chatrooms = { + new ChatroomModel(){ Id = "OIBbeKlkx", Name = "chatroomName1"}, + new ChatroomModel(){ Id = "chatroomId2", Name = "chatroomName2"} + }; + ResponseResult result = chatroom.Create(chatrooms); + + Console.WriteLine("create: " + result.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/chatroom.html#destory + * 销毁聊天室 + * + * */ + ChatroomModel chatroomModel = new ChatroomModel() + { + Id = "chatroomId2" + }; + + //ResponseResult chatroomDestroyResult = chatroom.Destroy(chatroomModel); + //Console.WriteLine("destroy: " + chatroomDestroyResult.ToString()); + + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/chatroom.html#getMembers + * 查询聊天室成员demo + * + * */ + + chatroomModel = new ChatroomModel() + { + Id = "OIBbeKlkx", + Count = 10, + Order = 1 + }; + + ChatroomUserQueryResult chatroomQueryUserResult = chatroom.Get(chatroomModel); + Console.WriteLine("queryUser: " + chatroomQueryUserResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/chatroom.html#isExist + * 查询聊天室成员是否存在 + * + * */ + ChatroomMember member = new ChatroomMember() + { + Id = "e5ZnCtyfE", + ChatroomId = "OIBbeKlkx" + }; + + CheckChatRoomUserResult checkMemberResult = chatroom.IsExist(member); + Console.WriteLine("checkChatroomUserResult: " + checkMemberResult.IsInChrm); + Console.ReadLine(); + + } + + } +} diff --git a/example/chatroom/DemotionExample.cs b/example/chatroom/DemotionExample.cs new file mode 100644 index 0000000..1d1854a --- /dev/null +++ b/example/chatroom/DemotionExample.cs @@ -0,0 +1,74 @@ +using io.rong.models.response; +using io.rong.methods.chatroom; +using io.rong.methods.chatroom.demotion; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; +using io.rong.models.conversation; + +namespace io.rong.example.chatroom +{ + class DemotionExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "kj7swf8okyqt2"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "mFe3U1UClx4gx"; + + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + + static void Main(String[] args) + { + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Demotion demotion = rongCloud.chatroom.demotion; + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/demotion.html#add + * 添加应用内聊天室降级消息 + * + * */ + String[] messageType = { "RC:VcMsg", "RC:ImgTextMsg", "RC:ImgMsg" }; + ResponseResult addResult = demotion.Add(messageType); + Console.WriteLine("add demotion: " + addResult.ToString()); + + /** + * + *API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/demotion.html#remove + * 移除应用内聊天室降级消息 + * + * */ + ResponseResult removeResult = demotion.Remove(messageType); + Console.WriteLine("remove demotion: " + removeResult.ToString()); + + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/demotion.html#getList + * 添加聊天室消息优先级demo + * + * */ + ChatroomDemotionMsgResult demotionMsgResult = demotion.GetList(); + Console.WriteLine("get demotion: " + demotionMsgResult.ToString()); + + Console.ReadLine(); + + } + } +} diff --git a/example/chatroom/DistributeExample.cs b/example/chatroom/DistributeExample.cs new file mode 100644 index 0000000..0505dba --- /dev/null +++ b/example/chatroom/DistributeExample.cs @@ -0,0 +1,66 @@ +using io.rong.models.response; +using io.rong.methods.chatroom; +using io.rong.methods.chatroom.distribute; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; +using io.rong.models.conversation; + +namespace io.rong.example.chatroom +{ + class DistributeExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "kj7swf8okyqt2"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "mFe3U1UClx4gx"; + + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Distribute distribute = rongCloud.chatroom.distribute; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/distribute.html#stop + * + * 聊天室消息停止分发 + * + */ + ChatroomModel chatroomModel = new ChatroomModel() + { + Id = "d7ec7a8b8d8546c98b0973417209a548" + }; + ResponseResult result = distribute.Stop(chatroomModel); + + Console.WriteLine("stopDistributionMessage: " + result.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/distribute.html#resume + * + * 聊天室消息恢复分发方法(每秒钟限 100 次) + */ + ResponseResult resumeResult = distribute.Resume(chatroomModel); + Console.WriteLine("resumeDistributionMessage: " + resumeResult.ToString()); + Console.ReadLine(); + } + } +} diff --git a/example/chatroom/GagExample.cs b/example/chatroom/GagExample.cs new file mode 100644 index 0000000..fa558a1 --- /dev/null +++ b/example/chatroom/GagExample.cs @@ -0,0 +1,92 @@ +using io.rong.models.response; +using io.rong.methods.chatroom; +using io.rong.methods.chatroom.gag; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; +using io.rong.models.conversation; + +namespace io.rong.example.chatroom +{ + class GagExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "appKey"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "appSecret"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + + static void main(String[] args) + { + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Gag gag = rongCloud.chatroom.gag; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/gag.html#add + * 添加禁言聊天室成员方法想(在 App 中如果不让某一用户在聊天室中发言时,可将此用户在聊天室中禁言, + * 被禁言用户可以接收查看聊天室中用户聊天信息,但不能发送消息.)获取某用户的黑名单列表方法(每秒钟限 100 次) + */ + + ChatroomMember[] members = { + new ChatroomMember() { + Id = "qawr34h" + }, + new ChatroomMember(){ Id = "qawr35h"} + }; + ChatroomModel chatroom = new ChatroomModel() + { + Id = "hjhf07kk", + Members = members, + Minute = 5 + }; + + ResponseResult result = gag.Add(chatroom); + Console.WriteLine("addGagUser: " + result.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/gag.html#remove + * 查询被禁言聊天室成员方法 + */ + chatroom = new ChatroomModel() + { + Id = "hjhf07kk" + }; + ListGagChatroomUserResult chatroomListGagUserResult = gag.GetList(chatroom); + Console.WriteLine("ListGagUser: " + chatroomListGagUserResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/gag.html#getList + * + * 移除禁言聊天室成员 + */ + chatroom = new ChatroomModel() + { + Id = "hjhf07kk", + Members = members + }; + + ResponseResult removeResult = gag.Remove(chatroom); + Console.WriteLine("rollbackGagUser: " + result.ToString()); + + Console.ReadLine(); + } + } +} diff --git a/example/chatroom/KeepaliveExample.cs b/example/chatroom/KeepaliveExample.cs new file mode 100644 index 0000000..dd7b99e --- /dev/null +++ b/example/chatroom/KeepaliveExample.cs @@ -0,0 +1,75 @@ +using io.rong.models.response; +using io.rong.methods.chatroom; +using io.rong.methods.chatroom.keepalive; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; +using io.rong.models.conversation; + +namespace io.rong.example.chatroom +{ + class KeepaliveExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "kj7swf8okyqt2"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "mFe3U1UClx4gx"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Keepalive keepalive = rongCloud.chatroom.keepalive; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/keepalive.html#add + * + * 添加保活聊天室 + * + **/ + ChatroomModel chatroom = new ChatroomModel() + { + Id = "d7ec7a8b8d8546c98b0973417209a548" + }; + ResponseResult addResult = keepalive.Add(chatroom); + Console.WriteLine("add keepalive result" + addResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/keepalive.html#remove + * + * 删除保活聊天室 + * + **/ + ResponseResult removeResult = keepalive.Remove(chatroom); + Console.WriteLine("keepalive remove" + removeResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/keepalive.html#getList + * + * 获取保活聊天室 + * + **/ + ChatroomKeepaliveResult result = keepalive.GetList(); + + Console.WriteLine("keepalive getList" + result.ToString()); + Console.ReadLine(); + } + } +} diff --git a/example/chatroom/whitelist/MessageExample.cs b/example/chatroom/whitelist/MessageExample.cs new file mode 100644 index 0000000..9d59fec --- /dev/null +++ b/example/chatroom/whitelist/MessageExample.cs @@ -0,0 +1,66 @@ +using io.rong.models.response; +using io.rong.methods.chatroom; +using io.rong.methods.chatroom.whitelist; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; +using io.rong.models.conversation; + +namespace io.rong.example.chatroom.whitelist +{ + class MessageExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "kj7swf8okyqt2"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "mFe3U1UClx4gx"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Whitelist whitelist = rongCloud.chatroom.whiteList; + String[] messageType = { "RC:VcMsg", "RC:ImgTextMsg", "RC:ImgMsg" }; + + /** + * API: 文档http://www.rongcloud.cn/docs/server_sdk_api/chatroom/whitelist/message.html#add + * 添加聊天室全局禁言 + * */ + + ResponseResult addResult = whitelist.Message.Add(messageType); + Console.WriteLine("add whitelist: " + addResult.ToString()); + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/whitelist/message.html#getList + * 添加聊天室全局禁言 + * */ + + ChatroomWhitelistMsgResult getResult = whitelist.Message.GetList(); + Console.WriteLine("get whitelist: " + getResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/whitelist/message.html#remove + * 添加聊天室全局禁言 + * */ + + ResponseResult removeResult = whitelist.Message.Remove(messageType); + Console.WriteLine("remove whitelist: " + addResult.ToString()); + + Console.ReadLine(); + } + } +} diff --git a/example/chatroom/whitelist/UserExample.cs b/example/chatroom/whitelist/UserExample.cs new file mode 100644 index 0000000..283aee1 --- /dev/null +++ b/example/chatroom/whitelist/UserExample.cs @@ -0,0 +1,75 @@ +using io.rong.models.response; +using io.rong.methods.chatroom; +using io.rong.methods.chatroom.whitelist; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; +using io.rong.models.conversation; + +namespace io.rong.example.chatroom.whitelist +{ + class UserExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "kj7swf8okyqt2"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "mFe3U1UClx4gx"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void main(String[] args) + { + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Whitelist whitelist = rongCloud.chatroom.whiteList; + + /** + * API: 文档http://www.rongcloud.cn/docs/server_sdk_api/chatroom/whitelist/user.html#add + * 添加聊天室用户白名单 + * */ + ChatroomMember[] members = { + new ChatroomMember(){ Id = "qawr34h"},new ChatroomMember(){ Id = "qawr35h"} + }; + ChatroomModel chatroom = new ChatroomModel() + { + Id = "d7ec7a8b8d8546c98b0973417209a548", + Members = members + }; + + ResponseResult addResult = whitelist.User.Add(chatroom); + Console.WriteLine("add whitelist: " + addResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/whitelist/user.html#getList + * 获取聊天室用户白名单 + * */ + + WhiteListResult getResult = whitelist.User.GetList(chatroom); + Console.WriteLine("get whitelist: " + getResult.ToString()); + + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/chatroom/whitelist/user.html#remove + * 删除聊天室用户白名单 + * */ + + ResponseResult removeResult = whitelist.User.Remove(chatroom); + Console.WriteLine("remove whitelist: " + removeResult.ToString()); + + Console.ReadLine(); + } + } +} diff --git a/example/conversation/ConversationExample.cs b/example/conversation/ConversationExample.cs new file mode 100644 index 0000000..5a1d44b --- /dev/null +++ b/example/conversation/ConversationExample.cs @@ -0,0 +1,68 @@ +using io.rong.methods.conversation; +using io.rong.models.conversation; +using io.rong.models.response; +using io.rong.util; +using System; + +namespace io.rong.example.conversation +{ + /** + * + * 会话示例 + * @author RongCloud + * + */ + class ConversationExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "pwe86ga5pwrj6"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "rb8fWki1mJcK"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api 地址方式 + // RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Conversation Conversation = rongCloud.conversation; + + ConversationModel conversation = new ConversationModel() + { + Type = CodeUtil.ConversationType.PRIVATE.Name, + UserId = "uPj70HUrRSUk-ixtt7iIGc", + TargetId = "Vu-oC0_LQ6kgPqltm_zYtI" + }; + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/conversation/conversation.html#mute + * 设置消息免打扰 + * + */ + ResponseResult muteConversationResult = Conversation.Mute(conversation); + + Console.WriteLine("muteConversationResult: " + muteConversationResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/conversation/conversation.html#unmute + * 解除消息免打扰 + * + * */ + ResponseResult unMuteConversationResult = Conversation.UnMute(conversation); + + Console.WriteLine("unMuteConversationResult: " + unMuteConversationResult.ToString()); + Console.ReadLine(); + } + } +} diff --git a/example/group/GagExample.cs b/example/group/GagExample.cs new file mode 100644 index 0000000..c70519f --- /dev/null +++ b/example/group/GagExample.cs @@ -0,0 +1,92 @@ +using io.rong.methods.group; +using io.rong.methods.group.gap; +using io.rong.models; +using io.rong.models.group; +using io.rong.models.response; +using System; + +namespace io.rong.example.group +{ + /** + * + * 群组禁言例子 + * + */ + class GagExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "pwe86ga5pwrj6"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "rb8fWki1mJcK"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + /** + * 本地调用测试 + * + * + * @throws Exception + */ + static void Main(String[] args) + { + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api 地址方式 + // RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Gag gag = rongCloud.group.Gag; + Group Group = rongCloud.group; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/gag.html#add + * 添加禁言群成员方法 + */ + + GroupMember[] members = { new GroupMember() { Id = "Vu-oC0_LQ6kgPqltm_zYtI" }, new GroupMember() { Id = "uPj70HUrRSUk-ixtt7iIGc" } }; + + GroupModel group = new GroupModel() + { + Id = "goupId1.NET", + Members = members, + Name = "groupName", + Minute = 5 + }; + + Result groupCreateResult = (Result)Group.Create(group); + Console.WriteLine("group create result: " + groupCreateResult.ToString()); + Console.WriteLine("get group users:" + Group.Get(new GroupModel() { Id = "goupId1.NET" }).ToString()); + + + Result result = gag.Add(group); + Console.WriteLine("group.gag.add: " + result.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/gag.html#getList + * 查询被禁言群成员 + */ + ListGagGroupUserResult groupLisGagUserResult = gag.GetList("goupId1.NET"); + Console.WriteLine("group.gag.getList: " + groupLisGagUserResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/gag.html#remove + * 移除禁言群成员 + */ + group = new GroupModel() + { + Id = "goupId1.NET", + Members = members + }; + + + Result groupRollBackGagUserResult = gag.Remove(group); + Console.WriteLine("group.gag.remove: " + groupRollBackGagUserResult.ToString()); + Console.ReadLine(); + + } + } +} diff --git a/example/group/GroupExample.cs b/example/group/GroupExample.cs new file mode 100644 index 0000000..ac1c521 --- /dev/null +++ b/example/group/GroupExample.cs @@ -0,0 +1,202 @@ +using io.rong.methods.group; +using io.rong.models; +using io.rong.models.group; +using io.rong.models.response; +using System; + +namespace io.rong.example.group +{ + /** + * + * 群组服务示例 + * + */ + class GroupExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "pwe86ga5pwrj6"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "rb8fWki1mJcK"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + /** + * 本地调用测试 + * + * @param args + * @throws Exception + */ + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api 地址方式 + // RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Group Group = rongCloud.group; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/group.html#create + * + * 创建群组方法 + * + */ + GroupMember[] members = { new GroupMember() { Id = "Vu-oC0_LQ6kgPqltm_zYtI" }, new GroupMember() { Id = "uPj70HUrRSUk-ixtt7iIGc" } }; + + + GroupModel group = new GroupModel() + { + Id = "goupId1.net", + Members = members, + Name = "groupName" + }; + + Result groupCreateResult = (Result)Group.Create(group); + Console.WriteLine("group create result: " + groupCreateResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/group.html#sync + * + * 同步用户所属群组方法 + */ + + GroupModel group1 = new GroupModel() + { + Id = "goupId1.net", + Name = "groupName1" + }; + + GroupModel group2 = new GroupModel() + { + Id = "goupId2.net", + Name = "groupName2" + }; + + GroupModel[] groups = { group1, group2 }; + UserGroup user = new UserGroup() + { + Id = "Vu-oC0_LQ6kgPqltm_zYtI", + Groups = groups + }; + + + Result syncResult = (Result)Group.Sync(user); + Console.WriteLine("group sync: " + syncResult.ToString()); + + Console.WriteLine("get group users:" + Group.Get(new GroupModel(){Id = "goupId1.NET"}).ToString()); + + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/group.html#refresh + * 刷新群组信息方法 + */ + //GroupMember[] members = {new GroupMember().setId("ghJiu7H1"),new GroupMember().setId("ghJiu7H2")}; + + group = new GroupModel() + { + Id = "goupId1.NET", + Name = "groupName" + }; + + Result refreshResult = (Result)Group.Update(group); + Console.WriteLine("refresh: " + refreshResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/group.html#join + * + * 邀请用户加入群组 + * + */ + group = new GroupModel() + { + Id = "goupId1.NET", + Members = members, + Name = "groupName" + }; + + Result groupInviteResult = (Result)rongCloud.group.Invite(group); + Console.WriteLine("invite: " + groupInviteResult.ToString()); + + Console.WriteLine("get group users:" + Group.Get(new GroupModel() { Id = "goupId1.NET" }).ToString()); + + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/group.html#join + * + * 用户加入指定群组 + * + */ + group = new GroupModel() + { + Id = "goupId1.NET", + Members = members, + Name = "groupName" + }; + + Result groupJoinResult = (Result)Group.Join(group); + Console.WriteLine("join: " + groupJoinResult.ToString()); + Console.WriteLine("get group users:" + Group.Get(new GroupModel() { Id = "goupId1.NET" }).ToString()); + + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/group.html#getMembers + * + * 查询群成员方法 + * + */ + group = new GroupModel() + { + Id = "goupId1.NET" + }; + GroupUserQueryResult getMemberesult = Group.Get(group); + Console.WriteLine("group getMember: " + getMemberesult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/group.html#quit + * + * 退出群组 + * + */ + group = new GroupModel() + { + Id = "goupId1.NET", + Members = new GroupMember[]{ new GroupMember() { Id = "uPj70HUrRSUk-ixtt7iIGc" } }, + Name = "groupName" + }; + + Result groupQuitResult = (Result)Group.Quit(group); + Console.WriteLine("quit: " + groupQuitResult.ToString()); + Console.WriteLine("get group users:" + Group.Get(new GroupModel() { Id = "goupId1.NET" }).ToString()); + + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/group/group.html#dismiss + * + * 解散群组 + * + */ + members = new GroupMember[]{ new GroupMember() { + Id = "Vu-oC0_LQ6kgPqltm_zYtI" + } }; + + group = new GroupModel() + { + Id = "goupId1.NET", + Members = members + }; + + Result groupDismissResult = (Result)Group.Dismiss(group); + Console.WriteLine("dismiss: " + groupDismissResult.ToString()); + Console.ReadLine(); + } + + } +} \ No newline at end of file diff --git a/example/messages/MessageExample.cs b/example/messages/MessageExample.cs new file mode 100644 index 0000000..4126b5b --- /dev/null +++ b/example/messages/MessageExample.cs @@ -0,0 +1,365 @@ +using io.rong.methods.user.blacklist; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using io.rong.messages; +using io.rong.models.message; +using io.rong.methods.messages._private; +using System.Text.RegularExpressions; +using io.rong.methods.messages.group; +using io.rong; +using io.rong.methods.messages.chatroom; +using io.rong.methods.messages.discussion; +using io.rong.methods.messages.history; +using System.IO; +using Newtonsoft.Json; +using io.rong.methods.messages.system; + +namespace io.rong.example.messages +{ + /** + * 消息发送示例 + * + */ + public class MessageExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "n19jmcy59f1q9"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "CuhqdZMeuLsKj"; + + private static readonly TxtMessage txtMessage = new TxtMessage(".NET hello", "helloExtra"); + private static readonly VoiceMessage voiceMessage = new VoiceMessage(".NET hello", "helloExtra", 20L); + /** + * 自定义api地址 + * */ + //private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api 地址方式 + //RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Private Private = rongCloud.message.msgPrivate; + // TODO + MsgSystem system = rongCloud.message.system; + methods.messages.group.Group group = rongCloud.message.group; + Chatroom chatroom = rongCloud.message.chatroom; + Discussion discussion = rongCloud.message.discussion; + History history = rongCloud.message.history; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/system.html#send + * + * 发送系统消息 + * + */ + String[] targetIds = { "uPj70HUrRSUk-ixtt7iIGc" }; + SystemMessage systemMessage = new SystemMessage() + { + SenderId = "Vu-oC0_LQ6kgPqltm_zYtI", + TargetId = targetIds, + ObjectName = txtMessage.GetType(), + Content = txtMessage, + PushContent = ".NET this is a push system", + PushData = "{'pushData':'.NET hello'}", + IsPersisted = 0, + IsCounted = 0, + ContentAvailable = 0 + }; + + ResponseResult result = rongCloud.message.system.Send(systemMessage); + Console.WriteLine("send system message: " + result.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/system.html#sendTemplate + * + * 发送系统模板消息方法 + * + */ + StreamReader file = null; + try + { + file = System.IO.File.OpenText("jsonsource/message/TemplateMessage.json"); + TemplateMessage template = JsonConvert.DeserializeObject(file.ReadToEnd()); + ResponseResult messagePublishTemplateResult = system.SendTemplate(template); + + Console.WriteLine("send systemTemplate message: " + messagePublishTemplateResult.ToString()); + + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + finally + { + file.Close(); + } + + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/system.html#sendTemplate + * + * 发送系统模板消息方法 + * + */ + BroadcastMessage message = new BroadcastMessage() + { + SenderId = "Vu-oC0_LQ6kgPqltm_zYtI", + ObjectName = txtMessage.GetType(), + Content = txtMessage, + Os = "Android" + }; + + ResponseResult broadcastResult = rongCloud.message.system.Broadcast(message); + Console.WriteLine("send broadcast: " + broadcastResult.ToString()); + + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/private.html#send + * + * 发送单聊消息 + * */ + PrivateMessage privateMessage = new PrivateMessage() + { + SenderId = "Vu-oC0_LQ6kgPqltm_zYtI", + TargetId = targetIds, + ObjectName = txtMessage.GetType(), + Content = txtMessage, + PushContent = ".NET this is a push private", + PushData = "{\"pushData\":\".NET hello\"}", + VerifyBlacklist = 0, + IsPersisted = 0, + IsCounted = 0, + ContentAvailable = 0, + IsIncludeSender = 0 + }; + + ResponseResult privateResult = Private.Send(privateMessage); + Console.WriteLine("send private message: " + privateResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/private.html#sendTemplate + * + * 发送单聊模板消息方法 + */ + try + { + file = System.IO.File.OpenText("jsonsource/message/TemplateMessage.json"); + TemplateMessage template = JsonConvert.DeserializeObject(file.ReadToEnd()); + ResponseResult messagePublishTemplateResult = Private.SendTemplate(template); + + Console.WriteLine("send privateTemplate message: " + messagePublishTemplateResult.ToString()); + + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + finally + { + file.Close(); + } + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/private.html#recall + * + * 撤回单聊消息 + * */ + RecallMessage recallMessage = new RecallMessage() + { + SenderId = "0fn8TiuHTUgjrZ1QJ8o50M", + TargetId = "qHPBAoUS6DmEBtJH72RSDi", + UId = "5H6P-CGC6-44QR-VB3R", + SentTime = "1519444243981" + }; + + ResponseResult recallPrivateResult = (ResponseResult)Private.Recall(recallMessage); + Console.WriteLine("recall private: " + recallPrivateResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/group.html#send + * + * 群组消息 + * */ + GroupMessage groupMessage = new GroupMessage() + { + SenderId = "Vu-oC0_LQ6kgPqltm_zYtI", + TargetId = new string[]{ "STRe0shISpQlSOBvek1FfU" }, + ObjectName = txtMessage.GetType(), + Content = txtMessage, + PushContent = "this is a push", + PushData = "{\"pushData\":\"hello\"}", + IsPersisted = 0, + IsCounted = 0, + IsIncludeSender = 0, + ContentAvailable = 0 + }; + + ResponseResult groupResult = group.Send(groupMessage); + + Console.WriteLine("send Group message: " + groupResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/group.html#recall + * + * 群组撤回消息 + * */ + recallMessage = new RecallMessage() + { + SenderId = "sea9901", + TargetId = "markoiwm", + UId = "5GSB-RPM1-KP8H-9JHF", + SentTime = "1507778882124" + }; + + ResponseResult recallMessageResult = (ResponseResult)group.Recall(recallMessage); + + Console.WriteLine("send recall group message: " + recallMessageResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/group.html#sendMention + * + * 群组@消息 + * */ + //要@的人 + String[] mentionIds = { "uPj70HUrRSUk-ixtt7iIGc", "Vu-oC0_LQ6kgPqltm_zYtI" }; + + MentionedInfo mentionedInfo = new MentionedInfo(1, mentionIds, ""); + //@内容 + MentionMessageContent content = new MentionMessageContent(txtMessage, mentionedInfo); + + MentionMessage mentionMessage = new MentionMessage() + { + SenderId = "Vu-oC0_LQ6kgPqltm_zYtI", + TargetId = new string[] { "STRe0shISpQlSOBvek1FfU" }, + ObjectName = txtMessage.GetType(), + Content = content, + PushContent = "this is a push", + PushData = "{\"pushData\":\"hello\"}", + IsPersisted = 0, + IsCounted = 0, + IsIncludeSender = 0, + ContentAvailable = 0 + }; + ResponseResult mentionResult = rongCloud.message.group.SendMention(mentionMessage); + + Console.WriteLine("group mention result: " + mentionResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/discussion.html#send + * + * 发送讨论组消息 + * */ + String[] discussionIds = { "lijhGk87", "lijhGk88" }; + DiscussionMessage discussionMessage = new DiscussionMessage() + { + SenderId = "JuikH78ko", + TargetId = discussionIds, + ObjectName = txtMessage.GetType(), + Content = txtMessage, + PushContent = "this is a push", + PushData = "{\"pushData\":\"hello\"}", + IsPersisted = 0, + IsCounted = 0, + IsIncludeSender = 0, + ContentAvailable = 0 + }; + + ResponseResult discussionResult = discussion.Send(discussionMessage); + + Console.WriteLine("send discussion message: " + discussionResult.ToString()); + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/discussion.html#recall + * + * 撤回讨论组消息 + * */ + recallMessage = new RecallMessage() + { + SenderId = "sea9901", + TargetId = "IXQhMs3ny", + UId = "5GSB-RPM1-KP8H-9JHF", + SentTime = "1519444243981" + }; + ResponseResult recallDiscussionResult = (ResponseResult)discussion.Recall(recallMessage); + + Console.WriteLine("recall discussion message: " + recallDiscussionResult.ToString()); + + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/chatroom.html#send + * + * 聊天室消息 + * */ + + String[] chatroomIds = { "OIBbeKlkx" }; + + CustomTxtMessage ctm = new CustomTxtMessage("hello world"); + ChatroomMessage chatroomMessage = new ChatroomMessage() + { + SenderId = "aP9uvganV", + TargetId = chatroomIds, + Content = ctm, + ObjectName = ctm.GetType() + }; + + ResponseResult chatroomResult = chatroom.Send(chatroomMessage); + Console.WriteLine("send chatroom message: " + chatroomResult.ToString()); + + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/chatroom.html#broadcast + * + * 聊天室广播消息 + * + * 此功能需开通专有服务: http://www.rongcloud.cn/deployment#overseas-cloud + * + * */ + chatroomMessage = new ChatroomMessage() + { + SenderId = "aP9uvganV", + Content = txtMessage, + ObjectName = txtMessage.GetType() + }; + + + ResponseResult chatroomBroadcastresult = chatroom.Broadcast(chatroomMessage); + Console.WriteLine("send chatroom broadcast message: " + chatroomBroadcastresult.ToString()); + + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/history.html#get + * + * 获取历史消息日志文件 + * + * */ + + HistoryMessageResult historyMessageResult = history.Get("2019011711"); + Console.WriteLine("get history message: " + historyMessageResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/message/history.html#get + * + * 删除历史消息日志文件 + * + * */ + ResponseResult removeHistoryMessageResult = history.Remove("2018030210"); + Console.WriteLine("remove history message: " + removeHistoryMessageResult.ToString()); + Console.ReadLine(); + + } + } +} diff --git a/example/sensitive/SensitiveExample.cs b/example/sensitive/SensitiveExample.cs new file mode 100644 index 0000000..98e519f --- /dev/null +++ b/example/sensitive/SensitiveExample.cs @@ -0,0 +1,103 @@ +using io.rong.models.response; +using io.rong.methods.sensitive; +using io.rong.models.sensitiveword; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Newtonsoft.Json; + +namespace io.rong.example.group +{ + + class SensitiveExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "pwe86ga5pwrj6"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "rb8fWki1mJcK"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api 地址方式 + // RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + SensitiveWord SensitiveWord = rongCloud.sensitiveword; + + /** + *API 文档: http://www.rongcloud.cn/docs/server_sdk_api/sensitive/sensitive.html#add + * + * 添加替换敏感词方法 + * + * */ + SensitiveWordModel sentiveWord = new SensitiveWordModel() + { + Type = 0, + Keyword = "黄赌黄", + Replace = "***" + }; + + ResponseResult addesult = SensitiveWord.Add(sentiveWord); + Console.WriteLine("sentiveWord add: " + addesult.ToString()); + + /** + *API 文档: http://www.rongcloud.cn/docs/server_sdk_api/sensitive/sensitive.html#add + * + * 添加替换敏感词方法 + * + * */ + sentiveWord = new SensitiveWordModel() + { + Type = 1, + Keyword = "黄赌黄" + }; + + ResponseResult addersult = SensitiveWord.Add(sentiveWord); + Console.WriteLine("sentiveWord add replace : " + addersult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/sensitive/sensitive.html#getList + * 查询敏感词列表方法 + * + * */ + ListWordfilterResult result = SensitiveWord.GetList(1); + Console.WriteLine("getList: " + result.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/sensitive/sensitive.html#remove + * 移除敏感词方法(从敏感词列表中,移除某一敏感词。) + * + * */ + + ResponseResult removeesult = SensitiveWord.Remove("黄赌黄"); + Console.WriteLine("SensitivewordDelete: " + removeesult.ToString()); + + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/sensitive/sensitive.html#remove + * 批量移除敏感词方法(从敏感词列表中,批量移除某一敏感词。) + * + * */ + String[] words = { "黄赌毒" }; + ResponseResult batchDeleteResult = SensitiveWord.BatchDelete(words); + Console.WriteLine("SensitivewordbatchDelete: " + batchDeleteResult.ToString()); + Console.ReadLine(); + + } + } +} diff --git a/example/user/BlackListExample.cs b/example/user/BlackListExample.cs new file mode 100644 index 0000000..17f5547 --- /dev/null +++ b/example/user/BlackListExample.cs @@ -0,0 +1,76 @@ +using io.rong.methods.user.blacklist; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.example.user +{ + class BlackListExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "pwe86ga5pwrj6"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "rb8fWki1mJcK"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api 地址方式 + // RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Blacklist blackList = rongCloud.user.blackList; + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/black.html#add + * 添加用户到黑名单方法 + */ + UserModel blackUser = new UserModel() { Id = "hdsjGB88" }; + UserModel[] blacklist = { blackUser }; + UserModel user = new UserModel() + { + Id = "hdsjGB89", + Blacklist = blacklist + } +; + + + Result userAddBlacklistResult = (Result)blackList.Add(user); + Console.WriteLine("addBlacklist: " + userAddBlacklistResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/black.html#getList + * 获取某用户的黑名单列表方法 + */ + UserModel user2 = new UserModel() { Id = "hdsjGB89" }; + + BlackListResult result = blackList.GetList(user2); + Console.WriteLine("query blacklist: " + result.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/black.html#remove + * 从黑名单中移除用户方法 + */ + Result removeResult = blackList.Remove(user); + Console.WriteLine("remove blacklist: " + removeResult.ToString()); + + Console.ReadLine(); + + } + } +} diff --git a/example/user/BlockExample.cs b/example/user/BlockExample.cs new file mode 100644 index 0000000..273238a --- /dev/null +++ b/example/user/BlockExample.cs @@ -0,0 +1,74 @@ +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using io.rong.methods.user; +using io.rong.methods.user.block; + +namespace io.rong.example.user +{ + class BlockExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "pwe86ga5pwrj6"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "rb8fWki1mJcK"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api 地址方式 + // RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + + Block block = rongCloud.user.block; + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/block.html#add + * 解除用户封禁 + * + */ + UserModel user = new UserModel() + { + Id = "hkjo09h", + Minute = 1000 + }; + + Result addBlockResult = (ResponseResult)block.Add(user); + Console.WriteLine("userAddBlock: " + addBlockResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/block.html#remove + * 解除用户封禁 + * + */ + ResponseResult unBlockResult = (ResponseResult)block.Remove(user.Id); + Console.WriteLine("unBlock: " + unBlockResult.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/block.html#getList + * 获取被封禁用户 + * + */ + BlockUserResult blockResult = (BlockUserResult)block.GetList(); + Console.Write("queryBlock: " + blockResult.ToString()); + + Console.ReadLine(); + + } + } +} diff --git a/example/user/UserExample.cs b/example/user/UserExample.cs new file mode 100644 index 0000000..c91066c --- /dev/null +++ b/example/user/UserExample.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using io.rong.methods.user; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; + +namespace io.rong.example.user +{ + class UserExample + { + /** + * 此处替换成您的appKey + * */ + private static readonly String appKey = "pwe86ga5pwrj6"; + /** + * 此处替换成您的appSecret + * */ + private static readonly String appSecret = "rb8fWki1mJcK"; + /** + * 自定义api地址 + * */ + private static readonly String api = "http://api.cn.ronghub.com"; + + static void Main(String[] args) + { + + RongCloud rongCloud = RongCloud.GetInstance(appKey, appSecret); + //自定义 api 地址方式 + // RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret,api); + User User = rongCloud.user; + + /** + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/user.html#register + * + * 注册用户,生成用户在融云的唯一身份标识 Token + */ + UserModel user = new UserModel + { + Id = "注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token注册用户,生成用户在融云的唯一身份标识 Token", + Name = "username", + Portrait = "http://www.rongcloud.cn/images/logo.png" + }; + + TokenResult result = User.Register(user); + Console.WriteLine("getToken: " + result.ToString()); + + /** + * + * API 文档: http://www.rongcloud.cn/docs/server_sdk_api/user/user.html#refresh + * + * 刷新用户信息方法 + */ + Result refreshResult = User.Update(user); + Console.WriteLine("refresh: " + refreshResult.ToString()); + + Console.ReadLine(); + + } + } +} diff --git a/exception/Error.cs b/exception/Error.cs new file mode 100644 index 0000000..acd3abf --- /dev/null +++ b/exception/Error.cs @@ -0,0 +1,49 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.exception +{ + class Error + { + [JsonProperty(PropertyName = "url")] + private String url; + [JsonProperty(PropertyName = "httpCode")] + private int httpCode = 200; + [JsonProperty(PropertyName = "code")] + private int code; + [JsonProperty(PropertyName = "errorMessage")] + private String errorMessage; + + [JsonIgnore] + public string Url { get => url; set => url = value; } + [JsonIgnore] + public int HttpCode { get => httpCode; set => httpCode = value; } + [JsonIgnore] + public int Code { get => code; set => code = value; } + [JsonIgnore] + public string ErrorMessage { get => errorMessage; set => errorMessage = value; } + + public Error(int code, int httpCode, String url, String errorMessage) + { + this.url = url; + this.code = code; + this.errorMessage = errorMessage; + this.httpCode = httpCode; + } + + public bool HasError() + { + return this.code != 200; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/exception/ParamError.cs b/exception/ParamError.cs new file mode 100644 index 0000000..9e99b38 --- /dev/null +++ b/exception/ParamError.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.exception +{ + class ParamError : Error + { + public ParamError(int errorCode, String apiURL, String errorMessage) : base(errorCode, errorCode, apiURL, errorMessage) + { + } + + public ParamError(int errorCode, int httpCode, String apiURL, + String errorMessage) : base(errorCode, httpCode, apiURL, errorMessage) + { + + } + + public ParamError(String apiURL) : base(1002, 400, apiURL, "缺少参数,请检查。") + { + } + + public ParamError(String apiURL, String message) : base(1002, 400, apiURL, message) + { + } + } +} diff --git a/exception/ParamException.cs b/exception/ParamException.cs new file mode 100644 index 0000000..93a00a3 --- /dev/null +++ b/exception/ParamException.cs @@ -0,0 +1,43 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.exception +{ + + class ParamException : RcloudException + { + + private static readonly long serialVersionUID = -5021603276540528761L; + + public ParamException() + { + this.error = new ParamError("/"); + } + + public ParamException(String message, Exception e) : base(new ParamError("/", message).ToString(), e) + { + this.error = new ParamError("/", message); + } + + public ParamException(Exception e) : base(e.Message) + { + this.error = new ParamError("/"); + } + + public ParamException(String message) : base(message) + { + this.error = new ParamError("/", message); + } + + public ParamException(int errorCode, String apiUrl, String message) : base(new ParamError(errorCode, apiUrl, message).ToString()) + { + this.error = new ParamError(errorCode, apiUrl, message); + + } + } +} + diff --git a/exception/RcloudException.cs b/exception/RcloudException.cs new file mode 100644 index 0000000..4c0dd2a --- /dev/null +++ b/exception/RcloudException.cs @@ -0,0 +1,67 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.exception +{ + + abstract class RcloudException : Exception + { + /** + * + */ + private static readonly long serialVersionUID = -700374663662873165L; + protected Error error = null; + public RcloudException() + { + } + + public RcloudException(String message, Exception e) : base(message, e) + { + } + + public RcloudException(Exception e) : base(e.Message) + { + } + + public RcloudException(String message) : base(message) + { + } + + public Error GetError() + { + return error; + } + + public int GetErrorCode() + { + if (error == null) + { + return 200; + } + return error.Code; + } + + public int GetHttpCode() + { + if (error == null) + { + return 200; + } + return error.HttpCode; + } + + public void SetUri(String uri) + { + if (error == null) + { + return; + } + error.Url = uri; + } + } +} + diff --git a/io.rong.csproj b/io.rong.csproj deleted file mode 100644 index 4cfc590..0000000 --- a/io.rong.csproj +++ /dev/null @@ -1,127 +0,0 @@ - - - - Debug - x86 - {8BCCEE67-2A37-4952-8D9B-9E413DA7A54A} - Exe - false - ConsoleApplication - v4.0 - - - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 - - - io.rong - - - - - packages\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll - True - - - - - - - - - - - - - - - - - - Always - - - Always - - - Always - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/io.rong.csproj.user b/io.rong.csproj.user deleted file mode 100644 index 53b551a..0000000 --- a/io.rong.csproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/io/rong/Example.cs b/io/rong/Example.cs deleted file mode 100644 index ca0734b..0000000 --- a/io/rong/Example.cs +++ /dev/null @@ -1,329 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Web; -using System.IO; - -using donet.io.rong; -using donet.io.rong.util; -using donet.io.rong.models; -using donet.io.rong.messages; -using Newtonsoft.Json; - - -namespace donet.io.rong { - class Program { - static void Main(string[] args) { - String appKey = "appKey"; - String appSecret = "secret"; - RongCloud rongcloud = RongCloud.getInstance(appKey, appSecret); - JsonSerializer serializer = new JsonSerializer(); - - Console.WriteLine("**************** user ****************"); - // 获取 Token 方法 - TokenReslut usergetTokenResult = rongcloud.user.getToken("userId1","username","http://www.rongcloud.cn/images/logo.png"); - Console.WriteLine("user.getToken: "+ usergetTokenResult.toString()); - Console.ReadKey(); - - // 刷新用户信息方法 - CodeSuccessReslut userrefreshResult = rongcloud.user.refresh("userId1","username","http://www.rongcloud.cn/images/logo.png"); - Console.WriteLine("user.refresh: "+ userrefreshResult.toString()); - Console.ReadKey(); - - // 检查用户在线状态 方法 - CheckOnlineReslut usercheckOnlineResult = rongcloud.user.checkOnline("userId1"); - Console.WriteLine("user.checkOnline: "+ usercheckOnlineResult.toString()); - Console.ReadKey(); - - // 封禁用户方法(每秒钟限 100 次) - CodeSuccessReslut userblockResult = rongcloud.user.block("userId4",10); - Console.WriteLine("user.block: "+ userblockResult.toString()); - Console.ReadKey(); - - // 解除用户封禁方法(每秒钟限 100 次) - CodeSuccessReslut userunBlockResult = rongcloud.user.unBlock("userId2"); - Console.WriteLine("user.unBlock: "+ userunBlockResult.toString()); - Console.ReadKey(); - - // 获取被封禁用户方法(每秒钟限 100 次) - QueryBlockUserReslut userqueryBlockResult = rongcloud.user.queryBlock(); - Console.WriteLine("user.queryBlock: "+ userqueryBlockResult.toString()); - Console.ReadKey(); - - // 添加用户到黑名单方法(每秒钟限 100 次) - CodeSuccessReslut useraddBlacklistResult = rongcloud.user.addBlacklist("userId1","userId2"); - Console.WriteLine("user.addBlacklist: "+ useraddBlacklistResult.toString()); - Console.ReadKey(); - - // 获取某用户的黑名单列表方法(每秒钟限 100 次) - QueryBlacklistUserReslut userqueryBlacklistResult = rongcloud.user.queryBlacklist("userId1"); - Console.WriteLine("user.queryBlacklist: "+ userqueryBlacklistResult.toString()); - Console.ReadKey(); - - // 从黑名单中移除用户方法(每秒钟限 100 次) - CodeSuccessReslut userremoveBlacklistResult = rongcloud.user.removeBlacklist("userId1","userId2"); - Console.WriteLine("user.removeBlacklist: "+ userremoveBlacklistResult.toString()); - Console.ReadKey(); - - - Console.WriteLine("**************** message ****************"); - // 发送单聊消息方法(一个用户向另外一个用户发送消息,单条消息最大 128k。每分钟最多发送 6000 条信息,每次发送用户上限为 1000 人,如:一次发送 1000 人时,示为 1000 条消息。) - String[] messagepublishPrivateToUserId = {"userId2","userid3","userId4"}; - VoiceMessage messagepublishPrivateVoiceMessage = new VoiceMessage("hello","helloExtra",20L); - CodeSuccessReslut messagepublishPrivateResult = rongcloud.message.publishPrivate("userId1",messagepublishPrivateToUserId ,messagepublishPrivateVoiceMessage ,"thisisapush","{\"pushData\":\"hello\"}","4",0,0,0); - Console.WriteLine("message.publishPrivate: "+ messagepublishPrivateResult.toString()); - Console.ReadKey(); - - // 发送单聊模板消息方法(一个用户向多个用户发送不同消息内容,单条消息最大 128k。每分钟最多发送 6000 条信息,每次发送用户上限为 1000 人。) - String str10 = File.ReadAllText("./TemplateMessage.json"); - TemplateMessage publishTemplateTemplateMessage = RongJsonUtil.JsonStringToObj(str10); - CodeSuccessReslut messagepublishTemplateResult = rongcloud.message.publishTemplate( publishTemplateTemplateMessage); - Console.WriteLine("message.publishTemplate: "+ messagepublishTemplateResult.toString()); - Console.ReadKey(); - - // 发送系统消息方法(一个用户向一个或多个用户发送系统消息,单条消息最大 128k,会话类型为 SYSTEM。每秒钟最多发送 100 条消息,每次最多同时向 100 人发送,如:一次发送 100 人时,示为 100 条消息。) - String[] messagepublishSystemToUserId = {"userId2","userid3","userId4"}; - TxtMessage messagepublishSystemTxtMessage = new TxtMessage("hello","helloExtra"); - CodeSuccessReslut messagepublishSystemResult = rongcloud.message.PublishSystem("userId1",messagepublishSystemToUserId ,messagepublishSystemTxtMessage ,"thisisapush","{\"pushData\":\"hello\"}",0,0); - Console.WriteLine("message.PublishSystem: "+ messagepublishSystemResult.toString()); - Console.ReadKey(); - - // 发送系统模板消息方法(一个用户向一个或多个用户发送系统消息,单条消息最大 128k,会话类型为 SYSTEM.每秒钟最多发送 100 条消息,每次最多同时向 100 人发送,如:一次发送 100 人时,示为 100 条消息。) - String str12 = File.ReadAllText("./TemplateMessage.json"); - TemplateMessage publishSystemTemplateTemplateMessage = RongJsonUtil.JsonStringToObj(str12); - CodeSuccessReslut messagepublishSystemTemplateResult = rongcloud.message.publishSystemTemplate( publishSystemTemplateTemplateMessage); - Console.WriteLine("message.publishSystemTemplate: "+ messagepublishSystemTemplateResult.toString()); - Console.ReadKey(); - - // 发送群组消息方法(以一个用户身份向群组发送消息,单条消息最大 128k.每秒钟最多发送 20 条消息,每次最多向 3 个群组发送,如:一次向 3 个群组发送消息,示为 3 条消息。) - String[] messagepublishGroupToGroupId = {"groupId1","groupId2","groupId3"}; - TxtMessage messagepublishGroupTxtMessage = new TxtMessage("hello","helloExtra"); - CodeSuccessReslut messagepublishGroupResult = rongcloud.message.publishGroup("userId",messagepublishGroupToGroupId ,messagepublishGroupTxtMessage ,"thisisapush","{\"pushData\":\"hello\"}",1,1); - Console.WriteLine("message.publishGroup: "+ messagepublishGroupResult.toString()); - Console.ReadKey(); - - // 发送讨论组消息方法(以一个用户身份向讨论组发送消息,单条消息最大 128k,每秒钟最多发送 20 条消息.) - TxtMessage messagepublishDiscussionTxtMessage = new TxtMessage("hello","helloExtra"); - CodeSuccessReslut messagepublishDiscussionResult = rongcloud.message.publishDiscussion("userId1","discussionId1",messagepublishDiscussionTxtMessage ,"thisisapush","{\"pushData\":\"hello\"}",1,1); - Console.WriteLine("message.publishDiscussion: "+ messagepublishDiscussionResult.toString()); - Console.ReadKey(); - - // 发送聊天室消息方法(一个用户向聊天室发送消息,单条消息最大 128k。每秒钟限 100 次。) - String[] messagepublishChatroomToChatroomId = {"ChatroomId1","ChatroomId2","ChatroomId3"}; - TxtMessage messagepublishChatroomTxtMessage = new TxtMessage("hello","helloExtra"); - CodeSuccessReslut messagepublishChatroomResult = rongcloud.message.publishChatroom("userId1",messagepublishChatroomToChatroomId ,messagepublishChatroomTxtMessage ); - Console.WriteLine("message.publishChatroom: "+ messagepublishChatroomResult.toString()); - Console.ReadKey(); - - // 发送广播消息方法(发送消息给一个应用下的所有注册用户,如用户未在线会对满足条件(绑定手机终端)的用户发送 Push 信息,单条消息最大 128k,会话类型为 SYSTEM。每小时只能发送 1 次,每天最多发送 3 次。) - TxtMessage messagebroadcastTxtMessage = new TxtMessage("hello","helloExtra"); - CodeSuccessReslut messagebroadcastResult = rongcloud.message.broadcast("userId1",messagebroadcastTxtMessage ,"thisisapush","{\"pushData\":\"hello\"}","iOS"); - Console.WriteLine("message.broadcast: "+ messagebroadcastResult.toString()); - Console.ReadKey(); - - // 消息历史记录下载地址获取 方法消息历史记录下载地址获取方法。获取 APP 内指定某天某小时内的所有会话消息记录的下载地址。(目前支持二人会话、讨论组、群组、聊天室、客服、系统通知消息历史记录下载) - HistoryMessageReslut messagegetHistoryResult = rongcloud.message.getHistory("2014010101"); - Console.WriteLine("message.getHistory: "+ messagegetHistoryResult.toString()); - Console.ReadKey(); - - // 消息历史记录删除方法(删除 APP 内指定某天某小时内的所有会话消息记录。调用该接口返回成功后,date参数指定的某小时的消息记录文件将在随后的5-10分钟内被永久删除。) - CodeSuccessReslut messagedeleteMessageResult = rongcloud.message.deleteMessage("2014010101"); - Console.WriteLine("message.deleteMessage: "+ messagedeleteMessageResult.toString()); - Console.ReadKey(); - - - Console.WriteLine("**************** wordfilter ****************"); - // 添加敏感词方法(设置敏感词后,App 中用户不会收到含有敏感词的消息内容,默认最多设置 50 个敏感词。) - CodeSuccessReslut wordfilteraddResult = rongcloud.wordfilter.add("money"); - Console.WriteLine("wordfilter.add: "+ wordfilteraddResult.toString()); - Console.ReadKey(); - - // 查询敏感词列表方法 - ListWordfilterReslut wordfiltergetListResult = rongcloud.wordfilter.getList(); - Console.WriteLine("wordfilter.getList: "+ wordfiltergetListResult.toString()); - Console.ReadKey(); - - // 移除敏感词方法(从敏感词列表中,移除某一敏感词。) - CodeSuccessReslut wordfilterdeleteResult = rongcloud.wordfilter.delete("money"); - Console.WriteLine("wordfilter.delete: "+ wordfilterdeleteResult.toString()); - Console.ReadKey(); - - - Console.WriteLine("**************** group ****************"); - // 创建群组方法(创建群组,并将用户加入该群组,用户将可以收到该群的消息,同一用户最多可加入 500 个群,每个群最大至 3000 人,App 内的群组数量没有限制.注:其实本方法是加入群组方法 /group/join 的别名。) - String[] groupcreateUserId = {"userId1","userid2","userId3"}; - CodeSuccessReslut groupcreateResult = rongcloud.group.create(groupcreateUserId ,"groupId1","groupName1"); - Console.WriteLine("group.create: "+ groupcreateResult.toString()); - Console.ReadKey(); - - // 同步用户所属群组方法(当第一次连接融云服务器时,需要向融云服务器提交 userId 对应的用户当前所加入的所有群组,此接口主要为防止应用中用户群信息同融云已知的用户所属群信息不同步。) - GroupInfo[] groupsyncGroupInfo = {new GroupInfo("groupId1","groupName1" ),new GroupInfo("groupId2","groupName2" ),new GroupInfo("groupId3","groupName3" )}; - CodeSuccessReslut groupsyncResult = rongcloud.group.sync("userId1",groupsyncGroupInfo ); - Console.WriteLine("group.sync: "+ groupsyncResult.toString()); - Console.ReadKey(); - - // 刷新群组信息方法 - CodeSuccessReslut grouprefreshResult = rongcloud.group.refresh("groupId1","newGroupName"); - Console.WriteLine("group.refresh: "+ grouprefreshResult.toString()); - Console.ReadKey(); - - // 将用户加入指定群组,用户将可以收到该群的消息,同一用户最多可加入 500 个群,每个群最大至 3000 人。 - String[] groupjoinUserId = {"userId2","userid3","userId4"}; - CodeSuccessReslut groupjoinResult = rongcloud.group.join(groupjoinUserId ,"groupId1","TestGroup"); - Console.WriteLine("group.join: "+ groupjoinResult.toString()); - Console.ReadKey(); - - // 查询群成员方法 - GroupUserQueryReslut groupqueryUserResult = rongcloud.group.queryUser("groupId1"); - Console.WriteLine("group.queryUser: "+ groupqueryUserResult.toString()); - Console.ReadKey(); - - // 退出群组方法(将用户从群中移除,不再接收该群组的消息.) - String[] groupquitUserId = {"userId2","userid3","userId4"}; - CodeSuccessReslut groupquitResult = rongcloud.group.quit(groupquitUserId ,"TestGroup"); - Console.WriteLine("group.quit: "+ groupquitResult.toString()); - Console.ReadKey(); - - // 添加禁言群成员方法(在 App 中如果不想让某一用户在群中发言时,可将此用户在群组中禁言,被禁言用户可以接收查看群组中用户聊天信息,但不能发送消息。) - CodeSuccessReslut groupaddGagUserResult = rongcloud.group.addGagUser("userId1","groupId1","1"); - Console.WriteLine("group.addGagUser: "+ groupaddGagUserResult.toString()); - Console.ReadKey(); - - // 查询被禁言群成员方法 - ListGagGroupUserReslut grouplisGagUserResult = rongcloud.group.lisGagUser("groupId1"); - Console.WriteLine("group.lisGagUser: "+ grouplisGagUserResult.toString()); - Console.ReadKey(); - - // 移除禁言群成员方法 - String[] grouprollBackGagUserUserId = {"userId2","userid3","userId4"}; - CodeSuccessReslut grouprollBackGagUserResult = rongcloud.group.rollBackGagUser(grouprollBackGagUserUserId ,"groupId1"); - Console.WriteLine("group.rollBackGagUser: "+ grouprollBackGagUserResult.toString()); - Console.ReadKey(); - - // 解散群组方法。(将该群解散,所有用户都无法再接收该群的消息。) - CodeSuccessReslut groupdismissResult = rongcloud.group.dismiss("userId1","groupId1"); - Console.WriteLine("group.dismiss: "+ groupdismissResult.toString()); - Console.ReadKey(); - - - Console.WriteLine("**************** chatroom ****************"); - // 创建聊天室方法 - ChatRoomInfo[] chatroomcreateChatRoomInfo = {new ChatRoomInfo("chatroomId1","chatroomName1" ),new ChatRoomInfo("chatroomId2","chatroomName2" ),new ChatRoomInfo("chatroomId3","chatroomName3" )}; - CodeSuccessReslut chatroomcreateResult = rongcloud.chatroom.create(chatroomcreateChatRoomInfo ); - Console.WriteLine("chatroom.create: "+ chatroomcreateResult.toString()); - Console.ReadKey(); - - // 加入聊天室方法 - String[] chatroomjoinUserId = {"userId2","userid3","userId4"}; - CodeSuccessReslut chatroomjoinResult = rongcloud.chatroom.join(chatroomjoinUserId ,"chatroomId1"); - Console.WriteLine("chatroom.join: "+ chatroomjoinResult.toString()); - Console.ReadKey(); - - // 查询聊天室信息方法 - String[] chatroomqueryChatroomId = {"chatroomId1","chatroomId2","chatroomId3"}; - ChatroomQueryReslut chatroomqueryResult = rongcloud.chatroom.query(chatroomqueryChatroomId ); - Console.WriteLine("chatroom.query: "+ chatroomqueryResult.toString()); - Console.ReadKey(); - - // 查询聊天室内用户方法 - ChatroomUserQueryReslut chatroomqueryUserResult = rongcloud.chatroom.queryUser("chatroomId1","500","2"); - Console.WriteLine("chatroom.queryUser: "+ chatroomqueryUserResult.toString()); - Console.ReadKey(); - - // 聊天室消息停止分发方法(可实现控制对聊天室中消息是否进行分发,停止分发后聊天室中用户发送的消息,融云服务端不会再将消息发送给聊天室中其他用户。) - CodeSuccessReslut chatroomstopDistributionMessageResult = rongcloud.chatroom.stopDistributionMessage("chatroomId1"); - Console.WriteLine("chatroom.stopDistributionMessage: "+ chatroomstopDistributionMessageResult.toString()); - Console.ReadKey(); - - // 聊天室消息恢复分发方法 - CodeSuccessReslut chatroomresumeDistributionMessageResult = rongcloud.chatroom.resumeDistributionMessage("chatroomId1"); - Console.WriteLine("chatroom.resumeDistributionMessage: "+ chatroomresumeDistributionMessageResult.toString()); - Console.ReadKey(); - - // 添加禁言聊天室成员方法(在 App 中如果不想让某一用户在聊天室中发言时,可将此用户在聊天室中禁言,被禁言用户可以接收查看聊天室中用户聊天信息,但不能发送消息.) - CodeSuccessReslut chatroomaddGagUserResult = rongcloud.chatroom.addGagUser("userId1","chatroomId1","1"); - Console.WriteLine("chatroom.addGagUser: "+ chatroomaddGagUserResult.toString()); - Console.ReadKey(); - - // 查询被禁言聊天室成员方法 - ListGagChatroomUserReslut chatroomlistGagUserResult = rongcloud.chatroom.ListGagUser("chatroomId1"); - Console.WriteLine("chatroom.ListGagUser: "+ chatroomlistGagUserResult.toString()); - Console.ReadKey(); - - // 移除禁言聊天室成员方法 - CodeSuccessReslut chatroomrollbackGagUserResult = rongcloud.chatroom.rollbackGagUser("userId1","chatroomId1"); - Console.WriteLine("chatroom.rollbackGagUser: "+ chatroomrollbackGagUserResult.toString()); - Console.ReadKey(); - - // 添加封禁聊天室成员方法 - CodeSuccessReslut chatroomaddBlockUserResult = rongcloud.chatroom.addBlockUser("userId1","chatroomId1","1"); - Console.WriteLine("chatroom.addBlockUser: "+ chatroomaddBlockUserResult.toString()); - Console.ReadKey(); - - // 查询被封禁聊天室成员方法 - ListBlockChatroomUserReslut chatroomgetListBlockUserResult = rongcloud.chatroom.getListBlockUser("chatroomId1"); - Console.WriteLine("chatroom.getListBlockUser: "+ chatroomgetListBlockUserResult.toString()); - Console.ReadKey(); - - // 移除封禁聊天室成员方法 - CodeSuccessReslut chatroomrollbackBlockUserResult = rongcloud.chatroom.rollbackBlockUser("userId1","chatroomId1"); - Console.WriteLine("chatroom.rollbackBlockUser: "+ chatroomrollbackBlockUserResult.toString()); - Console.ReadKey(); - - // 销毁聊天室方法 - String[] chatroomdestroyChatroomId = {"chatroomId","chatroomId1","chatroomId2"}; - CodeSuccessReslut chatroomdestroyResult = rongcloud.chatroom.destroy(chatroomdestroyChatroomId ); - Console.WriteLine("chatroom.destroy: "+ chatroomdestroyResult.toString()); - Console.ReadKey(); - - // 添加聊天室消息优先级方法 - String[] chatroomaddPriorityObjectName = {"RC:VcMsg","RC:ImgTextMsg","RC:ImgMsg"}; - CodeSuccessReslut chatroomaddPriorityResult = rongcloud.chatroom.addPriority(chatroomaddPriorityObjectName ); - Console.WriteLine("chatroom.addPriority: "+ chatroomaddPriorityResult.toString()); - Console.ReadKey(); - - // 添加聊天室白名单成员方法 - String[] chatroomaddWhiteListUserUserId = {"userId1","userId2","userId3","userId4","userId5"}; - CodeSuccessReslut chatroomaddWhiteListUserResult = rongcloud.chatroom.addWhiteListUser("chatroomId",chatroomaddWhiteListUserUserId ); - Console.WriteLine("chatroom.addWhiteListUser: "+ chatroomaddWhiteListUserResult.toString()); - Console.ReadKey(); - - - Console.WriteLine("**************** push ****************"); - // 添加 Push 标签方法 - String str47 = File.ReadAllText("./UserTag.json"); - UserTag setUserPushTagUserTag = RongJsonUtil.JsonStringToObj(str47); - CodeSuccessReslut pushsetUserPushTagResult = rongcloud.push.setUserPushTag( setUserPushTagUserTag); - Console.WriteLine("push.setUserPushTag: "+ pushsetUserPushTagResult.toString()); - Console.ReadKey(); - - // 广播消息方法(fromuserid 和 message为null即为不落地的push) - String str48 = File.ReadAllText("./PushMessage.json"); - PushMessage broadcastPushPushMessage = RongJsonUtil.JsonStringToObj(str48); - CodeSuccessReslut pushbroadcastPushResult = rongcloud.push.broadcastPush( broadcastPushPushMessage); - Console.WriteLine("push.broadcastPush: "+ pushbroadcastPushResult.toString()); - Console.ReadKey(); - - - Console.WriteLine("**************** SMS ****************"); - // 获取图片验证码方法 - SMSImageCodeReslut sMSgetImageCodeResult = rongcloud.sms.getImageCode("app-key"); - Console.WriteLine("SMS.getImageCode: "+ sMSgetImageCodeResult.toString()); - Console.ReadKey(); - - // 发送短信验证码方法。 - SMSSendCodeReslut sMSsendCodeResult = rongcloud.sms.sendCode("13500000000","dsfdsfd","86","1408706337","1408706337"); - Console.WriteLine("SMS.sendCode: "+ sMSsendCodeResult.toString()); - Console.ReadKey(); - - // 验证码验证方法 - CodeSuccessReslut sMSverifyCodeResult = rongcloud.sms.verifyCode("2312312","2312312"); - Console.WriteLine("SMS.verifyCode: "+ sMSverifyCodeResult.toString()); - Console.ReadKey(); - - - } - } -} \ No newline at end of file diff --git a/io/rong/RongCloud.cs b/io/rong/RongCloud.cs deleted file mode 100644 index 715e861..0000000 --- a/io/rong/RongCloud.cs +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 融云 Server API donet 客户端 - * create by kitName - * create datetime : 2016-10-19 - * - * v2.0.1 - */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Collections; -using System.Web; -using donet.io.rong.models; -using donet.io.rong.util; -using donet.io.rong.methods; -using System.Collections.Generic; - -namespace donet.io.rong { - public class RongCloud { - - private static Dictionary rongCloud = new Dictionary(); - public static String RONGCLOUDURI = "http://api.cn.ronghub.com"; - public static String RONGCLOUDSMSURI = "http://api.sms.ronghub.com"; - //确保线程同步 - private static readonly object locker = new object(); - - public User user; - public Message message; - public Wordfilter wordfilter; - public Group group; - public Chatroom chatroom; - public Push push; - public SMS sms; - - private RongCloud(String appKey, String appSecret) { - user = new User(appKey, appSecret); - message = new Message(appKey, appSecret); - wordfilter = new Wordfilter(appKey, appSecret); - group = new Group(appKey, appSecret); - chatroom = new Chatroom(appKey, appSecret); - push = new Push(appKey, appSecret); - sms = new SMS(appKey, appSecret); - - } - - public static RongCloud getInstance(String appKey, String appSecret) { - lock (locker) { - if (!rongCloud.ContainsKey(appKey)) { - rongCloud.Add(appKey, new RongCloud(appKey, appSecret)); - } - } - return rongCloud[appKey]; - } - } -} \ No newline at end of file diff --git a/io/rong/messages/CmdMsgMessage.cs b/io/rong/messages/CmdMsgMessage.cs deleted file mode 100644 index 03d2540..0000000 --- a/io/rong/messages/CmdMsgMessage.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 通用命令通知消息。此类型消息没有 Push 通知。此类型消息没有 Push 通知,与通用命令通知消息的区别是不存储、不计数。 - * - */ - public class CmdMsgMessage { - [JsonProperty] - private String name = ""; - [JsonProperty] - private String data = ""; - private static String TYPE = "RC:TxtMsg"; - - public CmdMsgMessage() { - - } - - public CmdMsgMessage(String name, String data) { - this.name = name; - this.data = data; - } - - public String getType() { - return TYPE; - } - - /** - * 获取命令名称,可以自行定义 - * - * @returnString - */ - public String getName() { - return name; - } - - /** - * 设置命令名称,可以自行定义 - * - * @return - */ - public void setName(String name) { - this.name = name; - } - - /** - * 获取命令的内容 - * - * @returnString - */ - public String getData() { - return data; - } - - /** - * 设置命令的内容 - * - * @return - */ - public void setData(String data) { - this.data = data; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/CmdNtfMessage.cs b/io/rong/messages/CmdNtfMessage.cs deleted file mode 100644 index 5196183..0000000 --- a/io/rong/messages/CmdNtfMessage.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 通用命令通知消息。此类型消息没有 Push 通知。 - * - */ - public class CmdNtfMessage { - [JsonProperty] - private String name = ""; - [JsonProperty] - private String data = ""; - private static String TYPE = "RC:CmdNtf"; - - public CmdNtfMessage() { - - } - - public CmdNtfMessage(String name, String data) { - this.name = name; - this.data = data; - } - - public String getType() { - return TYPE; - } - - /** - * 获取命令名称,可以自行定义 - * - * @returnString - */ - public String getName() { - return name; - } - - /** - * 设置命令名称,可以自行定义 - * - * @return - */ - public void setName(String name) { - this.name = name; - } - - /** - * 获取命令的内容 - * - * @returnString - */ - public String getData() { - return data; - } - - /** - * 设置命令的内容 - * - * @return - */ - public void setData(String data) { - this.data = data; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/ContactNtfMessage.cs b/io/rong/messages/ContactNtfMessage.cs deleted file mode 100644 index b99bb60..0000000 --- a/io/rong/messages/ContactNtfMessage.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 添加联系人消息。 - * - */ - public class ContactNtfMessage { - [JsonProperty] - private String operation = ""; - [JsonProperty] - private String extra = ""; - [JsonProperty] - private String sourceUserId = ""; - [JsonProperty] - private String targetUserId = ""; - [JsonProperty] - private String message = ""; - private static String TYPE = "RC:ContactNtf"; - - public ContactNtfMessage() { - - } - - public ContactNtfMessage(String operation, String extra, String sourceUserId, String targetUserId, String message) { - this.operation = operation; - this.extra = extra; - this.sourceUserId = sourceUserId; - this.targetUserId = targetUserId; - this.message = message; - } - - public String getType() { - return TYPE; - } - - /** - * 获取操作名。 - * - * @returnString - */ - public String getOperation() { - return operation; - } - - /** - * 设置操作名。 - * - * @return - */ - public void setOperation(String operation) { - this.operation = operation; - } - - /** - * 获取为附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @returnString - */ - public String getExtra() { - return extra; - } - - /** - * 设置为附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @return - */ - public void setExtra(String extra) { - this.extra = extra; - } - - /** - * 获取请求者或者响应者的 UserId。 - * - * @returnString - */ - public String getSourceUserId() { - return sourceUserId; - } - - /** - * 设置请求者或者响应者的 UserId。 - * - * @return - */ - public void setSourceUserId(String sourceUserId) { - this.sourceUserId = sourceUserId; - } - - /** - * 获取被请求者或者被响应者的 UserId。 - * - * @returnString - */ - public String getTargetUserId() { - return targetUserId; - } - - /** - * 设置被请求者或者被响应者的 UserId。 - * - * @return - */ - public void setTargetUserId(String targetUserId) { - this.targetUserId = targetUserId; - } - - /** - * 获取请求或者响应消息。 - * - * @returnString - */ - public String getMessage() { - return message; - } - - /** - * 设置请求或者响应消息。 - * - * @return - */ - public void setMessage(String message) { - this.message = message; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/CustomTxtMessage.cs b/io/rong/messages/CustomTxtMessage.cs deleted file mode 100644 index 3161612..0000000 --- a/io/rong/messages/CustomTxtMessage.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 自定义消息 - * - */ - public class CustomTxtMessage { - [JsonProperty] - private String content = ""; - private static String TYPE = "RC:TxtMsg"; - - public CustomTxtMessage() { - - } - - public CustomTxtMessage(String content) { - this.content = content; - } - - public String getType() { - return TYPE; - } - - /** - * 获取自定义消息内容。 - * - * @returnString - */ - public String getContent() { - return content; - } - - /** - * 设置自定义消息内容。 - * - * @return - */ - public void setContent(String content) { - this.content = content; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/ImgMessage.cs b/io/rong/messages/ImgMessage.cs deleted file mode 100644 index e18d3c4..0000000 --- a/io/rong/messages/ImgMessage.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 图片消息。 - * - */ - public class ImgMessage { - [JsonProperty] - private String content = ""; - [JsonProperty] - private String extra = ""; - [JsonProperty] - private String imageUri = ""; - private static String TYPE = "RC:ImgMsg"; - - public ImgMessage() { - - } - - public ImgMessage(String content, String extra, String imageUri) { - this.content = content; - this.extra = extra; - this.imageUri = imageUri; - } - - public String getType() { - return TYPE; - } - - /** - * 获取表示图片缩略图,格式为 JPG,大小不超过 30k,注意在 Base64 进行 Encode 后需要将所有 \r\n 和 \r 和 \n 替换成空。 - * - * @returnString - */ - public String getContent() { - return content; - } - - /** - * 设置表示图片缩略图,格式为 JPG,大小不超过 30k,注意在 Base64 进行 Encode 后需要将所有 \r\n 和 \r 和 \n 替换成空。 - * - * @return - */ - public void setContent(String content) { - this.content = content; - } - - /** - * 获取为附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @returnString - */ - public String getExtra() { - return extra; - } - - /** - * 设置为附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @return - */ - public void setExtra(String extra) { - this.extra = extra; - } - - /** - * 获取图片 Url。 - * - * @returnString - */ - public String getImageUri() { - return imageUri; - } - - /** - * 设置图片 Url。 - * - * @return - */ - public void setImageUri(String imageUri) { - this.imageUri = imageUri; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/ImgTextMessage.cs b/io/rong/messages/ImgTextMessage.cs deleted file mode 100644 index 2a9e453..0000000 --- a/io/rong/messages/ImgTextMessage.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 图文消息。 - * - */ - public class ImgTextMessage { - [JsonProperty] - private String content = ""; - [JsonProperty] - private String extra = ""; - [JsonProperty] - private String title = ""; - [JsonProperty] - private String imageUri = ""; - [JsonProperty] - private String url = ""; - private static String TYPE = "RC:ImgTextMsg"; - - public ImgTextMessage() { - - } - - public ImgTextMessage(String content, String extra, String title, String imageUri, String url) { - this.content = content; - this.extra = extra; - this.title = title; - this.imageUri = imageUri; - this.url = url; - } - - public String getType() { - return TYPE; - } - - /** - * 获取消息文本内容。 - * - * @returnString - */ - public String getContent() { - return content; - } - - /** - * 设置消息文本内容。 - * - * @return - */ - public void setContent(String content) { - this.content = content; - } - - /** - * 获取附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @returnString - */ - public String getExtra() { - return extra; - } - - /** - * 设置附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @return - */ - public void setExtra(String extra) { - this.extra = extra; - } - - /** - * 获取消息标题。 - * - * @returnString - */ - public String getTitle() { - return title; - } - - /** - * 设置消息标题。 - * - * @return - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * 获取图片地址。 - * - * @returnString - */ - public String getImageUri() { - return imageUri; - } - - /** - * 设置图片地址。 - * - * @return - */ - public void setImageUri(String imageUri) { - this.imageUri = imageUri; - } - - /** - * 获取 url 跳转地址。 - * - * @returnString - */ - public String getUrl() { - return url; - } - - /** - * 设置 url 跳转地址。 - * - * @return - */ - public void setUrl(String url) { - this.url = url; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/InfoNtfMessage.cs b/io/rong/messages/InfoNtfMessage.cs deleted file mode 100644 index 6f4e42b..0000000 --- a/io/rong/messages/InfoNtfMessage.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 提示条(小灰条)通知消息。此类型消息没有 Push 通知。 - * - */ - public class InfoNtfMessage { - [JsonProperty] - private String message = ""; - [JsonProperty] - private String extra = ""; - private static String TYPE = "RC:InfoNtf"; - - public InfoNtfMessage() { - - } - - public InfoNtfMessage(String message, String extra) { - this.message = message; - this.extra = extra; - } - - public String getType() { - return TYPE; - } - - /** - * 获取提示条消息内容。 - * - * @returnString - */ - public String getMessage() { - return message; - } - - /** - * 设置提示条消息内容。 - * - * @return - */ - public void setMessage(String message) { - this.message = message; - } - - /** - * 获取附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @returnString - */ - public String getExtra() { - return extra; - } - - /** - * 设置附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @return - */ - public void setExtra(String extra) { - this.extra = extra; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/LBSMessage.cs b/io/rong/messages/LBSMessage.cs deleted file mode 100644 index 9cef37c..0000000 --- a/io/rong/messages/LBSMessage.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 位置消息。 - * - */ - public class LBSMessage { - [JsonProperty] - private String content = ""; - [JsonProperty] - private String extra = ""; - [JsonProperty] - private double latitude = 0; - [JsonProperty] - private double longitude = 0; - [JsonProperty] - private String poi = ""; - private static String TYPE = "RC:LBSMsg"; - - public LBSMessage() { - - } - - public LBSMessage(String content, String extra, double latitude, double longitude, String poi) { - this.content = content; - this.extra = extra; - this.latitude = latitude; - this.longitude = longitude; - this.poi = poi; - } - - public String getType() { - return TYPE; - } - - /** - * 获取位置图片缩略图,格式为 JPG,以 Base64 进行 Encode 后需要将所有 \r\n 和 \r 和 \ - 替换成空。 - * - * @returnString - */ - public String getContent() { - return content; - } - - /** - * 设置位置图片缩略图,格式为 JPG,以 Base64 进行 Encode 后需要将所有 \r\n 和 \r 和 \ - 替换成空。 - * - * @return - */ - public void setContent(String content) { - this.content = content; - } - - /** - * 获取为附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @returnString - */ - public String getExtra() { - return extra; - } - - /** - * 设置为附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @return - */ - public void setExtra(String extra) { - this.extra = extra; - } - - /** - * 获取纬度。 - * - * @returndouble - */ - public double getLatitude() { - return latitude; - } - - /** - * 设置纬度。 - * - * @return - */ - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - /** - * 获取经度。 - * - * @returndouble - */ - public double getLongitude() { - return longitude; - } - - /** - * 设置经度。 - * - * @return - */ - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - /** - * 获取位置信息。 - * - * @returnString - */ - public String getPoi() { - return poi; - } - - /** - * 设置位置信息。 - * - * @return - */ - public void setPoi(String poi) { - this.poi = poi; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/ProfileNtfMessage.cs b/io/rong/messages/ProfileNtfMessage.cs deleted file mode 100644 index 865e0b3..0000000 --- a/io/rong/messages/ProfileNtfMessage.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 资料通知消息。此类型消息没有 Push 通知。 - * - */ - public class ProfileNtfMessage { - [JsonProperty] - private String operation = ""; - [JsonProperty] - private String data = ""; - [JsonProperty] - private String extra = ""; - private static String TYPE = "RC:ProfileNtf"; - - public ProfileNtfMessage() { - - } - - public ProfileNtfMessage(String operation, String data, String extra) { - this.operation = operation; - this.data = data; - this.extra = extra; - } - - public String getType() { - return TYPE; - } - - /** - * 获取为资料通知操作,可以自行定义。 - * - * @returnString - */ - public String getOperation() { - return operation; - } - - /** - * 设置为资料通知操作,可以自行定义。 - * - * @return - */ - public void setOperation(String operation) { - this.operation = operation; - } - - /** - * 获取操作的数据。 - * - * @returnString - */ - public String getData() { - return data; - } - - /** - * 设置操作的数据。 - * - * @return - */ - public void setData(String data) { - this.data = data; - } - - /** - * 获取附加内容(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @returnString - */ - public String getExtra() { - return extra; - } - - /** - * 设置附加内容(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @return - */ - public void setExtra(String extra) { - this.extra = extra; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/TxtMessage.cs b/io/rong/messages/TxtMessage.cs deleted file mode 100644 index e9e1123..0000000 --- a/io/rong/messages/TxtMessage.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 文本消息。 - * - */ - public class TxtMessage { - [JsonProperty] - private String content = ""; - [JsonProperty] - private String extra = ""; - private static String TYPE = "RC:TxtMsg"; - - public TxtMessage() { - - } - - public TxtMessage(String content, String extra) { - this.content = content; - this.extra = extra; - } - - public String getType() { - return TYPE; - } - - /** - * 获取消息内容。 - * - * @returnString - */ - public String getContent() { - return content; - } - - /** - * 设置消息内容。 - * - * @return - */ - public void setContent(String content) { - this.content = content; - } - - /** - * 获取附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @returnString - */ - public String getExtra() { - return extra; - } - - /** - * 设置附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @return - */ - public void setExtra(String extra) { - this.extra = extra; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/messages/VoiceMessage.cs b/io/rong/messages/VoiceMessage.cs deleted file mode 100644 index 694304b..0000000 --- a/io/rong/messages/VoiceMessage.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.messages { - - /** - * - * 语音消息。 - * - */ - public class VoiceMessage { - [JsonProperty] - private String content = ""; - [JsonProperty] - private String extra = ""; - [JsonProperty] - private long duration = 0L; - private static String TYPE = "RC:VcMsg"; - - public VoiceMessage() { - - } - - public VoiceMessage(String content, String extra, long duration) { - this.content = content; - this.extra = extra; - this.duration = duration; - } - - public String getType() { - return TYPE; - } - - /** - * 获取表示语音内容,格式为 AMR,以 Base64 进行 Encode 后需要将所有 \r\n 和 \r 和 \n 替换成空,大小不超过 60k,duration 表示语音长度,最长为 60 秒。 - * - * @returnString - */ - public String getContent() { - return content; - } - - /** - * 设置表示语音内容,格式为 AMR,以 Base64 进行 Encode 后需要将所有 \r\n 和 \r 和 \n 替换成空,大小不超过 60k,duration 表示语音长度,最长为 60 秒。 - * - * @return - */ - public void setContent(String content) { - this.content = content; - } - - /** - * 获取为附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @returnString - */ - public String getExtra() { - return extra; - } - - /** - * 设置为附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 - * - * @return - */ - public void setExtra(String extra) { - this.extra = extra; - } - - /** - * 获取持续时间。 - * - * @returnlong - */ - public long getDuration() { - return duration; - } - - /** - * 设置持续时间。 - * - * @return - */ - public void setDuration(long duration) { - this.duration = duration; - } - - public string toString() { - JsonSerializerSettings jsetting = new JsonSerializerSettings(); - jsetting.NullValueHandling = NullValueHandling.Ignore; - return JsonConvert.SerializeObject(this); - } - } -} - diff --git a/io/rong/methods/Chatroom.cs b/io/rong/methods/Chatroom.cs deleted file mode 100644 index b464a3d..0000000 --- a/io/rong/methods/Chatroom.cs +++ /dev/null @@ -1,416 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Collections; -using System.Web; - -using donet.io.rong.models; -using donet.io.rong.util; -using donet.io.rong.messages; -using Newtonsoft.Json; - -namespace donet.io.rong.methods { - - public class Chatroom { - - private static String UTF8 = "UTF-8"; - private String appKey; - private String appSecret; - - public Chatroom(String appKey, String appSecret) { - this.appKey = appKey; - this.appSecret = appSecret; - - } - - /** - * 创建聊天室方法 - * - * @param chatRoomInfo:id:要创建的聊天室的id;name:要创建的聊天室的name。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut create(ChatRoomInfo[] chatRoomInfo) { - - if(chatRoomInfo == null) { - throw new ArgumentNullException("Paramer 'chatRoomInfo' is required"); - } - - String postStr = ""; - if(chatRoomInfo != null){ - for (int i = 0; i < chatRoomInfo.Length; i++) { - String id = HttpUtility.UrlEncode(chatRoomInfo[i].getId(), Encoding.UTF8); - String name = HttpUtility.UrlEncode(chatRoomInfo[i].getName(), Encoding.UTF8); - postStr += "chatroom[" + id + "]=" + name + "&"; - } - } - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/create.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 加入聊天室方法 - * - * @param userId:要加入聊天室的用户 Id,可提交多个,最多不超过 50 个。(必传) - * @param chatroomId:要加入的聊天室 Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut join(String[] userId, String chatroomId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - for(int i = 0 ; i< userId.Length; i++){ - String child = userId[i]; - postStr += "userId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/join.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 查询聊天室信息方法 - * - * @param chatroomId:要查询的聊天室id(必传) - * - * @return ChatroomQueryReslut - **/ - public ChatroomQueryReslut query(String[] chatroomId) { - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - for(int i = 0 ; i< chatroomId.Length; i++){ - String child = chatroomId[i]; - postStr += "chatroomId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (ChatroomQueryReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/query.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 查询聊天室内用户方法 - * - * @param chatroomId:要查询的聊天室 ID。(必传) - * @param count:要获取的聊天室成员数,上限为 500 ,超过 500 时最多返回 500 个成员。(必传) - * @param order:加入聊天室的先后顺序, 1 为加入时间正序, 2 为加入时间倒序。(必传) - * - * @return ChatroomUserQueryReslut - **/ - public ChatroomUserQueryReslut queryUser(String chatroomId, String count, String order) { - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - if(count == null) { - throw new ArgumentNullException("Paramer 'count' is required"); - } - - if(order == null) { - throw new ArgumentNullException("Paramer 'order' is required"); - } - - String postStr = ""; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr += "count=" + HttpUtility.UrlEncode(count == null ? "" : count,Encoding.UTF8) + "&"; - postStr += "order=" + HttpUtility.UrlEncode(order == null ? "" : order,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (ChatroomUserQueryReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/user/query.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 聊天室消息停止分发方法(可实现控制对聊天室中消息是否进行分发,停止分发后聊天室中用户发送的消息,融云服务端不会再将消息发送给聊天室中其他用户。) - * - * @param chatroomId:聊天室 Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut stopDistributionMessage(String chatroomId) { - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/message/stopDistribution.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 聊天室消息恢复分发方法 - * - * @param chatroomId:聊天室 Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut resumeDistributionMessage(String chatroomId) { - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/message/resumeDistribution.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 添加禁言聊天室成员方法(在 App 中如果不想让某一用户在聊天室中发言时,可将此用户在聊天室中禁言,被禁言用户可以接收查看聊天室中用户聊天信息,但不能发送消息.) - * - * @param userId:用户 Id。(必传) - * @param chatroomId:聊天室 Id。(必传) - * @param minute:禁言时长,以分钟为单位,最大值为43200分钟。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut addGagUser(String userId, String chatroomId, String minute) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - if(minute == null) { - throw new ArgumentNullException("Paramer 'minute' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr += "minute=" + HttpUtility.UrlEncode(minute == null ? "" : minute,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/user/gag/add.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 查询被禁言聊天室成员方法 - * - * @param chatroomId:聊天室 Id。(必传) - * - * @return ListGagChatroomUserReslut - **/ - public ListGagChatroomUserReslut ListGagUser(String chatroomId) { - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (ListGagChatroomUserReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/user/gag/list.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 移除禁言聊天室成员方法 - * - * @param userId:用户 Id。(必传) - * @param chatroomId:聊天室Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut rollbackGagUser(String userId, String chatroomId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/user/gag/rollback.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 添加封禁聊天室成员方法 - * - * @param userId:用户 Id。(必传) - * @param chatroomId:聊天室 Id。(必传) - * @param minute:封禁时长,以分钟为单位,最大值为43200分钟。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut addBlockUser(String userId, String chatroomId, String minute) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - if(minute == null) { - throw new ArgumentNullException("Paramer 'minute' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr += "minute=" + HttpUtility.UrlEncode(minute == null ? "" : minute,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/user/block/add.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 查询被封禁聊天室成员方法 - * - * @param chatroomId:聊天室 Id。(必传) - * - * @return ListBlockChatroomUserReslut - **/ - public ListBlockChatroomUserReslut getListBlockUser(String chatroomId) { - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (ListBlockChatroomUserReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/user/block/list.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 移除封禁聊天室成员方法 - * - * @param userId:用户 Id。(必传) - * @param chatroomId:聊天室 Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut rollbackBlockUser(String userId, String chatroomId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/user/block/rollback.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 销毁聊天室方法 - * - * @param chatroomId:要销毁的聊天室 Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut destroy(String[] chatroomId) { - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - String postStr = ""; - for(int i = 0 ; i< chatroomId.Length; i++){ - String child = chatroomId[i]; - postStr += "chatroomId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/destroy.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 添加聊天室消息优先级方法 - * - * @param objectName:低优先级的消息类型,每次最多提交 5 个,设置的消息类型最多不超过 20 个。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut addPriority(String[] objectName) { - - if(objectName == null) { - throw new ArgumentNullException("Paramer 'objectName' is required"); - } - - String postStr = ""; - for(int i = 0 ; i< objectName.Length; i++){ - String child = objectName[i]; - postStr += "objectName=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/message/priority/add.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 添加聊天室白名单成员方法 - * - * @param chatroomId:聊天室中用户 Id,可提交多个,聊天室中白名单用户最多不超过 5 个。(必传) - * @param userId:聊天室 Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut addWhiteListUser(String chatroomId, String[] userId) { - - if(chatroomId == null) { - throw new ArgumentNullException("Paramer 'chatroomId' is required"); - } - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - String postStr = ""; - postStr += "chatroomId=" + HttpUtility.UrlEncode(chatroomId == null ? "" : chatroomId,Encoding.UTF8) + "&"; - for(int i = 0 ; i< userId.Length; i++){ - String child = userId[i]; - postStr += "userId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/chatroom/user/whitelist/add.json", postStr, "application/x-www-form-urlencoded" )); - } - - } - -} \ No newline at end of file diff --git a/io/rong/methods/Group.cs b/io/rong/methods/Group.cs deleted file mode 100644 index 51d0273..0000000 --- a/io/rong/methods/Group.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Collections; -using System.Web; - -using donet.io.rong.models; -using donet.io.rong.util; -using donet.io.rong.messages; -using Newtonsoft.Json; - -namespace donet.io.rong.methods { - - public class Group { - - private static String UTF8 = "UTF-8"; - private String appKey; - private String appSecret; - - public Group(String appKey, String appSecret) { - this.appKey = appKey; - this.appSecret = appSecret; - - } - - /** - * 创建群组方法(创建群组,并将用户加入该群组,用户将可以收到该群的消息,同一用户最多可加入 500 个群,每个群最大至 3000 人,App 内的群组数量没有限制.注:其实本方法是加入群组方法 /group/join 的别名。) - * - * @param userId:要加入群的用户 Id。(必传) - * @param groupId:创建群组 Id。(必传) - * @param groupName:群组 Id 对应的名称。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut create(String[] userId, String groupId, String groupName) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - if(groupName == null) { - throw new ArgumentNullException("Paramer 'groupName' is required"); - } - - String postStr = ""; - for(int i = 0 ; i< userId.Length; i++){ - String child = userId[i]; - postStr += "userId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr += "groupName=" + HttpUtility.UrlEncode(groupName == null ? "" : groupName,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/create.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 同步用户所属群组方法(当第一次连接融云服务器时,需要向融云服务器提交 userId 对应的用户当前所加入的所有群组,此接口主要为防止应用中用户群信息同融云已知的用户所属群信息不同步。) - * - * @param userId:被同步群信息的用户 Id。(必传) - * @param groupInfo:该用户的群信息,如群 Id 已经存在,则不会刷新对应群组名称,如果想刷新群组名称请调用刷新群组信息方法。 - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut sync(String userId, GroupInfo[] groupInfo) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(groupInfo == null) { - throw new ArgumentNullException("Paramer 'groupInfo' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - if(groupInfo != null){ - for (int i = 0; i < groupInfo.Length; i++){ - String id = HttpUtility.UrlEncode(groupInfo[i].getId(), Encoding.UTF8); - String name = HttpUtility.UrlEncode(groupInfo[i].getName(), Encoding.UTF8); - postStr += "group[" + id + "]=" + name + "&"; - } - } - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/sync.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 刷新群组信息方法 - * - * @param groupId:群组 Id。(必传) - * @param groupName:群名称。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut refresh(String groupId, String groupName) { - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - if(groupName == null) { - throw new ArgumentNullException("Paramer 'groupName' is required"); - } - - String postStr = ""; - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr += "groupName=" + HttpUtility.UrlEncode(groupName == null ? "" : groupName,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/refresh.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 将用户加入指定群组,用户将可以收到该群的消息,同一用户最多可加入 500 个群,每个群最大至 3000 人。 - * - * @param userId:要加入群的用户 Id,可提交多个,最多不超过 1000 个。(必传) - * @param groupId:要加入的群 Id。(必传) - * @param groupName:要加入的群 Id 对应的名称。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut join(String[] userId, String groupId, String groupName) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - if(groupName == null) { - throw new ArgumentNullException("Paramer 'groupName' is required"); - } - - String postStr = ""; - for(int i = 0 ; i< userId.Length; i++){ - String child = userId[i]; - postStr += "userId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr += "groupName=" + HttpUtility.UrlEncode(groupName == null ? "" : groupName,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/join.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 查询群成员方法 - * - * @param groupId:群组Id。(必传) - * - * @return GroupUserQueryReslut - **/ - public GroupUserQueryReslut queryUser(String groupId) { - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - String postStr = ""; - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (GroupUserQueryReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/user/query.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 退出群组方法(将用户从群中移除,不再接收该群组的消息.) - * - * @param userId:要退出群的用户 Id.(必传) - * @param groupId:要退出的群 Id.(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut quit(String[] userId, String groupId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - String postStr = ""; - for(int i = 0 ; i< userId.Length; i++){ - String child = userId[i]; - postStr += "userId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/quit.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 添加禁言群成员方法(在 App 中如果不想让某一用户在群中发言时,可将此用户在群组中禁言,被禁言用户可以接收查看群组中用户聊天信息,但不能发送消息。) - * - * @param userId:用户 Id。(必传) - * @param groupId:群组 Id。(必传) - * @param minute:禁言时长,以分钟为单位,最大值为43200分钟。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut addGagUser(String userId, String groupId, String minute) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - if(minute == null) { - throw new ArgumentNullException("Paramer 'minute' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr += "minute=" + HttpUtility.UrlEncode(minute == null ? "" : minute,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/user/gag/add.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 查询被禁言群成员方法 - * - * @param groupId:群组Id。(必传) - * - * @return ListGagGroupUserReslut - **/ - public ListGagGroupUserReslut lisGagUser(String groupId) { - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - String postStr = ""; - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (ListGagGroupUserReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/user/gag/list.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 移除禁言群成员方法 - * - * @param userId:用户Id。支持同时移除多个群成员(必传) - * @param groupId:群组Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut rollBackGagUser(String[] userId, String groupId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - String postStr = ""; - for(int i = 0 ; i< userId.Length; i++){ - String child = userId[i]; - postStr += "userId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/user/gag/rollback.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 解散群组方法。(将该群解散,所有用户都无法再接收该群的消息。) - * - * @param userId:操作解散群的用户 Id。(必传) - * @param groupId:要解散的群 Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut dismiss(String userId, String groupId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(groupId == null) { - throw new ArgumentNullException("Paramer 'groupId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "groupId=" + HttpUtility.UrlEncode(groupId == null ? "" : groupId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/group/dismiss.json", postStr, "application/x-www-form-urlencoded" )); - } - - } - -} \ No newline at end of file diff --git a/io/rong/methods/Message.cs b/io/rong/methods/Message.cs deleted file mode 100644 index 15126fc..0000000 --- a/io/rong/methods/Message.cs +++ /dev/null @@ -1,380 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Collections; -using System.Web; - -using donet.io.rong.models; -using donet.io.rong.util; -using donet.io.rong.messages; -using Newtonsoft.Json; - -namespace donet.io.rong.methods { - - public class Message { - - private static String UTF8 = "UTF-8"; - private String appKey; - private String appSecret; - - public Message(String appKey, String appSecret) { - this.appKey = appKey; - this.appSecret = appSecret; - - } - - /** - * 发送单聊消息方法(一个用户向另外一个用户发送消息,单条消息最大 128k。每分钟最多发送 6000 条信息,每次发送用户上限为 1000 人,如:一次发送 1000 人时,示为 1000 条消息。) - * - * @param fromUserId:发送人用户 Id。(必传) - * @param toUserId:接收用户 Id,可以实现向多人发送消息,每次上限为 1000 人。(必传) - * @param voiceMessage:消息。 - * @param pushContent:定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息。如果为自定义消息,则 pushContent 为自定义消息显示的 Push 内容,如果不传则用户不会收到 Push 通知。(可选) - * @param pushData:针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。(可选) - * @param count:针对 iOS 平台,Push 时用来控制未读消息显示数,只有在 toUserId 为一个用户 Id 的时候有效。(可选) - * @param verifyBlacklist:是否过滤发送人黑名单列表,0 表示为不过滤、 1 表示为过滤,默认为 0 不过滤。(可选) - * @param isPersisted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行存储,0 表示为不存储、 1 表示为存储,默认为 1 存储消息。(可选) - * @param isCounted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数,0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut publishPrivate(String fromUserId, String[] toUserId, VoiceMessage message, String pushContent, String pushData, String count, int verifyBlacklist, int isPersisted, int isCounted) { - - if(fromUserId == null) { - throw new ArgumentNullException("Paramer 'fromUserId' is required"); - } - - if(toUserId == null) { - throw new ArgumentNullException("Paramer 'toUserId' is required"); - } - - if(message.getType() == null) { - throw new ArgumentNullException("Paramer 'ObjectName' is required"); - } - - if(message.toString() == null) { - throw new ArgumentNullException("Paramer 'Content' is required"); - } - - String postStr = ""; - postStr += "fromUserId=" + HttpUtility.UrlEncode(fromUserId == null ? "" : fromUserId,Encoding.UTF8) + "&"; - for(int i = 0 ; i< toUserId.Length; i++){ - String child = toUserId[i]; - postStr += "toUserId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "objectName=" + HttpUtility.UrlEncode(message.getType(),Encoding.UTF8) + "&"; - postStr += "content=" + HttpUtility.UrlEncode(message.toString(),Encoding.UTF8) + "&"; - postStr += "pushContent=" + HttpUtility.UrlEncode(pushContent == null ? "" : pushContent,Encoding.UTF8) + "&"; - postStr += "pushData=" + HttpUtility.UrlEncode(pushData == null ? "" : pushData,Encoding.UTF8) + "&"; - postStr += "count=" + HttpUtility.UrlEncode(count == null ? "" : count,Encoding.UTF8) + "&"; - postStr += "verifyBlacklist=" + HttpUtility.UrlEncode(Convert.ToString(verifyBlacklist) == null ? "" : Convert.ToString(verifyBlacklist),Encoding.UTF8) + "&"; - postStr += "isPersisted=" + HttpUtility.UrlEncode(Convert.ToString(isPersisted) == null ? "" : Convert.ToString(isPersisted),Encoding.UTF8) + "&"; - postStr += "isCounted=" + HttpUtility.UrlEncode(Convert.ToString(isCounted) == null ? "" : Convert.ToString(isCounted),Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/private/publish.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 发送单聊模板消息方法(一个用户向多个用户发送不同消息内容,单条消息最大 128k。每分钟最多发送 6000 条信息,每次发送用户上限为 1000 人。) - * - * @param templateMessage:单聊模版消息。 - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut publishTemplate(TemplateMessage templateMessage) { - - if(templateMessage == null) { - throw new ArgumentNullException("Paramer 'templateMessage' is required"); - } - - String postStr = ""; - postStr = JsonConvert.SerializeObject(templateMessage); - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/private/publish_template.json", postStr, "application/json" )); - } - - /** - * 发送系统消息方法(一个用户向一个或多个用户发送系统消息,单条消息最大 128k,会话类型为 SYSTEM。每秒钟最多发送 100 条消息,每次最多同时向 100 人发送,如:一次发送 100 人时,示为 100 条消息。) - * - * @param fromUserId:发送人用户 Id。(必传) - * @param toUserId:接收用户 Id,提供多个本参数可以实现向多人发送消息,上限为 1000 人。(必传) - * @param txtMessage:发送消息内容(必传) - * @param pushContent:如果为自定义消息,定义显示的 Push 内容,内容中定义标识通过 values 中设置的标识位内容进行替换.如消息类型为自定义不需要 Push 通知,则对应数组传空值即可。(可选) - * @param pushData:针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。如不需要 Push 功能对应数组传空值即可。(可选) - * @param isPersisted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行存储,0 表示为不存储、 1 表示为存储,默认为 1 存储消息。(可选) - * @param isCounted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数,0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut PublishSystem(String fromUserId, String[] toUserId, TxtMessage message, String pushContent, String pushData, int isPersisted, int isCounted) { - - if(fromUserId == null) { - throw new ArgumentNullException("Paramer 'fromUserId' is required"); - } - - if(toUserId == null) { - throw new ArgumentNullException("Paramer 'toUserId' is required"); - } - - if(message.getType() == null) { - throw new ArgumentNullException("Paramer 'ObjectName' is required"); - } - - if(message.toString() == null) { - throw new ArgumentNullException("Paramer 'Content' is required"); - } - - String postStr = ""; - postStr += "fromUserId=" + HttpUtility.UrlEncode(fromUserId == null ? "" : fromUserId,Encoding.UTF8) + "&"; - for(int i = 0 ; i< toUserId.Length; i++){ - String child = toUserId[i]; - postStr += "toUserId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "objectName=" + HttpUtility.UrlEncode(message.getType(),Encoding.UTF8) + "&"; - postStr += "content=" + HttpUtility.UrlEncode(message.toString(),Encoding.UTF8) + "&"; - postStr += "pushContent=" + HttpUtility.UrlEncode(pushContent == null ? "" : pushContent,Encoding.UTF8) + "&"; - postStr += "pushData=" + HttpUtility.UrlEncode(pushData == null ? "" : pushData,Encoding.UTF8) + "&"; - postStr += "isPersisted=" + HttpUtility.UrlEncode(Convert.ToString(isPersisted) == null ? "" : Convert.ToString(isPersisted),Encoding.UTF8) + "&"; - postStr += "isCounted=" + HttpUtility.UrlEncode(Convert.ToString(isCounted) == null ? "" : Convert.ToString(isCounted),Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/system/publish.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 发送系统模板消息方法(一个用户向一个或多个用户发送系统消息,单条消息最大 128k,会话类型为 SYSTEM.每秒钟最多发送 100 条消息,每次最多同时向 100 人发送,如:一次发送 100 人时,示为 100 条消息。) - * - * @param templateMessage:系统模版消息。 - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut publishSystemTemplate(TemplateMessage templateMessage) { - - if(templateMessage == null) { - throw new ArgumentNullException("Paramer 'templateMessage' is required"); - } - - String postStr = ""; - postStr = JsonConvert.SerializeObject(templateMessage); - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/system/publish_template.json", postStr, "application/json" )); - } - - /** - * 发送群组消息方法(以一个用户身份向群组发送消息,单条消息最大 128k.每秒钟最多发送 20 条消息,每次最多向 3 个群组发送,如:一次向 3 个群组发送消息,示为 3 条消息。) - * - * @param fromUserId:发送人用户 Id 。(必传) - * @param toGroupId:接收群Id,提供多个本参数可以实现向多群发送消息,最多不超过 3 个群组。(必传) - * @param txtMessage:发送消息内容(必传) - * @param pushContent:定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息. 如果为自定义消息,则 pushContent 为自定义消息显示的 Push 内容,如果不传则用户不会收到 Push 通知。(可选) - * @param pushData:针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。(可选) - * @param isPersisted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行存储,0 表示为不存储、 1 表示为存储,默认为 1 存储消息。(可选) - * @param isCounted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数,0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut publishGroup(String fromUserId, String[] toGroupId, TxtMessage message, String pushContent, String pushData, int isPersisted, int isCounted) { - - if(fromUserId == null) { - throw new ArgumentNullException("Paramer 'fromUserId' is required"); - } - - if(toGroupId == null) { - throw new ArgumentNullException("Paramer 'toGroupId' is required"); - } - - if(message.getType() == null) { - throw new ArgumentNullException("Paramer 'ObjectName' is required"); - } - - if(message.toString() == null) { - throw new ArgumentNullException("Paramer 'Content' is required"); - } - - String postStr = ""; - postStr += "fromUserId=" + HttpUtility.UrlEncode(fromUserId == null ? "" : fromUserId,Encoding.UTF8) + "&"; - for(int i = 0 ; i< toGroupId.Length; i++){ - String child = toGroupId[i]; - postStr += "toGroupId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "objectName=" + HttpUtility.UrlEncode(message.getType(),Encoding.UTF8) + "&"; - postStr += "content=" + HttpUtility.UrlEncode(message.toString(),Encoding.UTF8) + "&"; - postStr += "pushContent=" + HttpUtility.UrlEncode(pushContent == null ? "" : pushContent,Encoding.UTF8) + "&"; - postStr += "pushData=" + HttpUtility.UrlEncode(pushData == null ? "" : pushData,Encoding.UTF8) + "&"; - postStr += "isPersisted=" + HttpUtility.UrlEncode(Convert.ToString(isPersisted) == null ? "" : Convert.ToString(isPersisted),Encoding.UTF8) + "&"; - postStr += "isCounted=" + HttpUtility.UrlEncode(Convert.ToString(isCounted) == null ? "" : Convert.ToString(isCounted),Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/group/publish.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 发送讨论组消息方法(以一个用户身份向讨论组发送消息,单条消息最大 128k,每秒钟最多发送 20 条消息.) - * - * @param fromUserId:发送人用户 Id。(必传) - * @param toDiscussionId:接收讨论组 Id。(必传) - * @param txtMessage:发送消息内容(必传) - * @param pushContent:定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息. 如果为自定义消息,则 pushContent 为自定义消息显示的 Push 内容,如果不传则用户不会收到 Push 通知。(可选) - * @param pushData:针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData.(可选) - * @param isPersisted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行存储,0 表示为不存储、 1 表示为存储,默认为 1 存储消息.(可选) - * @param isCounted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数,0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut publishDiscussion(String fromUserId, String toDiscussionId, TxtMessage message, String pushContent, String pushData, int isPersisted, int isCounted) { - - if(fromUserId == null) { - throw new ArgumentNullException("Paramer 'fromUserId' is required"); - } - - if(toDiscussionId == null) { - throw new ArgumentNullException("Paramer 'toDiscussionId' is required"); - } - - if(message.getType() == null) { - throw new ArgumentNullException("Paramer 'ObjectName' is required"); - } - - if(message.toString() == null) { - throw new ArgumentNullException("Paramer 'Content' is required"); - } - - String postStr = ""; - postStr += "fromUserId=" + HttpUtility.UrlEncode(fromUserId == null ? "" : fromUserId,Encoding.UTF8) + "&"; - postStr += "toDiscussionId=" + HttpUtility.UrlEncode(toDiscussionId == null ? "" : toDiscussionId,Encoding.UTF8) + "&"; - postStr += "objectName=" + HttpUtility.UrlEncode(message.getType(),Encoding.UTF8) + "&"; - postStr += "content=" + HttpUtility.UrlEncode(message.toString(),Encoding.UTF8) + "&"; - postStr += "pushContent=" + HttpUtility.UrlEncode(pushContent == null ? "" : pushContent,Encoding.UTF8) + "&"; - postStr += "pushData=" + HttpUtility.UrlEncode(pushData == null ? "" : pushData,Encoding.UTF8) + "&"; - postStr += "isPersisted=" + HttpUtility.UrlEncode(Convert.ToString(isPersisted) == null ? "" : Convert.ToString(isPersisted),Encoding.UTF8) + "&"; - postStr += "isCounted=" + HttpUtility.UrlEncode(Convert.ToString(isCounted) == null ? "" : Convert.ToString(isCounted),Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/discussion/publish.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 发送聊天室消息方法(一个用户向聊天室发送消息,单条消息最大 128k。每秒钟限 100 次。) - * - * @param fromUserId:发送人用户 Id。(必传) - * @param toChatroomId:接收聊天室Id,提供多个本参数可以实现向多个聊天室发送消息。(必传) - * @param txtMessage:发送消息内容(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut publishChatroom(String fromUserId, String[] toChatroomId, TxtMessage message) { - - if(fromUserId == null) { - throw new ArgumentNullException("Paramer 'fromUserId' is required"); - } - - if(toChatroomId == null) { - throw new ArgumentNullException("Paramer 'toChatroomId' is required"); - } - - if(message.getType() == null) { - throw new ArgumentNullException("Paramer 'ObjectName' is required"); - } - - if(message.toString() == null) { - throw new ArgumentNullException("Paramer 'Content' is required"); - } - - String postStr = ""; - postStr += "fromUserId=" + HttpUtility.UrlEncode(fromUserId == null ? "" : fromUserId,Encoding.UTF8) + "&"; - for(int i = 0 ; i< toChatroomId.Length; i++){ - String child = toChatroomId[i]; - postStr += "toChatroomId=" + HttpUtility.UrlEncode(child, Encoding.UTF8) + "&"; - } - - postStr += "objectName=" + HttpUtility.UrlEncode(message.getType(),Encoding.UTF8) + "&"; - postStr += "content=" + HttpUtility.UrlEncode(message.toString(),Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/chatroom/publish.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 发送广播消息方法(发送消息给一个应用下的所有注册用户,如用户未在线会对满足条件(绑定手机终端)的用户发送 Push 信息,单条消息最大 128k,会话类型为 SYSTEM。每小时只能发送 1 次,每天最多发送 3 次。) - * - * @param fromUserId:发送人用户 Id。(必传) - * @param txtMessage:文本消息。 - * @param pushContent:定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息. 如果为自定义消息,则 pushContent 为自定义消息显示的 Push 内容,如果不传则用户不会收到 Push 通知.(可选) - * @param pushData:针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。(可选) - * @param os:针对操作系统发送 Push,值为 iOS 表示对 iOS 手机用户发送 Push ,为 Android 时表示对 Android 手机用户发送 Push ,如对所有用户发送 Push 信息,则不需要传 os 参数。(可选) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut broadcast(String fromUserId, TxtMessage message, String pushContent, String pushData, String os) { - - if(fromUserId == null) { - throw new ArgumentNullException("Paramer 'fromUserId' is required"); - } - - if(message.getType() == null) { - throw new ArgumentNullException("Paramer 'ObjectName' is required"); - } - - if(message.toString() == null) { - throw new ArgumentNullException("Paramer 'Content' is required"); - } - - String postStr = ""; - postStr += "fromUserId=" + HttpUtility.UrlEncode(fromUserId == null ? "" : fromUserId,Encoding.UTF8) + "&"; - postStr += "objectName=" + HttpUtility.UrlEncode(message.getType(),Encoding.UTF8) + "&"; - postStr += "content=" + HttpUtility.UrlEncode(message.toString(),Encoding.UTF8) + "&"; - postStr += "pushContent=" + HttpUtility.UrlEncode(pushContent == null ? "" : pushContent,Encoding.UTF8) + "&"; - postStr += "pushData=" + HttpUtility.UrlEncode(pushData == null ? "" : pushData,Encoding.UTF8) + "&"; - postStr += "os=" + HttpUtility.UrlEncode(os == null ? "" : os,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/broadcast.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 消息历史记录下载地址获取 方法消息历史记录下载地址获取方法。获取 APP 内指定某天某小时内的所有会话消息记录的下载地址。(目前支持二人会话、讨论组、群组、聊天室、客服、系统通知消息历史记录下载) - * - * @param date:指定北京时间某天某小时,格式为2014010101,表示:2014年1月1日凌晨1点。(必传) - * - * @return HistoryMessageReslut - **/ - public HistoryMessageReslut getHistory(String date) { - - if(date == null) { - throw new ArgumentNullException("Paramer 'date' is required"); - } - - String postStr = ""; - postStr += "date=" + HttpUtility.UrlEncode(date == null ? "" : date,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (HistoryMessageReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/history.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 消息历史记录删除方法(删除 APP 内指定某天某小时内的所有会话消息记录。调用该接口返回成功后,date参数指定的某小时的消息记录文件将在随后的5-10分钟内被永久删除。) - * - * @param date:指定北京时间某天某小时,格式为2014010101,表示:2014年1月1日凌晨1点。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut deleteMessage(String date) { - - if(date == null) { - throw new ArgumentNullException("Paramer 'date' is required"); - } - - String postStr = ""; - postStr += "date=" + HttpUtility.UrlEncode(date == null ? "" : date,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/message/history/delete.json", postStr, "application/x-www-form-urlencoded" )); - } - - } - -} \ No newline at end of file diff --git a/io/rong/methods/Push.cs b/io/rong/methods/Push.cs deleted file mode 100644 index 503e607..0000000 --- a/io/rong/methods/Push.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Collections; -using System.Web; - -using donet.io.rong.models; -using donet.io.rong.util; -using donet.io.rong.messages; -using Newtonsoft.Json; - -namespace donet.io.rong.methods { - - public class Push { - - private static String UTF8 = "UTF-8"; - private String appKey; - private String appSecret; - - public Push(String appKey, String appSecret) { - this.appKey = appKey; - this.appSecret = appSecret; - - } - - /** - * 添加 Push 标签方法 - * - * @param userTag:用户标签。 - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut setUserPushTag(UserTag userTag) { - - if(userTag == null) { - throw new ArgumentNullException("Paramer 'userTag' is required"); - } - - String postStr = ""; - postStr = JsonConvert.SerializeObject(userTag); - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/tag/set.json", postStr, "application/json" )); - } - - /** - * 广播消息方法(fromuserid 和 message为null即为不落地的push) - * - * @param pushMessage:json数据 - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut broadcastPush(PushMessage pushMessage) { - - if(pushMessage == null) { - throw new ArgumentNullException("Paramer 'pushMessage' is required"); - } - - String postStr = ""; - postStr = JsonConvert.SerializeObject(pushMessage); - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/push.json", postStr, "application/json" )); - } - - } - -} \ No newline at end of file diff --git a/io/rong/methods/SMS.cs b/io/rong/methods/SMS.cs deleted file mode 100644 index 1ef1557..0000000 --- a/io/rong/methods/SMS.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Collections; -using System.Web; - -using donet.io.rong.models; -using donet.io.rong.util; -using donet.io.rong.messages; -using Newtonsoft.Json; - -namespace donet.io.rong.methods { - - public class SMS { - - private static String UTF8 = "UTF-8"; - private String appKey; - private String appSecret; - - public SMS(String appKey, String appSecret) { - this.appKey = appKey; - this.appSecret = appSecret; - - } - - /** - * 获取图片验证码方法 - * - * @param appKey:应用Id - * - * @return SMSImageCodeReslut - **/ - public SMSImageCodeReslut getImageCode(String appKey) { - - if(appKey == null) { - throw new ArgumentNullException("Paramer 'appKey' is required"); - } - - String postStr = ""; - postStr = RongCloud.RONGCLOUDSMSURI +"/getImgCode.json"; - postStr = postStr + ("?appKey=") + (HttpUtility.UrlEncode(appKey == null ? "" : appKey, Encoding.UTF8)); - - return (SMSImageCodeReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecuteGet(postStr)); - } - - /** - * 发送短信验证码方法。 - * - * @param mobile:接收短信验证码的目标手机号,每分钟同一手机号只能发送一次短信验证码,同一手机号 1 小时内最多发送 3 次。(必传) - * @param templateId:短信模板 Id,在开发者后台->短信服务->服务设置->短信模版中获取。(必传) - * @param region:手机号码所属国家区号,目前只支持中图区号 86) - * @param verifyId:图片验证标识 Id ,开启图片验证功能后此参数必传,否则可以不传。在获取图片验证码方法返回值中获取。 - * @param verifyCode:图片验证码,开启图片验证功能后此参数必传,否则可以不传。 - * - * @return SMSSendCodeReslut - **/ - public SMSSendCodeReslut sendCode(String mobile, String templateId, String region, String verifyId, String verifyCode) { - - if(mobile == null) { - throw new ArgumentNullException("Paramer 'mobile' is required"); - } - - if(templateId == null) { - throw new ArgumentNullException("Paramer 'templateId' is required"); - } - - if(region == null) { - throw new ArgumentNullException("Paramer 'region' is required"); - } - - String postStr = ""; - postStr += "mobile=" + HttpUtility.UrlEncode(mobile == null ? "" : mobile,Encoding.UTF8) + "&"; - postStr += "templateId=" + HttpUtility.UrlEncode(templateId == null ? "" : templateId,Encoding.UTF8) + "&"; - postStr += "region=" + HttpUtility.UrlEncode(region == null ? "" : region,Encoding.UTF8) + "&"; - postStr += "verifyId=" + HttpUtility.UrlEncode(verifyId == null ? "" : verifyId,Encoding.UTF8) + "&"; - postStr += "verifyCode=" + HttpUtility.UrlEncode(verifyCode == null ? "" : verifyCode,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (SMSSendCodeReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDSMSURI+"/sendCode.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 验证码验证方法 - * - * @param sessionId:短信验证码唯一标识,在发送短信验证码方法,返回值中获取。(必传) - * @param code:短信验证码内容。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut verifyCode(String sessionId, String code) { - - if(sessionId == null) { - throw new ArgumentNullException("Paramer 'sessionId' is required"); - } - - if(code == null) { - throw new ArgumentNullException("Paramer 'code' is required"); - } - - String postStr = ""; - postStr += "sessionId=" + HttpUtility.UrlEncode(sessionId == null ? "" : sessionId,Encoding.UTF8) + "&"; - postStr += "code=" + HttpUtility.UrlEncode(code == null ? "" : code,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDSMSURI+"/verifyCode.json", postStr, "application/x-www-form-urlencoded" )); - } - - } - -} \ No newline at end of file diff --git a/io/rong/methods/User.cs b/io/rong/methods/User.cs deleted file mode 100644 index b78969d..0000000 --- a/io/rong/methods/User.cs +++ /dev/null @@ -1,237 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Collections; -using System.Web; - -using donet.io.rong.models; -using donet.io.rong.util; -using donet.io.rong.messages; -using Newtonsoft.Json; - -namespace donet.io.rong.methods { - - public class User { - - private static String UTF8 = "UTF-8"; - private String appKey; - private String appSecret; - - public User(String appKey, String appSecret) { - this.appKey = appKey; - this.appSecret = appSecret; - - } - - /** - * 获取 Token 方法 - * - * @param userId:用户 Id,最大长度 64 字节.是用户在 App 中的唯一标识码,必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户。(必传) - * @param name:用户名称,最大长度 128 字节.用来在 Push 推送时显示用户的名称.用户名称,最大长度 128 字节.用来在 Push 推送时显示用户的名称。(必传) - * @param portraitUri:用户头像 URI,最大长度 1024 字节.用来在 Push 推送时显示用户的头像。(必传) - * - * @return TokenReslut - **/ - public TokenReslut getToken(String userId, String name, String portraitUri) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(name == null) { - throw new ArgumentNullException("Paramer 'name' is required"); - } - - if(portraitUri == null) { - throw new ArgumentNullException("Paramer 'portraitUri' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "name=" + HttpUtility.UrlEncode(name == null ? "" : name,Encoding.UTF8) + "&"; - postStr += "portraitUri=" + HttpUtility.UrlEncode(portraitUri == null ? "" : portraitUri,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (TokenReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/getToken.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 刷新用户信息方法 - * - * @param userId:用户 Id,最大长度 64 字节.是用户在 App 中的唯一标识码,必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户。(必传) - * @param name:用户名称,最大长度 128 字节。用来在 Push 推送时,显示用户的名称,刷新用户名称后 5 分钟内生效。(可选,提供即刷新,不提供忽略) - * @param portraitUri:用户头像 URI,最大长度 1024 字节。用来在 Push 推送时显示。(可选,提供即刷新,不提供忽略) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut refresh(String userId, String name, String portraitUri) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "name=" + HttpUtility.UrlEncode(name == null ? "" : name,Encoding.UTF8) + "&"; - postStr += "portraitUri=" + HttpUtility.UrlEncode(portraitUri == null ? "" : portraitUri,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/refresh.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 检查用户在线状态 方法 - * - * @param userId:用户 Id,最大长度 64 字节。是用户在 App 中的唯一标识码,必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户。(必传) - * - * @return CheckOnlineReslut - **/ - public CheckOnlineReslut checkOnline(String userId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CheckOnlineReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/checkOnline.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 封禁用户方法(每秒钟限 100 次) - * - * @param userId:用户 Id。(必传) - * @param minute:封禁时长,单位为分钟,最大值为43200分钟。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut block(String userId, int minute) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(minute == null) { - throw new ArgumentNullException("Paramer 'minute' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "minute=" + HttpUtility.UrlEncode(Convert.ToString(minute) == null ? "" : Convert.ToString(minute),Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/block.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 解除用户封禁方法(每秒钟限 100 次) - * - * @param userId:用户 Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut unBlock(String userId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/unblock.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 获取被封禁用户方法(每秒钟限 100 次) - * - * - * @return QueryBlockUserReslut - **/ - public QueryBlockUserReslut queryBlock() { - - String postStr = ""; - - return (QueryBlockUserReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/block/query.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 添加用户到黑名单方法(每秒钟限 100 次) - * - * @param userId:用户 Id。(必传) - * @param blackUserId:被加到黑名单的用户Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut addBlacklist(String userId, String blackUserId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(blackUserId == null) { - throw new ArgumentNullException("Paramer 'blackUserId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "blackUserId=" + HttpUtility.UrlEncode(blackUserId == null ? "" : blackUserId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/blacklist/add.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 获取某用户的黑名单列表方法(每秒钟限 100 次) - * - * @param userId:用户 Id。(必传) - * - * @return QueryBlacklistUserReslut - **/ - public QueryBlacklistUserReslut queryBlacklist(String userId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (QueryBlacklistUserReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/blacklist/query.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 从黑名单中移除用户方法(每秒钟限 100 次) - * - * @param userId:用户 Id。(必传) - * @param blackUserId:被移除的用户Id。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut removeBlacklist(String userId, String blackUserId) { - - if(userId == null) { - throw new ArgumentNullException("Paramer 'userId' is required"); - } - - if(blackUserId == null) { - throw new ArgumentNullException("Paramer 'blackUserId' is required"); - } - - String postStr = ""; - postStr += "userId=" + HttpUtility.UrlEncode(userId == null ? "" : userId,Encoding.UTF8) + "&"; - postStr += "blackUserId=" + HttpUtility.UrlEncode(blackUserId == null ? "" : blackUserId,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/user/blacklist/remove.json", postStr, "application/x-www-form-urlencoded" )); - } - - } - -} \ No newline at end of file diff --git a/io/rong/methods/Wordfilter.cs b/io/rong/methods/Wordfilter.cs deleted file mode 100644 index 848d63d..0000000 --- a/io/rong/methods/Wordfilter.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Collections; -using System.Web; - -using donet.io.rong.models; -using donet.io.rong.util; -using donet.io.rong.messages; -using Newtonsoft.Json; - -namespace donet.io.rong.methods { - - public class Wordfilter { - - private static String UTF8 = "UTF-8"; - private String appKey; - private String appSecret; - - public Wordfilter(String appKey, String appSecret) { - this.appKey = appKey; - this.appSecret = appSecret; - - } - - /** - * 添加敏感词方法(设置敏感词后,App 中用户不会收到含有敏感词的消息内容,默认最多设置 50 个敏感词。) - * - * @param word:敏感词,最长不超过 32 个字符。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut add(String word) { - - if(word == null) { - throw new ArgumentNullException("Paramer 'word' is required"); - } - - String postStr = ""; - postStr += "word=" + HttpUtility.UrlEncode(word == null ? "" : word,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/wordfilter/add.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 查询敏感词列表方法 - * - * - * @return ListWordfilterReslut - **/ - public ListWordfilterReslut getList() { - - String postStr = ""; - - return (ListWordfilterReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/wordfilter/list.json", postStr, "application/x-www-form-urlencoded" )); - } - - /** - * 移除敏感词方法(从敏感词列表中,移除某一敏感词。) - * - * @param word:敏感词,最长不超过 32 个字符。(必传) - * - * @return CodeSuccessReslut - **/ - public CodeSuccessReslut delete(String word) { - - if(word == null) { - throw new ArgumentNullException("Paramer 'word' is required"); - } - - String postStr = ""; - postStr += "word=" + HttpUtility.UrlEncode(word == null ? "" : word,Encoding.UTF8) + "&"; - postStr = postStr.Substring(0, postStr.LastIndexOf('&')); - - return (CodeSuccessReslut) RongJsonUtil.JsonStringToObj(RongHttpClient.ExecutePost(appKey, appSecret, RongCloud.RONGCLOUDURI+"/wordfilter/delete.json", postStr, "application/x-www-form-urlencoded" )); - } - - } - -} \ No newline at end of file diff --git a/io/rong/models/BlockChatRoomUser.cs b/io/rong/models/BlockChatRoomUser.cs deleted file mode 100644 index 3e01141..0000000 --- a/io/rong/models/BlockChatRoomUser.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 聊天室被封禁用户信息。 - */ - public class BlockChatRoomUser { - // 聊天室用户Id。 - [JsonProperty] - String id; - // 加入聊天室时间。 - [JsonProperty] - String time; - - public BlockChatRoomUser(String id, String time) { - this.id = id; - this.time = time; - } - - /** - * 设置id - * - */ - public void setId(String id) { - this.id = id; - } - - /** - * 获取id - * - * @return String - */ - public String getId() { - return id; - } - - /** - * 设置time - * - */ - public void setTime(String time) { - this.time = time; - } - - /** - * 获取time - * - * @return String - */ - public String getTime() { - return time; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/BlockUsers.cs b/io/rong/models/BlockUsers.cs deleted file mode 100644 index a1ebda1..0000000 --- a/io/rong/models/BlockUsers.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 封禁用户信息 - */ - public class BlockUsers { - // 被封禁用户 ID。 - [JsonProperty] - String userId; - // 封禁结束时间。 - [JsonProperty] - String blockEndTime; - - public BlockUsers(String userId, String blockEndTime) { - this.userId = userId; - this.blockEndTime = blockEndTime; - } - - /** - * 设置userId - * - */ - public void setUserId(String userId) { - this.userId = userId; - } - - /** - * 获取userId - * - * @return String - */ - public String getUserId() { - return userId; - } - - /** - * 设置blockEndTime - * - */ - public void setBlockEndTime(String blockEndTime) { - this.blockEndTime = blockEndTime; - } - - /** - * 获取blockEndTime - * - * @return String - */ - public String getBlockEndTime() { - return blockEndTime; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ChatRoom.cs b/io/rong/models/ChatRoom.cs deleted file mode 100644 index 42e8d12..0000000 --- a/io/rong/models/ChatRoom.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 聊天室信息。 - */ - public class ChatRoom { - // 聊天室 ID。 - [JsonProperty] - String chrmId; - // 聊天室名称。 - [JsonProperty] - String name; - // 聊天室创建时间。 - [JsonProperty] - String time; - - public ChatRoom(String chrmId, String name, String time) { - this.chrmId = chrmId; - this.name = name; - this.time = time; - } - - /** - * 设置chrmId - * - */ - public void setChrmId(String chrmId) { - this.chrmId = chrmId; - } - - /** - * 获取chrmId - * - * @return String - */ - public String getChrmId() { - return chrmId; - } - - /** - * 设置name - * - */ - public void setName(String name) { - this.name = name; - } - - /** - * 获取name - * - * @return String - */ - public String getName() { - return name; - } - - /** - * 设置time - * - */ - public void setTime(String time) { - this.time = time; - } - - /** - * 获取time - * - * @return String - */ - public String getTime() { - return time; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ChatRoomInfo.cs b/io/rong/models/ChatRoomInfo.cs deleted file mode 100644 index bddc0d7..0000000 --- a/io/rong/models/ChatRoomInfo.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 聊天室信息。 - */ - public class ChatRoomInfo { - // 聊天室Id。 - [JsonProperty] - String id; - // 聊天室名称。 - [JsonProperty] - String name; - - public ChatRoomInfo(String id, String name) { - this.id = id; - this.name = name; - } - - /** - * 设置id - * - */ - public void setId(String id) { - this.id = id; - } - - /** - * 获取id - * - * @return String - */ - public String getId() { - return id; - } - - /** - * 设置name - * - */ - public void setName(String name) { - this.name = name; - } - - /** - * 获取name - * - * @return String - */ - public String getName() { - return name; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ChatRoomUser.cs b/io/rong/models/ChatRoomUser.cs deleted file mode 100644 index 67d4373..0000000 --- a/io/rong/models/ChatRoomUser.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 聊天室用户信息。 - */ - public class ChatRoomUser { - // 聊天室用户Id。 - [JsonProperty] - String id; - // 加入聊天室时间。 - [JsonProperty] - String time; - - public ChatRoomUser(String id, String time) { - this.id = id; - this.time = time; - } - - /** - * 设置id - * - */ - public void setId(String id) { - this.id = id; - } - - /** - * 获取id - * - * @return String - */ - public String getId() { - return id; - } - - /** - * 设置time - * - */ - public void setTime(String time) { - this.time = time; - } - - /** - * 获取time - * - * @return String - */ - public String getTime() { - return time; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ChatroomQueryReslut.cs b/io/rong/models/ChatroomQueryReslut.cs deleted file mode 100644 index 1c87a94..0000000 --- a/io/rong/models/ChatroomQueryReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * chatroomQuery 返回结果 - */ - public class ChatroomQueryReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 聊天室信息数组。 - [JsonProperty] - List chatRooms; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public ChatroomQueryReslut(int code, List chatRooms, String errorMessage) { - this.code = code; - this.chatRooms = chatRooms; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置chatRooms - * - */ - public void setChatRooms(List chatRooms) { - this.chatRooms = chatRooms; - } - - /** - * 获取chatRooms - * - * @return List - */ - public List getChatRooms() { - return chatRooms; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ChatroomUserQueryReslut.cs b/io/rong/models/ChatroomUserQueryReslut.cs deleted file mode 100644 index 933c7f6..0000000 --- a/io/rong/models/ChatroomUserQueryReslut.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * chatroomUserQuery 返回结果 - */ - public class ChatroomUserQueryReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 聊天室中用户数。 - [JsonProperty] - int total; - // 聊天室成员列表。 - [JsonProperty] - List users; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public ChatroomUserQueryReslut(int code, int total, List users, String errorMessage) { - this.code = code; - this.total = total; - this.users = users; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置total - * - */ - public void setTotal(int total) { - this.total = total; - } - - /** - * 获取total - * - * @return Integer - */ - public int getTotal() { - return total; - } - - /** - * 设置users - * - */ - public void setUsers(List users) { - this.users = users; - } - - /** - * 获取users - * - * @return List - */ - public List getUsers() { - return users; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/CheckOnlineReslut.cs b/io/rong/models/CheckOnlineReslut.cs deleted file mode 100644 index 433e59d..0000000 --- a/io/rong/models/CheckOnlineReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * checkOnlineUser返回结果 - */ - public class CheckOnlineReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 在线状态,1为在线,0为不在线。 - [JsonProperty] - String status; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public CheckOnlineReslut(int code, String status, String errorMessage) { - this.code = code; - this.status = status; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置status - * - */ - public void setStatus(String status) { - this.status = status; - } - - /** - * 获取status - * - * @return String - */ - public String getStatus() { - return status; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/CodeSuccessReslut.cs b/io/rong/models/CodeSuccessReslut.cs deleted file mode 100644 index a39bd95..0000000 --- a/io/rong/models/CodeSuccessReslut.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * http 成功返回结果 - */ - public class CodeSuccessReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public CodeSuccessReslut(int code, String errorMessage) { - this.code = code; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/GagChatRoomUser.cs b/io/rong/models/GagChatRoomUser.cs deleted file mode 100644 index dad1687..0000000 --- a/io/rong/models/GagChatRoomUser.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 聊天室被禁言用户信息。 - */ - public class GagChatRoomUser { - // 解禁时间。 - [JsonProperty] - String time; - // 被封禁用户 Id。 - [JsonProperty] - String userId; - - public GagChatRoomUser(String time, String userId) { - this.time = time; - this.userId = userId; - } - - /** - * 设置time - * - */ - public void setTime(String time) { - this.time = time; - } - - /** - * 获取time - * - * @return String - */ - public String getTime() { - return time; - } - - /** - * 设置userId - * - */ - public void setUserId(String userId) { - this.userId = userId; - } - - /** - * 获取userId - * - * @return String - */ - public String getUserId() { - return userId; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/GagGroupUser.cs b/io/rong/models/GagGroupUser.cs deleted file mode 100644 index 89c54d6..0000000 --- a/io/rong/models/GagGroupUser.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 群组用户信息。 - */ - public class GagGroupUser { - // 解禁时间。 - [JsonProperty] - String time; - // 群成员 Id。 - [JsonProperty] - String userId; - - public GagGroupUser(String time, String userId) { - this.time = time; - this.userId = userId; - } - - /** - * 设置time - * - */ - public void setTime(String time) { - this.time = time; - } - - /** - * 获取time - * - * @return String - */ - public String getTime() { - return time; - } - - /** - * 设置userId - * - */ - public void setUserId(String userId) { - this.userId = userId; - } - - /** - * 获取userId - * - * @return String - */ - public String getUserId() { - return userId; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/GroupInfo.cs b/io/rong/models/GroupInfo.cs deleted file mode 100644 index cc0478d..0000000 --- a/io/rong/models/GroupInfo.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 群组信息。 - */ - public class GroupInfo { - // 群组Id。 - [JsonProperty] - String id; - // 群组名称。 - [JsonProperty] - String name; - - public GroupInfo(String id, String name) { - this.id = id; - this.name = name; - } - - /** - * 设置id - * - */ - public void setId(String id) { - this.id = id; - } - - /** - * 获取id - * - * @return String - */ - public String getId() { - return id; - } - - /** - * 设置name - * - */ - public void setName(String name) { - this.name = name; - } - - /** - * 获取name - * - * @return String - */ - public String getName() { - return name; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/GroupUser.cs b/io/rong/models/GroupUser.cs deleted file mode 100644 index 91de473..0000000 --- a/io/rong/models/GroupUser.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 群组用户信息。 - */ - public class GroupUser { - // 用户 Id。 - [JsonProperty] - String id; - - public GroupUser(String id) { - this.id = id; - } - - /** - * 设置id - * - */ - public void setId(String id) { - this.id = id; - } - - /** - * 获取id - * - * @return String - */ - public String getId() { - return id; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/GroupUserQueryReslut.cs b/io/rong/models/GroupUserQueryReslut.cs deleted file mode 100644 index 02d2edf..0000000 --- a/io/rong/models/GroupUserQueryReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * groupUserQuery返回结果 - */ - public class GroupUserQueryReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 群成员用户Id。 - [JsonProperty] - String id; - // 群成员列表。 - [JsonProperty] - List users; - - public GroupUserQueryReslut(int code, String id, List users) { - this.code = code; - this.id = id; - this.users = users; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置id - * - */ - public void setId(String id) { - this.id = id; - } - - /** - * 获取id - * - * @return String - */ - public String getId() { - return id; - } - - /** - * 设置users - * - */ - public void setUsers(List users) { - this.users = users; - } - - /** - * 获取users - * - * @return List - */ - public List getUsers() { - return users; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/HistoryMessageReslut.cs b/io/rong/models/HistoryMessageReslut.cs deleted file mode 100644 index aaeeca1..0000000 --- a/io/rong/models/HistoryMessageReslut.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * historyMessage返回结果 - */ - public class HistoryMessageReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 历史消息下载地址。 - [JsonProperty] - String url; - // 历史记录时间。(yyyymmddhh) - [JsonProperty] - String date; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public HistoryMessageReslut(int code, String url, String date, String errorMessage) { - this.code = code; - this.url = url; - this.date = date; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置url - * - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * 获取url - * - * @return String - */ - public String getUrl() { - return url; - } - - /** - * 设置date - * - */ - public void setDate(String date) { - this.date = date; - } - - /** - * 获取date - * - * @return String - */ - public String getDate() { - return date; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ListBlockChatroomUserReslut.cs b/io/rong/models/ListBlockChatroomUserReslut.cs deleted file mode 100644 index beb0740..0000000 --- a/io/rong/models/ListBlockChatroomUserReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * listBlockChatroomUser返回结果 - */ - public class ListBlockChatroomUserReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 被封禁用户列表。 - [JsonProperty] - List users; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public ListBlockChatroomUserReslut(int code, List users, String errorMessage) { - this.code = code; - this.users = users; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置users - * - */ - public void setUsers(List users) { - this.users = users; - } - - /** - * 获取users - * - * @return List - */ - public List getUsers() { - return users; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ListGagChatroomUserReslut.cs b/io/rong/models/ListGagChatroomUserReslut.cs deleted file mode 100644 index 1d20dcb..0000000 --- a/io/rong/models/ListGagChatroomUserReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * listGagChatroomUser返回结果 - */ - public class ListGagChatroomUserReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 聊天室被禁言用户列表。 - [JsonProperty] - List users; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public ListGagChatroomUserReslut(int code, List users, String errorMessage) { - this.code = code; - this.users = users; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置users - * - */ - public void setUsers(List users) { - this.users = users; - } - - /** - * 获取users - * - * @return List - */ - public List getUsers() { - return users; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ListGagGroupUserReslut.cs b/io/rong/models/ListGagGroupUserReslut.cs deleted file mode 100644 index 56fdfcd..0000000 --- a/io/rong/models/ListGagGroupUserReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * lisitGagGroupUser 返回结果 - */ - public class ListGagGroupUserReslut { - // 返回码,200 为正常. - [JsonProperty] - int code; - // 群组被禁言用户列表。 - [JsonProperty] - List users; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public ListGagGroupUserReslut(int code, List users, String errorMessage) { - this.code = code; - this.users = users; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置users - * - */ - public void setUsers(List users) { - this.users = users; - } - - /** - * 获取users - * - * @return List - */ - public List getUsers() { - return users; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/ListWordfilterReslut.cs b/io/rong/models/ListWordfilterReslut.cs deleted file mode 100644 index 59bc228..0000000 --- a/io/rong/models/ListWordfilterReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * listWordfilter返回结果 - */ - public class ListWordfilterReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 敏感词内容。 - [JsonProperty] - String word; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public ListWordfilterReslut(int code, String word, String errorMessage) { - this.code = code; - this.word = word; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置word - * - */ - public void setWord(String word) { - this.word = word; - } - - /** - * 获取word - * - * @return String - */ - public String getWord() { - return word; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/MsgObj.cs b/io/rong/models/MsgObj.cs deleted file mode 100644 index 7110edd..0000000 --- a/io/rong/models/MsgObj.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 用于Push中的message。 - */ - public class MsgObj { - // push 消息中的消息体。 - [JsonProperty] - String content; - // 聊天室名称。 - [JsonProperty] - String objectName; - - public MsgObj(String content, String objectName) { - this.content = content; - this.objectName = objectName; - } - - /** - * 设置content - * - */ - public void setContent(String content) { - this.content = content; - } - - /** - * 获取content - * - * @return String - */ - public String getContent() { - return content; - } - - /** - * 设置objectName - * - */ - public void setObjectName(String objectName) { - this.objectName = objectName; - } - - /** - * 获取objectName - * - * @return String - */ - public String getObjectName() { - return objectName; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/Notification.cs b/io/rong/models/Notification.cs deleted file mode 100644 index 41a2be4..0000000 --- a/io/rong/models/Notification.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 按操作系统类型推送消息内容,如 platform 中设置了给 ios 和 android 系统推送消息,而在 notification 中只设置了 ios 的推送内容,则 android 的推送内容为最初 alert 设置的内容。(非必传) - */ - public class Notification { - // 默认推送消息内容,如填写了 ios 或 android 下的 alert 时,则推送内容以对应平台系统的 alert 为准。(必传) - [JsonProperty] - String alert; - // 设置 iOS 平台下的推送及附加信息。 - [JsonProperty] - PlatformNotification ios; - // 设置 Android 平台下的推送及附加信息。 - [JsonProperty] - PlatformNotification android; - - public Notification(String alert, PlatformNotification ios, PlatformNotification android) { - this.alert = alert; - this.ios = ios; - this.android = android; - } - - /** - * 设置alert - * - */ - public void setAlert(String alert) { - this.alert = alert; - } - - /** - * 获取alert - * - * @return String - */ - public String getAlert() { - return alert; - } - - /** - * 设置ios - * - */ - public void setIos(PlatformNotification ios) { - this.ios = ios; - } - - /** - * 获取ios - * - * @return PlatformNotification - */ - public PlatformNotification getIos() { - return ios; - } - - /** - * 设置android - * - */ - public void setAndroid(PlatformNotification android) { - this.android = android; - } - - /** - * 获取android - * - * @return PlatformNotification - */ - public PlatformNotification getAndroid() { - return android; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/PlatformNotification.cs b/io/rong/models/PlatformNotification.cs deleted file mode 100644 index 119264a..0000000 --- a/io/rong/models/PlatformNotification.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 设备中的推送内容。(非必传) - */ - public class PlatformNotification { - // 默认推送消息内容,如填写了 ios 或 android 下的 alert 时,则推送内容以对应平台系统的 alert 为准。(必传) - [JsonProperty] - String alert; - // ios 或 android 不同平台下的附加信息,如果开发者自己需要,可以自己在 App 端进行解析。(非必传) - [JsonProperty] - Dictionary extras; - - public PlatformNotification(String alert, Dictionary extras) { - this.alert = alert; - this.extras = extras; - } - - /** - * 设置alert - * - */ - public void setAlert(String alert) { - this.alert = alert; - } - - /** - * 获取alert - * - * @return String - */ - public String getAlert() { - return alert; - } - - /** - * 设置extras - * - */ - public void setExtras(Dictionary extras) { - this.extras = extras; - } - - /** - * 获取extras - * - * @return Map - */ - public Dictionary getExtras() { - return extras; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/PushMessage.cs b/io/rong/models/PushMessage.cs deleted file mode 100644 index af8ec39..0000000 --- a/io/rong/models/PushMessage.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 不落地 push 消息体。 - */ - public class PushMessage { - // 目标操作系统。(iOS、Android)。(必传) - [JsonProperty] - String[] platform; - // 发送人用户 Id。(必传) - [JsonProperty] - String fromuserid; - // 推送条件,包括: tag 、 userid 、 is_to_all。(必传) - [JsonProperty] - TagObj audience; - // true为全部,忽略上面的tag、userId。 - [JsonProperty] - MsgObj message; - // 按操作系统类型推送消息内容,如 platform 中设置了给 ios 和 android 系统推送消息,而在 notification 中只设置了 ios 的推送内容,则 android 的推送内容为最初 alert 设置的内容。 - [JsonProperty] - Notification notification; - - public PushMessage(String[] platform, String fromuserid, TagObj audience, MsgObj message, Notification notification) { - this.platform = platform; - this.fromuserid = fromuserid; - this.audience = audience; - this.message = message; - this.notification = notification; - } - - /** - * 设置platform - * - */ - public void setPlatform(String[] platform) { - this.platform = platform; - } - - /** - * 获取platform - * - * @return String[] - */ - public String[] getPlatform() { - return platform; - } - - /** - * 设置fromuserid - * - */ - public void setFromuserid(String fromuserid) { - this.fromuserid = fromuserid; - } - - /** - * 获取fromuserid - * - * @return String - */ - public String getFromuserid() { - return fromuserid; - } - - /** - * 设置audience - * - */ - public void setAudience(TagObj audience) { - this.audience = audience; - } - - /** - * 获取audience - * - * @return TagObj - */ - public TagObj getAudience() { - return audience; - } - - /** - * 设置message - * - */ - public void setMessage(MsgObj message) { - this.message = message; - } - - /** - * 获取message - * - * @return MsgObj - */ - public MsgObj getMessage() { - return message; - } - - /** - * 设置notification - * - */ - public void setNotification(Notification notification) { - this.notification = notification; - } - - /** - * 获取notification - * - * @return Notification - */ - public Notification getNotification() { - return notification; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/QueryBlacklistUserReslut.cs b/io/rong/models/QueryBlacklistUserReslut.cs deleted file mode 100644 index b77fa35..0000000 --- a/io/rong/models/QueryBlacklistUserReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * queryBlacklistUser返回结果 - */ - public class QueryBlacklistUserReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 黑名单用户列表。 - [JsonProperty] - String[] users; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public QueryBlacklistUserReslut(int code, String[] users, String errorMessage) { - this.code = code; - this.users = users; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置users - * - */ - public void setUsers(String[] users) { - this.users = users; - } - - /** - * 获取users - * - * @return String[] - */ - public String[] getUsers() { - return users; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/QueryBlockUserReslut.cs b/io/rong/models/QueryBlockUserReslut.cs deleted file mode 100644 index 970e176..0000000 --- a/io/rong/models/QueryBlockUserReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * queryBlockUser返回结果 - */ - public class QueryBlockUserReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 被封禁用户列表。 - [JsonProperty] - List users; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public QueryBlockUserReslut(int code, List users, String errorMessage) { - this.code = code; - this.users = users; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置users - * - */ - public void setUsers(List users) { - this.users = users; - } - - /** - * 获取users - * - * @return List - */ - public List getUsers() { - return users; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/SMSImageCodeReslut.cs b/io/rong/models/SMSImageCodeReslut.cs deleted file mode 100644 index 3215a6f..0000000 --- a/io/rong/models/SMSImageCodeReslut.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * getImageCode 成功返回结果 - */ - public class SMSImageCodeReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 返回的图片验证码 URL 地址。 - [JsonProperty] - String url; - // 返回图片验证标识 Id。 - [JsonProperty] - String verifyId; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public SMSImageCodeReslut(int code, String url, String verifyId, String errorMessage) { - this.code = code; - this.url = url; - this.verifyId = verifyId; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置url - * - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * 获取url - * - * @return String - */ - public String getUrl() { - return url; - } - - /** - * 设置verifyId - * - */ - public void setVerifyId(String verifyId) { - this.verifyId = verifyId; - } - - /** - * 获取verifyId - * - * @return String - */ - public String getVerifyId() { - return verifyId; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/SMSSendCodeReslut.cs b/io/rong/models/SMSSendCodeReslut.cs deleted file mode 100644 index 7bd5ba3..0000000 --- a/io/rong/models/SMSSendCodeReslut.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * SMSSendCodeReslut 成功返回结果 - */ - public class SMSSendCodeReslut { - // 返回码,200 为正常。 - [JsonProperty] - int code; - // 短信验证码唯一标识。 - [JsonProperty] - String sessionId; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public SMSSendCodeReslut(int code, String sessionId, String errorMessage) { - this.code = code; - this.sessionId = sessionId; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置sessionId - * - */ - public void setSessionId(String sessionId) { - this.sessionId = sessionId; - } - - /** - * 获取sessionId - * - * @return String - */ - public String getSessionId() { - return sessionId; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/TagObj.cs b/io/rong/models/TagObj.cs deleted file mode 100644 index 4e1a67b..0000000 --- a/io/rong/models/TagObj.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 用于Push中的 标签。 - */ - public class TagObj { - // 标签。(最多20个) - [JsonProperty] - String[] tag; - // 如果填 userId 给 userId 发如果没有给 tag 发。(最多1000个) - [JsonProperty] - String[] userid; - // true为全部,忽略上面的tag、userId。(必传) - [JsonProperty] - Boolean is_to_all; - - public TagObj(String[] tag, String[] userid, Boolean is_to_all) { - this.tag = tag; - this.userid = userid; - this.is_to_all = is_to_all; - } - - /** - * 设置tag - * - */ - public void setTag(String[] tag) { - this.tag = tag; - } - - /** - * 获取tag - * - * @return String[] - */ - public String[] getTag() { - return tag; - } - - /** - * 设置userid - * - */ - public void setUserid(String[] userid) { - this.userid = userid; - } - - /** - * 获取userid - * - * @return String[] - */ - public String[] getUserid() { - return userid; - } - - /** - * 设置is_to_all - * - */ - public void setIs_to_all(Boolean is_to_all) { - this.is_to_all = is_to_all; - } - - /** - * 获取is_to_all - * - * @return Boolean - */ - public Boolean getIs_to_all() { - return is_to_all; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/TemplateMessage.cs b/io/rong/models/TemplateMessage.cs deleted file mode 100644 index 0b842f9..0000000 --- a/io/rong/models/TemplateMessage.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 模版消息对象。 - */ - public class TemplateMessage { - // 发送人用户 Id。(必传) - [JsonProperty] - String fromUserId; - // 接收用户 Id,提供多个本参数可以实现向多人发送消息,上限为 1000 人。(必传) - [JsonProperty] - String[] toUserId; - // 发送消息内容,内容中定义标识通过 values 中设置的标识位内容进行替换,参考融云消息类型表.示例说明;如果 objectName 为自定义消息类型,该参数可自定义格式。(必传) - [JsonProperty] - String content; - // 消息内容中,标识位对应内容。(必传) - [JsonProperty] - List> values; - // 接收用户 Id,提供多个本参数可以实现向多人发送消息,上限为 1000 人。(必传) - [JsonProperty] - String objectName; - // 定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息。如果为自定义消息,定义显示的 Push 内容,内容中定义标识通过 values 中设置的标识位内容进行替换。如消息类型为自定义不需要 Push 通知,则对应数组传空值即可。(必传) - [JsonProperty] - String[] pushContent; - // 针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。如不需要 Push 功能对应数组传空值即可。(可选) - [JsonProperty] - String[] pushData; - // 是否过滤发送人黑名单列表,0 为不过滤、 1 为过滤,默认为 0 不过滤。(可选) - [JsonProperty] - int verifyBlacklist; - - public TemplateMessage(String fromUserId, String[] toUserId, String content, List> values, String objectName, String[] pushContent, String[] pushData, int verifyBlacklist) { - this.fromUserId = fromUserId; - this.toUserId = toUserId; - this.content = content; - this.values = values; - this.objectName = objectName; - this.pushContent = pushContent; - this.pushData = pushData; - this.verifyBlacklist = verifyBlacklist; - } - - /** - * 设置fromUserId - * - */ - public void setFromUserId(String fromUserId) { - this.fromUserId = fromUserId; - } - - /** - * 获取fromUserId - * - * @return String - */ - public String getFromUserId() { - return fromUserId; - } - - /** - * 设置toUserId - * - */ - public void setToUserId(String[] toUserId) { - this.toUserId = toUserId; - } - - /** - * 获取toUserId - * - * @return String[] - */ - public String[] getToUserId() { - return toUserId; - } - - /** - * 设置content - * - */ - public void setContent(String content) { - this.content = content; - } - - /** - * 获取content - * - * @return String - */ - public String getContent() { - return content; - } - - /** - * 设置values - * - */ - public void setValues(List> values) { - this.values = values; - } - - /** - * 获取values - * - * @return List> - */ - public List> getValues() { - return values; - } - - /** - * 设置objectName - * - */ - public void setObjectName(String objectName) { - this.objectName = objectName; - } - - /** - * 获取objectName - * - * @return String - */ - public String getObjectName() { - return objectName; - } - - /** - * 设置pushContent - * - */ - public void setPushContent(String[] pushContent) { - this.pushContent = pushContent; - } - - /** - * 获取pushContent - * - * @return String[] - */ - public String[] getPushContent() { - return pushContent; - } - - /** - * 设置pushData - * - */ - public void setPushData(String[] pushData) { - this.pushData = pushData; - } - - /** - * 获取pushData - * - * @return String[] - */ - public String[] getPushData() { - return pushData; - } - - /** - * 设置verifyBlacklist - * - */ - public void setVerifyBlacklist(int verifyBlacklist) { - this.verifyBlacklist = verifyBlacklist; - } - - /** - * 获取verifyBlacklist - * - * @return Integer - */ - public int getVerifyBlacklist() { - return verifyBlacklist; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/TokenReslut.cs b/io/rong/models/TokenReslut.cs deleted file mode 100644 index 8107189..0000000 --- a/io/rong/models/TokenReslut.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * getToken 返回结果 - */ - public class TokenReslut { - // 返回码,200 为正常.如果您正在使用开发环境的 AppKey,您的应用只能注册 100 名用户,达到上限后,将返回错误码 2007.如果您需要更多的测试账户数量,您需要在应用配置中申请“增加测试人数”。 - [JsonProperty] - int code; - // 用户 Token,可以保存应用内,长度在 256 字节以内.用户 Token,可以保存应用内,长度在 256 字节以内。 - [JsonProperty] - String token; - // 用户 Id,与输入的用户 Id 相同.用户 Id,与输入的用户 Id 相同。 - [JsonProperty] - String userId; - // 错误信息。 - [JsonProperty] - String errorMessage; - - public TokenReslut(int code, String token, String userId, String errorMessage) { - this.code = code; - this.token = token; - this.userId = userId; - this.errorMessage = errorMessage; - } - - /** - * 设置code - * - */ - public void setCode(int code) { - this.code = code; - } - - /** - * 获取code - * - * @return Integer - */ - public int getCode() { - return code; - } - - /** - * 设置token - * - */ - public void setToken(String token) { - this.token = token; - } - - /** - * 获取token - * - * @return String - */ - public String getToken() { - return token; - } - - /** - * 设置userId - * - */ - public void setUserId(String userId) { - this.userId = userId; - } - - /** - * 获取userId - * - * @return String - */ - public String getUserId() { - return userId; - } - - /** - * 设置errorMessage - * - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * 获取errorMessage - * - * @return String - */ - public String getErrorMessage() { - return errorMessage; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/io/rong/models/UserTag.cs b/io/rong/models/UserTag.cs deleted file mode 100644 index cb9736a..0000000 --- a/io/rong/models/UserTag.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace donet.io.rong.models { - - /** - * 用于打标签的对象。 - */ - public class UserTag { - // 用户标签,一个用户最多添加 20 个标签,每个 tags 最大不能超过 40 个字节,标签中不能包含特殊字符。(必传) - [JsonProperty] - String[] tags; - // 用户 Id。(必传) - [JsonProperty] - String userId; - - public UserTag(String[] tags, String userId) { - this.tags = tags; - this.userId = userId; - } - - /** - * 设置tags - * - */ - public void setTags(String[] tags) { - this.tags = tags; - } - - /** - * 获取tags - * - * @return String[] - */ - public String[] getTags() { - return tags; - } - - /** - * 设置userId - * - */ - public void setUserId(String userId) { - this.userId = userId; - } - - /** - * 获取userId - * - * @return String - */ - public String getUserId() { - return userId; - } - - public String toString() { - return JsonConvert.SerializeObject(this); - } - } -} diff --git a/jsonsource/PushMessage.json b/jsonsource/PushMessage.json new file mode 100644 index 0000000..4446bf4 --- /dev/null +++ b/jsonsource/PushMessage.json @@ -0,0 +1,14 @@ +{ + "platform": ["ios","android"], + "fromuserid": "U161142135", + "audience": { + "tag":["1"], + "is_to_all": false + }, + "message": { + "content":"{\"content\":\"sadfsadfa\",\"extra\":\"www.baidu.com\"}", + "objectName": "RC:TxtMsg" + }, + "notification":{"alert":"this is a push"} +} + diff --git a/TemplateMessage.json b/jsonsource/TemplateMessage.json similarity index 76% rename from TemplateMessage.json rename to jsonsource/TemplateMessage.json index d323195..82f9ed2 100644 --- a/TemplateMessage.json +++ b/jsonsource/TemplateMessage.json @@ -1,9 +1,9 @@ { - "fromUserId": "fromuser", + "fromUserId": "Vu-oC0_LQ6kgPqltm_zYtI", "objectName": "RC:TxtMsg", "content": "{\"content\":\"{c}{d}{e}\",\"extra\":\"bb\"}", "toUserId": [ - "21", + "uPj70HUrRSUk-ixtt7iIGc", "22" ], "values": [ @@ -22,8 +22,8 @@ "push{c}", "push{c}" ], - "pushData": [ - "pushd", - "pushd" - ] -} \ No newline at end of file + "pushData": [ + "pushd", + "pushd" + ] +} diff --git a/UserTag.json b/jsonsource/UserTag.json similarity index 100% rename from UserTag.json rename to jsonsource/UserTag.json diff --git a/jsonsource/broadcast/api.json b/jsonsource/broadcast/api.json new file mode 100644 index 0000000..58a1b39 --- /dev/null +++ b/jsonsource/broadcast/api.json @@ -0,0 +1,50 @@ +{ + "send": { + "docs": "http://www.rongcloud.cn/docs/server.html#message_broadcast", + "url": "user/getToken", + "params": { + "message": { + "conversationType": 1, + "from": "2191", + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + }, + "pushContent": "this is a push", + "pushData": { + "pushData":"hello" + }, + "os": "ios", + "contentAvailable": 0 + } + }, + "response": { + "success": { + "code": 200 + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + + } +} \ No newline at end of file diff --git a/jsonsource/broadcast/verify.json b/jsonsource/broadcast/verify.json new file mode 100644 index 0000000..c188b93 --- /dev/null +++ b/jsonsource/broadcast/verify.json @@ -0,0 +1,42 @@ +{ + "broadcast": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "fromUserId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "objectName": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 32, + "min": 1, + "invalid": "20003" + } + }, + "message": { + "require": { + "must": true, + "invalid": "20005" + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/api.json b/jsonsource/chatroom/api.json new file mode 100644 index 0000000..430f66a --- /dev/null +++ b/jsonsource/chatroom/api.json @@ -0,0 +1,169 @@ +{ + "create": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_create", + "url": "chatroom/create", + "params": { + "chatroom": [{ + "id": "chatroomId01", + "name": "大融云" + }] + }, + "response": { + "success": { + "code": 200, + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "destory": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_destroy", + "url": "chatroom/destroy", + "params": { + "chatroom": [{ + "id": "chatroomId01" + }] + }, + "response": { + "success": { + "code": 200, + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "get": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_query", + "url": "chatroom/user/query", + "params": { + "chatroom": { + "id": "chatromId01", + "count": 10, + "order": 1 + } + }, + "response": { + "success": { + "code": 200, + "total": 1000, + "members": [{ + "id": "member1", + "time": "2015-09-10 16:38:26" + }, { + "id": "member2", + "time": "2015-09-10 16:38:26" + }] + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "isExist": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_exist", + "url": "chatroom/user/exist", + "params": { + "member": { + "id": "memberId01", + "chatroomId": ["chatroomId01"] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/block/api.json b/jsonsource/chatroom/block/api.json new file mode 100644 index 0000000..27c3f59 --- /dev/null +++ b/jsonsource/chatroom/block/api.json @@ -0,0 +1,136 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_block_add", + "url": "chatroom/user/block/add", + "params": { + "chatroom": { + "id": "chatroomId01", + "members": [ + {"id":"hjHy78"}, + {"id":"hjHy79"} + ], + "minute": 10 + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20004": { + "code": "1002", + "errorMessage": "封禁时间 minute 不正确,minute >= 1 且 minute <= 43200 单位: 分钟" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_block_rollback", + "url": "chatroom/user/block/rollback", + "params": { + "chatroom": { + "id": "chatroomId01", + "members": [{ + "id": "memberId01" + }] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_block_list", + "url": "chatroom/user/block/list", + "params": { + "chatroom": { + "id": "chatroomId01" + } + }, + "response": { + "success": { + "code": "200", + "blockMembers": [{ + "time": "2015-09-25 16:12:38", + "id": "2582" + }] + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/demotion/api.json b/jsonsource/chatroom/demotion/api.json new file mode 100644 index 0000000..25b5f48 --- /dev/null +++ b/jsonsource/chatroom/demotion/api.json @@ -0,0 +1,105 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_message_priority_add", + "url": "chatroom/message/priority/add", + "params": { + "message": { + "type": ["RC:TxtMsg", "RC:ImgMsg"] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20002": { + "code": "1502", + "errorMessage": "msgs 数量超限, msgs.length >= 1 且 msgs.length <=5 " + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20007": { + "code": "1002", + "errorMessage": "protrait 不是合法地址,请检查 protrait 是否正确" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_message_priority_remove", + "url": "chatroom/message/priority/remove", + "params": { + "message": { + "type": ["RC:TxtMsg", "RC:ImgMsg"] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20002": { + "code": "1502", + "errorMessage": "msgs 个数超限, msgs.length >= 1 且 msgs.length <=5 " + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20007": { + "code": "1002", + "errorMessage": "protrait 不是合法地址,请检查 protrait 是否正确" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_message_priority_query", + "url": "chatroom/message/priority/query", + "params": {}, + "response": { + "success": { + "code": 200, + "objectNames": ["RC:ImgMsg", "RC:ImgTextMsg", "RC:VcMsg"] + }, + "fail": { + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/distribute/api.json b/jsonsource/chatroom/distribute/api.json new file mode 100644 index 0000000..49595b0 --- /dev/null +++ b/jsonsource/chatroom/distribute/api.json @@ -0,0 +1,76 @@ +{ + "stop": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_message_stop_distribution", + "url": "chatroom/message/stopDistribution", + "params": { + "chatroom": { + "id": "chatroom01" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "resume": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_message_resume_distribution", + "url": "chatroom/message/resumeDistribution", + "params": { + "chatroom": { + "id": "chatroom01" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/global-gag/api.json b/jsonsource/chatroom/global-gag/api.json new file mode 100644 index 0000000..90b08db --- /dev/null +++ b/jsonsource/chatroom/global-gag/api.json @@ -0,0 +1,117 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_ban_add", + "url": "chatroom/user/ban/add", + "params": { + "chatroom": { + "members": [{ + "id": "memberId01" + }], + "minute": 100 + } + }, + "response": { + "success": { + "code": 200, + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20004": { + "code": "1002", + "errorMessage": "封禁时间 minute 不正确,minute >= 1 且 minute <= 43200 单位: 分钟" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_ban_remove", + "url": "chatroom/user/ban/remove", + "params": { + "chatroom": { + "members": [{ + "id": "memberId01" + }] + } + }, + "response": { + "success": { + "code": 200, + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_ban_query", + "url": "chatroom/user/ban/query", + "params": {}, + "response": { + "success": { + "code": "200", + "members": [{ + "time": "2015-09-25 16:12:38", + "id": "2582" + }] + }, + "fail": { + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/keepalive/api.json b/jsonsource/chatroom/keepalive/api.json new file mode 100644 index 0000000..f5c0094 --- /dev/null +++ b/jsonsource/chatroom/keepalive/api.json @@ -0,0 +1,97 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_keepalive_add", + "url": "chatroom/keepalive/add", + "params": { + "chatroom": { + "id": "chatroomId01" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "chatroomId 长度超限, chatroomId >= 1 且 chatroomId <= 64 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_keepalive_remove", + "url": "chatroom/keepalive/remove", + "params": { + "chatroom": { + "id": "chatroomId01" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "chatroomId 长度超限, chatroomId >= 1 且 chatroomId <= 64 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_keepalive_query", + "url": "chatroom/keepalive/query", + "params": {}, + "response": { + "success": { + "code": "200", + "chatrooms": ["chatroomId1", "chatroomId2"] + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "chatroomId 长度超限, chatroomId >= 1 且 chatroomId <= 64 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/member-gag/api.json b/jsonsource/chatroom/member-gag/api.json new file mode 100644 index 0000000..02c8de4 --- /dev/null +++ b/jsonsource/chatroom/member-gag/api.json @@ -0,0 +1,111 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_gag_add", + "url": "chatroom/user/gag/add", + "params": { + "chatroom": { + "id":"dsd", + "members": [{"id":"akfj0a1"}, {"id":"akfj0a2"}], + "minute": 100 + } + }, + "response": { + "success": { + "code": 200, + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20004": { + "code": "1002", + "errorMessage": "封禁时间 minute 不正确,minute >= 1 且 minute <= 43200 单位: 分钟" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_gag_remove", + "url": "chatroom/user/gag/remove", + "params": { + "chatroom": { + "id":"dsd", + "members": [{"id":"akfj0a1"}, {"id":"akfj0a2"}], + } + }, + "response": { + "success": { + "code": 200, + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_gag_query", + "url": "chatroom/user/gag/query", + "params": { + "chatroom": { + "id": "akfj0a1" + } + }, + "response": { + "success": { + "code": "200", + "members": [{ + "time": "2015-09-25 16:12:38", + "id": "2582" + }] + }, + "fail": { + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/verify.json b/jsonsource/chatroom/verify.json new file mode 100644 index 0000000..481465a --- /dev/null +++ b/jsonsource/chatroom/verify.json @@ -0,0 +1,145 @@ +{ + "chatroom": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + } + }, + "id": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 32, + "min": 1, + "invalid": "20003" + }, + "typeof": { + "type": "string", + "invalid": "20001" + } + }, + "name": { + "require": { + "must": true, + "invalid": "20005" + } + }, + "members": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 20, + "min": 1, + "invalid": "20002" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + }, + "count": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 500, + "min": 1, + "invalid": "20002" + }, + "typeof": { + "type": "number|int", + "invalid": "20001" + } + }, + "order": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "string", + "invalid": "20001" + } + }, + "minute": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 43200, + "min": 1, + "invalid": "20004" + }, + "typeof": { + "type": "number|int", + "invalid": "20001" + } + } + }, + "message": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + } + }, + "type": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 5, + "min": 1, + "invalid": "20002" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + } + }, + "member": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + } + }, + "id": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20002" + } + }, + "chatroomId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20002" + } + }, + "time": { + "require": { + "must": true, + "invalid": "20005" + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/whitelist/message/api.json b/jsonsource/chatroom/whitelist/message/api.json new file mode 100644 index 0000000..14a1036 --- /dev/null +++ b/jsonsource/chatroom/whitelist/message/api.json @@ -0,0 +1,108 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_whitelist_add", + "url": "chatroom/user/whitelist/add", + "params": { + "message": { + "type": ["RC:TxtMsg", "RC:ImgMsg"] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_message_priority_remove", + "url": "chatroom/message/priority/remove", + "params": { + "message": { + "type": ["RC:TxtMsg", "RC:ImgMsg"] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_whitelist_query", + "url": "chatroom/user/whitelist/query", + "params": {}, + "response": { + "success": { + "code": "200", + "members": [ + "member1", + "member2" + ] + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "chatroomId 长度超限, chatroomId >= 1 且 chatroomId <= 64 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/chatroom/whitelist/user/api.json b/jsonsource/chatroom/whitelist/user/api.json new file mode 100644 index 0000000..9abcc40 --- /dev/null +++ b/jsonsource/chatroom/whitelist/user/api.json @@ -0,0 +1,122 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_whitelist_add", + "url": "chatroom/user/whitelist/add", + "params": { + "chatroom": { + "id": "chatroomId01", + "members": [{ + "id": "memberId01" + }] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_message_priority_remove", + "url": "chatroom/message/priority/remove", + "params": { + "chatroom": { + "id": "chatroomId01", + "members": [{ + "id": "memberId01" + }] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "chatroomId 长度超限, chatroomId >= 1 且 chatroomId <= 64 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#chatroom_user_whitelist_query", + "url": "chatroom/user/whitelist/query", + "params": { + "chatroom": { + "id": "chatroomId01" + } + }, + "response": { + "success": { + "code": "200", + "members": [ + "member1", + "member2" + ] + }, + "fail": { + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/conversation/api.json b/jsonsource/conversation/api.json new file mode 100644 index 0000000..5e4a246 --- /dev/null +++ b/jsonsource/conversation/api.json @@ -0,0 +1,80 @@ +{ + "mute": { + "docs": "http://rongcloud.cn/docs/server.html#conversation_notification_set", + "url": "conversation/notification/set", + "params": { + "conversation": { + "type": "1", + "targetId": "UAhIaLkR0", + "userId": "b5NwvIrW8" + } + }, + "response":{ + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "unmute": { + "docs": "http://rongcloud.cn/docs/server.html#conversation_notification_set", + "url": "conversation/notification/set", + "params": { + "conversation": { + "type": "1", + "targetId": "UAhIaLkR0", + "userId": "b5NwvIrW8" + } + }, + "response":{ + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "参数 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/conversation/verify.json b/jsonsource/conversation/verify.json new file mode 100644 index 0000000..676dc42 --- /dev/null +++ b/jsonsource/conversation/verify.json @@ -0,0 +1,68 @@ +{ + "conversation": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "type": { + "require": { + "must": true, + "invalid": "20005" + } + }, + "userId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "targetId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "name": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "portrait": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 1024, + "min": 1, + "invalid": "20003" + }, + "url": { + "legal": "url 正则", + "invalid": "20007" + } + } + } +} \ No newline at end of file diff --git a/jsonsource/group/api.json b/jsonsource/group/api.json new file mode 100644 index 0000000..27c807d --- /dev/null +++ b/jsonsource/group/api.json @@ -0,0 +1,353 @@ +{ + "sync": { + "//":"注解", + "docs": "http://rongcloud.cn/docs/server.html#group_sync", + "url": "group/sync", + "params": { + "user": { + "id": "123werm98", + "groups": [ + {"id": "wer987","name":"greoupName1"}, + {"id":"wer989","name": "greoupName2"} + ] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "create": { + "docs": "http://rongcloud.cn/docs/server.html#group_create", + "url": "group/create", + "params": { + "group": { + "id": "10001", + "name": "TestGroup", + "members": [{ + "id": "memberId01" + }] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "invite": { + "docs": "http://rongcloud.cn/docs/server.html#group_join", + "url": "group/join", + "params": { + "group": { + "members": [{ + "id": "memberId01" + }], + "id": "10001", + "name": "TestGroup" + } + }, + "response":{ + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "join": { + "docs": "http://rongcloud.cn/docs/server.html#group_join", + "url": "group/join", + "params": { + "group": { + "members": [{ + "id": "memberId01" + }], + "id": "10001", + "name": "TestGroup" + } + }, + "response":{ + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "quit": { + "docs": "http://rongcloud.cn/docs/server.html#group_quit", + "url": "group/quit", + "params": { + "group": { + "id": "10001", + "members": [{ + "id": "memberId01" + }] + } + }, + "response":{ + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "dismiss": { + "docs": "http://rongcloud.cn/docs/server.html#group_dismiss", + "url": "group/dismiss", + "params": { + "group":{ + "id": "10001", + "member": {"id":"aFo990k"} + } + + }, + "response":{ + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "update": { + "docs": "http://rongcloud.cn/docs/server.html#group_refresh", + "url": "group/refresh", + "params": { + "group": { + "id":"10001", + "name": "testGroup1" + } + }, + "response":{ + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "get": { + "docs": "http://rongcloud.cn/docs/server.html#group_user_query", + "url": "group/user/query", + "params": { + "group": { + "id": "10001" + } + }, + "response":{ + "success": { + "code": "200", + "members": [{ + "id": "10001" + }, { + "id": "10002" + }, { + "id": "10000" + }, { + "id": "10003" + }] + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/group/gag/api.json b/jsonsource/group/gag/api.json new file mode 100644 index 0000000..b0e56dd --- /dev/null +++ b/jsonsource/group/gag/api.json @@ -0,0 +1,135 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#group_user_gag_add", + "url": "group/user/gag/add", + "params": { + "group": { + "id": "10001", + "members": [{ + "id": "memberId01" + }], + "minute": 60 + } + }, + "response":{ + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + }, + "20004": { + "code": "1002", + "errorMessage": "封禁时间不正确, 当前传入为 {{size}}, 正确范围 0 - 43200 分钟, 0 为永久禁言" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#group_user_gag_rollback", + "url": "group/user/gag/rollback", + "params": { + "group": { + "id": "10001", + "members": [{ + "id": "memberId01" + }] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + }, + "20004": { + "code": "1002", + "errorMessage": "封禁时间超限, 最长不超过 43200 分钟" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#group_user_gag_list", + "url": "group/user/gag/list", + "params": { + "group": { + "id": "10001", + } + }, + "response":{ + "success": { + "code": "200", + "members": [{ + "time": "2015-09-25 16:12:38", + "id": "2582" + }] + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/group/verify.json b/jsonsource/group/verify.json new file mode 100644 index 0000000..b88264b --- /dev/null +++ b/jsonsource/group/verify.json @@ -0,0 +1,131 @@ +{ + "group": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "id": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "members": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + }, + "name": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "portrait": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 1024, + "min": 1, + "invalid": "20003" + }, + "url": { + "legal": "url 正则", + "invalid": "20007" + } + }, + "minute": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 43200, + "min": 1, + "invalid": "20004" + }, + "typeof": { + "type": "number|int", + "invalid": "20001" + } + }, + "operator": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + } + }, + "user":{ + "id": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "groups":{ + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + } + }, + "minute": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 43200, + "min": 1, + "invalid": "20004" + }, + "typeof": { + "type": "number|int", + "invalid": "20001" + } + } + +} \ No newline at end of file diff --git a/jsonsource/message/TemplateMessage.json b/jsonsource/message/TemplateMessage.json new file mode 100644 index 0000000..038c138 --- /dev/null +++ b/jsonsource/message/TemplateMessage.json @@ -0,0 +1,16 @@ + { + "senderId": "Vu-oC0_LQ6kgPqltm_zYtI", + "objectName": "RC:TxtMsg", + "template": { + "content": ".NET{name}, 语文成绩 {score} 分 template" + }, + "content": { + "uPj70HUrRSUk-ixtt7iIGc": { + "data": { + "{name}": "小明", + "{score}": "90" + }, + "push": ".NET{name} 你的成绩出来了 template" + } + } + } \ No newline at end of file diff --git a/jsonsource/message/_private/api.json b/jsonsource/message/_private/api.json new file mode 100644 index 0000000..046b81f --- /dev/null +++ b/jsonsource/message/_private/api.json @@ -0,0 +1,154 @@ +{ + "send": { + "params": { + "message": { + "conversationType": 1, + "senderId": "2191", + "targetId": ["2192","jjjj"], + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + }, + "pushContent": "thisisapush", + "pushData": { + "pushData":"hello" + }, + "isCounted": "1", + "verifyBlacklist": 0, + "isPersisted": 1, + "isCounted": 1, + "isIncludeSender": 0, + "contentAvailable": 0 + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "sendTemplate": { + "params": { + "message": { + "senderId": "fhdjfh00f", + "objectName": "RC:TxtMsg", + "template": { + "content": "{name}, 语文成绩 {score} 分" + }, + "content": { + "sea9901": { + "data": { + "{name}": "小明", + "{score}": "90" + }, + "push": "{name} 考试成绩" + }, + "sea9902": { + "data": { + "{name}": "小红", + "{score}": "95" + }, + "push": "{name} 考试成绩" + } + } + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "recall": { + "params": { + "message": { + "senderId": "fDR2cVpxxR5zSMUNh3yAwh", + "targetId": "MersNRhaKwJkRV9mJR5JXY", + "uId": "5FGT-7VA9-G4DD-4V5P", + "sentTime": "20007778882124" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/message/api.json b/jsonsource/message/api.json new file mode 100644 index 0000000..a7e2f3b --- /dev/null +++ b/jsonsource/message/api.json @@ -0,0 +1,133 @@ +{ + "send": { + "url": { + "1": "message/private/publish", + "2": "message/system/publish", + "3": "message/group/publish", + "4": "message/discussion/publish", + "5": "message/chatroom/publish", + "6": "message/broadcast" + }, + "params": { + "message": { + "conversationType": 1, + "from": "2191", + "to": "2192", + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + }, + "pushContent": "thisisapush", + "pushData": { + "pushData":"hello" + }, + "count": "4", + "isFilterBlack": 0, + "isPersisted": 1, + "isCounted": 1, + "owner": 0 + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "publishTemplate": { + "url": { + "1": "message/private/publish_template", + "2": "message/system/publish_template" + }, + "params": { + "message": { + "conversationType": 1, + "senderUserId": "2191", + "objectName": "RC:TxtMsg", + "template": { + "21":{"{c}":"1","{d}":"2","{e}":"3"},"22":{"{c}":"4","{d}":"5","{e}":"6"} + }, + "data":{ + "content":"{c}{d}{e}", + "extra":"bb" + } + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "recall": { + "docs": "http://rongcloud.cn/docs/server.html#message_recall", + "url": "message/recall", + "params": { + "message": { + "senderUserId": "fDR2cVpxxR5zSMUNh3yAwh", + "conversationType": "1", + "targetId": "MersNRhaKwJkRV9mJR5JXY", + "uId": "5FGT-7VA9-G4DD-4V5P", + "sentTime": "20007778882124" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/message/chatroom/api.json b/jsonsource/message/chatroom/api.json new file mode 100644 index 0000000..e911217 --- /dev/null +++ b/jsonsource/message/chatroom/api.json @@ -0,0 +1,90 @@ +{ + "send": { + "params": { + "chatroomMessage": { + "senderId": "2191", + "targetId": "2192", + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + } + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "broadcast": { + "url": "message/chatroom/broadcast", + "params": { + "message": { + "senderId": "2191", + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + } + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型, 应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/message/discussion/api.json b/jsonsource/message/discussion/api.json new file mode 100644 index 0000000..1827f80 --- /dev/null +++ b/jsonsource/message/discussion/api.json @@ -0,0 +1,92 @@ +{ + "send": { + "params": { + "discussionMessage": { + "senderId": "2191", + "targetId": "2192", + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + }, + "pushContent": "thisisapush", + "pushData": { + "pushData":"hello" + }, + "count": "4", + "verifyBlacklist": 0, + "isPersisted": 1, + "isCounted": 1, + "isIncludeSender": 0, + "contentAvailable": 0 + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "recall": { + "docs": "http://rongcloud.cn/docs/server.html#message_recall", + "url": "message/recall", + "params": { + "recallMessage": { + "senderId": "fDR2cVpxxR5zSMUNh3yAwh", + "targetId": "MersNRhaKwJkRV9mJR5JXY", + "uId": "5FGT-7VA9-G4DD-4V5P", + "sentTime": "20007778882124" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/message/group/api.json b/jsonsource/message/group/api.json new file mode 100644 index 0000000..a224a9d --- /dev/null +++ b/jsonsource/message/group/api.json @@ -0,0 +1,149 @@ +{ + "send": { + "params": { + "groupMessage": { + "conversationType": 1, + "senderId": "2191", + "targetId": "2192", + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + }, + "pushContent": "thisisapush", + "pushData": { + "pushData":"hello" + }, + "isCounted": "1", + "verifyBlacklist": 0, + "isPersisted": 1, + "isCounted": 1, + "isIncludeSender": 0 + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "sendMention": { + "url": "message/group/publish", + "params": { + "message": { + "senderId": "2191", + "targetId": "2192", + "objectName": "RC:TxtMsg", + "mentionedInfo": { + "type": 1, + "userIds": ["userId"] + }, + "content": { + "content":"hello" + } + } + }, + "response": { + "success": { + "code": "200", + "msg": "成功返回" + }, + "fail": { + "20002": { + "code": "20002", + "msg": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "20003", + "msg": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "20005", + "msg": "{{name}} 参数为必传项" + }, + "20006": { + "code": "20006", + "msg": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "20000", + "msg": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "20001", + "msg": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "recall": { + "docs": "http://rongcloud.cn/docs/server.html#message_recall", + "url": "message/recall", + "params": { + "recallMessage": { + "senderId": "fDR2cVpxxR5zSMUNh3yAwh", + "targetId": "MersNRhaKwJkRV9mJR5JXY", + "uId": "5FGT-7VA9-G4DD-4V5P", + "sentTime": "20007778882124" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "20002": { + "code": "1502", + "errorMessage": "{{name}} 个数超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/message/history/api.json b/jsonsource/message/history/api.json new file mode 100644 index 0000000..aa6a5b9 --- /dev/null +++ b/jsonsource/message/history/api.json @@ -0,0 +1,67 @@ +{ + "get": { + "docs": "http://rongcloud.cn/docs/server.html#history_message_download", + "url": "message/history", + "params": { + "message": { + "date": "2018010101" + } + }, + "response": { + "success": { + "code": "200", + "url": "http://120.92.22.186/9/2018030119/5e398bf3-df16-4e75-9385-7e37c65db649.zip" + }, + "fail": { + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#history_message_delete", + "url": "message/delete", + "params": { + "message": { + "date": "2017010101" + } + }, + "response": { + "success": { + "code": "200", + }, + "fail": { + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/message/recall/api.json b/jsonsource/message/recall/api.json new file mode 100644 index 0000000..3e2bb8c --- /dev/null +++ b/jsonsource/message/recall/api.json @@ -0,0 +1,38 @@ +{ + "recall": { + "docs": "http://rongcloud.cn/docs/server.html#message_recall", + "url": "message/recall", + "params": { + "recallMessage": { + "senderId": "fDR2cVpxxR5zSMUNh3yAwh", + "targetId": "MersNRhaKwJkRV9mJR5JXY", + "uId": "5FGT-7VA9-G4DD-4V5P", + "sentTime": "20007778882124" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/message/system/api.json b/jsonsource/message/system/api.json new file mode 100644 index 0000000..f5ee338 --- /dev/null +++ b/jsonsource/message/system/api.json @@ -0,0 +1,154 @@ +{ + "send": { + "params": { + "systemMessage": { + "conversationType": 1, + "senderId": "2191", + "targetId": "2192", + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + }, + "pushContent": "thisisapush", + "pushData": { + "pushData":"hello" + }, + "verifyBlacklist": 0, + "isPersisted": 1, + "isCounted": 1, + "isIncludeSender": 0, + "contentAvailable": 0 + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "sendTemplate": { + "params": { + "message": { + "senderId": "fhdjfh00f", + "objectName": "RC:TxtMsg", + "template": { + "content": "{name}, 语文成绩 {score} 分" + }, + "content": { + "sea9901": { + "data": { + "{name}": "小明", + "{score}": "90" + }, + "push": "{name} 考试成绩" + }, + "sea9902": { + "data": { + "{name}": "小红", + "{score}": "95" + }, + "push": "{name} 考试成绩" + } + } + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "broadcast": { + "docs": "http://www.rongcloud.cn/docs/server.html#message_broadcast", + "url": "message/", + "params": { + "message": { + "senderId":"sds", + "objectName": "RC:TxtMsg", + "content": { + "content":"hello" + }, + "pushContent": "this is a push", + "pushData": { + "pushData":"hello" + }, + "os": "ios", + "contentAvailable": 0 + } + }, + "response": { + "success": { + "code": 200 + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + + } +} \ No newline at end of file diff --git a/jsonsource/message/verify.json b/jsonsource/message/verify.json new file mode 100644 index 0000000..dfd14a7 --- /dev/null +++ b/jsonsource/message/verify.json @@ -0,0 +1,337 @@ +{ + "message": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "senderId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "targetId": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 1000, + "min": 1, + "invalid": "20002" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + }, + "objectName": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 32, + "min": 1, + "invalid": "20002" + } + }, + "content": { + "require": { + "must": true, + "invalid": "20005" + } + } + }, + "systemMessage": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "senderId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "targetId": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 100, + "min": 1, + "invalid": "20002" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + }, + "objectName": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 32, + "min": 1, + "invalid": "20003" + } + }, + "content": { + "require": { + "must": true, + "invalid": "20005" + } + } + }, + "groupMessage": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "senderId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "targetId": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 3, + "min": 1, + "invalid": "20002" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + }, + "objectName": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 32, + "min": 1, + "invalid": "20003" + } + }, + "content": { + "require": { + "must": true, + "invalid": "20005" + } + } + }, + "chatroomMessage": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "senderId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "targetId": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 10, + "min": 1, + "invalid": "20002" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + }, + "objectName": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 32, + "min": 1, + "invalid": "20003" + } + }, + "content": { + "require": { + "must": true, + "invalid": "20005" + } + } + }, + "discussionMessage": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "senderId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "targetId": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 3, + "min": 1, + "invalid": "20002" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + }, + "objectName": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 32, + "min": 1, + "invalid": "20003" + } + }, + "content": { + "require": { + "must": true, + "invalid": "20005" + } + } + }, + "mentionedInfo":{ + "type": { + "require": { + "must": true, + "invalid": "20005" + } + }, + "userIds": { + "require": { + "must": true, + "invalid": "20005" + } + } + }, + "recallMessage": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "senderId": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "targetIds": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "uId": { + "require": { + "must": true, + "invalid": "20005" + } + }, + "sentTime": { + "require": { + "must": true, + "invalid": "20005" + } + } + } +} \ No newline at end of file diff --git a/jsonsource/sensitiveword/api.json b/jsonsource/sensitiveword/api.json new file mode 100644 index 0000000..96687e3 --- /dev/null +++ b/jsonsource/sensitiveword/api.json @@ -0,0 +1,156 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#sensitiveword_add", + "url": "sensitiveword/add", + "params": { + "sensitive": { + "type": 1, + "keyword": "法轮功", + "replace": "***" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#sensitiveword_delete", + "url": "sensitiveword/delete", + "params": { + "sensitive": { + "keywords": "法轮功" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "batchDelete": { + "docs": "http://www.rongcloud.cn/docs/server.html#sensitiveword_batch_delete", + "url": "/sensitiveword/batch/delete", + "params": { + "sensitive": { + "keywords": ["法轮功", "国名党"] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "参数类型类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#sensitiveword_list", + "url": "sensitiveword/list", + "params": {}, + "response": { + "success": { + "code": 200, + "words": [{ + "type": 0, + "word": "黄赌毒", + "replaceWord": "***" + }, { + "type": 0, + "word": "法轮功", + "replaceWord": "---" + }] + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "参数类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/sensitiveword/verify.json b/jsonsource/sensitiveword/verify.json new file mode 100644 index 0000000..3b26ada --- /dev/null +++ b/jsonsource/sensitiveword/verify.json @@ -0,0 +1,77 @@ +{ + "rule": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "keyword": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "replace": { + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + } + }, + "sensitive": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "keyword": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "replace": { + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "keywords": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 50, + "min": 1, + "invalid": "20003" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + } + } +} \ No newline at end of file diff --git a/jsonsource/user/api.json b/jsonsource/user/api.json new file mode 100644 index 0000000..12d1f16 --- /dev/null +++ b/jsonsource/user/api.json @@ -0,0 +1,90 @@ +{ + "register": { + "docs": "http://rongcloud.cn/docs/server.html#user_get_token", + "url": "user/getToken", + "params": { + "user": { + "id": "aFo990k", + "name": "Martin", + "portrait": "http://image.rongcloud.cn/portrait.png" + } + }, + "response": { + "success": { + "code": 200, + "userId": "jlk456j5", + "token": "MAo+IhwqEO3+h/DdXg1w6m20V27XsDF2Dx+" + }, + "fail": { + "2007": { + "code": "2007", + "errorMessage": "开发环境下注册用户上限为 100 个,生产环境下注册用户不超过 100 可免费使用,超过 100 需要开通 IM 商用版" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "20007": { + "code": "1002", + "errorMessage": "protrait 不是合法地址,请检查 protrait 是否正确" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + + }, + "update": { + "docs": "http://rongcloud.cn/docs/server.html#user_refresh", + "url": "user/refresh", + "params": { + "user": { + "id": "aFo990k", + "name": "Martin", + "portrait": "http://image.rongcloud.cn/portrait.png" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20007": { + "code": "1002", + "errorMessage": "protrait 不是合法地址,请检查 protrait 是否正确" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/user/blacklist/api.json b/jsonsource/user/blacklist/api.json new file mode 100644 index 0000000..a44690d --- /dev/null +++ b/jsonsource/user/blacklist/api.json @@ -0,0 +1,125 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#user_blacklist_add", + "url": "user/blacklist/add", + "params": { + "user": { + "id": "kkfh091", + "blacklist": [{ + "id": "kkfh091" + }] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#user_blacklist_remove", + "url": "user/blacklist/remove", + "params": { + "user": { + "id": "kkfh091", + "blacklist": [{ + "id": "kkfh091" + }] + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20002": { + "code": "1502", + "errorMessage": "{{name}} 数量超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#user_blacklist_query", + "url": "user/blacklist/query", + "params": { + "user": { + "id": "kkfh091" + } + }, + "success": { + "code": "200", + "users": [{ + "id": "kkfh091" + }] + }, + "response": { + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/user/block/api.json b/jsonsource/user/block/api.json new file mode 100644 index 0000000..b01feb2 --- /dev/null +++ b/jsonsource/user/block/api.json @@ -0,0 +1,94 @@ +{ + "add": { + "docs": "http://rongcloud.cn/docs/server.html#user_block_add", + "url": "user/block", + "params": { + "user": { + "id": "aFo990k", + "minute": 30 + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20004": { + "code": "1002", + "errorMessage": "minute 不正确,minute >= 1 且 minute <= 43200 单位: 分钟" + }, + "20001": { + "code": "1501", + "errorMessage": "{{name}} 类型不正确,请检查参数类型,应该为 {{type}} 传入为 {{currentType}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "remove": { + "docs": "http://rongcloud.cn/docs/server.html#user_unblock", + "url": "user/unblock", + "params": { + "user": { + "id": "aFo990k" + } + }, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "20001": { + "code": "1501", + "errorMessage": "minute 参数不正确,请检查参数类型,应该为 number 传入为 {{currentType}}" + }, + "20005": { + "code": "1002", + "errorMessage": "{{name}} 参数为必传项" + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + }, + "getList": { + "docs": "http://rongcloud.cn/docs/server.html#user_block_query", + "url": "user/block/query", + "params": {}, + "response": { + "success": { + "code": "200", + "errorMessage": "成功返回" + }, + "fail": { + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/user/online-status/api.json b/jsonsource/user/online-status/api.json new file mode 100644 index 0000000..912be63 --- /dev/null +++ b/jsonsource/user/online-status/api.json @@ -0,0 +1,39 @@ +{ + "check": { + "docs": "http://rongcloud.cn/docs/server.html#user_check_online", + "url": "user/checkOnline", + "params": { + "user": { + "id": "aFo990k" + } + }, + "response": { + "success": { + "code": 200, + "status": 1 + }, + "fail": { + "20003": { + "code": "1002", + "errorMessage": "{{name}} 长度超限, {{name}} >= {{min}} 且 {{name}} <= {{max}} 单位: 字节" + }, + "20005": { + "code": "1002", + "errorMessage": "id 为必传项" + }, + "20001": { + "code": "1501", + "errorMessage": "user 类型不正确,请检查参数类型,应该为 Object 传入为 {{currentType}} " + }, + "1004": { + "code": "1004", + "errorMessage": "签名错误, 请排查 Appkey、Secret 是否正确" + }, + "1008": { + "code": "1008", + "errorMessage": "调用频率超限,每秒钟限制 100 次,调整频率上限请移步至专有云 http://www.rongcloud.cn/pricing#pay" + } + } + } + } +} \ No newline at end of file diff --git a/jsonsource/user/verify.json b/jsonsource/user/verify.json new file mode 100644 index 0000000..4c6cb41 --- /dev/null +++ b/jsonsource/user/verify.json @@ -0,0 +1,77 @@ +{ + "user": { + "_self": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "object", + "invalid": "20001" + } + }, + "id": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "name": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 64, + "min": 1, + "invalid": "20003" + } + }, + "portrait": { + "require": { + "must": true, + "invalid": "20005" + }, + "length": { + "max": 1024, + "min": 1, + "invalid": "20003" + }, + "url": { + "legal": "url 正则", + "invalid": "20007" + } + }, + "minute": { + "require": { + "must": true, + "invalid": "20005" + }, + "size": { + "max": 43200, + "min": 1, + "invalid": "20004" + }, + "typeof": { + "type": "number|int", + "invalid": "20001" + } + }, + "blacklist": { + "require": { + "must": true, + "invalid": "20005" + }, + "typeof": { + "type": "array", + "invalid": "20001" + } + } + + } +} \ No newline at end of file diff --git a/messages/BaseMessage.cs b/messages/BaseMessage.cs new file mode 100644 index 0000000..160ec2f --- /dev/null +++ b/messages/BaseMessage.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + abstract class BaseMessage + { + public abstract String GetType(); + + override + public abstract String ToString(); + } +} diff --git a/messages/CmdMsgMessage.cs b/messages/CmdMsgMessage.cs new file mode 100644 index 0000000..98128a6 --- /dev/null +++ b/messages/CmdMsgMessage.cs @@ -0,0 +1,45 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + /** + * + * 通用命令通知消息。此类型消息没有 Push 通知。此类型消息没有 Push 通知,与通用命令通知消息的区别是不存储、不计数。 + * + */ + class CmdMsgMessage : BaseMessage + { + [JsonProperty(PropertyName = "name")] + private String name = ""; + [JsonProperty(PropertyName = "data")] + private String data = ""; + private static readonly String TYPE = "RC:CmdMsg"; + + [JsonIgnore] + public string Name { get => name; set => name = value; } + [JsonIgnore] + public string Data { get => data; set => data = value; } + + public CmdMsgMessage(String name, String data) + { + this.name = name; + this.data = data; + } + + override + public String GetType() + { + return TYPE; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/CmdNtfMessage.cs b/messages/CmdNtfMessage.cs new file mode 100644 index 0000000..799eb24 --- /dev/null +++ b/messages/CmdNtfMessage.cs @@ -0,0 +1,45 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + + /** + * + * 通用命令通知消息。此类型消息没有 Push 通知。 + * + */ + class CmdNtfMessage : BaseMessage + { + [JsonProperty(PropertyName = "name")] + private String name = ""; + [JsonProperty(PropertyName = "data")] + private String data = ""; + private static readonly String TYPE = "RC:CmdNtf"; + + [JsonIgnore] + public string Name { get => name; set => name = value; } + [JsonIgnore] + public string Data { get => data; set => data = value; } + + public CmdNtfMessage(String name, String data) + { + this.name = name; + this.data = data; + } + override + public String GetType() + { + return TYPE; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/ContactNtfMessage.cs b/messages/ContactNtfMessage.cs new file mode 100644 index 0000000..81d402f --- /dev/null +++ b/messages/ContactNtfMessage.cs @@ -0,0 +1,59 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + /** + * + * 添加联系人消息。 + * + */ + class ContactNtfMessage : BaseMessage + { + [JsonProperty(PropertyName = "operation")] + private String operation = ""; + [JsonProperty(PropertyName = "extra")] + private String extra = ""; + [JsonProperty(PropertyName = "sourceUserId")] + private String sourceUserId = ""; + [JsonProperty(PropertyName = "targetUserId")] + private String targetUserId = ""; + [JsonProperty(PropertyName = "message")] + private String message = ""; + private static readonly String TYPE = "RC:ContactNtf"; + + [JsonIgnore] + public string Operation { get => operation; set => operation = value; } + [JsonIgnore] + public string Extra { get => extra; set => extra = value; } + [JsonIgnore] + public string SourceUserId { get => sourceUserId; set => sourceUserId = value; } + [JsonIgnore] + public string TargetUserId { get => targetUserId; set => targetUserId = value; } + [JsonIgnore] + public string Message { get => message; set => message = value; } + + public ContactNtfMessage(String operation, String extra, String sourceUserId, String targetUserId, String message) + { + this.operation = operation; + this.extra = extra; + this.sourceUserId = sourceUserId; + this.targetUserId = targetUserId; + this.message = message; + } + override + public String GetType() + { + return TYPE; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/CustomTxtMessage.cs b/messages/CustomTxtMessage.cs new file mode 100644 index 0000000..5d053d9 --- /dev/null +++ b/messages/CustomTxtMessage.cs @@ -0,0 +1,59 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + /** + * + * 自定义消息 + * + */ + class CustomTxtMessage : BaseMessage + { + [JsonProperty(PropertyName = "content")] + private String content = ""; + private static readonly String TYPE = "RC:TxtMsg"; + + [JsonIgnore] + public string Content { get => content; set => content = value; } + + public CustomTxtMessage(String content) + { + this.content = content; + } + override + public String GetType() + { + return TYPE; + } + + /** + * 获取自定义消息内容。 + * + * @return String + */ + public String getContent() + { + return content; + } + + /** + * @param content 设置自定义消息内容。 + * + * + */ + public void setContent(String content) + { + this.content = content; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/ImgMessage.cs b/messages/ImgMessage.cs new file mode 100644 index 0000000..6bf32de --- /dev/null +++ b/messages/ImgMessage.cs @@ -0,0 +1,53 @@ +using io.rong.messages; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.message +{ + + /** + * + * 图片消息。 + * + */ + class ImgMessage : BaseMessage + { + [JsonProperty(PropertyName = "content")] + private String content = ""; + [JsonProperty(PropertyName = "extra")] + private String extra = ""; + [JsonProperty(PropertyName = "imageUri")] + private String imageUri = ""; + private static readonly String TYPE = "RC:ImgMsg"; + + [JsonIgnore] + public string Content { get => content; set => content = value; } + [JsonIgnore] + public string Extra { get => extra; set => extra = value; } + [JsonIgnore] + public string ImageUri { get => imageUri; set => imageUri = value; } + + public static string TYPE1=> TYPE; + + public ImgMessage(String content, String extra, String imageUri) + { + this.content = content; + this.extra = extra; + this.imageUri = imageUri; + } + override + public String GetType() + { + return TYPE; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/ImgTextMessage.cs b/messages/ImgTextMessage.cs new file mode 100644 index 0000000..3dc03b7 --- /dev/null +++ b/messages/ImgTextMessage.cs @@ -0,0 +1,62 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + + /** + * + * 图文消息。 + * + */ + class ImgTextMessage : BaseMessage + { + [JsonProperty(PropertyName = "content")] + private String content = ""; + [JsonProperty(PropertyName = "extra")] + private String extra = ""; + [JsonProperty(PropertyName = "title")] + private String title = ""; + [JsonProperty(PropertyName = "imageUri")] + private String imageUri = ""; + [JsonProperty(PropertyName = "conturlent")] + private String url = ""; + private static readonly String TYPE = "RC:ImgTextMsg"; + + [JsonIgnore] + public string Content { get => content; set => content = value; } + [JsonIgnore] + public string Extra { get => extra; set => extra = value; } + [JsonIgnore] + public string Title { get => title; set => title = value; } + [JsonIgnore] + public string ImageUri { get => imageUri; set => imageUri = value; } + [JsonIgnore] + public string Url { get => url; set => url = value; } + + public static string TYPE1 => TYPE; + + public ImgTextMessage(String content, String extra, String title, String imageUri, String url) + { + this.content = content; + this.extra = extra; + this.title = title; + this.imageUri = imageUri; + this.url = url; + } + override + public String GetType() + { + return TYPE; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/InfoNtfMessage.cs b/messages/InfoNtfMessage.cs new file mode 100644 index 0000000..71bb588 --- /dev/null +++ b/messages/InfoNtfMessage.cs @@ -0,0 +1,58 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + + /** + * + * 提示条(小灰条)通知消息。此类型消息没有 Push 通知。 + * + */ + class InfoNtfMessage : BaseMessage + { + [JsonProperty(PropertyName = "content")] + private String message = ""; + [JsonProperty(PropertyName = "content")] + private String extra = ""; + private static readonly String TYPE = "RC:InfoNtf"; + + [JsonIgnore] + public string Message { get => message; set => message = value; } + [JsonIgnore] + public string Extra { get => extra; set => extra = value; } + + public static string TYPE1 => TYPE; + + public InfoNtfMessage(String message, String extra) + { + this.message = message; + this.extra = extra; + } + override + public String GetType() + { + return TYPE; + } + + + /** + * @param extra 设置附加信息(如果开发者自己需要,可以自己在 App 端进行解析)。 + * + * + */ + public void setExtra(String extra) + { + this.extra = extra; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/LBSMessage.cs b/messages/LBSMessage.cs new file mode 100644 index 0000000..615b101 --- /dev/null +++ b/messages/LBSMessage.cs @@ -0,0 +1,61 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + + /** + * + * 位置消息。 + * + */ + class LBSMessage : BaseMessage + { + [JsonProperty(PropertyName = "content")] + private String content = ""; + [JsonProperty(PropertyName = "extra")] + private String extra = ""; + [JsonProperty(PropertyName = "latitude")] + private double latitude = 0; + [JsonProperty(PropertyName = "longitude")] + private double longitude = 0; + [JsonProperty(PropertyName = "poi")] + private String poi = ""; + private static readonly String TYPE = "RC:LBSMsg"; + + [JsonIgnore] + public string Content { get => content; set => content = value; } + [JsonIgnore] + public string Extra { get => extra; set => extra = value; } + [JsonIgnore] + public double Latitude { get => latitude; set => latitude = value; } + [JsonIgnore] + public double Longitude { get => longitude; set => longitude = value; } + [JsonIgnore] + public string Poi { get => poi; set => poi = value; } + + public LBSMessage(String content, String extra, double latitude, double longitude, String poi) + { + this.content = content; + this.extra = extra; + this.latitude = latitude; + this.longitude = longitude; + this.poi = poi; + } + override + public String GetType() + { + return TYPE; + } + + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/ProfileNtfMessage.cs b/messages/ProfileNtfMessage.cs new file mode 100644 index 0000000..34dbe23 --- /dev/null +++ b/messages/ProfileNtfMessage.cs @@ -0,0 +1,51 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + /** + * + * 资料通知消息。此类型消息没有 Push 通知。 + * + */ + class ProfileNtfMessage : BaseMessage + { + [JsonProperty(PropertyName = "operation")] + private String operation = ""; + [JsonProperty(PropertyName = "data")] + private String data = ""; + [JsonProperty(PropertyName = "extra")] + private String extra = ""; + private static readonly String TYPE = "RC:ProfileNtf"; + + [JsonIgnore] + public string Operation { get => operation; set => operation = value; } + [JsonIgnore] + public string Data { get => data; set => data = value; } + [JsonIgnore] + public string Extra { get => extra; set => extra = value; } + + public ProfileNtfMessage(String operation, String data, String extra) + { + this.operation = operation; + this.data = data; + this.extra = extra; + } + override + public String GetType() + { + return TYPE; + } + + + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/TxtMessage.cs b/messages/TxtMessage.cs new file mode 100644 index 0000000..551bf39 --- /dev/null +++ b/messages/TxtMessage.cs @@ -0,0 +1,46 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + /** + * + * 文本消息。 + * + */ + class TxtMessage : BaseMessage + { + [JsonProperty(PropertyName = "content")] + private String content = ""; + [JsonProperty(PropertyName = "extra")] + private String extra = ""; + private static readonly String TYPE = "RC:TxtMsg"; + + [JsonIgnore] + public string Content { get => content; set => content = value; } + [JsonIgnore] + public string Extra { get => extra; set => extra = value; } + + public TxtMessage(String content, String extra) + { + this.content = content; + this.extra = extra; + } + + override + public String GetType() + { + return TYPE; + } + + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/messages/VoiceMessage.cs b/messages/VoiceMessage.cs new file mode 100644 index 0000000..317542e --- /dev/null +++ b/messages/VoiceMessage.cs @@ -0,0 +1,50 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.messages +{ + /** + * + * 语音消息。 + * + */ + class VoiceMessage : BaseMessage + { + [JsonProperty(PropertyName = "content")] + private String content = ""; + [JsonProperty(PropertyName = "extra")] + private String extra = ""; + [JsonProperty(PropertyName = "duration")] + private long duration = 0L; + private static readonly String TYPE = "RC:VcMsg"; + + [JsonIgnore] + public string Content { get => content; set => content = value; } + [JsonIgnore] + public string Extra { get => extra; set => extra = value; } + [JsonIgnore] + public long Duration { get => duration; set => duration = value; } + + public VoiceMessage(String content, String extra, long duration) + { + this.content = content; + this.extra = extra; + this.duration = duration; + } + override + public String GetType() + { + return TYPE; + } + + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/methods/chatroom/Chatroom.cs b/methods/chatroom/Chatroom.cs new file mode 100644 index 0000000..57de261 --- /dev/null +++ b/methods/chatroom/Chatroom.cs @@ -0,0 +1,195 @@ +using io.rong.util; +using io.rong.methods.chatroom.block; +using io.rong.methods.chatroom.ban; +using io.rong.methods.chatroom.demotion; +using io.rong.methods.chatroom.distribute; +using io.rong.methods.chatroom.gag; +using io.rong.methods.chatroom.keepalive; +using io.rong.methods.chatroom.whitelist; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.chatroom; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.methods.chatroom +{ + /** + * + * 聊天室服务 + * docs: "http://www.rongcloud.cn/docs/server.html#chatroom" + * + * */ + class Chatroom + { + + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom"; + private String appKey; + private String appSecret; + public Block block; + public Gag gag; + public Ban ban; + public Keepalive keepalive; + public Demotion demotion; + public Whitelist whiteList; + public Distribute distribute; + private RongCloud rongCloud; + + internal RongCloud RongCloud + { + get => rongCloud; set + { + rongCloud = value; + gag.RongCloud = value; + keepalive.RongCloud = value; + demotion.RongCloud = value; + whiteList.RongCloud = value; + block.RongCloud = value; + demotion.RongCloud = value; + distribute.RongCloud = value; + ban.RongCloud = value; + } + } + + public Chatroom(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + this.gag = new Gag(appKey, appSecret); + this.keepalive = new Keepalive(appKey, appSecret); + this.demotion = new Demotion(appKey, appSecret); + this.whiteList = new Whitelist(appKey, appSecret); + this.block = new Block(appKey, appSecret); + this.distribute = new Distribute(appKey, appSecret); + this.ban = new Ban(appKey, appSecret); + + } + /** + * 创建聊天室方法 + * + * @param chatrooms:chatroom.id,name(必传) + * + * @return ResponseResult + **/ + public ResponseResult Create(ChatroomModel[] chatrooms) + { + if (chatrooms == null) + { + return new ResponseResult(1002, "Paramer 'chatrooms' is required"); + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < chatrooms.Length; i++) + { + ChatroomModel chatroom = chatrooms[i]; + sb.Append("&chatroom[" + chatroom.Id + "]=").Append(HttpUtility.UrlEncode(chatroom.Name, UTF8)); + } + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/create.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.CREATE, result)); + + } + /** + * 销毁聊天室方法 + * + * @param chatroom:要销毁的聊天室 Id。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Destroy(ChatroomModel chatroom) + { + if (chatroom == null) + { + return new ResponseResult(1002, "Paramer 'chatroomId' is required"); + } + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.DESTORY); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id, UTF8)); + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/destroy.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.DESTORY, result)); + } + /** + * 查询聊天室内用户方法 + * + * @param chatroom:聊天室.id,count,order(必传) + * + * @return ChatroomUserQueryResult + **/ + public ChatroomUserQueryResult Get(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.GET); + if (null != message) + { + return (ChatroomUserQueryResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + sb.Append("&count=").Append(HttpUtility.UrlEncode(chatroom.Count.ToString(), UTF8)); + sb.Append("&order=").Append(HttpUtility.UrlEncode(chatroom.Order.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/query.json", "application/x-www-form-urlencoded"); + + return (ChatroomUserQueryResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GET, result)); + } + /** + * 查询用户是否存在聊天室 + * + * @param member:聊天室成员。(必传) + * + * @return ResponseResult + **/ + public CheckChatRoomUserResult IsExist(ChatroomMember member) + { + String message = CommonUtil.CheckFiled(member, PATH, CheckMethod.ISEXIST); + if (null != message) + { + return (CheckChatRoomUserResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(member.ChatroomId.ToString(), UTF8)); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/exist.json", "application/x-www-form-urlencoded"); + + return (CheckChatRoomUserResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ISEXIST, result)); + } + } +} \ No newline at end of file diff --git a/methods/chatroom/ban/Ban.cs b/methods/chatroom/ban/Ban.cs new file mode 100644 index 0000000..06991a9 --- /dev/null +++ b/methods/chatroom/ban/Ban.cs @@ -0,0 +1,128 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.ban +{ + + /** + * 聊天室全局禁言服务 + * docs:http://www.rongcloud.cn/docs/server.html#chatroom_user_ban + * + * */ + class Ban + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/global-gag"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public Ban(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + } + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + /** + * 添加用户聊天室全局禁言方法 + * + * @param chatroom : Id,minute。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Add(ChatroomModel chatroom) + { + String errMsg = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.ADD); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + + StringBuilder sb = new StringBuilder(); + ChatroomMember[] members = chatroom.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id, UTF8)); + } + sb.Append("&minute=").Append(HttpUtility.UrlEncode(chatroom.Minute.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/ban/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + + /** + * 查询被聊天室全局禁言用户方法 + * + * @return ListGagChatroomUserResult + **/ + public ListGagChatroomUserResult GetList() + { + String result = RongHttpClient.ExecutePost(appKey, appSecret, "", + rongCloud.ApiHostType.Type + "/chatroom/user/ban/query.json", "application/x-www-form-urlencoded"); + + return (ListGagChatroomUserResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + + /** + * 移除用户聊天室全局禁言方法 + * + * @param chatroom: memberIds。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Remove(ChatroomModel chatroom) + { + if (chatroom == null) + { + return new ResponseResult(1002, "Paramer 'chatroom' is required"); + } + + String errMsg = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.REMOVE); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + + StringBuilder sb = new StringBuilder(); + ChatroomMember[] members = chatroom.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id, UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/ban/remove.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + } + } +} + + diff --git a/methods/chatroom/block/Block.cs b/methods/chatroom/block/Block.cs new file mode 100644 index 0000000..5afd503 --- /dev/null +++ b/methods/chatroom/block/Block.cs @@ -0,0 +1,137 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.block +{ + /** + * + * 聊天室封禁服务 + * docs: "http://www.rongcloud.cn/docs/server.html#chatroom_user_block" + * + * */ + class Block + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/block"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public Block(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + /** +* 添加封禁聊天室成员方法 +* +* @param chatroom:聊天室信息,memberIds(必传支持多个最多20个),minute:封禁时长,以分钟为单位,最大值为43200分钟。(必传) +* +* @return ResponseResult +**/ + public ResponseResult Add(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.ADD); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + ChatroomMember[] members = chatroom.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id, UTF8)); + } + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + sb.Append("&minute=").Append(HttpUtility.UrlEncode(chatroom.Minute.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/block/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + + /** + * 查询被封禁聊天室成员方法 + * + * @param chatroomId:聊天室 Id。(必传) + * + * @return ListBlockChatroomUserResult + **/ + public ListBlockChatroomUserResult GetList(String chatroomId) + { + String message = CommonUtil.CheckParam("id", chatroomId, PATH, CheckMethod.GETLIST); + if (null != message) + { + return (ListBlockChatroomUserResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroomId.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/block/list.json", "application/x-www-form-urlencoded"); + + return (ListBlockChatroomUserResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + + /** + * 移除封禁聊天室成员方法 + * + * @param chatroom: 封禁的聊天室信息 其中聊天室 Id。(必传),用户 Id。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Remove(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + ChatroomMember[] members = chatroom.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id, UTF8)); + } + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/block/rollback.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + } + } +} diff --git a/methods/chatroom/demotion/Demotion.cs b/methods/chatroom/demotion/Demotion.cs new file mode 100644 index 0000000..538ed08 --- /dev/null +++ b/methods/chatroom/demotion/Demotion.cs @@ -0,0 +1,117 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.demotion +{ + class Demotion + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/demotion"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public Demotion(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 添加应用内聊天室降级消息 + * + * @param objectName:消息类型,每次最多提交 5 个,设置的消息类型最多不超过 20 个。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Add(String[] objectName) + { + String message = CommonUtil.CheckParam("type", objectName, PATH, CheckMethod.ADD); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < objectName.Length; i++) + { + String child = objectName[i]; + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/message/priority/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + + /** + * 移除应用内聊天室降级消息 + * + * @param objectNames:要销毁消息类型表。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Remove(String[] objectNames) + { + String message = CommonUtil.CheckParam("type", objectNames, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < objectNames.Length; i++) + { + String child = objectNames[i]; + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/message/priority/remove.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + + + } + /** + * 获取应用内聊天室降级消息 + * + * + * @return ResponseResult + **/ + public ChatroomDemotionMsgResult GetList() + { + String result = RongHttpClient.ExecutePost(appKey, appSecret, "", + rongCloud.ApiHostType.Type + "/chatroom/message/priority/query.json", "application/x-www-form-urlencoded"); + + return (ChatroomDemotionMsgResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + } +} diff --git a/methods/chatroom/distribute/Distribute.cs b/methods/chatroom/distribute/Distribute.cs new file mode 100644 index 0000000..99931bf --- /dev/null +++ b/methods/chatroom/distribute/Distribute.cs @@ -0,0 +1,93 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.distribute +{ + class Distribute + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/distribute"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public Distribute(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + /** + * 停止聊天室消息分发(可实现控制对聊天室中消息是否进行分发,停止分发后聊天室中用户发送的消息,融云服务端不会再将消息发送给聊天室中其他用户。) + * + * @param chatroom:聊天室信息,其中聊天室 Id。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Stop(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.STOP_DISTRIBUTION); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/message/stopDistribution.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.STOP_DISTRIBUTION, result)); + + } + + /** + * 恢复聊天室消息分发 + * + * @param chatroom:聊天室 Id。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Resume(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.RESUME_DISTRIBUTION); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/message/resumeDistribution.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.RESUME_DISTRIBUTION, result)); + } + } +} diff --git a/methods/chatroom/gag/Gag.cs b/methods/chatroom/gag/Gag.cs new file mode 100644 index 0000000..45541a0 --- /dev/null +++ b/methods/chatroom/gag/Gag.cs @@ -0,0 +1,143 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.gag +{ + class Gag + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/member-gag"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public RongCloud getRongCloud() + { + return rongCloud; + } + public void setRongCloud(RongCloud rongCloud) + { + this.rongCloud = rongCloud; + } + public Gag(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 添加禁言聊天室成员方法(在 App 中如果不想让某一用户在聊天室中发言时,可将此用户在聊天室中禁言,被禁言用户可以接收查看聊天室中用户聊天信息,但不能发送消息.) + * + * @param chatroom:封禁的聊天室信息,其中聊天室 d(必传),minute(必传), memberIds(必传支持多个最多20个) + * + * @return ResponseResult + **/ + public ResponseResult Add(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.ADD); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + /* message = CommonUtil.checkParam("minute",minute,PATH,CheckMethod.ADD); + if(null != message){ + return (ResponseResult)RongJsonUtil.JsonStringToObj(message,ResponseResult.class); + }*/ + + StringBuilder sb = new StringBuilder(); + ChatroomMember[] members = chatroom.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id, UTF8)); + } + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + sb.Append("&minute=").Append(HttpUtility.UrlEncode(chatroom.Minute.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/gag/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + + /** + * 查询聊天室被禁言成员方法 + * + * @param chatroom:聊天室信息 Id。(必传) + * + * @return ListGagChatroomUserResult + **/ + public ListGagChatroomUserResult GetList(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.GETLIST); + if (null != message) + { + return (ListGagChatroomUserResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/gag/list.json", "application/x-www-form-urlencoded"); + + return (ListGagChatroomUserResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + + } + + /** + * 移除禁言聊天室成员方法 + * + * @param chatroom:封禁的聊天室信息,其中聊天室 Id。(必传),用户 Id。(必传支持多个最多20个) + * @return ResponseResult + **/ + public ResponseResult Remove(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + ChatroomMember[] members = chatroom.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id, UTF8)); + } + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/gag/rollback.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + + } + } + +} diff --git a/methods/chatroom/keepalive/Keepalive.cs b/methods/chatroom/keepalive/Keepalive.cs new file mode 100644 index 0000000..bc96e22 --- /dev/null +++ b/methods/chatroom/keepalive/Keepalive.cs @@ -0,0 +1,102 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.keepalive +{ + class Keepalive + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/keepalive"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public Keepalive(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 添加聊天室保活方法 + * + * @param chatroom: 聊天室信息,id(必传) + * + * @return ResponseResult + **/ + public ResponseResult Add(ChatroomModel chatroom) + { + + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.ADD); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/keepalive/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + /** + * 删除聊天室保活方法 + * + * @param chatroom: 聊天室信息,id(必传) + * + * @return ResponseResult + **/ + public ResponseResult Remove(ChatroomModel chatroom) + { + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/keepalive/remove.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + } + /** + * 获取聊天室保活 + * + * + * @return ResponseResult + **/ + public ChatroomKeepaliveResult GetList() + { + String result = RongHttpClient.ExecutePost(appKey, appSecret, "", + rongCloud.ApiHostType.Type + "/chatroom/keepalive/query.json", "application/x-www-form-urlencoded"); + + return (ChatroomKeepaliveResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + } +} diff --git a/methods/chatroom/whitelist/Messages.cs b/methods/chatroom/whitelist/Messages.cs new file mode 100644 index 0000000..a9c82a2 --- /dev/null +++ b/methods/chatroom/whitelist/Messages.cs @@ -0,0 +1,124 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.whitelist +{ + class Messages + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/whitelist/message"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public Messages(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + } + /** + * 添加聊天室消息白名单成员方法 + * + * @param objectNames:消息类型列表 + * + * @return ResponseResult + **/ + public ResponseResult Add(String[] objectNames) + { + if (objectNames == null) + { + return new ResponseResult(1002, "Paramer 'objectNames' is required"); + } + + String errMsg = CommonUtil.CheckParam("objectNames", objectNames, PATH, CheckMethod.ADD); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < objectNames.Length; i++) + { + String child = objectNames[i]; + sb.Append("&objectnames=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/whitelist/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + + /** + * 删除聊天室消息白名单方法 + * + * @param objectNames:消息类型列表 + * + * @return ResponseResult + **/ + public ResponseResult Remove(String[] objectNames) + { + if (objectNames == null) + { + return new ResponseResult(1002, "Paramer 'objectNames' is required"); + } + String errMsg = CommonUtil.CheckParam("objectNames", objectNames, PATH, CheckMethod.REMOVE); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < objectNames.Length; i++) + { + String child = objectNames[i]; + sb.Append("&objectnames=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/whitelist/delete.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + } + + /** + * 获取聊天室消息类型白名单列表 + * + * + * @return ResponseResult + **/ + public ChatroomWhitelistMsgResult GetList() + { + String result = RongHttpClient.ExecutePost(appKey, appSecret, "", + rongCloud.ApiHostType.Type + "/chatroom/whitelist/query.json", "application/x-www-form-urlencoded"); + + return (ChatroomWhitelistMsgResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + + } + } +} + diff --git a/methods/chatroom/whitelist/User.cs b/methods/chatroom/whitelist/User.cs new file mode 100644 index 0000000..f196a73 --- /dev/null +++ b/methods/chatroom/whitelist/User.cs @@ -0,0 +1,147 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.whitelist +{ + class User + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/whitelist/user"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public User(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 添加聊天室白名单成员方法 + * + * @param chatroom:聊天室.Id,memberIds 聊天室中白名单成员最多不超过 5 个。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Add(ChatroomModel chatroom) + { + + if (chatroom == null) + { + return new ResponseResult(1002, "Paramer 'chatroom' is required"); + } + + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.ADD); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + + ChatroomMember[] members = chatroom.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id, UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/whitelist/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + /** + * 添加聊天室白名单成员方法 + * + * @param chatroom:聊天室.Id,memberIds 聊天室中白名单成员最多不超过 5 个。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Remove(ChatroomModel chatroom) + { + if (chatroom == null) + { + return new ResponseResult(1002, "Paramer 'chatroom' is required"); + } + + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + + ChatroomMember[] members = chatroom.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id, UTF8)); + } + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/whitelist/remove.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + } + + /** + * 添加聊天室白名单成员方法 + * + * + * @return WhiteListResult + **/ + public WhiteListResult GetList(ChatroomModel chatroom) + { + if (chatroom == null) + { + return new WhiteListResult(1002, "Paramer 'chatroom' is required"); + } + + String message = CommonUtil.CheckFiled(chatroom, PATH, CheckMethod.GETLIST); + if (null != message) + { + return (WhiteListResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&chatroomId=").Append(HttpUtility.UrlEncode(chatroom.Id.ToString(), UTF8)); + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/chatroom/user/whitelist/query.json", "application/x-www-form-urlencoded"); + + return (WhiteListResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + } +} diff --git a/methods/chatroom/whitelist/Whitelist.cs b/methods/chatroom/whitelist/Whitelist.cs new file mode 100644 index 0000000..d86ccd8 --- /dev/null +++ b/methods/chatroom/whitelist/Whitelist.cs @@ -0,0 +1,50 @@ +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using io.rong.models.chatroom; + +namespace io.rong.methods.chatroom.whitelist +{ + class Whitelist + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "chatroom/whitelist"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + private User user; + private Messages message; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud + { + get => rongCloud; + set + { + rongCloud = value; + message.RongCloud = value; + user.RongCloud = value; + } + } + internal User User { get => user; set => user = value; } + internal Messages Message { get => message; set => message = value; } + + public Whitelist(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + this.message = new Messages(appKey, appSecret); + this.user = new User(appKey, appSecret); + } + } +} diff --git a/methods/conversation/Conversation.cs b/methods/conversation/Conversation.cs new file mode 100644 index 0000000..faf3309 --- /dev/null +++ b/methods/conversation/Conversation.cs @@ -0,0 +1,105 @@ +using io.rong.util; +using io.rong.methods.user.blacklist; +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.methods.conversation +{ + /** + * + * 会话消息免打扰服务 + * docs: "http://www.rongcloud.cn/docs/server.html#conversation_notification" + * + * */ + class Conversation + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "conversation"; + private static String method = ""; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public Conversation(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 设置用户某会话接收新消息时是否进行消息提醒。 + * + * @param conversation 会话信息 其中type(必传) + * @return ResponseResult + **/ + public ResponseResult Mute(ConversationModel conversation) + { + String message = CommonUtil.CheckFiled(conversation, PATH, CheckMethod.MUTE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&conversationType=").Append(HttpUtility.UrlEncode(conversation.Type.ToString(), UTF8)); + sb.Append("&requestId=").Append(HttpUtility.UrlEncode(conversation.UserId.ToString(), UTF8)); + sb.Append("&targetId=").Append(HttpUtility.UrlEncode(conversation.TargetId.ToString(), UTF8)); + sb.Append("&isMuted=").Append(HttpUtility.UrlEncode("1", UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/conversation/notification/set.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.MUTE, result)); + } + + /** + * 设置用户某会话接收新消息时是否进行消息提醒。 + * + * @param conversation 会话信息 其中type(必传) + * @return ResponseResult + **/ + public ResponseResult UnMute(ConversationModel conversation) + { + String message = CommonUtil.CheckFiled(conversation, PATH, CheckMethod.UNMUTE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&conversationType=").Append(HttpUtility.UrlEncode(conversation.Type.ToString(), UTF8)); + sb.Append("&requestId=").Append(HttpUtility.UrlEncode(conversation.UserId.ToString(), UTF8)); + sb.Append("&targetId=").Append(HttpUtility.UrlEncode(conversation.TargetId.ToString(), UTF8)); + sb.Append("&isMuted=").Append(HttpUtility.UrlEncode("0", UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/conversation/notification/set.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.UNMUTE, result)); + + } + } +} \ No newline at end of file diff --git a/methods/group/Group.cs b/methods/group/Group.cs new file mode 100644 index 0000000..ff1c2b7 --- /dev/null +++ b/methods/group/Group.cs @@ -0,0 +1,326 @@ +using io.rong.util; +using io.rong.methods.user.blacklist; +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models.conversation; +using io.rong.models; +using io.rong.models.response; +using io.rong.methods.group.gap; +using io.rong.models.group; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.methods.group +{ + /** + * 群组服务 + * http://www.rongcloud.cn/docs/server.html#group + * + * */ + class Group + { + + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "group"; + private String appKey; + private String appSecret; + private Gag gag; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal Gag Gag { get => gag; set => gag = value; } + internal RongCloud RongCloud { get => rongCloud; set { rongCloud = value; gag.RongCloud = value; } } + + public Group(string appKey, string appSecret) + { + AppKey = appKey; + AppSecret = appSecret; + gag = new Gag(appKey, appSecret); + gag.RongCloud = rongCloud; + } + + + + /** + * 创建群组方法(创建群组,并将用户加入该群组,用户将可以收到该群的消息,同一用户最多可加入 500 个群,每个群最大至 3000 人,App 内的群组数量没有限制.注:其实本方法是加入群组方法 /group/join 的别名。) + * + * url /group/create.json + * docs http://rongcloud.cn/docs/server.html#group_sync" + * + * @param group 创建群组的群组信息 + * + * @return Result + **/ + public Result Create(GroupModel group) + { + //需要校验的字段 + String message = CommonUtil.CheckFiled(group, PATH, CheckMethod.CREATE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + + GroupMember[] members = group.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id.ToString(), UTF8)); + } + + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + sb.Append("&groupName=").Append(HttpUtility.UrlEncode(group.Name.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/create.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.CREATE, result)); + } + + /** + * 同步用户所属群组方法(当第一次连接融云服务器时,需要向融云服务器提交 userId 对应的用户当前所加入的所有群组,此接口主要为防止应用中用户群信息同融云已知的用户所属群信息不同步。) + * + * @param user:用户群组信息 + * + * @return ResponseResult + **/ + public Result Sync(UserGroup user) + { + + if (user == null) + { + return new ResponseResult(1002, "Paramer 'user' is required"); + } + String message = CommonUtil.CheckFiled(user, PATH, CheckMethod.SYNC); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(user.getId(), UTF8)); + + for (int i = 0; i < user.Groups.Length; i++) + { + GroupModel child = user.getGroups()[i]; + if (child.Name == null) + { + return new ResponseResult(1002, "Paramer 'group.name' is required"); + } + if (child.Id == null) + { + return new ResponseResult(1002, "Paramer 'group.id' is required"); + } + sb.Append("&group[" + child.Id + "]=").Append(HttpUtility.UrlEncode(child.Name, UTF8)); + } + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/sync.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.SYNC, result)); + } + + /** + * 刷新群组信息方法 + * + * @param group:群组信息。id,name(必传) + * + * @return ResponseResult + **/ + public Result Update(GroupModel group) + { + String message = CommonUtil.CheckFiled(group, PATH, CheckMethod.UPDATE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + sb.Append("&groupName=").Append(HttpUtility.UrlEncode(group.Name.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/refresh.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.UPDATE, result)); + } + /** + * 邀请用户加入指定群组,加入后可以接收该群消息,同一用户最多可加入 500 个群,每个群最大至 3000 人。 + * + * @param group 用户加入指定群组参数 + * + * @return Result + **/ + public Result Invite(GroupModel group) + { + String message = CommonUtil.CheckFiled(group, PATH, CheckMethod.INVITE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + + GroupMember[] members = group.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id.ToString(), UTF8)); + } + + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + sb.Append("&groupName=").Append(HttpUtility.UrlEncode(group.Name.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/join.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.INVITE, result)); + + } + /** + * 将用户加入指定群组,用户将可以收到该群的消息,同一用户最多可加入 500 个群,每个群最大至 3000 人。 + * + * @param group 用户加入指定群组参数 + * + * @return Result + **/ + public Result Join(GroupModel group) + { + String message = CommonUtil.CheckFiled(group, PATH, CheckMethod.JOIN); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + + GroupMember[] members = group.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id.ToString(), UTF8)); + } + + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + sb.Append("&groupName=").Append(HttpUtility.UrlEncode(group.Name.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/join.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.JOIN, result)); + } + + /** + * 查询群信息 + * + * @param group:群组.Id。(必传) + * + * @return GroupUserQueryResult + **/ + public GroupUserQueryResult Get(GroupModel group) + { + + String errMsg = CommonUtil.CheckFiled(group, PATH, CheckMethod.GET); + if (null != errMsg) + { + return (GroupUserQueryResult)RongJsonUtil.JsonStringToObj(errMsg); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/user/query.json", "application/x-www-form-urlencoded"); + + return (GroupUserQueryResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GET, result)); + } + + /** + * 退出群组方法(将用户从群中移除,不再接收该群组的消息.) + * + * @param group:群组.id, memberIds(必传) + * + * @return ResponseResult + **/ + public Result Quit(GroupModel group) + { + + String message = CommonUtil.CheckFiled(group, PATH, CheckMethod.QUIT); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + + GroupMember[] members = group.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id.ToString(), UTF8)); + } + + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/quit.json", "application/x-www-form-urlencoded"); + + return (GroupUserQueryResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.QUIT, result)); + } + + /** + * 解散群组方法。(将该群解散,所有用户都无法再接收该群的消息。) + * + * @param group: id,member。(必传) + * + * @return ResponseResult + **/ + public Result Dismiss(GroupModel group) + { + String message = CommonUtil.CheckFiled(group, PATH, CheckMethod.DISMISS); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + GroupMember member = group.Members[0]; + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id.ToString(), UTF8)); + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/dismiss.json", "application/x-www-form-urlencoded"); + + return (GroupUserQueryResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.DISMISS, result)); + } + } +} \ No newline at end of file diff --git a/methods/group/gag/Gag.cs b/methods/group/gag/Gag.cs new file mode 100644 index 0000000..4a8c1d3 --- /dev/null +++ b/methods/group/gag/Gag.cs @@ -0,0 +1,140 @@ +using io.rong.util; +using io.rong.models.group; +using io.rong.models; +using io.rong.models.response; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.methods.group.gap +{ + /** + * 群组成员禁言服务 + * docs : http://www.rongcloud.cn/docs/server.html#group_user_gag + * + * */ + class Gag + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "group/gag"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + + public Gag(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + /** + * 添加禁言群成员方法(在 App 中如果不想让某一用户在群中发言时,可将此用户在群组中禁言,被禁言用户可以接收查看群组中用户聊天信息,但不能发送消息。) + * + * @param group:群组信息。id , munite , memberIds(必传) + * + * @return Result + **/ + public Result Add(GroupModel group) + { + String message = CommonUtil.CheckFiled(group, PATH, CheckMethod.ADD); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + /* message = CommonUtil.checkParam("munite",munite,PATH,CheckMethod.ADD); + if(null != message){ + return (Result)RongJsonUtil.JsonStringToObj(message,Result.class); + }*/ + + StringBuilder sb = new StringBuilder(); + GroupMember[] members = group.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id.ToString(), UTF8)); + } + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + sb.Append("&minute=").Append(HttpUtility.UrlEncode(group.Minute.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/user/gag/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + + } + + /** + * 查询被禁言群成员方法 + * + * @param groupId:群组Id。(必传) + * + * @return ListGagGroupUserResult + **/ + public ListGagGroupUserResult GetList(String groupId) + { + String message = CommonUtil.CheckParam("id", groupId, PATH, CheckMethod.GETLIST); + if (null != message) + { + return (ListGagGroupUserResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(groupId.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/user/gag/list.json", "application/x-www-form-urlencoded"); + + return (ListGagGroupUserResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + + /** + * 移除禁言群成员方法 + * + * @param group:群组(必传) + * + * @return ResponseResult + **/ + public Result Remove(GroupModel group) + { + //参数校验 + String message = CommonUtil.CheckFiled(group, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + + GroupMember[] members = group.Members; + foreach (var member in members) + { + sb.Append("&userId=").Append(HttpUtility.UrlEncode(member.Id.ToString(), UTF8)); + } + + sb.Append("&groupId=").Append(HttpUtility.UrlEncode(group.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/group/user/gag/rollback.json", "application/x-www-form-urlencoded"); + + return (ListGagGroupUserResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + } + } +} \ No newline at end of file diff --git a/methods/message/Message.cs b/methods/message/Message.cs new file mode 100644 index 0000000..8417417 --- /dev/null +++ b/methods/message/Message.cs @@ -0,0 +1,58 @@ +using io.rong.methods.messages._private; +using io.rong.methods.messages.chatroom; +using io.rong.methods.messages.discussion; +using io.rong.methods.messages.system; +using io.rong.methods.messages.history; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace io.rong.methods.message +{ + class Message + { + + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "message"; + private static String method = ""; + private String appKey; + private String appSecret; + public Private msgPrivate; + public Chatroom chatroom; + public Discussion discussion; + public messages.group.Group group; + public History history; + public MsgSystem system; + private RongCloud rongCloud; + + public RongCloud RongCloud + { + get => rongCloud; + set + { + this.rongCloud = value; + msgPrivate.RongCloud = value; + chatroom.RongCloud = value; + discussion.RongCloud = value; + group.RongCloud = value; + history.RongCloud = value; + system.RongCloud = value; + } + } + + public Message(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + this.msgPrivate = new Private(appKey, appSecret); + this.chatroom = new Chatroom(appKey, appSecret); + this.discussion = new Discussion(appKey, appSecret); + this.group = new messages.group.Group(appKey, appSecret); + this.history = new History(appKey, appSecret); + this.system = new MsgSystem(appKey, appSecret); + + } + } +} diff --git a/methods/message/_private/Private.cs b/methods/message/_private/Private.cs new file mode 100644 index 0000000..ee01fab --- /dev/null +++ b/methods/message/_private/Private.cs @@ -0,0 +1,198 @@ +using io.rong.models; +using io.rong.models.message; +using io.rong.models.response; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Text; +using System.Web; + +namespace io.rong.methods.messages._private +{ + + /** + * 发送单聊消息方法 + * docs : http://www.rongcloud.cn/docs/server.html#message_private_publish + */ + class Private + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "message/_private"; + private static readonly String RECAL_PATH = "message/recall"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public Private(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + /** + * 发送单聊消息方法(一个用户向另外一个用户发送消息,单条消息最大 128k。每分钟最多发送 6000 条信息,每次发送用户上限为 1000 人,如:一次发送 1000 人时,示为 1000 条消息。) + * + * @param message 单聊消息 + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult Send(PrivateMessage message) + { + if (null == message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj("Paramer 'message' is required"); + } + String errMsg = CommonUtil.CheckFiled(message, PATH, CheckMethod.SEND); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + + for (int i = 0; i < message.TargetId.Length; i++) + { + String child = message.TargetId[i]; + if (null != child) + { + sb.Append("&toUserId=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + } + + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(message.Content.GetType(), UTF8)); + sb.Append("&content=").Append(HttpUtility.UrlEncode(message.Content.ToString(), UTF8)); + + if (message.PushContent != null) + { + sb.Append("&pushContent=").Append(HttpUtility.UrlEncode(message.PushContent.ToString(), UTF8)); + } + + if (message.PushData != null) + { + sb.Append("&pushData=").Append(HttpUtility.UrlEncode(message.PushData.ToString(), UTF8)); + } + + if (message.Count != null) + { + sb.Append("&count=").Append(HttpUtility.UrlEncode(message.Count.ToString(), UTF8)); + } + + if (0 != message.VerifyBlacklist) + { + sb.Append("&verifyBlacklist=").Append(HttpUtility.UrlEncode(message.VerifyBlacklist.ToString(), UTF8)); + } + + if (0 != message.IsPersisted) + { + sb.Append("&isPersisted=").Append(HttpUtility.UrlEncode(message.IsPersisted.ToString(), UTF8)); + } + + if (0 != message.IsCounted) + { + sb.Append("&isCounted=").Append(HttpUtility.UrlEncode(message.IsCounted.ToString(), UTF8)); + } + + if (0 != message.IsIncludeSender) + { + sb.Append("&isIncludeSender=").Append(HttpUtility.UrlEncode(message.IsIncludeSender.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/private/publish.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.PUBLISH, result)); + } + + /** + * 发送单聊模板消息方法(一个用户向多个用户发送不同消息内容,单条消息最大 128k。每分钟最多发送 6000 条信息,每次发送用户上限为 1000 人。) + * + * @param message:单聊模版消息。 + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult SendTemplate(TemplateMessage message) + { + + String errMsg = CommonUtil.CheckFiled(message, PATH, CheckMethod.SENDTEMPLATE); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + + Templates templateMessage = new Templates(); + + List toUserIds = new List(); + List> values = new List>(); + List push = new List(); + + foreach (var vo in message.Content) + { + toUserIds.Add(vo.Key); + values.Add(vo.Value.Data); + push.Add(vo.Value.Push); + } + templateMessage.FromUserId = message.SenderId; + templateMessage.ToUserId = toUserIds.ToArray(); + templateMessage.ObjectName = message.ObjectName; + templateMessage.Content = message.Template.ToString(); + templateMessage.Values = values; + templateMessage.PushContent = push.ToArray(); + templateMessage.PushData = push.ToArray(); + templateMessage.VerifyBlacklist = message.VerifyBlacklist; + templateMessage.ContentAvailable = message.ContentAvailable; + + String result = RongHttpClient.ExecutePost(appKey, appSecret, templateMessage.ToString(), + rongCloud.ApiHostType.Type + "/message/private/publish_template.json", "application/json"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.PUBLISHTEMPLATE, result)); + } + + /** + * 设置用户某会话接收新消息时是否进行消息提醒。 + * + * @param message + * + * @return ResponseResult + * @throws Exception + **/ + public Result Recall(RecallMessage message) + { + + String errMsg = CommonUtil.CheckFiled(message, RECAL_PATH, CheckMethod.RECALL); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&conversationType=").Append(HttpUtility.UrlEncode("1", UTF8)); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + sb.Append("&targetId=").Append(HttpUtility.UrlEncode(message.TargetId.ToString(), UTF8)); + sb.Append("&messageUID=").Append(HttpUtility.UrlEncode(message.UId.ToString(), UTF8)); + sb.Append("&sentTime=").Append(HttpUtility.UrlEncode(message.SentTime.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/recall.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.RECALL, result)); + } + } + +} \ No newline at end of file diff --git a/methods/message/chatroom/Chatroom.cs b/methods/message/chatroom/Chatroom.cs new file mode 100644 index 0000000..c1f1be5 --- /dev/null +++ b/methods/message/chatroom/Chatroom.cs @@ -0,0 +1,115 @@ +using io.rong.models; +using io.rong.models.response; +using System; +using System.Collections.Generic; +using System.Text; +using io.rong.models.message; +using io.rong.exception; +using io.rong.util; +using System.Web; +using io.rong.util; + +namespace io.rong.methods.messages.chatroom +{ + /** + * 发送聊天室消息方法 + * docs : http://www.rongcloud.cn/docs/server.html#message_chatroom_publish + * + */ + class Chatroom + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "message/chatroom"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public Chatroom(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + /** + * 发送聊天室消息方法(一个用户向聊天室发送消息,单条消息最大 128k。每秒钟限 100 次。) + * + * @param message:发送消息内容,参考融云消息类型表.示例说明;如果 objectName 为自定义消息类型,该参数可自定义格式。融云消息类型在messages下,自定义消息继承BaseMessage即可(必传) + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult Send(ChatroomMessage message) + { + + String errMsg = CommonUtil.CheckFiled(message, PATH, CheckMethod.SEND); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId, UTF8)); + + for (int i = 0; i < message.TargetId.Length; i++) + { + String child = message.TargetId[i]; + if (null != child) + { + sb.Append("&toChatroomId=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + } + + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(message.Content.GetType(), UTF8)); + sb.Append("&content=").Append(HttpUtility.UrlEncode(message.Content.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/chatroom/publish.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.PUBLISH, result)); + } + + /** + * 发送聊天室消广播消息方法(一个用户向聊天室发送消息,单条消息最大 128k。每秒钟限 100 次。) + * + * @param message:发送消息内容,参考融云消息类型表.示例说明;如果 objectName 为自定义消息类型,该参数可自定义格式。融云消息类型在messages下,自定义消息继承BaseMessage即可(必传) + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult Broadcast(ChatroomMessage message) + { + + String code = CommonUtil.CheckFiled(message, PATH, CheckMethod.BROADCAST); + if (null != code) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(code); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + + + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(message.Content.GetType(), UTF8)); + sb.Append("&content=").Append(HttpUtility.UrlEncode(message.Content.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/chatroom/broadcast.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.BROADCAST, result)); + + } + } +} diff --git a/methods/message/discussion/Discussion.cs b/methods/message/discussion/Discussion.cs new file mode 100644 index 0000000..8d99343 --- /dev/null +++ b/methods/message/discussion/Discussion.cs @@ -0,0 +1,153 @@ +using io.rong.models; +using io.rong.models.response; +using System; +using System.Collections.Generic; +using System.Text; +using io.rong.models.message; +using io.rong.exception; +using io.rong.util; +using System.Web; +using io.rong.util; + +namespace io.rong.methods.messages.discussion +{ + + /** + * 发送讨论组消息方法 + * + * docs : http://www.rongcloud.cn/docs/server.html#message_discussion_publish + * @author RongCloud + * + */ + class Discussion + { + + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "message/discussion"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public RongCloud getRongCloud() + { + return rongCloud; + } + + public void setRongCloud(RongCloud rongCloud) + { + this.rongCloud = rongCloud; + } + public Discussion(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 发送讨论组消息方法(以一个用户身份向讨论组发送消息,单条消息最大 128k,每秒钟最多发送 20 条消息.) + * + * + * @param message:发送消息内容,参考融云消息类型表.示例说明;如果 objectName 为自定义消息类型,该参数可自定义格式。(必传) + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult Send(DiscussionMessage message) + { + + + String code = CommonUtil.CheckFiled(message, PATH, CheckMethod.PUBLISH); + if (null != code) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(code); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + for (int i = 0; i < message.TargetId.Length; i++) + { + String child = message.TargetId[i]; + if (null != child) + { + sb.Append("&toDiscussionId=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + } + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(message.Content.GetType(), UTF8)); + sb.Append("&content=").Append(HttpUtility.UrlEncode(message.Content.ToString(), UTF8)); + + if (message.PushContent != null) + { + sb.Append("&pushContent=").Append(HttpUtility.UrlEncode(message.PushContent.ToString(), UTF8)); + } + + if (message.PushData != null) + { + sb.Append("&pushData=").Append(HttpUtility.UrlEncode(message.PushData.ToString(), UTF8)); + } + + if (0 == message.IsPersisted || message.IsPersisted != null) + { + sb.Append("&isPersisted=").Append(HttpUtility.UrlEncode(message.IsPersisted.ToString(), UTF8)); + } + + if (0 == message.IsCounted || message.IsCounted != null) + { + sb.Append("&isCounted=").Append(HttpUtility.UrlEncode(message.IsCounted.ToString(), UTF8)); + } + + if (0 == message.IsIncludeSender || message.IsIncludeSender != null) + { + sb.Append("&isIncludeSender=").Append(HttpUtility.UrlEncode(message.IsIncludeSender.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/discussion/publish.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.PUBLISH, result)); + } + + /** + * 设置用户某会话接收新消息时是否进行消息提醒。 + * + * @param message + * + * @return ResponseResult + * @throws Exception + **/ + public Result Recall(RecallMessage message) + { + //需要校验的字段 + String msgErr = CommonUtil.CheckFiled(message, PATH, CheckMethod.RECALL); + if (null != msgErr) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(msgErr); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&conversationType=").Append(HttpUtility.UrlEncode("2", UTF8)); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + sb.Append("&targetId=").Append(HttpUtility.UrlEncode(message.TargetId.ToString(), UTF8)); + sb.Append("&messageUID=").Append(HttpUtility.UrlEncode(message.UId.ToString(), UTF8)); + sb.Append("&sentTime=").Append(HttpUtility.UrlEncode(message.SentTime.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/recall.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.RECALL, result)); + + } + } +} diff --git a/methods/message/group/Group.cs b/methods/message/group/Group.cs new file mode 100644 index 0000000..814344a --- /dev/null +++ b/methods/message/group/Group.cs @@ -0,0 +1,216 @@ +using io.rong.models; +using io.rong.models.response; +using System; +using System.Collections.Generic; +using System.Text; +using io.rong.models.message; +using io.rong.exception; +using io.rong.util; +using System.Web; +using io.rong.util; + +namespace io.rong.methods.messages.group +{ + /** + * 发送群组消息方法 + * + * docs : http://www.rongcloud.cn/docs/server.html#message_group_publish + * @author RongCloud + * + */ + class Group + { + + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "message/group"; + private static readonly String RECAL_PATH = "message/recall"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public Group(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 发送群组消息方法(以一个用户身份向群组发送消息,单条消息最大 128k.每秒钟最多发送 20 条消息,每次最多向 3 个群组发送,如:一次向 3 个群组发送消息,示为 3 条消息。) + * + * @param message + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult Send(GroupMessage message) + { + + String code = CommonUtil.CheckFiled(message, PATH, CheckMethod.PUBLISH); + if (null != code) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(code); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + + for (int i = 0; i < message.TargetId.Length; i++) + { + String child = message.TargetId[i]; + if (null != child) + { + sb.Append("&toGroupId=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + } + + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(message.Content.GetType(), UTF8)); + sb.Append("&content=").Append(HttpUtility.UrlEncode(message.Content.ToString(), UTF8)); + + if (message.PushContent != null) + { + sb.Append("&pushContent=").Append(HttpUtility.UrlEncode(message.PushContent.ToString(), UTF8)); + } + + if (message.PushData != null) + { + sb.Append("&pushData=").Append(HttpUtility.UrlEncode(message.PushData.ToString(), UTF8)); + } + + if (0 != message.IsPersisted || message.IsPersisted != null) + { + sb.Append("&isPersisted=").Append(HttpUtility.UrlEncode(message.IsPersisted.ToString(), UTF8)); + } + + if (0 != message.IsCounted || message.IsCounted != null) + { + sb.Append("&isCounted=").Append(HttpUtility.UrlEncode(message.IsCounted.ToString(), UTF8)); + } + + if (0 != message.IsIncludeSender || message.IsIncludeSender != null) + { + sb.Append("&isIncludeSender=").Append(HttpUtility.UrlEncode(message.IsIncludeSender.ToString(), UTF8)); + } + if (0 != message.ContentAvailable || message.ContentAvailable != null) + { + sb.Append("&contentAvailable=").Append(HttpUtility.UrlEncode(message.ContentAvailable.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/group/publish.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.PUBLISH, result)); + } + + /** + * 发送群组@消息方法(以一个用户身份向群组发送消息,单条消息最大 128k.每秒钟最多发送 20 条消息,每次最多向 3 个群组发送,如:一次向 3 个群组发送消息,示为 3 条消息。) + * + * @param message + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult SendMention(MentionMessage message) + { + + String code = CommonUtil.CheckFiled(message, PATH, CheckMethod.PUBLISH); + if (null != code) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(code); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + String[] groupIds = message.TargetId; + for (int i = 0; i < groupIds.Length; i++) + { + String child = groupIds[i]; + sb.Append("&toGroupId=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(message.Content.Content.GetType(), UTF8)); + sb.Append("&content=").Append(HttpUtility.UrlEncode(message.Content.Content.ToString(), UTF8)); + + if (message.PushContent != null) + { + sb.Append("&pushContent=").Append(HttpUtility.UrlEncode(message.PushContent.ToString(), UTF8)); + } + + if (message.PushContent != null) + { + sb.Append("&pushData=").Append(HttpUtility.UrlEncode(message.PushContent.ToString(), UTF8)); + } + + if (0 != message.IsPersisted || message.IsPersisted != null) + { + sb.Append("&isPersisted=").Append(HttpUtility.UrlEncode(message.IsPersisted.ToString(), UTF8)); + } + + if (0 != message.IsCounted || message.IsCounted != null) + { + sb.Append("&isCounted=").Append(HttpUtility.UrlEncode(message.IsCounted.ToString(), UTF8)); + } + + if (0 != message.IsIncludeSender || message.IsIncludeSender != null) + { + sb.Append("&isIncludeSender=").Append(HttpUtility.UrlEncode(message.IsIncludeSender.ToString(), UTF8)); + } + + sb.Append("&isMentioned=").Append(HttpUtility.UrlEncode("1", UTF8)); + + if (0 != message.ContentAvailable || message.ContentAvailable != null) + { + sb.Append("&contentAvailable=").Append(HttpUtility.UrlEncode(message.ContentAvailable.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/group/publish.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.PUBLISH, result)); + } + + /** + * 撤回群组消息。 + * + * @param message + * + * @return ResponseResult + * @throws Exception + **/ + public Result Recall(RecallMessage message) + { + //需要校验的字段 + String errMsg = CommonUtil.CheckFiled(message, RECAL_PATH, CheckMethod.RECALL); + if (null != errMsg) + { + return (Result)RongJsonUtil.JsonStringToObj(errMsg); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&conversationType=").Append(HttpUtility.UrlEncode("3", UTF8)); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + sb.Append("&targetId=").Append(HttpUtility.UrlEncode(message.TargetId.ToString(), UTF8)); + sb.Append("&messageUID=").Append(HttpUtility.UrlEncode(message.UId.ToString(), UTF8)); + sb.Append("&sentTime=").Append(HttpUtility.UrlEncode(message.SentTime.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/recall.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.RECALL, result)); + } + } +} diff --git a/methods/message/history/History.cs b/methods/message/history/History.cs new file mode 100644 index 0000000..f11cdce --- /dev/null +++ b/methods/message/history/History.cs @@ -0,0 +1,98 @@ +using io.rong.models; +using io.rong.models.response; +using System; +using System.Collections.Generic; +using System.Text; +using io.rong.models.message; +using io.rong.exception; +using io.rong.util; +using System.Web; +using io.rong.util; + +namespace io.rong.methods.messages.history +{ + /** + * 消息历史记录服务 + * + * docs : http://www.rongcloud.cn/docs/server.html#history_message + * @author RongCloud + * + */ + class History + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "message/history"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + + public History(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + /** +* 消息历史记录下载地址获取 方法消息历史记录下载地址获取方法。获取 APP 内指定某天某小时内的所有会话消息记录的下载地址。(目前支持二人会话、讨论组、群组、聊天室、客服、系统通知消息历史记录下载) +* +* @param date:指定北京时间某天某小时,格式为2014010101,表示:2014年1月1日凌晨1点。(必传) +* +* @return HistoryMessageResult +* @throws Exception +**/ + public HistoryMessageResult Get(String date) + { + if (date == null) + { + return new HistoryMessageResult(1002, "", "", "Paramer 'date' is required"); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&date=").Append(HttpUtility.UrlEncode(date.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/history.json", "application/x-www-form-urlencoded"); + + return (HistoryMessageResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GET, result)); + } + + /** + * 消息历史记录删除方法(删除 APP 内指定某天某小时内的所有会话消息记录。调用该接口返回成功后,date参数指定的某小时的消息记录文件将在随后的5-10分钟内被永久删除。) + * + * @param date:指定北京时间某天某小时,格式为2014010101,表示:2014年1月1日凌晨1点。(必传) + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult Remove(String date) + { + if (date == null) + { + return new ResponseResult(1002, "Paramer 'date' is required"); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&date=").Append(HttpUtility.UrlEncode(date.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/history/delete.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + + } + } +} diff --git a/methods/message/system/MsgSystem.cs b/methods/message/system/MsgSystem.cs new file mode 100644 index 0000000..516afa5 --- /dev/null +++ b/methods/message/system/MsgSystem.cs @@ -0,0 +1,207 @@ +using io.rong.models; +using io.rong.models.response; +using System; +using System.Collections.Generic; +using System.Text; +using io.rong.models.message; +using io.rong.exception; +using io.rong.util; +using System.Web; +using io.rong.util; + +namespace io.rong.methods.messages.system +{ + /** + * 发送系统消息方法 + * + * docs : http://www.rongcloud.cn/docs/server.html#message_system_publish + * + */ + class MsgSystem + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private String appKey; + private String appSecret; + private static readonly String PATH = "message/system"; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + + public static string PATH1 => PATH; + + public RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public MsgSystem(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + /** + * 发送系统消息方法(一个用户向一个或多个用户发送系统消息,单条消息最大 128k,会话类型为 SYSTEM。 + * 每秒钟最多发送 100 条消息,每次最多同时向 100 人发送,如:一次发送 100 人时,示为 100 条消息。) + * + * @param message 消息体 + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult Send(MessageModel message) + { + SystemMessage systemMessage = (SystemMessage)message; + String code = CommonUtil.CheckFiled(systemMessage, PATH, CheckMethod.PUBLISH); + if (null != code) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(code); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(systemMessage.SenderId.ToString(), UTF8)); + + for (int i = 0; i < systemMessage.TargetId.Length; i++) + { + String child = systemMessage.TargetId[i]; + if (null != child) + { + sb.Append("&toUserId=").Append(HttpUtility.UrlEncode(child, UTF8)); + } + } + + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(systemMessage.Content.GetType(), UTF8)); + sb.Append("&content=").Append(HttpUtility.UrlEncode(systemMessage.Content.ToString(), UTF8)); + + if (systemMessage.PushContent != null) + { + sb.Append("&pushContent=").Append(HttpUtility.UrlEncode(systemMessage.PushContent.ToString(), UTF8)); + } + + if (systemMessage.PushData != null) + { + sb.Append("&pushData=").Append(HttpUtility.UrlEncode(systemMessage.PushData.ToString(), UTF8)); + } + + if (systemMessage.IsPersisted != null) + { + sb.Append("&isPersisted=").Append(HttpUtility.UrlEncode(systemMessage.IsPersisted.ToString(), UTF8)); + } + + + + if (0 == systemMessage.IsPersisted || systemMessage.IsPersisted != null) + { + sb.Append("&isPersisted=").Append(HttpUtility.UrlEncode(systemMessage.IsPersisted.ToString(), UTF8)); + } + + if (0 == systemMessage.IsCounted || systemMessage.IsCounted != null) + { + sb.Append("&isCounted=").Append(HttpUtility.UrlEncode(systemMessage.IsCounted.ToString(), UTF8)); + } + + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/system/publish.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.PUBLISH, result)); + } + + /** + * 发送系统模板消息方法(一个用户向一个或多个用户发送系统消息,单条消息最大 128k,会话类型为 SYSTEM.每秒钟最多发送 100 条消息,每次最多同时向 100 人发送,如:一次发送 100 人时,示为 100 条消息。) + * + * @param template:系统模版消息。 + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult SendTemplate(TemplateMessage template) + { + + String code = CommonUtil.CheckFiled(template, PATH, CheckMethod.PUBLISHTEMPLATE); + if (null != code) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(code); + } + + List toUserIds = new List(); + List> values = new List>(); + List push = new List(); + + foreach (var vo in template.Content) + { + toUserIds.Add(vo.Key); + values.Add(vo.Value.Data); + push.Add(vo.Value.Push); + } + Templates templateMessage = new Templates() + { + FromUserId = template.SenderId, + ToUserId = toUserIds.ToArray(), + ObjectName = template.ObjectName, + Content = template.Template.ToString(), + Values = values, + PushContent = push.ToArray(), + PushData = template.PushData, + ContentAvailable = template.ContentAvailable + }; + String result = RongHttpClient.ExecutePost(appKey, appSecret, templateMessage.ToString(), + rongCloud.ApiHostType.Type + "/message/system/publish_template.json", "application/json"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.PUBLISHTEMPLATE, result)); + } + + /** + * 发送广播消息方法(发送消息给一个应用下的所有注册用户,如用户未在线会对满足条件(绑定手机终端)的用户发送 Push 信息,单条消息最大 128k,会话类型为 SYSTEM。每小时只能发送 2 次,每天最多发送 3 次。) + * 该功能开发环境下可免费使用。生产环境下,您需要登录开发者后台,在“应用/IM 服务/高级功能设置”中开通公有云专业版后,在“广播消息和推送”中,开启后才能使用 + * + * @param message 消息体 + * + * @return ResponseResult + * @throws Exception + **/ + public ResponseResult Broadcast(BroadcastMessage message) + { + + String errMsg = CommonUtil.CheckFiled(message, PATH, CheckMethod.BROADCAST); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&fromUserId=").Append(HttpUtility.UrlEncode(message.SenderId.ToString(), UTF8)); + sb.Append("&objectName=").Append(HttpUtility.UrlEncode(message.Content.GetType(), UTF8)); + sb.Append("&content=").Append(HttpUtility.UrlEncode(message.Content.ToString(), UTF8)); + + if (message.PushContent != null) + { + sb.Append("&pushContent=").Append(HttpUtility.UrlEncode(message.PushContent.ToString(), UTF8)); + } + + if (message.PushData != null) + { + sb.Append("&pushData=").Append(HttpUtility.UrlEncode(message.PushData.ToString(), UTF8)); + } + + if (message.Os != null) + { + sb.Append("&os=").Append(HttpUtility.UrlEncode(message.Os.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/message/broadcast.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.BROADCAST, result)); + + + } + } +} diff --git a/methods/sensitive/SensitiveWord.cs b/methods/sensitive/SensitiveWord.cs new file mode 100644 index 0000000..d6351a4 --- /dev/null +++ b/methods/sensitive/SensitiveWord.cs @@ -0,0 +1,174 @@ +using io.rong.util; +using io.rong.models.sensitiveword; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.methods.sensitive +{ + /** + * + * 敏感词服务 + * docs: "http://www.rongcloud.cn/docs/server.html#sensitiveword" + * + * */ + class SensitiveWord + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "sensitiveword"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + public RongCloud getRongCloud() + { + return rongCloud; + } + + public void setRongCloud(RongCloud rongCloud) + { + this.rongCloud = rongCloud; + } + public SensitiveWord(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + + /** + * 添加敏感词方法(设置敏感词后,App 中用户不会收到含有敏感词的消息内容,默认最多设置 50 个敏感词。) + * + * @param sensitiveword:敏感词 + * @return ResponseResult + **/ + public ResponseResult Add(SensitiveWordModel sensitiveword) + { + + String errMsg = CommonUtil.CheckFiled(sensitiveword, PATH, CheckMethod.ADD); + if (null != errMsg) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(errMsg); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&word=").Append(HttpUtility.UrlEncode(sensitiveword.Keyword.ToString(), UTF8)); + + if (0 == sensitiveword.Type) + { + if (null == sensitiveword.Replace) + { + return new ResponseResult(1002, "replace 参数为必传项"); + } + sb.Append("&replaceWord=").Append(HttpUtility.UrlEncode(sensitiveword.Replace.ToString(), UTF8)); + } + + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/sensitiveword/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + + /** + * 查询敏感词列表方法 + * + * @param type:查询敏感词的类型,0 为查询替换敏感词,1 为查询屏蔽敏感词,2 为查询全部敏感词。默认为 1。(非必传) + * + * @return ListWordfilterResult + **/ + public ListWordfilterResult GetList(int type) + { + StringBuilder sb = new StringBuilder(); + + if (type != null) + { + sb.Append("&type=").Append(HttpUtility.UrlEncode(type.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/sensitiveword/list.json", "application/x-www-form-urlencoded"); + + return (ListWordfilterResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + + /** + * 移除敏感词方法(从敏感词列表中,移除某一敏感词。) + * + * @param word:敏感词,最长不超过 32 个字符。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Remove(String word) + { + String message = CommonUtil.CheckParam("keyword", word, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&word=").Append(HttpUtility.UrlEncode(word.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/sensitiveword/delete.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + } + /** + * 批量移除敏感词方法(从敏感词列表中,移除某一敏感词。) + * + * @param words:敏感词数组,一次最多移除 50 个敏感词(必传) + * + * @return ResponseResult + **/ + public ResponseResult BatchDelete(String[] words) + { + String message = CommonUtil.CheckParam("keyword", words, PATH, CheckMethod.BATCH_DELETE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + foreach (var word in words) + { + sb.Append("&words=").Append(HttpUtility.UrlEncode(word.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/sensitiveword/batch/delete.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.BATCH_DELETE, result)); + + } + + } +} \ No newline at end of file diff --git a/methods/sensitive/Wordfilter.cs b/methods/sensitive/Wordfilter.cs new file mode 100644 index 0000000..2fec6cd --- /dev/null +++ b/methods/sensitive/Wordfilter.cs @@ -0,0 +1,112 @@ +using io.rong.models; +using io.rong.models.response; +using io.rong.util; +using System; +using System.Text; +using System.Web; + +namespace io.rong.methods.sensitive +{ + /** + * + * 敏感词服务 + * docs: "http://www.rongcloud.cn/docs/server.html#sensitiveword" + * + * */ + class Wordfilter + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "sensitiveword"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + + public Wordfilter(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + public string AppKey { get => appKey; set => appKey = value; } + public string AppSecret { get => appSecret; set => appSecret = value; } + internal RongCloud RongCloud { get => rongCloud; set => rongCloud = value; } + + + /** + * 添加敏感词方法(设置敏感词后,App 中用户不会收到含有敏感词的消息内容,默认最多设置 50 个敏感词。) + * + * @param word:敏感词,最长不超过 32 个字符。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Add(String word) + { + String message = CommonUtil.CheckParam("keyword", word, PATH, CheckMethod.ADD); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&word=").Append(HttpUtility.UrlEncode(word.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/wordfilter/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + + /** + * 查询敏感词列表方法 + * + * + * @return ListWordfilterResult + **/ + public ListWordfilterResult GetList() + { + StringBuilder sb = new StringBuilder(); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/wordfilter/list.json", "application/x-www-form-urlencoded"); + + return (ListWordfilterResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + + /** + * 移除敏感词方法(从敏感词列表中,移除某一敏感词。) + * + * @param word:敏感词,最长不超过 32 个字符。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Remove(String word) + { + if (word == null) + { + return new ResponseResult(1002, "Paramer 'word' is required"); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&word=").Append(HttpUtility.UrlEncode(word.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/wordfilter/delete.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + } + } +} \ No newline at end of file diff --git a/methods/user/User.cs b/methods/user/User.cs new file mode 100644 index 0000000..9c5413a --- /dev/null +++ b/methods/user/User.cs @@ -0,0 +1,124 @@ +using io.rong.util; +using io.rong.methods.user.blacklist; +using io.rong.methods.user.block; +using io.rong.methods.user.onlineStatus; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.methods.user +{ + class User + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "user"; + private String appKey; + private String appSecret; + public Block block; + public Blacklist blackList; + public OnlineStatus onlineStatus; + private RongCloud rongCloud; + + public RongCloud RongCloud + { + get { return this.rongCloud; } + set + { + this.rongCloud = value; + block.RongCloud = value; + blackList.RongCloud = value; + onlineStatus.RongCloud = value; + } + } + + + public User(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + this.block = new Block(appKey, appSecret); + this.blackList = new Blacklist(appKey, appSecret); + this.onlineStatus = new OnlineStatus(appKey, appSecret); + } + /** + * 获取 Token 方法 + * url "/user/getToken" + * docs "http://rongcloud.cn/docs/server.html#getToken" + * + * @param user 用户信息 id,name,portrait(必传) + * + * @return TokenResult + **/ + public TokenResult Register(UserModel user) + { + //需要校验的字段 + String message = CommonUtil.CheckFiled(user, PATH, CheckMethod.REGISTER); + if (null != message) + { + return (TokenResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(user.id.ToString(), UTF8)); + sb.Append("&name=").Append(HttpUtility.UrlEncode(user.name.ToString(), UTF8)); + sb.Append("&portraitUri=").Append(HttpUtility.UrlEncode(user.portrait.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length-1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + rongCloud.ApiHostType.Type + "/user/getToken.json", "application/x-www-form-urlencoded"); + + return (TokenResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REGISTER, result)); + } + + /** + * 刷新用户信息方法 + * url "/user/refresh" + * docs "http://www.rongcloud.cn/docs/server.html#user_refresh" + * + * @param user 用户信息 id name portrait(必传) + * + * @return ResponseResult + **/ + public Result Update(UserModel user) + { + //需要校验的字段 + String message = CommonUtil.CheckFiled(user, PATH, CheckMethod.UPDATE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(user.id.ToString(), UTF8)); + + if (user.name != null) + { + sb.Append("&name=").Append(HttpUtility.UrlEncode(user.name.ToString(), UTF8)); + } + + if (user.portrait != null) + { + sb.Append("&portraitUri=").Append(HttpUtility.UrlEncode(user.portrait.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length-1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + RongCloud.ApiHostType.Type + "/user/refresh.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.UPDATE, result)); + } + } +} diff --git a/methods/user/blacklist/Blacklist.cs b/methods/user/blacklist/Blacklist.cs new file mode 100644 index 0000000..3052ecf --- /dev/null +++ b/methods/user/blacklist/Blacklist.cs @@ -0,0 +1,139 @@ +using io.rong.util; +using io.rong; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +/** + * + * 用户黑名单服务 + * docs: "http://www.rongcloud.cn/docs/server.html#black" + * + * @author RongCloud + * @version + * */ +namespace io.rong.methods.user.blacklist +{ + class Blacklist + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "user/blacklist"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public RongCloud RongCloud + { + get { return this.rongCloud; } + set { this.rongCloud = value; } + } + public Blacklist(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + + /** + * 添加用户到黑名单方法(每秒钟限 100 次) + * + * @param user:用户 Id,blacklist(必传) + * + * @return ResponseResult + **/ + public Result Add(UserModel user) + { + + String message = CommonUtil.CheckFiled(user, PATH, CheckMethod.ADD); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(user.Id.ToString(), UTF8)); + foreach (UserModel blackUser in user.GetBlacklist()) + { + sb.Append("&blackUserId=").Append(HttpUtility.UrlEncode(blackUser.Id.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + RongCloud.ApiHostType.Type + "/user/blacklist/add.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + + } + + /** + * 获取某用户的黑名单列表方法(每秒钟限 100 次) + * + * @param user:用户 Id。(必传) + * + * @return QueryBlacklistUserResult + **/ + public BlackListResult GetList(UserModel user) + { + String message = CommonUtil.CheckFiled(user, PATH, CheckMethod.GETLIST); + if (null != message) + { + return (BlackListResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(user.Id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + RongCloud.ApiHostType.Type + "/user/blacklist/query.json", "application/x-www-form-urlencoded"); + + return (BlackListResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + } + + /** + * 从黑名单中移除用户方法(每秒钟限 100 次) + * + * @param user:用户 Id,blacklist(必传) + * + * @return ResponseResult + **/ + public Result Remove(UserModel user) + { + String message = CommonUtil.CheckFiled(user, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(user.Id.ToString(), UTF8)); + foreach (UserModel blackUser in user.GetBlacklist()) + { + sb.Append("&blackUserId=").Append(HttpUtility.UrlEncode(blackUser.Id.ToString(), UTF8)); + } + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + RongCloud.ApiHostType.Type + "/user/blacklist/remove.json", "application/x-www-form-urlencoded"); + + return (BlackListResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + + } + } +} diff --git a/methods/user/block/Block.cs b/methods/user/block/Block.cs new file mode 100644 index 0000000..cb3ed72 --- /dev/null +++ b/methods/user/block/Block.cs @@ -0,0 +1,114 @@ +using io.rong.models.user; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using io.rong.util; +using io.rong.models; +using System.Web; +using io.rong.models.response; +using io.rong.util; + +namespace io.rong.methods.user.block +{ + class Block + { + private static Encoding UTF8 = Encoding.UTF8; + private static String PATH = "user/block"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public RongCloud RongCloud + { + get { return this.rongCloud; } + set { this.rongCloud = value; } + } + + public Block(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 封禁用户方法(每秒钟限 100 次) + * + * @param user :用户信息 Id,minute(必传) + * + * @return Result + **/ + public Result Add(UserModel user) + { + + String message = CommonUtil.CheckFiled(user, PATH, CheckMethod.ADD); + if (null != message) + { + return RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(user.Id.ToString(), UTF8)); + sb.Append("&minute=").Append(HttpUtility.UrlEncode(user.Minute.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, RongCloud.ApiHostType.Type + "/user/block.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.ADD, result)); + } + + /** + * 解除用户封禁方法(每秒钟限 100 次) + * + * @param userId:用户 Id。(必传) + * + * @return ResponseResult + **/ + public ResponseResult Remove(String userId) + { + //参数校验 + String message = CommonUtil.CheckParam("id", userId, PATH, CheckMethod.REMOVE); + if (null != message) + { + return (ResponseResult)RongJsonUtil.JsonStringToObj(message); + } + + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(userId.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, RongCloud.ApiHostType.Type + "/user/unblock.json", "application/x-www-form-urlencoded"); + + return (ResponseResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.REMOVE, result)); + + } + + /** + * 获取被封禁用户方法(每秒钟限 100 次) + * + * + * @return QueryBlockUserResult + **/ + public BlockUserResult GetList() + { + StringBuilder sb = new StringBuilder(); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length - 1); + } + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, RongCloud.ApiHostType.Type + "/user/block/query.json", "application/x-www-form-urlencoded"); + + return (BlockUserResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.GETLIST, result)); + + } + } +} diff --git a/methods/user/onlineStatus/OnlineStatus.cs b/methods/user/onlineStatus/OnlineStatus.cs new file mode 100644 index 0000000..e792581 --- /dev/null +++ b/methods/user/onlineStatus/OnlineStatus.cs @@ -0,0 +1,73 @@ +using io.rong.util; +using io.rong.models; +using io.rong.models.response; +using io.rong.models.user; +using io.rong.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace io.rong.methods.user.onlineStatus +{ + class OnlineStatus + { + private static readonly Encoding UTF8 = Encoding.UTF8; + private static readonly String PATH = "user/online-status"; + private String appKey; + private String appSecret; + private RongCloud rongCloud; + + public RongCloud RongCloud + { + get { return this.rongCloud; } + set { this.rongCloud = value; } + } + + public RongCloud getRongCloud() + { + return rongCloud; + } + + public OnlineStatus(String appKey, String appSecret) + { + this.appKey = appKey; + this.appSecret = appSecret; + + } + /** + * 检查用户在线状态 方法(每秒钟限100次) + * 请不要频繁循环调用此接口,而是选择合适的频率和时机调用,此接口设置了一定的频率限制。 + * + * url /user/checkOnline + * docs http://www.rongcloud.cn/docs/server.html#user_check_online + * + * @param user:用户 id(必传) + * + * @return CheckOnlineResult + **/ + public CheckOnlineResult Check(UserModel user) + { + //参数校验 + String message = CommonUtil.CheckFiled(user, PATH, CheckMethod.CHECK); + if (null != message) + { + return (CheckOnlineResult)RongJsonUtil.JsonStringToObj(message); + } + StringBuilder sb = new StringBuilder(); + sb.Append("&userId=").Append(HttpUtility.UrlEncode(user.id.ToString(), UTF8)); + String body = sb.ToString(); + if (body.IndexOf("&") == 0) + { + body = body.Substring(1, body.Length); + } + + String result = RongHttpClient.ExecutePost(appKey, appSecret, body, + RongCloud.ApiHostType.Type + "/user/checkOnline.json", "application/x-www-form-urlencoded"); + + return (CheckOnlineResult)RongJsonUtil.JsonStringToObj(CommonUtil.GetResponseByCode(PATH, CheckMethod.CHECK, result)); + + } + } +} diff --git a/models/BlockUsers.cs b/models/BlockUsers.cs new file mode 100644 index 0000000..6b61f9d --- /dev/null +++ b/models/BlockUsers.cs @@ -0,0 +1,35 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models +{ + class BlockUsers + { + // 被封禁用户 ID。 + [JsonProperty(PropertyName = "id")] + String id; + // 封禁结束时间。 + [JsonProperty(PropertyName = "blockEndTime")] + String blockEndTime; + + [JsonIgnore] + public string Id { get => id; set => id = value; } + [JsonIgnore] + public string BlockEndTime { get => blockEndTime; set => blockEndTime = value; } + + public BlockUsers(String id, String blockEndTime) + { + this.id = id; + this.blockEndTime = blockEndTime; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/CheckMethod.cs b/models/CheckMethod.cs new file mode 100644 index 0000000..30182c5 --- /dev/null +++ b/models/CheckMethod.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models +{ + class CheckMethod + { + public static String ADD = "add"; + public static String GETLIST = "getList"; + public static String REMOVE = "remove"; + public static String CREATE = "create"; + public static String DESTORY = "destory"; + public static String GET_MEMBERS = "getMembers"; + public static String ISEXIST = "isExist"; + public static String STOP_DISTRIBUTION = "stop"; + public static String RESUME_DISTRIBUTION = "resume"; + public static String MUTE = "mute"; + public static String UNMUTE = "unmute"; + public static String GET = "get"; + public static String SYNC = "sync"; + public static String JOIN = "join"; + public static String QUIT = "quit"; + public static String KICK = "kick"; + public static String DISMISS = "dismiss"; + public static String REFRESH = "refresh"; + public static String UPDATE = "update"; + public static String GET_MEMBERS_LIST = "getMemberList"; + public static String PUSH = "push"; + public static String SET_TAG = "setTag"; + public static String BATCH_DELETE = "batchDelete"; + public static String GET_IMAGE = "getImage"; + public static String VERIFY = "verify"; + public static String SEND = "send"; + public static String REGISTER = "register"; + public static String GET_TOKEN = "getToken"; + public static String INVITE = "invite"; + + + public static String CHECK = "check"; + public static String QUERY = "query"; + public static String PUBLISH = "send"; + public static String SENDTEMPLATE = "sendTemplate"; + public static String PUBLISHTEMPLATE = "sendTemplate"; + public static String BROADCAST = "broadcast"; + public static String SET_USER_TAG = "setUserTag"; + public static String RECALL = "recall"; + } +} diff --git a/models/Result.cs b/models/Result.cs new file mode 100644 index 0000000..e5d3695 --- /dev/null +++ b/models/Result.cs @@ -0,0 +1,76 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models +{ + class Result + { + /** + * 返回码,200 为正常。 + * + */ + [JsonProperty(PropertyName = "code")] + protected int code; + /** + * 错误信息。 + * + */ + [JsonProperty(PropertyName = "msg")] + protected String msg; + + [JsonIgnore] + public int Code { get => code; set => code = value; } + [JsonIgnore] + public string Msg { get => msg; set => msg = value; } + + public Result(int code, String msg) + { + this.code = code; + this.msg = msg; + } + + public Result() + { + + } + /** + * 设置code + * + */ + public void setCode(int code) + { + this.code = code; + } + + /** + * 获取code + * + * @return int + */ + public int getCode() + { + return code; + } + + /** + * 获取msg + * + * @return String + */ + public String getMsg() + { + return this.msg; + } + /** + * 设置msg + * + */ + public void setMsg(String msg) + { + this.msg = msg; + } + } +} diff --git a/models/Templates.cs b/models/Templates.cs new file mode 100644 index 0000000..ba6a803 --- /dev/null +++ b/models/Templates.cs @@ -0,0 +1,88 @@ +using io.rong.util; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models +{ + class Templates + { + /** + * 发送人用户 Id。(必传) + * */ + [JsonProperty(PropertyName = "fromUserId")] + private String fromUserId; + /** + * 接收用户 Id,提供多个本参数可以实现向多人发送消息,上限为 1000 人。(必传) + **/ + [JsonProperty(PropertyName = "toUserId")] + private String[] toUserId; + /** + *发送消息内容,内容中定义标识通过 values 中设置的标识位内容进行替换,参考融云消息类型表.示例说明;如果 objectName 为自定义消息类型,该参数可自定义格式。(必传) + * */ + [JsonProperty(PropertyName = "content")] + private String content; + /** + * + */ + [JsonProperty(PropertyName = "values")] + private List> values; + // 接收用户 Id,提供多个本参数可以实现向多人发送消息,上限为 1000 人。(必传) + [JsonProperty(PropertyName = "objectName")] + private String objectName; + // 定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息。如果为自定义消息,定义显示的 Push 内容,内容中定义标识通过 values 中设置的标识位内容进行替换。如消息类型为自定义不需要 Push 通知,则对应数组传空值即可。(必传) + [JsonProperty(PropertyName = "pushContent")] + private String[] pushContent; + // 针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。如不需要 Push 功能对应数组传空值即可。(可选) + [JsonProperty(PropertyName = "pushData")] + private String[] pushData; + // 是否过滤发送人黑名单列表,0 为不过滤、 1 为过滤,默认为 0 不过滤。(可选) + + [JsonProperty(PropertyName = "verifyBlacklist")] + private int verifyBlacklist; + [JsonProperty(PropertyName = "contentAvailable")] + private int contentAvailable; + + public Templates() + { + } + + public Templates(String fromUserId, String[] toUserId, String content, List> values, String objectName, String[] pushContent, String[] pushData, int verifyBlacklist) + { + this.fromUserId = fromUserId; + this.toUserId = toUserId; + this.content = content; + this.values = values; + this.objectName = objectName; + this.pushContent = pushContent; + this.pushData = pushData; + this.verifyBlacklist = verifyBlacklist; + } + [JsonIgnore] + public string FromUserId { get => fromUserId; set => fromUserId = value; } + [JsonIgnore] + public string[] ToUserId { get => toUserId; set => toUserId = value; } + [JsonIgnore] + public string Content { get => content; set => content = value; } + [JsonIgnore] + public List> Values { get => values; set => values = value; } + [JsonIgnore] + public string ObjectName { get => objectName; set => objectName = value; } + [JsonIgnore] + public string[] PushContent { get => pushContent; set => pushContent = value; } + [JsonIgnore] + public string[] PushData { get => pushData; set => pushData = value; } + [JsonIgnore] + public int VerifyBlacklist { get => verifyBlacklist; set => verifyBlacklist = value; } + [JsonIgnore] + public int ContentAvailable { get => contentAvailable; set => contentAvailable = value; } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/chatroom/ChatroomMember.cs b/models/chatroom/ChatroomMember.cs new file mode 100644 index 0000000..3ce0857 --- /dev/null +++ b/models/chatroom/ChatroomMember.cs @@ -0,0 +1,81 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.chatroom +{ + class ChatroomMember + { + /** + * 聊天室用户Id。 + * */ + [JsonProperty(PropertyName = "id")] + private String id; + /** + * 加入聊天室时间。 + * */ + [JsonProperty(PropertyName = "time")] + private String time; + /** + * 聊天室ID + * */ + [JsonProperty(PropertyName = "chatroomId")] + private String chatroomId; + + [JsonProperty(PropertyName = "munite")] + private int munite; + + [JsonIgnore] + public string Id { get => id; set => id = value; } + [JsonIgnore] + public string Time { get => time; set => time = value; } + [JsonIgnore] + public string ChatroomId { get => chatroomId; set => chatroomId = value; } + [JsonIgnore] + public int Munite { get => munite; set => munite = value; } + + public ChatroomMember():base() + { + + } + public ChatroomMember(String id, String time) + { + this.id = id; + this.time = time; + } + + public ChatroomMember(String id, String chatroomId, String time) + { + this.id = id; + this.chatroomId = chatroomId; + this.time = time; + } + + /** + * 获取禁言时长 + * + * @return String + */ + public int getMunite() + { + return this.munite; + } + /** + * 设置munite + * + * + */ + public void setMunite(int munite) + { + this.munite = munite; + } + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + + } +} diff --git a/models/chatroom/ChatroomModel.cs b/models/chatroom/ChatroomModel.cs new file mode 100644 index 0000000..f4d4f90 --- /dev/null +++ b/models/chatroom/ChatroomModel.cs @@ -0,0 +1,88 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.chatroom +{ + class ChatroomModel + { + /** + * 聊天室 id。 + */ + [JsonProperty(PropertyName ="id")] + String id; + /** + * 聊天室名。 + */ + [JsonProperty(PropertyName = "name")] + String name; + /** + * 聊天室创建时间。 + */ + [JsonProperty(PropertyName = "time")] + String time; + /** + * 聊天室成员。 + */ + [JsonProperty(PropertyName = "members")] + ChatroomMember[] members; + /** + * 聊天室成员数。 + */ + [JsonProperty(PropertyName = "count")] + int count; + /** + * 加入聊天室的先后顺序,1正序,2倒叙。 + */ + [JsonProperty(PropertyName = "order")] + int order; + + /** + * 禁言时间 + * */ + [JsonProperty(PropertyName = "minute")] + int minute; + + [JsonIgnore] + public string Id { get => id; set => id = value; } + [JsonIgnore] + public string Name { get => name; set => name = value; } + [JsonIgnore] + public string Time { get => time; set => time = value; } + [JsonIgnore] + public ChatroomMember[] Members { get => members; set => members = value; } + [JsonIgnore] + public int Count { get => count; set => count = value; } + [JsonIgnore] + public int Order { get => order; set => order = value; } + [JsonIgnore] + public int Minute { get => minute; set => minute = value; } + + public ChatroomModel() : base() + { + + } + /** + * 聊天室构造函数 全量 + * */ + public ChatroomModel(String id, String name, String time, ChatroomMember[] members, + int count, int order, int minute) + { + this.id = id; + this.name = name; + this.time = time; + this.members = members; + this.count = count; + this.order = order; + this.minute = minute; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/conversation/ConversationModel.cs b/models/conversation/ConversationModel.cs new file mode 100644 index 0000000..c66c211 --- /dev/null +++ b/models/conversation/ConversationModel.cs @@ -0,0 +1,44 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.conversation +{ + class ConversationModel + { + [JsonProperty(PropertyName = "type")] + private String type; + [JsonProperty(PropertyName = "userId")] + private String userId; + [JsonProperty(PropertyName = "targetId")] + private String targetId; + + [JsonIgnore] + public string Type { get => type; set => type = value; } + [JsonIgnore] + public string UserId { get => userId; set => userId = value; } + [JsonIgnore] + public string TargetId { get => targetId; set => targetId = value; } + + public ConversationModel() + { + } + + /** + * 构造函数。 + * + * @param type:会话类型。 + * @param userId:设置消息免打扰的用户 Id + * @param targetId:目标Id + * + **/ + public ConversationModel(String type, String userId, String targetId) + { + this.type = type; + this.userId = userId; + this.targetId = targetId; + } + } +} diff --git a/models/group/GroupMember.cs b/models/group/GroupMember.cs new file mode 100644 index 0000000..2733918 --- /dev/null +++ b/models/group/GroupMember.cs @@ -0,0 +1,52 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.group +{ + + public class GroupMember + { + /** + * 群组成员Id。 + * */ + [JsonProperty(PropertyName = "id")] + private String id; + /** + * 群组ID + * */ + [JsonProperty(PropertyName = "goupId1.NET")] + private String groupId; + /** + * 禁言时间 + * */ + [JsonProperty(PropertyName = "munite")] + private int munite; + + public GroupMember() : base() + { + } + + public GroupMember(String id, String groupId, int munite) + { + this.id = id; + this.groupId = groupId; + this.munite = munite; + } + [JsonIgnore] + public string Id { get => id; set => id = value; } + [JsonIgnore] + public string GroupId { get => groupId; set => groupId = value; } + [JsonIgnore] + public int Munite { get => munite; set => munite = value; } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + + } +} diff --git a/models/group/GroupModel.cs b/models/group/GroupModel.cs new file mode 100644 index 0000000..9fc0033 --- /dev/null +++ b/models/group/GroupModel.cs @@ -0,0 +1,57 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.group +{ + /** + * 群组数据模型 + * + * */ + class GroupModel + { + /** + * 群组id + **/ + private String id; + /** + * 群组成员 + **/ + private GroupMember[] members; + /** + * 群组名 + **/ + private String name; + + /** + * 禁言时间 + * */ + private int minute; + + public GroupModel() + { + } + /** + * 构造方法 + * + * @param id 群组id + * @param members 群组成员 + * @param name 群名 + */ + public GroupModel(String id, GroupMember[] members, String name, int minute) + { + this.id = id; + this.members = members; + this.name = name; + this.minute = minute; + } + + public int Minute { get => minute; set => minute = value; } + public string Id { get => id; set => id = value; } + public GroupMember[] Members { get => members; set => members = value; } + public string Name { get => name; set => name = value; } + + } +} diff --git a/models/group/UserGroup.cs b/models/group/UserGroup.cs new file mode 100644 index 0000000..56b3b42 --- /dev/null +++ b/models/group/UserGroup.cs @@ -0,0 +1,50 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.group +{ + class UserGroup + { + + private String id; + private GroupModel[] groups; + + public string Id { get => id; set => id = value; } + public GroupModel[] Groups { get => groups; set => groups = value; } + + public UserGroup() + { + } + + public UserGroup(String id, GroupModel[] groups) + { + this.id = id; + this.groups = groups; + } + + public String getId() + { + return this.id; + } + + public UserGroup setId(String id) + { + this.id = id; + return this; + } + + public GroupModel[] getGroups() + { + return this.groups; + } + + public UserGroup setGroups(GroupModel[] groups) + { + this.groups = groups; + return this; + } + } +} diff --git a/models/message/BroadcastMessage.cs b/models/message/BroadcastMessage.cs new file mode 100644 index 0000000..05a2dbb --- /dev/null +++ b/models/message/BroadcastMessage.cs @@ -0,0 +1,27 @@ +using io.rong.messages; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + + class BroadcastMessage : MessageModel + { + + private String os; + + public BroadcastMessage() + { + } + + public BroadcastMessage(String senderUserId, String[] targetId, String objectName, BaseMessage content, String pushContent, String pushData, + String os) : base(senderUserId, targetId, objectName, content, pushContent, pushData) + { + this.os = os; + } + + public string Os { get => os; set => os = value; } + } +} \ No newline at end of file diff --git a/models/message/ChatroomMessage.cs b/models/message/ChatroomMessage.cs new file mode 100644 index 0000000..1d35252 --- /dev/null +++ b/models/message/ChatroomMessage.cs @@ -0,0 +1,23 @@ +using io.rong.messages; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + class ChatroomMessage : MessageModel + { + + public ChatroomMessage() + { + + } + + public ChatroomMessage(String senderUserId, String[] targetId, String objectName, BaseMessage content) : base(senderUserId, targetId, objectName, content, null, null) + { + + } + + } +} diff --git a/models/message/DiscussionMessage.cs b/models/message/DiscussionMessage.cs new file mode 100644 index 0000000..d929250 --- /dev/null +++ b/models/message/DiscussionMessage.cs @@ -0,0 +1,57 @@ +using io.rong.messages; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + + /** + * 讨论组消息体 + * @author hc + */ + class DiscussionMessage : MessageModel + { + + /** + * 针对 iOS 平台,Push 时用来控制未读消息显示数,只有在 toUserId 为一个用户 Id 的时候有效。(可选) + */ + private int isPersisted; + /** + * 当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数, + * 0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) + */ + private int isCounted; + + /** + * 当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数, + * 0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) + */ + private int isIncludeSender; + + /** + * ios静默推送 0关闭 1开启 + **/ + private int contentAvailable; + + public int IsPersisted { get => isPersisted; set => isPersisted = value; } + public int IsCounted { get => isCounted; set => isCounted = value; } + public int IsIncludeSender { get => isIncludeSender; set => isIncludeSender = value; } + public int ContentAvailable { get => contentAvailable; set => contentAvailable = value; } + + public DiscussionMessage() + { + } + + public DiscussionMessage(String senderId, String[] targetId, String objectName, BaseMessage content, String pushContent, String pushData, + int isPersisted, int isCounted, int isIncludeSender, int contentAvailable):base(senderId, targetId, objectName, content, pushContent, pushData) + { + + this.isPersisted = isPersisted; + this.isCounted = isCounted; + this.isIncludeSender = isIncludeSender; + this.contentAvailable = contentAvailable; + } + } +} diff --git a/models/message/GroupMessage.cs b/models/message/GroupMessage.cs new file mode 100644 index 0000000..119d9d9 --- /dev/null +++ b/models/message/GroupMessage.cs @@ -0,0 +1,58 @@ +using io.rong.messages; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + class GroupMessage : MessageModel + { + + /** + * 发送者自己是否接收此条消息, 0: 不接收, 1: 接收, 默认: 0 + **/ + private int isIncludeSender; + /** + * 针对 iOS 平台,Push 时用来控制未读消息显示数,只有在 toUserId 为一个用户 Id 的时候有效。(可选) + */ + private int isPersisted; + /** + * 当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数, + * 0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) + */ + private int isCounted; + + /** + * ios静默推送 0关闭 1开启 + **/ + private int contentAvailable; + + public int IsIncludeSender { get => isIncludeSender; set => isIncludeSender = value; } + public int IsPersisted { get => isPersisted; set => isPersisted = value; } + public int IsCounted { get => isCounted; set => isCounted = value; } + public int ContentAvailable { get => contentAvailable; set => contentAvailable = value; } + + public GroupMessage() + { + } + /** + * @param senderId:发送人用户 Id 。(必传) + * @param targetId:接收群Id,提供多个本参数可以实现向多群发送消息,最多不超过 3 个群组。(必传) + * @param content:发送消息内容,参考融云消息类型表.示例说明;如果 objectName 为自定义消息类型,该参数可自定义格式。(必传) + * @param pushContent:定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息. 如果为自定义消息,则 pushContent 为自定义消息显示的 Push 内容,如果不传则用户不会收到 Push 通知。(可选) + * @param pushData:针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。(可选) + * @param isPersisted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行存储,0 表示为不存储、 1 表示为存储,默认为 1 存储消息。(可选) + * @param isCounted:当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数,0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) + * @param isIncludeSender:发送用户自已是否接收消息,0 表示为不接收,1 表示为接收,默认为 0 不接收。(可选) + * + * */ + public GroupMessage(String senderId, String[] targetId, String objectName, BaseMessage content, String pushContent, String pushData, int isIncludeSender, int isPersisted, int isCounted, int contentAvailable) : base(senderId, targetId, objectName, content, pushContent, pushData) + { + this.isIncludeSender = isIncludeSender; + this.isPersisted = isPersisted; + this.isCounted = isCounted; + this.contentAvailable = contentAvailable; + } + } +} diff --git a/models/message/MentionMessage.cs b/models/message/MentionMessage.cs new file mode 100644 index 0000000..adaa453 --- /dev/null +++ b/models/message/MentionMessage.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + class MentionMessage + { + private String senderId; + /** + * 接收群 Id,提供多个本参数可以实现向多群发送消息,最多不超过 3 个群组。(必传) + */ + private String[] targetId; + private String objectName; + /** + * 消息 内容 + */ + private MentionMessageContent content; + private String pushContent; + private String pushData; + private int isPersisted; + private int isCounted; + private int isIncludeSender; + private int contentAvailable; + + public string[] TargetId { get => targetId; set => targetId = value; } + public string ObjectName { get => objectName; set => objectName = value; } + public MentionMessageContent Content { get => content; set => content = value; } + public string PushContent { get => pushContent; set => pushContent = value; } + public string PushData { get => pushData; set => pushData = value; } + public int IsPersisted { get => isPersisted; set => isPersisted = value; } + public int IsCounted { get => isCounted; set => isCounted = value; } + public int IsIncludeSender { get => isIncludeSender; set => isIncludeSender = value; } + public int ContentAvailable { get => contentAvailable; set => contentAvailable = value; } + public string SenderId { get => senderId; set => senderId = value; } + + public MentionMessage() + { + } + + public MentionMessage(String senderId, String[] targetId, String objectName, MentionMessageContent content, String pushContent, String pushData, + int isPersisted, int isCounted, int isIncludeSender, int contentAvailable) + { + this.senderId = senderId; + this.targetId = targetId; + this.objectName = objectName; + this.content = content; + this.pushContent = pushContent; + this.pushData = pushData; + this.isPersisted = isPersisted; + this.isCounted = isCounted; + this.isIncludeSender = isIncludeSender; + this.contentAvailable = contentAvailable; + } + } +} diff --git a/models/message/MentionMessageContent.cs b/models/message/MentionMessageContent.cs new file mode 100644 index 0000000..eabe7ad --- /dev/null +++ b/models/message/MentionMessageContent.cs @@ -0,0 +1,34 @@ +using io.rong.messages; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + class MentionMessageContent + { + [JsonProperty(PropertyName = "content")] + private BaseMessage content; + [JsonProperty(PropertyName = "mentionedInfo")] + private MentionedInfo mentionedInfo; + + [JsonIgnore] + internal BaseMessage Content { get => content; set => content = value; } + [JsonIgnore] + public MentionedInfo MentionedInfo { get => mentionedInfo; set => mentionedInfo = value; } + + public MentionMessageContent(BaseMessage content, MentionedInfo mentionedInfo) + { + this.content = content; + this.mentionedInfo = mentionedInfo; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/message/MentionedInfo.cs b/models/message/MentionedInfo.cs new file mode 100644 index 0000000..f922193 --- /dev/null +++ b/models/message/MentionedInfo.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + public class MentionedInfo + { + [JsonProperty(PropertyName = "type")] + private int type; + [JsonProperty(PropertyName = "userIds")] + private String[] userIds; + [JsonProperty(PropertyName = "pushContent")] + private String pushContent; + + [JsonIgnore] + public int Type { get => type; set => type = value; } + [JsonIgnore] + public string[] UserIds { get => userIds; set => userIds = value; } + [JsonIgnore] + public string PushContent { get => pushContent; set => pushContent = value; } + + public MentionedInfo(int type, String[] userIds, String pushContent) + { + this.type = type; + this.userIds = userIds; + this.pushContent = pushContent; + } + } +} diff --git a/models/message/MessageModel.cs b/models/message/MessageModel.cs new file mode 100644 index 0000000..53b7d5f --- /dev/null +++ b/models/message/MessageModel.cs @@ -0,0 +1,72 @@ +using io.rong.messages; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + class MessageModel + { + [JsonProperty(PropertyName = "senderId")] + private String senderId; + /** + * + * 接受 Id 可能是用户Id,聊天Id ,群组Id,讨论组Id(必传) + **/ + [JsonProperty(PropertyName = "targetId")] + private String[] targetId; + /** + *消息类型 (必传) + **/ + [JsonProperty(PropertyName = "objectName")] + private String objectName; + /** + * 发送消息内容,参考融云消息类型表.示例说明;如果 objectName + * 为自定义消息类型,该参数可自定义格式。(必传)。 + **/ + [JsonProperty(PropertyName = "content")] + private BaseMessage content; + /** + * 定义显示的 Push 内容,如果 objectName 为融云内置消息类型时, + * 则发送后用户一定会收到 Push 信息。如果为自定义消息,则 pushContent + * 为自定义消息显示的 Push 内容,如果不传则用户不会收到 Push 通知。(可选) + */ + [JsonProperty(PropertyName = "pushContent")] + private String pushContent; + /** + * 针对 iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData。(可选) + */ + [JsonProperty(PropertyName = "pushData")] + private String pushData; + + [JsonIgnore] + public string SenderId { get => senderId; set => senderId = value; } + [JsonIgnore] + public string[] TargetId { get => targetId; set => targetId = value; } + [JsonIgnore] + public string ObjectName { get => objectName; set => objectName = value; } + [JsonIgnore] + public BaseMessage Content { get => content; set => content = value; } + [JsonIgnore] + public string PushContent { get => pushContent; set => pushContent = value; } + [JsonIgnore] + public string PushData { get => pushData; set => pushData = value; } + + public MessageModel() + { + } + + public MessageModel(String senderId, String[] targetId, String objectName, BaseMessage content, + String pushContent, String pushData) + { + this.senderId = senderId; + this.targetId = targetId; + this.objectName = objectName; + this.content = content; + this.pushContent = pushContent; + this.pushData = pushData; + } + } +} diff --git a/models/message/PrivateMessage.cs b/models/message/PrivateMessage.cs new file mode 100644 index 0000000..6c60ead --- /dev/null +++ b/models/message/PrivateMessage.cs @@ -0,0 +1,61 @@ +using io.rong.messages; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + class PrivateMessage : MessageModel + { + + /** + * 针对 iOS 平台,Push 时用来控制未读消息显示数,只有在 toUserId 为一个用户 Id 的时候有效。(可选) + **/ + private String count; + /** + * 针对 iOS 平台,Push 时用来控制未读消息显示数,只有在 toUserId 为一个用户 Id 的时候有效。(可选) + */ + private int isPersisted; + /** + * 当前版本有新的自定义消息,而老版本没有该自定义消息时,老版本客户端收到消息后是否进行未读消息计数, + * 0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) + */ + private int isCounted; + + /** + *是否过滤发送人黑名单列表,0 表示为不过滤、 1 表示为过滤,默认为 0 不过滤。(可选 + */ + private int verifyBlacklist; + /** + * 发送用户自已是否接收消息,0 表示为不接收,1 表示为接收,默认为 0 不接收。(可选) + */ + private int isIncludeSender; + + private int contentAvailable; + + public string Count { get => count; set => count = value; } + public int IsPersisted { get => isPersisted; set => isPersisted = value; } + public int IsCounted { get => isCounted; set => isCounted = value; } + public int VerifyBlacklist { get => verifyBlacklist; set => verifyBlacklist = value; } + public int IsIncludeSender { get => isIncludeSender; set => isIncludeSender = value; } + public int ContentAvailable { get => contentAvailable; set => contentAvailable = value; } + + public PrivateMessage() + { + } + + public PrivateMessage(String senderId, String[] targetId, String objectName, BaseMessage content, String pushContent, String pushData, + String count, int isPersisted, int isCounted, int verifyBlacklist, int isIncludeSender, int contentAvailable) : base(senderId, targetId, objectName, content, pushContent, pushData) + { + + this.count = count; + this.isPersisted = isPersisted; + this.isCounted = isCounted; + this.verifyBlacklist = verifyBlacklist; + this.isIncludeSender = isIncludeSender; + this.contentAvailable = contentAvailable; + } + + } +} diff --git a/models/message/RecallMessage.cs b/models/message/RecallMessage.cs new file mode 100644 index 0000000..99015c2 --- /dev/null +++ b/models/message/RecallMessage.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + public class RecallMessage + { + /** + * 撤回消息体 + * 发送人id + * */ + private String senderId; + /** + * 接收人id + * */ + private String targetId; + /** + * 消息唯一标识 各端 SDK 发送消息成功后会返回 uId + * */ + private String uId; + /** + * 消息的发送时间,各端 SDK 发送消息成功后会返回 sentTime + * */ + private String sentTime; + + public string SenderId { get => senderId; set => senderId = value; } + public string TargetId { get => targetId; set => targetId = value; } + public string UId { get => uId; set => uId = value; } + public string SentTime { get => sentTime; set => sentTime = value; } + + public RecallMessage() + { + } + + /** + * @param senderId String 消息发送人用户 Id。(必传) + * @param conversationType Int 会话类型,二人会话是 1 、讨论组会话是 2 、群组会话是 3 。(必传) + * @param targetId String 目标 Id,根据不同的 ConversationType,可能是用户 Id、讨论组 Id、群组 Id。(必传) + * @param uId String 消息唯一标识,可通过服务端实时消息路由获取,对应名称为 msgUID。(必传) + * @param sentTime + * + * */ + public RecallMessage(String senderId, String conversationType, String targetId, + String uId, String sentTime) + { + this.senderId = senderId; + this.targetId = targetId; + this.uId = uId; + this.sentTime = sentTime; + } + } +} \ No newline at end of file diff --git a/models/message/SystemMessage.cs b/models/message/SystemMessage.cs new file mode 100644 index 0000000..15a4b38 --- /dev/null +++ b/models/message/SystemMessage.cs @@ -0,0 +1,44 @@ +using io.rong.messages; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + class SystemMessage : MessageModel + { + /** + * 当前版本有新的自定义消息,而老版本没有该自定义消息时, + * 老版本客户端收到消息后是否进行存储,0 表示为不存储、 1 表示为存储,默认为 1 存储消息。(可选) + * + * */ + private int isPersisted; + /** + * 当前版本有新的自定义消息,而老版本没有该自定义消息时, + * 老版本客户端收到消息后是否进行未读消息计数,0 表示为不计数、 1 表示为计数,默认为 1 计数,未读消息数增加 1。(可选) + * */ + private int isCounted; + /** + * 针对 iOS 平台,对 SDK 处于后台暂停状态时为静默推送,是 iOS7 之后推出的一种推送方式。 + * 允许应用在收到通知后在后台运行一段代码,且能够马上执行。1 表示为开启,0 表示为关闭,默认为 0(可选) + * */ + private int contentAvailable; + + public SystemMessage() + { + } + + public SystemMessage(String senderUserId, String[] targetId, String objectName, BaseMessage content, String pushContent, String pushData, + int isPersisted, int isCounted, int contentAvailable) : base(senderUserId, targetId, objectName, content, pushContent, pushData) + { + this.isPersisted = isPersisted; + this.isCounted = isCounted; + this.contentAvailable = contentAvailable; + } + + public int IsPersisted { get => isPersisted; set => isPersisted = value; } + public int IsCounted { get => isCounted; set => isCounted = value; } + public int ContentAvailable { get => contentAvailable; set => contentAvailable = value; } + } +} diff --git a/models/message/TemplateMessage.cs b/models/message/TemplateMessage.cs new file mode 100644 index 0000000..4ac439d --- /dev/null +++ b/models/message/TemplateMessage.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.message +{ + public class TemplateMessage + { + /** + * 发送人Id + * */ + private String senderId; + /** + * 消息类型 + * */ + private String objectName; + /** + * 发送消息内容,内容中定义模版,标识通过 content 中的标识位内容进行替换, + * 参考融云消息类型表.示例说明;如果 objectName 为自定义消息类型,该参数可自定义格式。(必传) + * */ + private Object template; + /** + * key 用户Id ,value 模板赋值内容 + * + * */ + private Dictionary content; + + private String[] pushData; + + private int verifyBlacklist; + + private int contentAvailable; + + public string SenderId { get => senderId; set => senderId = value; } + public string ObjectName { get => objectName; set => objectName = value; } + public object Template { get => template; set => template = value; } + public Dictionary Content { get => content; set => content = value; } + public string[] PushData { get => pushData; set => pushData = value; } + public int VerifyBlacklist { get => verifyBlacklist; set => verifyBlacklist = value; } + public int ContentAvailable { get => contentAvailable; set => contentAvailable = value; } + } + + public class ContentData + { + /** + * 消息内容数据,key对应模版的标识 ,value具体内容 + */ + private Dictionary data; + /** + * push内容 + */ + private String push; + + public string Push { get => push; set => push = value; } + public Dictionary Data { get => data; set => data = value; } + } +} diff --git a/models/response/BlackListResult.cs b/models/response/BlackListResult.cs new file mode 100644 index 0000000..fc03bee --- /dev/null +++ b/models/response/BlackListResult.cs @@ -0,0 +1,51 @@ +using io.rong.models.user; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class BlackListResult : Result + { + /** + * 黑名单用户列表 + */ + [JsonProperty(PropertyName = "users")] + UserModel[] users; + + [JsonIgnore] + public UserModel[] Users { get => users; set => users = value; } + + public BlackListResult(int code, String msg, UserModel[] users) : base(code, msg) + { + this.users = users; + } + + + /** + * 获取users + * + * @return User[] + */ + public UserModel[] getUsers() + { + return this.users; + } + /** + * 设置users + * + */ + public void setUsers(UserModel[] users) + { + this.users = users; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/BlockUserList.cs b/models/response/BlockUserList.cs new file mode 100644 index 0000000..da3dc26 --- /dev/null +++ b/models/response/BlockUserList.cs @@ -0,0 +1,54 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class BlockUserList + { + /** + * 返回码,200 为正常。 + * + */ + private int code; + /** + * 黑名单用户列表 + */ + private String[] users; + + + public BlockUserList(int code, String[] users) + { + this.code = code; + this.users = users; + } + + public String[] getUsers() + { + return this.users; + } + + public void setUsers(String[] users) + { + this.users = users; + } + + public int getCode() + { + return this.code; + } + + public void setCode(int code) + { + this.code = code; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/models/response/BlockUserResult.cs b/models/response/BlockUserResult.cs new file mode 100644 index 0000000..3d27c1f --- /dev/null +++ b/models/response/BlockUserResult.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class BlockUserResult : Result + { + // 被封禁用户列表。 + [JsonProperty(PropertyName = "users")] + List users; + + [JsonIgnore] + public List Users { get => users; set => users = value; } + + public BlockUserResult(int code, String errorMessage, List users) : base(code, errorMessage) + { + this.users = users; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/ChatroomDemotionMsgResult.cs b/models/response/ChatroomDemotionMsgResult.cs new file mode 100644 index 0000000..49f64d3 --- /dev/null +++ b/models/response/ChatroomDemotionMsgResult.cs @@ -0,0 +1,39 @@ +using io.rong.models.user; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ChatroomDemotionMsgResult : Result + { + [JsonProperty(PropertyName = "objectNames")] + private String[] objectNames; + + [JsonIgnore] + public string[] ObjectNames { get => objectNames; set => objectNames = value; } + + public ChatroomDemotionMsgResult() + { + + } + + public ChatroomDemotionMsgResult(int code, String msg, String[] objectNames) : base(code, msg) + { + this.objectNames = objectNames; + } + + public ChatroomDemotionMsgResult(String[] objectNames) + { + this.objectNames = objectNames; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/ChatroomKeepaliveResult.cs b/models/response/ChatroomKeepaliveResult.cs new file mode 100644 index 0000000..9430857 --- /dev/null +++ b/models/response/ChatroomKeepaliveResult.cs @@ -0,0 +1,29 @@ +using io.rong.models.user; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ChatroomKeepaliveResult : Result + { + [JsonProperty(PropertyName = "chatrooms")] + private String[] chatrooms; + + public ChatroomKeepaliveResult(int code, String msg, String[] chatrooms) : base(code, msg) + { + this.chatrooms = chatrooms; + } + [JsonIgnore] + public string[] Chatrooms { get => chatrooms; set => chatrooms = value; } + + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/ChatroomQueryResult.cs b/models/response/ChatroomQueryResult.cs new file mode 100644 index 0000000..657475c --- /dev/null +++ b/models/response/ChatroomQueryResult.cs @@ -0,0 +1,33 @@ +using io.rong.models.chatroom; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ChatroomQueryResult : Result + { + [JsonProperty(PropertyName = "chatRooms")] + List chatRooms; + + [JsonIgnore] + internal List ChatRooms { get => chatRooms; set => chatRooms = value; } + + public ChatroomQueryResult() + { + + } + public ChatroomQueryResult(int code, String errorMessage, List chatRooms) : base(code, errorMessage) + { + this.chatRooms = chatRooms; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/ChatroomUserQueryResult.cs b/models/response/ChatroomUserQueryResult.cs new file mode 100644 index 0000000..9b955b2 --- /dev/null +++ b/models/response/ChatroomUserQueryResult.cs @@ -0,0 +1,53 @@ +using io.rong.models.chatroom; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ChatroomUserQueryResult : Result + { + /** + * 聊天室中用户数。 + * + */ + [JsonProperty(PropertyName = "total")] + int total; + /** + * 聊天室成员列表。 + * + */ + [JsonProperty(PropertyName = "members")] + List members; + + [JsonIgnore] + public int Total { get => total; set => total = value; } + [JsonIgnore] + internal List Members { get => members; set => members = value; } + + public ChatroomUserQueryResult() + { + + } + + public ChatroomUserQueryResult(int code, String msg, int total, List members) : base(code, msg) + { + this.total = total; + this.members = members; + } + + public ChatroomUserQueryResult(int total, List members) + { + this.total = total; + this.members = members; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/ChatroomWhitelistMsgResult.cs b/models/response/ChatroomWhitelistMsgResult.cs new file mode 100644 index 0000000..2e4bb0f --- /dev/null +++ b/models/response/ChatroomWhitelistMsgResult.cs @@ -0,0 +1,39 @@ +using io.rong.models.chatroom; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ChatroomWhitelistMsgResult : Result + { + [JsonProperty(PropertyName = "objectNames")] + private String[] objectNames; + + [JsonIgnore] + public string[] ObjectNames { get => objectNames; set => objectNames = value; } + + public ChatroomWhitelistMsgResult() + { + + } + + public ChatroomWhitelistMsgResult(int code, String msg, String[] objectNames) : base(code, msg) + { + this.objectNames = objectNames; + } + + public ChatroomWhitelistMsgResult(String[] objectNames) + { + this.objectNames = objectNames; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/CheckChatRoomUserResult.cs b/models/response/CheckChatRoomUserResult.cs new file mode 100644 index 0000000..7999f8c --- /dev/null +++ b/models/response/CheckChatRoomUserResult.cs @@ -0,0 +1,34 @@ +using io.rong.models.chatroom; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class CheckChatRoomUserResult + { + [JsonProperty(PropertyName = "code")] + private String code; + [JsonProperty(PropertyName = "isInChrm")] + private Boolean isInChrm; + + [JsonIgnore] + public string Code { get => code; set => code = value; } + [JsonIgnore] + public bool IsInChrm { get => isInChrm; set => isInChrm = value; } + + public CheckChatRoomUserResult(String code, Boolean isInChrm) + { + this.code = code; + this.isInChrm = isInChrm; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/CheckOnlineResult.cs b/models/response/CheckOnlineResult.cs new file mode 100644 index 0000000..24c9ac3 --- /dev/null +++ b/models/response/CheckOnlineResult.cs @@ -0,0 +1,48 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class CheckOnlineResult : Result + { + // 在线状态,1为在线,0为不在线。 + [JsonProperty(PropertyName = "status")] + String status; + + public string Status { get => status; set => status = value; } + + public CheckOnlineResult(int code, String status, String errorMessage):base(code, errorMessage) + { + this.code = code; + this.status = status; + this.msg = errorMessage; + } + /** + * 设置status + * + */ + public void setStatus(String status) + { + this.status = status; + } + + /** + * 获取status + * + * @return String + */ + public String getStatus() + { + return status; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/GagGroupUser.cs b/models/response/GagGroupUser.cs new file mode 100644 index 0000000..749206a --- /dev/null +++ b/models/response/GagGroupUser.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json; + +namespace io.rong.models.response +{ + + /** + * 群组用户封禁信息。 + */ + class GagGroupUser + { + // 解禁时间。 + String time; + // 群成员 Id。 + String id; + + public GagGroupUser(String time, String id) + { + this.time = time; + this.id = id; + } + + /** + * 设置time + * + */ + public GagGroupUser setTime(String time) + { + this.time = time; + return this; + } + + /** + * 获取time + * + * @return String + */ + public String getTime() + { + return time; + } + + /** + * 获取userId + * + * @return String + */ + public String getId() + { + return this.id; + } + + /** + * 设置userId + * + */ + public void setId(String id) + { + this.id = id; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + + } + } +} diff --git a/models/response/GroupUser.cs b/models/response/GroupUser.cs new file mode 100644 index 0000000..fe75428 --- /dev/null +++ b/models/response/GroupUser.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class GroupUser + { + // 用户 Id。 + [JsonProperty(PropertyName = "id")] + String id; + + public GroupUser(String id) + { + this.id = id; + } + + [JsonIgnore] + public string Id { get => id; set => id = value; } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/GroupUserQueryResult.cs b/models/response/GroupUserQueryResult.cs new file mode 100644 index 0000000..e6f0b9d --- /dev/null +++ b/models/response/GroupUserQueryResult.cs @@ -0,0 +1,52 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class GroupUserQueryResult : Result + { + + // 群成员用户Id。 + [JsonProperty(PropertyName = "id")] + String id; + // 群成员列表。 + [JsonProperty(PropertyName = "members")] + List members; + + [JsonIgnore] + public string Id { get => id; set => id = value; } + [JsonIgnore] + public List Members { get => members; set => members = value; } + + public GroupUserQueryResult() + { + + } + public GroupUserQueryResult(int code, String msg, String id, List members) : base(code, msg) + { + this.id = id; + this.members = members; + } + + public GroupUserQueryResult(int code, List members): base(code, "") + { + this.members = members; + } + + + public GroupUserQueryResult(String id, List members) + { + this.id = id; + this.members = members; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/HistoryMessageResult.cs b/models/response/HistoryMessageResult.cs new file mode 100644 index 0000000..5f2f652 --- /dev/null +++ b/models/response/HistoryMessageResult.cs @@ -0,0 +1,41 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + /** + * historyMessage返回结果 + */ + class HistoryMessageResult : Result + { + + // 历史消息下载地址。 + [JsonProperty(PropertyName = "url")] + String url; + // 历史记录时间。(yyyymmddhh) + [JsonProperty(PropertyName = "date")] + String date; + + [JsonIgnore] + public string Url { get => url; set => url = value; } + [JsonIgnore] + public string Date { get => date; set => date = value; } + + public HistoryMessageResult(int code, String url, String date, String errorMessage):base(code, errorMessage) + { + this.code = code; + this.url = url; + this.date = date; + this.msg = errorMessage; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} \ No newline at end of file diff --git a/models/response/ListBlockChatroomUserResult.cs b/models/response/ListBlockChatroomUserResult.cs new file mode 100644 index 0000000..0a3ecdc --- /dev/null +++ b/models/response/ListBlockChatroomUserResult.cs @@ -0,0 +1,43 @@ +using io.rong.models.chatroom; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ListBlockChatroomUserResult : Result + { + /** + * 被封禁用户列表 + * + */ + [JsonProperty(PropertyName = "members")] + List members; + + [JsonIgnore] + internal List Members { get => members; set => members = value; } + + public ListBlockChatroomUserResult() + { + + } + + public ListBlockChatroomUserResult(int code, String msg, List members) : base(code, msg) + { + this.members = members; + } + + public ListBlockChatroomUserResult(List members) + { + this.members = members; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/ListGagChatroomUserResult.cs b/models/response/ListGagChatroomUserResult.cs new file mode 100644 index 0000000..832f640 --- /dev/null +++ b/models/response/ListGagChatroomUserResult.cs @@ -0,0 +1,43 @@ +using io.rong.models.chatroom; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ListGagChatroomUserResult : Result + { + /** + * 聊天室被禁言用户列表。 + * + */ + [JsonProperty(PropertyName = "members")] + List members; + + [JsonIgnore] + internal List Members { get => members; set => members = value; } + + public ListGagChatroomUserResult() + { + + } + + public ListGagChatroomUserResult(int code, String msg, List members) : base(code, msg) + { + this.members = members; + } + + public ListGagChatroomUserResult(List members) + { + this.members = members; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/ListGagGroupUserResult.cs b/models/response/ListGagGroupUserResult.cs new file mode 100644 index 0000000..713f594 --- /dev/null +++ b/models/response/ListGagGroupUserResult.cs @@ -0,0 +1,56 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ListGagGroupUserResult : Result + { + // 群组被禁言用户列表。 + List members; + + public ListGagGroupUserResult(int code, String msg, List members) : base(code, msg) + { + this.members = members; + } + + public ListGagGroupUserResult(List members) + { + this.members = members; + } + + public ListGagGroupUserResult() + { + } + + + + /** + * 获取members + * + * @return List + */ + public List getMembers() + { + return this.members; + } + + /** + * 设置members + * + */ + public void setMembers(List members) + { + this.members = members; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + + } + } +} diff --git a/models/response/ListWordfilterResult.cs b/models/response/ListWordfilterResult.cs new file mode 100644 index 0000000..ca346da --- /dev/null +++ b/models/response/ListWordfilterResult.cs @@ -0,0 +1,37 @@ +using Newtonsoft.Json; +using io.rong.models.sensitiveword; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ListWordfilterResult:Result + { + // 敏感词内容。 + + [JsonProperty(PropertyName = "words")] + List words; + + [JsonIgnore] + public List Words { get => words; set => words = value; } + + public ListWordfilterResult() + { + } + + public ListWordfilterResult(int code, List words, String errorMessage):base(code, errorMessage) + { + this.code = code; + this.words = words; + this.msg = errorMessage; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/ResponseResult.cs b/models/response/ResponseResult.cs new file mode 100644 index 0000000..fdc8388 --- /dev/null +++ b/models/response/ResponseResult.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class ResponseResult : Result + { + public ResponseResult(int code, string msg) : base(code, msg) + { + this.code = code; + this.msg = msg; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + + } +} diff --git a/models/response/TokenResult.cs b/models/response/TokenResult.cs new file mode 100644 index 0000000..092478e --- /dev/null +++ b/models/response/TokenResult.cs @@ -0,0 +1,49 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +/** + * getToken 返回结果 + */ +namespace io.rong.models.response +{ + class TokenResult : Result + { + // 用户 Token,可以保存应用内,长度在 256 字节以内.用户 Token,可以保存应用内,长度在 256 字节以内。 + [JsonProperty(PropertyName = "token")] + String token; + // 用户 Id,与输入的用户 Id 相同. + [JsonProperty(PropertyName = "userId")] + private String userId; + + public TokenResult(int code, String token, String userId, String errorMessage) + { + this.code = code; + this.token = token; + this.userId = userId; + this.msg = errorMessage; + } + + [JsonIgnore] + public String Token + + { + get { return this.token; } + set { this.token = value; } + } + + [JsonIgnore] + public string UserId { get => userId; set => userId = value; } + [JsonIgnore] + public string UserId1 { get => userId; set => userId = value; } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + + } +} diff --git a/models/response/UserList.cs b/models/response/UserList.cs new file mode 100644 index 0000000..e46064b --- /dev/null +++ b/models/response/UserList.cs @@ -0,0 +1,60 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class UserList + { + /** + * 返回码,200 为正常。 + * + */ + [JsonProperty(PropertyName = "code")] + private int code; + /** + * 黑名单用户列表 + */ + [JsonProperty(PropertyName = "users")] + private String[] users; + + [JsonIgnore] + public int Code { get => code; set => code = value; } + [JsonIgnore] + public string[] Users { get => users; set => users = value; } + + public UserList(int code, String[] users) + { + this.code = code; + this.users = users; + } + + public String[] getUsers() + { + return this.users; + } + + public void setUsers(String[] users) + { + this.users = users; + } + + public int getCode() + { + return this.code; + } + + public void setCode(int code) + { + this.code = code; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/response/WhiteListResult.cs b/models/response/WhiteListResult.cs new file mode 100644 index 0000000..7711026 --- /dev/null +++ b/models/response/WhiteListResult.cs @@ -0,0 +1,49 @@ +using io.rong.models.user; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.response +{ + class WhiteListResult : Result + { + [JsonProperty(PropertyName = "members")] + private UserModel[] members; + + [JsonIgnore] + internal UserModel[] Members { get => members; set => members = value; } + + public WhiteListResult(int code, String msg) :base(code, msg) + { + + } + + public WhiteListResult(int code, String msg, UserModel[] members) : base(code, msg) + { + this.members = members; + } + + public WhiteListResult(UserModel[] members) + { + this.members = members; + } + + public UserModel[] getMembers() + { + return this.members; + } + + public void setMembers(UserModel[] members) + { + this.members = members; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/sensitiveword/SensitiveWordModel.cs b/models/sensitiveword/SensitiveWordModel.cs new file mode 100644 index 0000000..fff1c11 --- /dev/null +++ b/models/sensitiveword/SensitiveWordModel.cs @@ -0,0 +1,54 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.sensitiveword +{ + /** + * 敏感词、替换词信息 + */ + class SensitiveWordModel + { + /** + * 敏感词类型 + */ + [JsonProperty(PropertyName = "type")] + int type = 1; + /** + *敏感词 + */ + [JsonProperty(PropertyName = "keyword")] + String keyword; + /** + *替换词 + */ + [JsonProperty(PropertyName = "replace")] + String replace; + + [JsonIgnore] + public int Type { get => type; set => type = value; } + [JsonIgnore] + public string Keyword { get => keyword; set => keyword = value; } + [JsonIgnore] + public string Replace { get => replace; set => replace = value; } + + public SensitiveWordModel(int type, String keyword, String replace) + { + this.type = type; + this.keyword = keyword; + this.replace = replace; + } + + public SensitiveWordModel() + { + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/models/user/BlockUser.cs b/models/user/BlockUser.cs new file mode 100644 index 0000000..3041277 --- /dev/null +++ b/models/user/BlockUser.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.models.user +{ + class BlockUser + { + } +} diff --git a/models/user/UserModel.cs b/models/user/UserModel.cs new file mode 100644 index 0000000..fdc0e51 --- /dev/null +++ b/models/user/UserModel.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json; + + +namespace io.rong.models.user +{ + class UserModel + { + /** + * 用户 Id,最大长度 64 字节.是用户在 App 中的唯一标识码, + * 必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户。(必传) + */ + public String id; + /** + * 用户名称,最大长度 128 字节。用来在 Push 推送时,显示用户的名称, + * 刷新用户名称后 5 分钟内生效。(可选,提供即刷新,不提供忽略) + */ + public String name; + /** + * 用户头像 URI,最大长度 1024 字节。 + * 用来在 Push 推送时显示。(可选,提供即刷新,不提供忽略) + */ + public String portrait; + + public int minute; + /** + * 黑名单列表。 + */ + public UserModel[] blacklist; + + + public UserModel() + { + } + + public UserModel(String id, String name, String portrait) + { + this.id = id; + this.name = name; + this.portrait = portrait; + } + + [JsonIgnore] + public String Id + { + get { return this.id; } + set { this.id = value; } + } + + public String GetId() + { + return this.id; + } + + public UserModel SetId(String id) + { + this.id = id; + return this; + } + + [JsonIgnore] + public String Name + { + get { return this.name; } + set { this.name = value; } + } + + public String GetName() + { + return this.name; + } + + public UserModel SetName(String name) + { + this.name = name; + return this; + } + + [JsonIgnore] + public String Portrait + { + get { return this.portrait; } + set { this.portrait = value; } + } + + public String GetPortrait() + { + return this.portrait; + } + + public UserModel SetPortrait(String portrait) + { + this.portrait = portrait; + return this; + } + + [JsonIgnore] + public int Minute + { + get { return this.minute; } + set { this.minute = value; } + } + + public int GetMinute() + { + return this.minute; + } + + public UserModel SetMinute(int minute) + { + this.minute = minute; + return this; + } + + [JsonIgnore] + public UserModel[] Blacklist + { + get { return this.blacklist; } + set { this.blacklist = value; } + } + + public UserModel[] GetBlacklist() + { + return this.blacklist; + } + + public UserModel SetBlacklist(UserModel[] blacklist) + { + this.blacklist = blacklist; + return this; + } + + override + public String ToString() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + } +} diff --git a/util/CodeUtil.cs b/util/CodeUtil.cs new file mode 100644 index 0000000..9ca3bb4 --- /dev/null +++ b/util/CodeUtil.cs @@ -0,0 +1,279 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace io.rong.util +{ + public class CodeUtil + { + + /// + /// 会话类型 + /// + public sealed class ConversationType + { + //二人会话 + public static readonly ConversationType PRIVATE = new ConversationType("PRIVATE", InnerEnum.PRIVATE, "1"); + //讨论组会话 + public static readonly ConversationType DISCUSSION = new ConversationType("DISCUSSION", InnerEnum.DISCUSSION, "2"); + //群组会话 + public static readonly ConversationType GROUP = new ConversationType("GROUP", InnerEnum.GROUP, "3"); + //系统通知 + public static readonly ConversationType SYSTEM = new ConversationType("SYSTEM", InnerEnum.SYSTEM, "6"); + //客服会话 + public static readonly ConversationType KF = new ConversationType("KF", InnerEnum.KF, "5"); + //应用公众服务 + public static readonly ConversationType MC = new ConversationType("MC", InnerEnum.MC, "7"); + //公众服务 + public static readonly ConversationType MP = new ConversationType("MP", InnerEnum.MP, "8"); + + private static readonly IList valueList = new List(); + + static ConversationType() + { + valueList.Add(PRIVATE); + valueList.Add(DISCUSSION); + valueList.Add(GROUP); + valueList.Add(SYSTEM); + valueList.Add(KF); + valueList.Add(MC); + valueList.Add(MP); + } + + public enum InnerEnum + { + PRIVATE, + DISCUSSION, + GROUP, + SYSTEM, + KF, + MC, + MP + } + + public readonly InnerEnum innerEnumValue; + private readonly string nameValue; + private readonly int ordinalValue; + private static int nextOrdinal = 0; + + + internal string name; + internal ConversationType(string nameValue, InnerEnum innerEnum, string name) + { + this.name = name; + + this.nameValue = nameValue; + ordinalValue = nextOrdinal++; + innerEnumValue = innerEnum; + } + public string Name + { + get + { + return this.name; + } + } + + public static IList values() + { + return valueList; + } + + public int ordinal() + { + return ordinalValue; + } + + public override string ToString() + { + return nameValue; + } + + public static ConversationType valueOf(string name) + { + foreach (ConversationType enumInstance in ConversationType.valueList) + { + if (enumInstance.nameValue == name) + { + return enumInstance; + } + } + throw new System.ArgumentException(name); + } + } + + public sealed class ServiceType + { + public static readonly ServiceType chatRoom = new ServiceType("chatRoom", InnerEnum.chatRoom, 1); + public static readonly ServiceType group = new ServiceType("group", InnerEnum.group, 2); + public static readonly ServiceType message = new ServiceType("message", InnerEnum.message, 3); + public static readonly ServiceType push = new ServiceType("push", InnerEnum.push, 4); + public static readonly ServiceType sensitiveword = new ServiceType("sensitiveword", InnerEnum.sensitiveword, 5); + public static readonly ServiceType sms = new ServiceType("sms", InnerEnum.sms, 6); + public static readonly ServiceType user = new ServiceType("user", InnerEnum.user, 7); + public static readonly ServiceType worefilter = new ServiceType("worefilter", InnerEnum.worefilter, 8); + + private static readonly IList valueList = new List(); + + static ServiceType() + { + valueList.Add(chatRoom); + valueList.Add(group); + valueList.Add(message); + valueList.Add(push); + valueList.Add(sensitiveword); + valueList.Add(sms); + valueList.Add(user); + valueList.Add(worefilter); + } + + public enum InnerEnum + { + chatRoom, + group, + message, + push, + sensitiveword, + sms, + user, + worefilter + } + + public readonly InnerEnum innerEnumValue; + private readonly string nameValue; + private readonly int ordinalValue; + private static int nextOrdinal = 0; + + internal int resultCode; + + internal ServiceType(string name, InnerEnum innerEnum, int resultCode) + { + this.resultCode = resultCode; + this.nameValue = name; + ordinalValue = nextOrdinal++; + innerEnumValue = innerEnum; + } + public int ResutCode + { + get + { + return this.resultCode; + } + } + + public static IList values() + { + return valueList; + } + + public int ordinal() + { + return ordinalValue; + } + + public override string ToString() + { + return nameValue; + } + + public static ServiceType valueOf(string name) + { + foreach (ServiceType enumInstance in ServiceType.valueList) + { + if (enumInstance.nameValue == name) + { + return enumInstance; + } + } + throw new System.ArgumentException(name); + } + } + + public sealed class ErrorType + { + public static readonly ErrorType chatRoom = new ErrorType("chatRoom", InnerEnum.chatRoom, 1); + public static readonly ErrorType group = new ErrorType("group", InnerEnum.group, 2); + public static readonly ErrorType message = new ErrorType("message", InnerEnum.message, 3); + public static readonly ErrorType push = new ErrorType("push", InnerEnum.push, 4); + public static readonly ErrorType sensitiveword = new ErrorType("sensitiveword", InnerEnum.sensitiveword, 5); + public static readonly ErrorType sms = new ErrorType("sms", InnerEnum.sms, 6); + public static readonly ErrorType user = new ErrorType("user", InnerEnum.user, 7); + public static readonly ErrorType worefilter = new ErrorType("worefilter", InnerEnum.worefilter, 8); + + private static readonly IList valueList = new List(); + + static ErrorType() + { + valueList.Add(chatRoom); + valueList.Add(group); + valueList.Add(message); + valueList.Add(push); + valueList.Add(sensitiveword); + valueList.Add(sms); + valueList.Add(user); + valueList.Add(worefilter); + } + + public enum InnerEnum + { + chatRoom, + group, + message, + push, + sensitiveword, + sms, + user, + worefilter + } + + public readonly InnerEnum innerEnumValue; + private readonly string nameValue; + private readonly int ordinalValue; + private static int nextOrdinal = 0; + + internal int resultCode; + + internal ErrorType(string name, InnerEnum innerEnum, int resultCode) + { + this.resultCode = resultCode; + this.nameValue = name; + ordinalValue = nextOrdinal++; + innerEnumValue = innerEnum; + } + public int ResutCode + { + get + { + return this.resultCode; + } + } + + public static IList values() + { + return valueList; + } + + public int ordinal() + { + return ordinalValue; + } + + public override string ToString() + { + return nameValue; + } + + public static ErrorType valueOf(string name) + { + foreach (ErrorType enumInstance in ErrorType.valueList) + { + if (enumInstance.nameValue == name) + { + return enumInstance; + } + } + throw new System.ArgumentException(name); + } + } + } +} \ No newline at end of file diff --git a/util/CommonUtil.cs b/util/CommonUtil.cs new file mode 100644 index 0000000..319f3b5 --- /dev/null +++ b/util/CommonUtil.cs @@ -0,0 +1,683 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Reflection; +using io.rong.models.response; +using io.rong.models.user; + +namespace io.rong.util +{ + class CommonUtil + { + public static String VERIFY_JSON_NAME = "/verify.json"; + public static String API_JSON_NAME = "/api.json"; + public static String CHRARCTER = "UTF-8"; + + public static bool ValidateParams(Object paramObj, int length) + { + try + { + if (null == paramObj) + { + return false; + } + if (paramObj.GetType() == typeof(String[])) + { + String[] param = (String[])paramObj; + int len = param.Length; + if (len <= length) + { + return true; + } + } + else if (paramObj.GetType() == typeof(String)) + { + String param = (String)paramObj; + int len = param.Length; + if (len <= length) + { + return true; + } + } + else if (paramObj.GetType() == typeof(int)) + { + int param = (int)paramObj; + if (param <= length) + { + return true; + } + } + } + catch (Exception e) + { + Console.WriteLine("长度校验错误" + e.Message); + } + return false; + } + + /** + * 从文件读取 json 对象 + * + * @param path 文件路径 + * + * @return Jobj + **/ + private static JObject FromPath(String path) + { + Console.WriteLine(Directory.GetCurrentDirectory()); + StreamReader file = System.IO.File.OpenText("jsonsource/" + path); + JsonTextReader reader = new JsonTextReader(file); + JObject jObject = (JObject)JToken.ReadFrom(reader); + + //reader.Close(); + + return jObject; + } + + private static List GetKeys(JToken jToken) + { + Dictionary dictObj = jToken.ToObject>(); + + return dictObj.Keys.ToList(); + } + + private static Dictionary> GetMessages(JToken jToken) + { + Dictionary> dictObj = jToken.ToObject>>(); + Dictionary> messageSet = new Dictionary>(); + foreach (var item in dictObj) + { + Dictionary msg = new Dictionary(); + foreach (var dict in item.Value) + { + msg.Add(dict.Key, dict.Value); + } + messageSet.Add(item.Key, msg); + } + + return messageSet; + } + + /** + * 参数校验方法 + * + * @param model 校验对象 + * @param path 路径 + * @param method 需要校验方法 + * + * @return String + **/ + public static String CheckFiled(Object model, String path, String method) + { + try + { + String code = "200"; + int max = 64; + //api.json 的路径 + String apiPath = path; + String type = ""; + if (path.Contains("/")) + { + path = path.Substring(0, path.IndexOf("/")); + } + String[] fileds = { }; + String checkObjectKey = ""; + //获取需要校验的参数 + Dictionary checkInfo = GetCheckInfo(apiPath, method); + foreach (var item in checkInfo) + { + checkObjectKey = item.Key; + fileds = item.Value; + } + + //获取校验文件 + JObject verify = FromPath(path + VERIFY_JSON_NAME); + + //获取校验key + List keys = GetKeys(verify.GetValue(checkObjectKey)); + //获取具体校验规则 + + JObject entity = (JObject)verify.GetValue(checkObjectKey); + //Dictionary entity = verify.GetValue(checkObjectKey).ToObject>(); + foreach (String name in fileds) + { + foreach (String key in keys) + { + if (name.Equals(key)) + { + //将属性的首字符大写,方便构造get,set方法 + String nameTemp = name.Substring(0, 1).ToUpper() + name.Substring(1); + //获取属性的类型 + //String type = field.getGenericType().ToString(); + + MethodInfo m = model.GetType().GetMethod("Get" + nameTemp); + PropertyInfo propertyInfo = model.GetType().GetProperty(nameTemp); + //.GetValue(model, null) + + //获取字段的具体校验规则 + JObject obj = (JObject)entity.GetValue(name); + if (obj.GetValue("require") != null) + { + Boolean must = (Boolean)((JObject)obj.GetValue("require")).GetValue("must"); + Object result = null; + if (null != m) + { + result = m.Invoke(model, new Object[] { }); + } else + { + result = propertyInfo.GetValue(model, null); + } + + if (result != null && result.GetType() == typeof(String)) + { + String value = (String)result; + if (String.IsNullOrEmpty(value)) + { + code = (String)((JObject)obj.GetValue("require")).GetValue("invalid"); + } + } + else + { + Object value = result; + if (null == value) + { + code = (String)((JObject)obj.GetValue("require")).GetValue("invalid"); + } + } + } + if (obj.GetValue("length") != null) + { + max = (int)((JObject)obj.GetValue("length")).GetValue("max"); + Object result = null; + if (null != m) + { + result = m.Invoke(model, new Object[] { }); + } + else + { + result = propertyInfo.GetValue(model, null); + } + if (null != result && result.GetType() == typeof(String)) + { + String value = (String)result; + if ("200".Equals(code) && String.IsNullOrEmpty(value)) + { + code = (String)((JObject)obj.GetValue("length")).GetValue("invalid"); + } + if ("200".Equals(code) && value.Length > max) + { + code = (String)((JObject)obj.GetValue("length")).GetValue("invalid"); + } + } + else if (null != result && result.GetType() == typeof(String[])) + { + String[] value = (String[])result; + if ("200".Equals(code) && value.Length > max) + { + code = (String)((JObject)obj.GetValue("length")).GetValue("invalid"); + } + } + + } + if (obj.GetValue("size") != null) + { + max = (int)((JObject)obj.GetValue("size")).GetValue("max"); + type = (String)((JObject)obj.GetValue("typeof")).GetValue("type"); + if (type.Contains("array")) + { + Object[] value = null; + if (null != m) + { + value = (Object[])m.Invoke(model, new Object[] { }); + } + else + { + value = (Object[])propertyInfo.GetValue(model, null); + } + if ("200".Equals(code) && null == value) + { + code = (String)((JObject)obj.GetValue("size")).GetValue("invalid"); + } + if ("200".Equals(code) && value.Length > max) + { + code = (String)((JObject)obj.GetValue("size")).GetValue("invalid"); + } + + } + else if (type.Contains("int")) + { + int value = 0; + try + { + if (null != m) + { + value = (int)m.Invoke(model, new Object[] { }); + } + else + { + value = (int)propertyInfo.GetValue(model, null); + } + } + catch (Exception e) + { + code = (String)((JObject)obj.GetValue("typeof")).GetValue("invalid"); + } + + if ("200".Equals(code) && 0 == value) + { + code = (String)((JObject)obj.GetValue("size")).GetValue("invalid"); + } + if ("200".Equals(code) && value > max) + { + code = (String)((JObject)obj.GetValue("size")).GetValue("invalid"); + } + + } + } + if (!"200".Equals(code)) + { + //根据错误码获取错误信息 + String message = (String)CommonUtil.GetErrorMessage(apiPath, method, code, name, max.ToString(), "1", type); + //对 errorMessage 替换 + message = message.Replace("errorMessage", "msg"); + return message; + } + } + } + + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + throw e; + } + return null; + } + + /** + * 获取校验信息 + * + * @param path 路径 (获取校验文件路径) + * @param method 校验方法(需要校验的方法) + * + * @return Map + **/ + public static Dictionary GetCheckInfo(String path, String method) + { + JObject api = null; + try + { + api = FromPath(path + API_JSON_NAME); + List keys = GetKeys(((JObject)api.GetValue(method)).GetValue("params")); + //ISet keys = api.GetValue(method).GetValue("params").keySet(); + String key = keys[0]; + if (String.IsNullOrEmpty(key)) + { + return null; + } + List subkeys; + + JToken obj = ((JObject)((JObject)api.GetValue(method)).GetValue("params")).GetValue(key); + + if (null != obj) + { + subkeys = GetKeys(obj); + } + else + { + subkeys = keys; + } + Dictionary map = new Dictionary + { + { key, subkeys.ToArray() } + }; + return map; + } + catch (IOException e) + { + Console.WriteLine(e.Message); + throw e; + } + } + + + /** + * 获取错误信息 + * + * @param path 路径 (获取校验文件路径) + * @param method 校验方法(需要校验的方法) + * @param errorCode 错误码 + * @param name 具体字段名 + * @param max 字段需要的最大值 + * @param min 字段的最小值 + * @param type 类型 + * + * @return Map + **/ + public static Object GetErrorMessage(String path, String method, String errorCode, String name, String max, String min, String type) + { + JObject api = null; + try + { + api = FromPath(path + API_JSON_NAME); + Dictionary> messages = GetMessages(((JObject)((JObject)api.GetValue(method)).GetValue("response")).GetValue("fail")); + String[] searchList = { "{{name}}", "{{max}}", "{{name}}", "{{min}}", "{{currentType}}" }; + String[] replaceList = { name, max, name, min, type }; + foreach (var item in messages) + { + if (errorCode.Equals(item.Key)) + { + String text = JsonConvert.SerializeObject(item.Value); + //StringUtils.replaceEach(text,serchList,replaceList); + for (int i = 0; i < searchList.Length; i++) + { + text = text.Replace(searchList[i], replaceList[i]); + } + + return text; + } + } + } + catch (IOException e) + { + throw e; + } + return null; + } + + /** + * 参数校验 + * + * @param checkFiled 需要校验的字段 + * @param value 传入参数值 + * @param path 路径 (获取校验文件路径) + * @param method 需要校验方法 + * + * @return String + **/ + public static String CheckParam(String checkFiled, Object value, String path, String method) + { + try + { + String code = "200"; + bool flag = false; + int max = 64; + String type = ""; + String apiPath = path; + if (path.Contains("/")) + { + path = path.Substring(0, path.IndexOf("/")); + } + //String[] fileds = {}; + String checkObject = ""; + //获取需要校验的key + Dictionary checkInfo = GetCheckInfo(apiPath, method); + foreach (var item in checkInfo) + { + //fileds = entry.getValue(); + checkObject = item.Key; + } + JToken verify = FromPath(path + VERIFY_JSON_NAME); + List keys = GetKeys(((JObject)verify).GetValue(checkObject)); + JObject entity = (JObject)((JObject)verify).GetValue(checkObject); + foreach (String key in keys) + { + if (checkFiled.Equals(key)) + { + JObject obj = (JObject)entity.GetValue(checkFiled); + if (obj.GetValue("require") != null) + { + Boolean must = (Boolean)((JObject)obj.GetValue("require")).GetValue("must"); + if (value.GetType() == typeof(String)) + { + if (String.IsNullOrEmpty(value.ToString())) + { + code = (String)((JObject)obj.GetValue("require")).GetValue("invalid"); + } + + } + else + { + if (null == value) + { + code = (String)((JObject)obj.GetValue("require")).GetValue("invalid"); + } + } + } + if (obj.GetValue("length") != null) + { + max = (int)((JObject)obj.GetValue("length")).GetValue("max"); + if (value.GetType() == typeof(String)) + { + if ("200".Equals(code) && String.IsNullOrEmpty(value.ToString())) + { + code = (String)((JObject)obj.GetValue("length")).GetValue("invalid"); + } + if ("200".Equals(code) && value.ToString().Length > max) + { + code = (String)((JObject)(JObject)obj.GetValue("length")).GetValue("invalid"); + } + } + else if (value.GetType() == typeof(String[])) + { + String[] valueTemp = { }; + try + { + valueTemp = (String[])value; + } + catch (Exception e) + { + code = (String)((JObject)obj.GetValue("typeof")).GetValue("invalid"); + } + if ("200".Equals(code) && valueTemp.Length > max) + { + code = (String)((JObject)obj.GetValue("length")).GetValue("invalid"); + } + } + + } + if (obj.GetValue("size") != null) + { + max = (int)((JObject)obj.GetValue("size")).GetValue("max"); + type = (String)((JObject)obj.GetValue("typeof")).GetValue("type"); + if (type.Contains("array")) + { + String[] valueTemp = null; + if ("200".Equals(code) && null == value) + { + code = (String)((JObject)obj.GetValue("size")).GetValue("invalid"); + } + try + { + valueTemp = (String[])value; + } + catch (Exception e) + { + code = (String)((JObject)obj.GetValue("typeof")).GetValue("invalid"); + } + + if ("200".Equals(code) && valueTemp.Length > max) + { + code = (String)((JObject)obj.GetValue("size")).GetValue("invalid"); + } + + } + else if (type.Contains("int")) + { + int valueTemp = 64; + try + { + valueTemp = (int)value; + } + catch (Exception e) + { + code = (String)((JObject)obj.GetValue("typeof")).GetValue("invalid"); + } + if ("200".Equals(code) && null == value) + { + code = (String)((JObject)obj.GetValue("size")).GetValue("invalid"); + } + if ("200".Equals(code) && valueTemp > max) + { + code = (String)((JObject)obj.GetValue("size")).GetValue("invalid"); + } + + } + } + String message = (String)CommonUtil.GetErrorMessage(apiPath, method, code, checkFiled, max.ToString(), "1", type); + if (null != message) + { + message = message.Replace("errorMessage", "msg"); + return message; + } + + } + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + throw e; + } + return null; + } + + /** + * 获取response信息 + * + * @param path 路径 (获取校验文件路径) + * @param method 校验方法(需要校验的方法) + * @param response 返回信息 + * + * @return String + **/ + public static String GetResponseByCode(String path, String method, String response) + { + JObject api = null; + try + { + JObject obj = (JObject)JToken.Parse(response); + String code = obj.GetValue("code").ToString(); + api = FromPath(path + API_JSON_NAME); + Dictionary> messages = GetMessages(((JObject)((JObject)api.GetValue(method)).GetValue("response")).GetValue("fail")); + String text = response; + if (code.Equals("200")) + { + if (path.Contains("blacklist") && method.Equals("getList")) + { + + UserList userList = JsonConvert.DeserializeObject(response); + List users = new List(); + foreach (String id in userList.getUsers()) + { + UserModel tmpUser = new UserModel + { + Id = id + }; + users.Add(tmpUser); + } + UserModel[] members = users.ToArray(); + + BlackListResult blacklist = new BlackListResult(userList.getCode(), null, members); + + text = blacklist.ToString(); + + } + else if (path.Contains("whitelist/user") && method.Equals("getList")) + { + + UserList userList = JsonConvert.DeserializeObject(response); + //User[] members = {}; + List users = new List(); + foreach (String id in userList.getUsers()) + { + users.Add(new UserModel() { Id = id }); + } + UserModel[] members = users.ToArray(); + WhiteListResult whitelist = new WhiteListResult(userList.getCode(), null, members); + + text = whitelist.ToString(); + + } + else if (path.Contains("chatroom") || path.Contains("group")) + { + text = response.Replace("users", "members"); + if (text.Contains("whitlistMsgType")) + { + text = text.Replace( "whitlistMsgType", "objNames"); + } + if (path.Contains("gag") || path.Contains("block")) + { + text = text.Replace("userId", "id"); + } + } + else if (path.Contains("user")) + { + if (path.Contains("block") || path.Contains("blacklist")) + { + text = response.Replace("userId", "id"); + } + } + else if (path.Contains("sensitiveword")) + { + text = response.Replace("word", "keyword"); + if (text.Contains("keywords")) + { + text = text.Replace("keywords", "words"); + } + text = text.Replace("replaceWord", "replace"); + + } + else + { + text = response; + } + return text; + } + else + { + foreach (var item in messages) + { + if (code.Equals(item.Key)) + { + text = JsonConvert.SerializeObject(item.Value); + //text = StringUtils.replace(text,"msg","errorMessage"); + text = text.Replace("errorMessage", "msg"); + + return text; + } + } + text = response.Replace("errorMessage", "msg"); + if (path.Contains("chatroom")) + { + text = text.Replace("users", "members"); + //对于 聊天室保活成功返回的code是0 更改统一返回200 + if (path.Contains("keepalive") && "0".Equals(code)) + { + text = text.Replace("chatroomIds", "chatrooms"); + text = text.Replace("0", "200"); + + } + } + return text; + } + } + catch (Exception e) + { + Console.WriteLine("-------------" + e.Message); + } + return response; + } + static void Main(string[] args) + { + UserModel user = new UserModel("user_id", "user_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_nameuser_name", "url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url_url"); + String msg = CommonUtil.CheckFiled(user, "user", "register"); + Console.WriteLine(msg); + Console.ReadLine(); + } + } +} diff --git a/util/HostType.cs b/util/HostType.cs new file mode 100644 index 0000000..05f61de --- /dev/null +++ b/util/HostType.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace io.rong.util +{ + class HostType + { + private String type; + + public HostType(String type) + { + this.type = type; + } + + public String Type + { + get { return this.type; } + } + } +} diff --git a/io/rong/util/RongHttpClient.cs b/util/RongHttpClient.cs similarity index 91% rename from io/rong/util/RongHttpClient.cs rename to util/RongHttpClient.cs index 2a7dd55..a6e30b8 100644 --- a/io/rong/util/RongHttpClient.cs +++ b/util/RongHttpClient.cs @@ -1,136 +1,135 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Net; -using System.Security.Cryptography; -using System.Web; -using System.IO; -using System.Net.Security; -using System.Security.Cryptography.X509Certificates; -using donet.io.rong.models; - - -namespace donet.io.rong.util { - class RongHttpClient { - - public static String ExecuteGet(string url) { - if (string.IsNullOrEmpty(url)) { - throw new ArgumentNullException("url"); - } - HttpWebRequest myRequest = WebRequest.Create(url) as HttpWebRequest; - myRequest.Method = "GET"; - myRequest.ReadWriteTimeout = 30 * 1000; - - return returnResult(myRequest); - } - - - public static String ExecutePost(String appkey, String appSecret, String methodUrl, String postStr, String contentType) { - Random rd = new Random(); - int rd_i = rd.Next(); - String nonce = Convert.ToString(rd_i); - - String timestamp = Convert.ToString(ConvertDateTimeInt(DateTime.Now)); - - String signature = GetHash(appSecret + nonce + timestamp); - - HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(methodUrl); - - myRequest.Method = "POST"; - if (contentType == null || contentType.Equals("") || contentType.Length < 10) { - myRequest.ContentType = "application/x-www-form-urlencoded"; - } else { - myRequest.ContentType = contentType; - } - myRequest.ProtocolVersion = HttpVersion.Version10; - - - myRequest.Headers.Add("App-Key", appkey); - myRequest.Headers.Add("Nonce", nonce); - myRequest.Headers.Add("Timestamp", timestamp); - myRequest.Headers.Add("Signature", signature); - myRequest.ReadWriteTimeout = 30 * 1000; - - byte[] data = Encoding.UTF8.GetBytes(postStr); - myRequest.ContentLength = data.Length; - - Stream newStream = myRequest.GetRequestStream(); - - // Send the data. - newStream.Write(data, 0, data.Length); - newStream.Close(); - - return returnResult(myRequest); - - } - - /// - /// DateTime时间格式转换为Unix时间戳格式 - /// - /// DateTime时间格式 - /// Unix时间戳格式 - public static int ConvertDateTimeInt(System.DateTime time) { - System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); - return (int)(time - startTime).TotalSeconds; - } - - public static String GetHash(String input) { - //建立SHA1对象 - SHA1 sha = new SHA1CryptoServiceProvider(); - - //将mystr转换成byte[] - UTF8Encoding enc = new UTF8Encoding(); - byte[] dataToHash = enc.GetBytes(input); - - //Hash运算 - byte[] dataHashed = sha.ComputeHash(dataToHash); - - //将运算结果转换成string - string hash = BitConverter.ToString(dataHashed).Replace("-", ""); - - return hash; - } - - /// - /// Certificate validation callback. - /// - private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { - // If the certificate is a valid, signed certificate, return true. - if (error == System.Net.Security.SslPolicyErrors.None) { - return true; - } - - Console.WriteLine("X509Certificate [{0}] Policy Error: '{1}'", - cert.Subject, - error.ToString()); - - return false; - } - - - public static string returnResult(HttpWebRequest myRequest) { - HttpWebResponse myResponse = null; - int httpStatus = 200; - string content; - try { - myResponse = (HttpWebResponse)myRequest.GetResponse(); - httpStatus = (int)myResponse.StatusCode; - StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); - - content = reader.ReadToEnd(); - } catch (WebException e) { //异常请求 - myResponse = (HttpWebResponse)e.Response; - httpStatus = (int)myResponse.StatusCode; - using (Stream errData = myResponse.GetResponseStream()) { - using (StreamReader reader = new StreamReader(errData)) { - content = reader.ReadToEnd(); - } - } - } - return content; - } - - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Net; +using System.Security.Cryptography; +using System.Web; +using System.IO; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using io.rong.models; + + +namespace io.rong.util { + class RongHttpClient { + + public static String ExecuteGet(string url) { + if (string.IsNullOrEmpty(url)) { + throw new ArgumentNullException("url"); + } + HttpWebRequest myRequest = WebRequest.Create(url) as HttpWebRequest; + myRequest.Method = "GET"; + myRequest.ReadWriteTimeout = 30 * 1000; + + return ReturnResult(myRequest); + } + + + public static String ExecutePost(String appkey, String appSecret, String postStr, String methodUrl, String contentType) { + Random rd = new Random(); + int rd_i = rd.Next(); + String nonce = Convert.ToString(rd_i); + + String timestamp = Convert.ToString(ConvertDateTimeInt(DateTime.Now)); + + String signature = GetHash(appSecret + nonce + timestamp); + + HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(methodUrl); + + myRequest.Method = "POST"; + if (contentType == null || contentType.Equals("") || contentType.Length < 10) { + myRequest.ContentType = "application/x-www-form-urlencoded"; + } else { + myRequest.ContentType = contentType; + } + myRequest.ProtocolVersion = HttpVersion.Version10; + + myRequest.Headers.Add("App-Key", appkey); + myRequest.Headers.Add("Nonce", nonce); + myRequest.Headers.Add("Timestamp", timestamp); + myRequest.Headers.Add("Signature", signature); + myRequest.ReadWriteTimeout = 30 * 1000; + + byte[] data = Encoding.UTF8.GetBytes(postStr); + myRequest.ContentLength = data.Length; + + Stream newStream = myRequest.GetRequestStream(); + + // Send the data. + newStream.Write(data, 0, data.Length); + newStream.Close(); + + return ReturnResult(myRequest); + + } + + /// + /// DateTime时间格式转换为Unix时间戳格式 + /// + /// DateTime时间格式 + /// Unix时间戳格式 + public static int ConvertDateTimeInt(System.DateTime time) { + System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); + return (int)(time - startTime).TotalSeconds; + } + + public static String GetHash(String input) { + //建立SHA1对象 + SHA1 sha = new SHA1CryptoServiceProvider(); + + //将mystr转换成byte[] + UTF8Encoding enc = new UTF8Encoding(); + byte[] dataToHash = enc.GetBytes(input); + + //Hash运算 + byte[] dataHashed = sha.ComputeHash(dataToHash); + + //将运算结果转换成string + string hash = BitConverter.ToString(dataHashed).Replace("-", ""); + + return hash; + } + + /// + /// Certificate validation callback. + /// + private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { + // If the certificate is a valid, signed certificate, return true. + if (error == System.Net.Security.SslPolicyErrors.None) { + return true; + } + + Console.WriteLine("X509Certificate [{0}] Policy Error: '{1}'", + cert.Subject, + error.ToString()); + + return false; + } + + + public static string ReturnResult(HttpWebRequest myRequest) { + HttpWebResponse myResponse = null; + int httpStatus = 200; + string content; + try { + myResponse = (HttpWebResponse)myRequest.GetResponse(); + httpStatus = (int)myResponse.StatusCode; + StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); + + content = reader.ReadToEnd(); + } catch (WebException e) { //异常请求 + myResponse = (HttpWebResponse)e.Response; + httpStatus = (int)myResponse.StatusCode; + using (Stream errData = myResponse.GetResponseStream()) { + using (StreamReader reader = new StreamReader(errData)) { + content = reader.ReadToEnd(); + } + } + } + return content; + } + + } +} diff --git a/io/rong/util/RongJsonUtil.cs b/util/RongJsonUtil.cs similarity index 89% rename from io/rong/util/RongJsonUtil.cs rename to util/RongJsonUtil.cs index 3ff0368..452d432 100644 --- a/io/rong/util/RongJsonUtil.cs +++ b/util/RongJsonUtil.cs @@ -1,7 +1,7 @@ using System; using Newtonsoft.Json; -namespace donet.io.rong.util { +namespace io.rong.util { class RongJsonUtil { public static ObjType JsonStringToObj(string JsonString) where ObjType : class { ObjType s = JsonConvert.DeserializeObject(JsonString);