8000 Merge pull request #169 from notion-dotnet/feature/168-add-support-to… · hognevevle/notion-sdk-net@12bc6ab · GitHub
[go: up one dir, main page]

Skip to content

Commit 12bc6ab

Browse files
Merge pull request notion-dotnet#169 from notion-dotnet/feature/168-add-support-to-retrieve-bot-user-assigned-to-a-token
Add support to retrieve bot user assigned to a token ✨
2 parents ce76079 + 51f4876 commit 12bc6ab

File tree

15 files changed

+192
-12
lines changed

15 files changed

+192
-12
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ var complexFiler = new CompoundFilter(
117117
- [x] Users
118118
- [x] Retrieve a User
119119
- [x] List all users
120+
- [x] Retrieve your token's bot user
120121
- [x] Search
121122

122123
## Contribution Guideline

Src/Notion.Client/Api/ApiEndpoints.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace Notion.Client
1+
using System;
2+
3+
namespace Notion.Client
24
{
35
public static class ApiEndpoints
46
{
@@ -15,6 +17,12 @@ public static class UsersApiUrls
1517
{
1618
public static string Retrieve(string userId) => $"/v1/users/{userId}";
1719
public static string List() => "/v1/users";
20+
21+
/// <summary>
22+
/// Get the <see cref="uri string"/> for retrieve your token's bot user.
23+
/// </summary>
24+
/// <returns>Returns a <see cref="uri string"/> retrieve your token's bot user.</returns>
25+
public static string Me() => "/v1/users/me";
1826
}
1927

2028
public static class BlocksApiUrls

Src/Notion.Client/Api/Users/IUsersClient.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,11 @@ public interface IUsersClient
66
{
77
Task<User> RetrieveAsync(string userId);
88
Task<PaginatedList<User>> ListAsync();
9+
10+
/// <summary>
11+
/// Retrieves the bot User associated with the API token provided in the authorization header.
12+
/// </summary>
13+
/// <returns>User object of type bot having an owner field with information about the person who authorized the integration.</returns>
14+
Task<User> MeAsync();
915
}
1016
}

Src/Notion.Client/Api/Users/UsersClient.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,14 @@ public async Task<PaginatedList<User>> ListAsync()
2121
{
2222
return await _client.GetAsync<PaginatedList<User>>(UsersApiUrls.List());
2323
}
24+
25+
/// <summary>
26+
/// Retrieves the bot User associated with the API token provided in the authorization header.
27+
/// </summary>
28+
/// <returns>User object of type bot having an owner field with information about the person who authorized the integration.</returns>
29+
public async Task<User> MeAsync()
30+
{
31+
return await _client.GetAsync<User>(UsersApiUrls.Me());
32+
}
2433
}
2534
}

Src/Notion.Client/Models/User/Bot.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class Bot
6+
{
7+
[JsonProperty("owner")]
8+
public IBotOwner Owner { get; set; }
9+
}
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using JsonSubTypes;
2+
using Newtonsoft.Json;
3+
4+
namespace Notion.Client
5+
{
6+
[JsonConverter(typeof(JsonSubtypes), "type")]
7+
[JsonSubtypes.KnownSubType(typeof(UserOwner), "user")]
8+
[JsonSubtypes.KnownSubType(typeof(WorkspaceIntegrationOwner), "workspace")]
9+
public interface IBotOwner
10+
{
11+
[JsonProperty("type")]
12+
string Type { get; set; }
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class UserOwner : IBotOwner
6+
{
7+
public string Type { get; set; }
8+
9+
[JsonProperty("user")]
10+
public User User { get; set; }
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class WorkspaceIntegrationOwner : IBotOwner
6+
{
7+
public string Type { get; set; }
8+
9+
[JsonProperty("workspace")]
10+
public bool Workspace { get; set; }
11+
}
12+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Notion.Client
4+
{
5+
public class Person
6+
{
7+
[JsonProperty("email")]
8+
public string Email { get; set; }
9+
}
10+
}

Src/Notion.Client/Models/User.cs renamed to Src/Notion.Client/Models/User/User.cs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,4 @@ public class User : IObject
2222
[JsonProperty("bot")]
2323
public Bot Bot { get; set; }
2424
}
25-
26-
public class Person
27-
{
28-
[JsonProperty("email")]
29-
public string Email { get; set; }
30-
}
31-
32-
public class Bot
33-
{
34-
35-
}
3625
}

Test/Notion.UnitTests/Notion.UnitTests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@
8181
<None Update="data\users\RetrieveUserResponse.json">
8282
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
8383
</None>
84+
<None Update="data\users\MeResponse.json">
85+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
86+
</None>
87+
<None Update="data\users\MeUserLevelResponse.json">
88+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
89+
</None>
8490
<None Update="data\search\SearchResponse.json">
8591
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
8692
</None>

Test/Notion.UnitTests/UserClientTest.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,72 @@ public async Task RetrieveUser()
7878
user.Person.Email.Should().Be("vedkoditkar@gmail.com");
7979
user.Bot.Should().BeNull();
8080
}
81+
82+
[Fact]
83+
public async Task RetrieveTokenUser_WorkspaceInternalToken()
84+
{
85+
// Arrange
86+
var jsonData = await File.ReadAllTextAsync("data/users/MeResponse.json");
87+
88+
var path = ApiEndpoints.UsersApiUrls.Me();
89+
90+
Server.Given(CreateGetRequestBuilder(path))
91+
.RespondWith(
92+
Response.Create()
93+
.WithStatusCode(200)
94+
.WithBody(jsonData)
95+
);
96+
97+
// Act
98+
var user = await _client.MeAsync();
99+
100+
// Assert
101+
user.Id.Should().Be("590693f3-797f-4970-98ff-7284106393e5");
102+
user.Name.Should().Be("Test");
103+
user.AvatarUrl.Should().BeNull();
104+
user.Type.Should().Be("bot");
105+
user.Person.Should().BeNull();
106+
user.Bot.Should().NotBeNull();
107+
user.Bot.Owner.Should().BeOfType<WorkspaceIntegrationOwner>();
108+
109+
var owner = (WorkspaceIntegrationOwner)user.Bot.Owner;
110+
owner.Workspace.Should().BeTrue();
111+
}
112+
113+
[Fact]
114+
public async Task RetrieveTokenUser_UserLevelToken()
115+
{
116+
// Arrange
117+
var jsonData = await File.ReadAllTextAsync("data/users/MeUserLevelResponse.json");
118+
119+
var path = ApiEndpoints.UsersApiUrls.Me();
120+
121+
Server.Given(CreateGetRequestBuilder(path))
122+
.RespondWith(
123+
Response.Create()
124+
.WithStatusCode(200)
125+
.WithBody(jsonData)
126+
);
127+
128+
// Act
129+
var user = await _client.MeAsync();
130+
131+
// Assert
132+
user.Id.Should().Be("16d84278-ab0e-484c-9bdd-b35da3bd8905");
133+
user.Name.Should().Be("pied piper");
134+
user.AvatarUrl.Should().BeNull();
135+
user.Type.Should().Be("bot");
136+
user.Person.Should().BeNull();
137+
user.Bot.Should().NotBeNull();
138+
user.Bot.Owner.Should().BeOfType<UserOwner>();
139+
140+
var owner = (UserOwner)user.Bot.Owner;
141+
owner.User.Id.Should().Be("5389a034-eb5c-47b5-8a9e-f79c99ef166c");
142+
owner.User.Name.Should().Be("christine makenotion");
143+
owner.User.AvatarUrl.Should().BeNull();
144+
owner.User.Type.Should().Be("person");
145+
owner.User.Person.Email.Should().Be("christine@makenotion.com");
146+
owner.User.Bot.Should().BeNull();
147+
}
81148
}
82149
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"object": "user",
3+
"id": "590693f3-797f-4970-98ff-7284106393e5",
4+
"name": "Test",
5+
"avatar_url": null,
6+
"type": "bot",
7+
"bot": {
8+
"owner": {
9+
"type": "workspace",
10+
"workspace": true
11+
}
12+
}
13+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"object": "user",
3+
"id": "16d84278-ab0e-484c-9bdd-b35da3bd8905",
4+
"name": "pied piper",
5+
"avatar_url": null,
6+
"type": "bot",
7+
"bot": {
8+
"owner": {
9+
"type": "user",
10+
"user": {
11+
"object": "user",
12+
"id": "5389a034-eb5c-47b5-8a9e-f79c99ef166c",
13+
"name": "christine makenotion",
14+
"avatar_url": null,
15+
"type": "person",
16+
"person": {
17+
"email": "christine@makenotion.com"
18+
}
19+
}
20+
}
21+
}
22+
}

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ var complexFiler = new CompoundFilter(
8484
- [x] Users
8585
- [x] Retrieve a User
8686
- [x] List all users
87+
- [x] Retrieve your token's bot user
8788
- [x] Search
8889

8990
## Contribution Guideline

0 commit comments

Comments
 (0)
0