Skip to content

Commit 3347465

Browse files
add fetch block children api 💬
1 parent 9d7967a commit 3347465

File tree

5 files changed

+284
-1
lines changed

5 files changed

+284
-1
lines changed

Src/Notion.Client/Api/ApiEndpoints.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,10 @@ public static class UsersApiUrls
1414
public static string Retrieve(string userId) => $"/v1/users/{userId}";
1515
public static string List() => "/v1/users";
1616
}
17+
18+
public static class BlocksApiUrls
19+
{
20+
public static string RetrieveChildren(string blockId) => $"/v1/blocks/{blockId}/children";
21+
}
1722
}
1823
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using static Notion.Client.ApiEndpoints;
5+
6+
namespace Notion.Client
7+
{
8+
public interface IBlocksClient
9+
{
10+
Task<PaginatedList<BlockBase>> RetrieveChildrenAsync(string blockId, BlockRetrieveChildrenParameters parameters = null);
11+
}
12+
13+
public class BlocksClient : IBlocksClient
14+
{
15+
private readonly IRestClient _client;
16+
17+
public BlocksClient(IRestClient client)
18+
{
19+
_client = client;
20+
}
21+
22+
public async Task<PaginatedList<BlockBase>> RetrieveChildrenAsync(string blockId, BlockRetrieveChildrenParameters parameters = null)
23+
{
24+
if (string.IsNullOrWhiteSpace(blockId))
25+
{
26+
throw new ArgumentNullException(nameof(blockId));
27+
}
28+
29+
var url = BlocksApiUrls.RetrieveChildren(blockId);
30+
31+
var queryParameters = (IBlockRetrieveChildrenQueryParameters)parameters;
32+
33+
var queryParams = new Dictionary<string, string>()
34+
{
35+
{ "start_cursor", queryParameters?.StartCursor?.ToString() },
36+
{ "page_size", queryParameters?.PageSize?.ToString() }
37+
};
38+
39+
return await _client.GetAsync<PaginatedList<BlockBase>>(url, queryParams);
40+
}
41+
}
42+
43+
public interface IBlockRetrieveChildrenQueryParameters : IPaginationParameters
44+
{
45+
}
46+
47+
public interface IBlockRetrieveChildrenParameters : IBlockRetrieveChildrenQueryParameters
48+
{
49+
}
50+
51+
public class BlockRetrieveChildrenParameters : IBlockRetrieveChildrenParameters
52+
{
53+
public string StartCursor { get; set; }
54+
public string PageSize { get; set; }
55+
}
56+
}

Src/Notion.Client/Models/Block.cs

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
using System.Collections.Generic;
2+
using System.Runtime.Serialization;
3+
using JsonSubTypes;
4+
using Newtonsoft.Json;
5+
using Newtonsoft.Json.Converters;
6+
7+
namespace Notion.Client
8+
{
9+
[JsonConverter(typeof(JsonSubtypes), "type")]
10+
[JsonSubtypes.KnownSubType(typeof(BulletedListItemBlock), BlockType.BulletedListItem)]
11+
[JsonSubtypes.KnownSubType(typeof(ChildPageBlock), BlockType.ChildPage)]
12+
[JsonSubtypes.KnownSubType(typeof(HeadingOneBlock), BlockType.Heading_1)]
13+
[JsonSubtypes.KnownSubType(typeof(HeadingTwoBlock), BlockType.Heading_2)]
14+
[JsonSubtypes.KnownSubType(typeof(HeadingThreeeBlock), BlockType.Heading_3)]
15+
[JsonSubtypes.KnownSubType(typeof(NumberedListItemBlock), BlockType.NumberedListItem)]
16+
[JsonSubtypes.KnownSubType(typeof(ParagraphBlock), BlockType.Paragraph)]
17+
[JsonSubtypes.KnownSubType(typeof(ToDoBlock), BlockType.ToDo)]
18+
[JsonSubtypes.KnownSubType(typeof(ToggleBlock), BlockType.Toggle)]
19+
[JsonSubtypes.KnownSubType(typeof(UnsupportedBlock), BlockType.Unsupported)]
20+
public class BlockBase
21+
{
22+
public string Object => "block";
23+
public string Id { get; set; }
24+
25+
[JsonConverter(typeof(StringEnumConverter))]
26+
public BlockType Type { get; set; }
27+
28+
[JsonProperty("created_time")]
29+
public string CreatedTime { get; set; }
30+
31+
32+
[JsonProperty("last_edited_time")]
33+
public string LastEditedTime { get; set; }
34+
35+
36+
[JsonProperty("has_children")]
37+
public virtual bool HasChildren { get; set; }
38+
39+
}
40+
41+
public class ParagraphBlock : BlockBase
42+
{
43+
public ParagraphClass Paragraph { get; set; }
44+
45+
public class ParagraphClass
46+
{
47+
public IEnumerable<RichTextBase> Text { get; set; }
48+
public IEnumerable<BlockBase> Children { get; set; }
49+
}
50+
}
51+
52+
public class HeadingOneBlock : BlockBase
53+
{
54+
[JsonProperty("heading_1")]
55+
public HeadingOneClass Heading_1 { get; set; }
56+
57+
public override bool HasChildren => false;
58+
59+
public class HeadingOneClass
60+
{
61+
public IEnumerable<RichTextBase> Text { get; set; }
62+
}
63+
}
64+
65+
public class HeadingTwoBlock : BlockBase
66+
{
67+
[JsonProperty("heading_2")]
68+
public HeadingTwoClass Heading_2 { get; set; }
69+
70+
public override bool HasChildren => false;
71+
72+
public class HeadingTwoClass
73+
{
74+
public IEnumerable<RichTextBase> Text { get; set; }
75+
}
76+
}
77+
78+
public class HeadingThreeeBlock : BlockBase
79+
{
80+
[JsonProperty("heading_3")]
81+
public HeadingThreeClass Heading_3 { get; set; }
82+
83+
public override bool HasChildren => false;
84+
85+
public class HeadingThreeClass
86+
{
87+
public IEnumerable<RichTextBase> Text { get; set; }
88+
}
89+
}
90+
91+
public class BulletedListItemBlock : BlockBase
92+
{
93+
[JsonProperty("bulleted_list_item")]
94+
public BulletedListItemClass BulletedListItem { get; set; }
95+
96+
public class BulletedListItemClass
97+
{
98+
public IEnumerable<RichTextBase> Text { get; set; }
99+
public IEnumerable<BlockBase> Children { get; set; }
100+
}
101+
}
102+
103+
public class NumberedListItemBlock : BlockBase
104+
{
105+
106+
[JsonProperty("numbered_list_item")]
107+
public NumberedListItemClass NumberedListItem { get; set; }
108+
109+
public class NumberedListItemClass
110+
{
111+
public IEnumerable<RichTextBase> Text { get; set; }
112+
public IEnumerable<BlockBase> Children { get; set; }
113+
}
114+
}
115+
116+
public class ToDoBlock : BlockBase
117+
{
118+
[JsonProperty("to_do")]
119+
public ToDoClass ToDo { get; set; }
120+
121+
public class ToDoClass
122+
{
123+
public IEnumerable<RichTextBase> Text { get; set; }
124+
125+
[JsonProperty("checked")]
126+
public bool IsChecked { get; set; }
127+
128+
public IEnumerable<BlockBase> Children { get; set; }
129+
}
130+
}
131+
132+
public class ToggleBlock : BlockBase
133+
{
134+
public ToggleClass Toggle { get; set; }
135+
136+
public class ToggleClass
137+
{
138+
public IEnumerable<RichTextBase> Text { get; set; }
139+
public IEnumerable<BlockBase> Children { get; set; }
140+
}
141+
}
142+
143+
public class ChildPageBlock : BlockBase
144+
{
145+
146+
[JsonProperty("child_page")]
147+
public ChildPageClass ChildPage { get; set; }
148+
149+
public class ChildPageClass
150+
{
151+
public string Title { get; set; }
152+
}
153+
}
154+
155+
public class UnsupportedBlock : BlockBase
156+
{
157+
}
158+
159+
public enum BlockType
160+
{
161+
[EnumMember(Value = "paragraph")]
162+
Paragraph,
163+
164+
[EnumMember(Value = "heading_1")]
165+
Heading_1,
166+
167+
[EnumMember(Value = "heading_2")]
168+
Heading_2,
169+
170+
[EnumMember(Value = "heading_3")]
171+
Heading_3,
172+
173+
[EnumMember(Value = "bulleted_list_item")]
174+
BulletedListItem,
175+
176+
[EnumMember(Value = "numbered_list_item")]
177+
NumberedListItem,
178+
179+
[EnumMember(Value = "to_do")]
180+
ToDo,
181+
182+
[EnumMember(Value = "toggle")]
183+
Toggle,
184+
185+
[EnumMember(Value = "child_page")]
186+
ChildPage,
187+
188+
[EnumMember(Value = "unsupported")]
189+
Unsupported
190+
}
191+
}

Src/Notion.Client/Models/PaginatedList.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public interface IPaginationParameters
1111

1212
public class PaginatedList<T>
1313
{
14-
public const string Object = "List";
14+
public const string Object = "list";
1515

1616
public List<T> Results { get; set; }
1717

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Threading.Tasks;
2+
using Notion.Client;
3+
using Xunit;
4+
5+
namespace Notion.UnitTests
6+
{
7+
public class BlocksClientTests
8+
{
9+
private readonly IBlocksClient _client;
10+
11+
public BlocksClientTests()
12+
{
13+
var options = new ClientOptions()
14+
{
15+
AuthToken = "<Token>"
16+
};
17+
18+
_client = new BlocksClient(new RestClient(options));
19+
}
20+
21+
[Fact(Skip ="Dev only")]
22+
public async Task RetrieveBlockChildren()
23+
{
24+
string blockId = "3c357473-a281-49a4-88c0-10d2b245a589";
25+
26+
var children = await _client.RetrieveChildrenAsync(blockId, new BlockRetrieveChildrenParameters());
27+
28+
Assert.NotNull(children);
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)