Skip to content

Commit

Permalink
#1507 добавляет GroupIdConverter, SecretConverter, UpdateTypeConverte…
Browse files Browse the repository at this point in the history
…r, обновляет GroupUpdatesConverter для поддержки Callback API (#1508)

* "#1507 добавляет CallbackGroupUpdatesConverter, GroupIdConverter, SecretConverter, UpdateTypeConverter"

* #1507 Заставить работать и для LongPoll

* Мелкие изменения
  • Loading branch information
justmavi authored Apr 26, 2023
1 parent e5ef1b3 commit 380c56c
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 106 deletions.
4 changes: 1 addition & 3 deletions VkNet/Model/BotsLongPollHistoryResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ public class BotsLongPollHistoryResponse
/// <summary>
/// Номер последнего события, начиная с которого нужно получать данные;
/// </summary>
[JsonProperty("ts")]
public string Ts { get; set; }

/// <summary>
/// Обновления группы
/// </summary>
[JsonConverter(typeof(GroupUpdateJsonConverter))]
[JsonProperty("updates")]
[JsonProperty(ItemConverterType = typeof(GroupUpdateJsonConverter))]
public List<GroupUpdate.GroupUpdate> Updates { get; set; }
}
5 changes: 4 additions & 1 deletion VkNet/Model/GroupUpdate/GroupUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Newtonsoft.Json;
using VkNet.Enums.SafetyEnums;
using VkNet.Utils;
using VkNet.Utils.JsonConverter;

namespace VkNet.Model.GroupUpdate;

Expand All @@ -19,18 +20,20 @@ public class GroupUpdate
/// <summary>
/// Тип обновления
/// </summary>
[JsonConverter(typeof(UpdateTypeConverter))]
public UpdateType Type { get; set; }

/// <summary>
/// ID группы
/// </summary>
[JsonProperty("group_id")]
[JsonConverter(typeof(GroupIdConverter))]
public GroupId GroupId { get; set; }

/// <summary>
/// <c>Secret Key</c> для Callback
/// </summary>
[JsonProperty("secret")]
[JsonConverter(typeof(SecretConverter))]
public Secret Secret { get; set; }

/// <summary>
Expand Down
25 changes: 25 additions & 0 deletions VkNet/Utils/JsonConverter/GroupIdConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json;
using System;
using VkNet.Model.GroupUpdate;

namespace VkNet.Utils.JsonConverter;

/// <inheritdoc />
public class GroupIdConverter : JsonConverter<GroupId>
{
/// <inheritdoc />
public override GroupId ReadJson(JsonReader reader, Type objectType, GroupId existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.Value == null)
return null;

var id = Convert.ToUInt64(reader.Value);
return new GroupId(id);
}

/// <inheritdoc />
public override void WriteJson(JsonWriter writer, GroupId value, JsonSerializer serializer)
{
writer.WriteValue(value?.Value);
}
}
154 changes: 52 additions & 102 deletions VkNet/Utils/JsonConverter/GroupUpdateJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using VkNet.Enums.SafetyEnums;
using VkNet.Infrastructure;
using VkNet.Model;
using VkNet.Model.Attachments;
Expand All @@ -26,115 +22,69 @@ public class GroupUpdateJsonConverter : Newtonsoft.Json.JsonConverter
/// <exception cref="T:System.TypeAccessException"> </exception>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (!objectType.IsGenericType)
{
throw new TypeAccessException();
}

if (reader.TokenType == JsonToken.Null)
{
return null;
}

if (reader.TokenType != JsonToken.StartArray)
{
return null;
}

var keyType = objectType.GetGenericArguments()[0];

var constructedListType = typeof(List<>).MakeGenericType(keyType);

var list = (IList) Activator.CreateInstance(type: constructedListType);

var obj = JArray.Load(reader: reader);

foreach (var item in obj)
{
var resObj = item["object"].ToString();
var resObj1 = resObj.Contains("client_info");

var type = item["type"]
.ToString();

var groupUpdate = type switch
{
"message_new" or "message_edit" or "message_reply" => resObj1
? CreateTyped(JsonConvert.DeserializeObject<MessageNew>(resObj))
: CreateTyped(JsonConvert.DeserializeObject<Message>(resObj)),
"message_allow" => CreateTyped(JsonConvert.DeserializeObject<MessageAllow>(resObj)),
"message_typing_state" => CreateTyped(JsonConvert.DeserializeObject<MessageTypingState>(resObj)),
"vkpay_transaction" => CreateTyped(JsonConvert.DeserializeObject<VkPayTransaction>(resObj)),
"like_add" => CreateTyped(JsonConvert.DeserializeObject<LikeAdd>(resObj)),
"like_remove" => CreateTyped(JsonConvert.DeserializeObject<LikeRemove>(resObj)),
"group_change_settings" => CreateTyped(JsonConvert.DeserializeObject<GroupChangeSettings>(resObj)),
"message_deny" => CreateTyped(JsonConvert.DeserializeObject<MessageDeny>(resObj)),
"photo_new" => CreateTyped(JsonConvert.DeserializeObject<Photo>(resObj)),
"photo_comment_new" or "photo_comment_edit" or "photo_comment_restore" => CreateTyped(JsonConvert.DeserializeObject<PhotoComment>(resObj)),
"photo_comment_delete" => CreateTyped(JsonConvert.DeserializeObject<PhotoCommentDelete>(resObj)),
"audio_new" => CreateTyped(JsonConvert.DeserializeObject<Audio>(resObj)),
"video_new" => CreateTyped(JsonConvert.DeserializeObject<Video>(resObj)),
"video_comment_new" or "video_comment_edit" or "video_comment_restore" => CreateTyped(JsonConvert.DeserializeObject<VideoComment>(resObj)),
"video_comment_delete" => CreateTyped(JsonConvert.DeserializeObject<VideoCommentDelete>(resObj)),
"wall_post_new" or "wall_repost" => CreateTyped(JsonConvert.DeserializeObject<WallPost>(resObj)),
"market_comment_new" or "market_comment_edit" or "market_comment_restore" =>
CreateTyped(JsonConvert.DeserializeObject<VkNet.Model.GroupUpdate.MarketComment>(resObj)),
"wall_reply_new" or "wall_reply_edit" or "wall_reply_restore" =>
CreateTyped(JsonConvert.DeserializeObject<VkNet.Model.GroupUpdate.WallReply>(resObj)),
"wall_reply_delete" => CreateTyped(JsonConvert.DeserializeObject<WallReplyDelete>(resObj)),
"board_post_new" or "board_post_edit" or "board_post_restore" => CreateTyped(JsonConvert.DeserializeObject<BoardPost>(resObj)),
"board_post_delete" => CreateTyped(JsonConvert.DeserializeObject<BoardPostDelete>(resObj)),
"market_comment_delete" => CreateTyped(JsonConvert.DeserializeObject<MarketCommentDelete>(resObj)),
"group_leave" => CreateTyped(JsonConvert.DeserializeObject<GroupLeave>(resObj)),
"group_join" => CreateTyped(JsonConvert.DeserializeObject<GroupJoin>(resObj)),
"user_block" => CreateTyped(JsonConvert.DeserializeObject<UserBlock>(resObj)),
"user_unblock" => CreateTyped(JsonConvert.DeserializeObject<UserUnblock>(resObj)),
"poll_vote_new" => CreateTyped(JsonConvert.DeserializeObject<PollVoteNew>(resObj)),
"group_change_photo" => CreateTyped(JsonConvert.DeserializeObject<GroupChangePhoto>(resObj)),
"group_officers_edit" => CreateTyped(JsonConvert.DeserializeObject<GroupOfficersEdit>(resObj)),
"message_event" => CreateTyped(JsonConvert.DeserializeObject<MessageEvent>(resObj)),
"donut_subscription_create" or "donut_subscription_prolonged" => CreateTyped(JsonConvert.DeserializeObject<DonutNew>(resObj)),
"donut_subscription_cancelled" or "donut_subscription_expired" => CreateTyped(JsonConvert.DeserializeObject<DonutEnd>(resObj)),
"donut_subscription_price_changed" => CreateTyped(JsonConvert.DeserializeObject<DonutChanged>(resObj)),
"donut_money_withdraw" or "donut_money_withdraw_error" => CreateTyped(JsonConvert.DeserializeObject<DonutWithdraw>(resObj)),
"market_order_new" => CreateTyped(JsonConvert.DeserializeObject<MarketOrder>(resObj)),
"market_order_edit" => CreateTyped(JsonConvert.DeserializeObject<MarketOrder>(resObj)),
"app_payload" => CreateTyped(JsonConvert.DeserializeObject<AppPayload>(resObj)),
var obj = JObject.Load(reader: reader);

_ => JsonConvert.DeserializeObject<GroupUpdate>(item.ToString(), JsonConfigure.JsonSerializerSettings)
};
var resObj = obj["object"]?.ToString();
var resObj1 = resObj?.Contains("client_info");
var type = obj["type"].ToString();

groupUpdate.Raw = JsonConvert.DeserializeObject<VkResponse>(item.ToString());
groupUpdate.Type = new(Utilities.Deserialize<GroupUpdateType>(groupUpdate.Instance.ToString()).GetValueOrDefault());
groupUpdate.GroupId = new(Convert.ToUInt64(item["group_id"]));

if (item["secret"] is not null)
{
groupUpdate.Secret = new(item["secret"]
.ToString());
}

list.Add(groupUpdate);
}
var groupUpdate = JsonConvert.DeserializeObject<GroupUpdate>(obj.ToString(), JsonConfigure.JsonSerializerSettings);

return list;
}

#region Приватные методы

private static GroupUpdate CreateTyped<TGroupUpdate>(TGroupUpdate instance)
where TGroupUpdate : IGroupUpdate
{
var update = new GroupUpdate
groupUpdate.Instance = type switch
{
Instance = instance
"message_new" or "message_edit" or "message_reply" => resObj1!.Value
? JsonConvert.DeserializeObject<MessageNew>(resObj)
: JsonConvert.DeserializeObject<Message>(resObj),
"message_allow" => JsonConvert.DeserializeObject<MessageAllow>(resObj),
"message_typing_state" => JsonConvert.DeserializeObject<MessageTypingState>(resObj),
"vkpay_transaction" => JsonConvert.DeserializeObject<VkPayTransaction>(resObj),
"like_add" => JsonConvert.DeserializeObject<LikeAdd>(resObj),
"like_remove" => JsonConvert.DeserializeObject<LikeRemove>(resObj),
"group_change_settings" => JsonConvert.DeserializeObject<GroupChangeSettings>(resObj),
"message_deny" => JsonConvert.DeserializeObject<MessageDeny>(resObj),
"photo_new" => JsonConvert.DeserializeObject<Photo>(resObj),
"photo_comment_new" or "photo_comment_edit" or "photo_comment_restore" => JsonConvert.DeserializeObject<PhotoComment>(resObj),
"photo_comment_delete" => JsonConvert.DeserializeObject<PhotoCommentDelete>(resObj),
"audio_new" => JsonConvert.DeserializeObject<Audio>(resObj),
"video_new" => JsonConvert.DeserializeObject<Video>(resObj),
"video_comment_new" or "video_comment_edit" or "video_comment_restore" => JsonConvert.DeserializeObject<VideoComment>(resObj),
"video_comment_delete" => JsonConvert.DeserializeObject<VideoCommentDelete>(resObj),
"wall_post_new" or "wall_repost" => JsonConvert.DeserializeObject<WallPost>(resObj),
"market_comment_new" or "market_comment_edit" or "market_comment_restore" =>
JsonConvert.DeserializeObject<Model.GroupUpdate.MarketComment>(resObj),
"wall_reply_new" or "wall_reply_edit" or "wall_reply_restore" =>
JsonConvert.DeserializeObject<Model.GroupUpdate.WallReply>(resObj),
"wall_reply_delete" => JsonConvert.DeserializeObject<WallReplyDelete>(resObj),
"board_post_new" or "board_post_edit" or "board_post_restore" => JsonConvert.DeserializeObject<BoardPost>(resObj),
"board_post_delete" => JsonConvert.DeserializeObject<BoardPostDelete>(resObj),
"market_comment_delete" => JsonConvert.DeserializeObject<MarketCommentDelete>(resObj),
"group_leave" => JsonConvert.DeserializeObject<GroupLeave>(resObj),
"group_join" => JsonConvert.DeserializeObject<GroupJoin>(resObj),
"user_block" => JsonConvert.DeserializeObject<UserBlock>(resObj),
"user_unblock" => JsonConvert.DeserializeObject<UserUnblock>(resObj),
"poll_vote_new" => JsonConvert.DeserializeObject<PollVoteNew>(resObj),
"group_change_photo" => JsonConvert.DeserializeObject<GroupChangePhoto>(resObj),
"group_officers_edit" => JsonConvert.DeserializeObject<GroupOfficersEdit>(resObj),
"message_event" => JsonConvert.DeserializeObject<MessageEvent>(resObj),
"donut_subscription_create" or "donut_subscription_prolonged" => JsonConvert.DeserializeObject<DonutNew>(resObj),
"donut_subscription_cancelled" or "donut_subscription_expired" => JsonConvert.DeserializeObject<DonutEnd>(resObj),
"donut_subscription_price_changed" => JsonConvert.DeserializeObject<DonutChanged>(resObj),
"donut_money_withdraw" or "donut_money_withdraw_error" => JsonConvert.DeserializeObject<DonutWithdraw>(resObj),
"market_order_new" => JsonConvert.DeserializeObject<MarketOrder>(resObj),
"market_order_edit" => JsonConvert.DeserializeObject<MarketOrder>(resObj),
"app_payload" => JsonConvert.DeserializeObject<AppPayload>(resObj),
_ => null
};
groupUpdate.Raw = JsonConvert.DeserializeObject<VkResponse>(obj.ToString());

return update;
return groupUpdate;
}

#endregion

/// <inheritdoc />
public override bool CanConvert(Type objectType) => typeof(ReadOnlyCollection<>).IsAssignableFrom(c: objectType);
public override bool CanConvert(Type objectType) => typeof(GroupUpdate).IsAssignableFrom(c: objectType);
}
24 changes: 24 additions & 0 deletions VkNet/Utils/JsonConverter/SecretConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Newtonsoft.Json;
using System;
using VkNet.Model.GroupUpdate;

namespace VkNet.Utils.JsonConverter;

/// <inheritdoc />
public class SecretConverter : JsonConverter<Secret>
{
/// <inheritdoc />
public override Secret ReadJson(JsonReader reader, Type objectType, Secret existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.Value == null)
return null;

return new Secret(reader.Value.ToString());
}

/// <inheritdoc />
public override void WriteJson(JsonWriter writer, Secret value, JsonSerializer serializer)
{
writer.WriteValue(value?.Value);
}
}
31 changes: 31 additions & 0 deletions VkNet/Utils/JsonConverter/UpdateTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Newtonsoft.Json;
using System;
using System.Globalization;
using VkNet.Enums.SafetyEnums;
using VkNet.Model.GroupUpdate;

namespace VkNet.Utils.JsonConverter;

/// <inheritdoc />
public class UpdateTypeConverter : JsonConverter<UpdateType>
{
/// <inheritdoc />
public override UpdateType ReadJson(JsonReader reader, Type objectType, UpdateType existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.Value == null)
return null;

var info = CultureInfo.CurrentCulture.TextInfo;

var groupUpdateTypeStr = reader.Value.ToString().ToLower().Replace("_", " ");
groupUpdateTypeStr = info.ToTitleCase(groupUpdateTypeStr).Replace(" ", string.Empty);

return new UpdateType(Utilities.Deserialize<GroupUpdateType>(groupUpdateTypeStr).Value);
}

/// <inheritdoc />
public override void WriteJson(JsonWriter writer, UpdateType value, JsonSerializer serializer)
{
writer.WriteValue(value?.Value);
}
}

0 comments on commit 380c56c

Please sign in to comment.