Repository: jomei/notionapi
Pull request #123 (2023-01-05 17:04:53)

Add user-me-Method for bots
You can find out the ID of the current bot here by calling the `/users/me` endpoint.

https://developers.notion.com/reference/get-self


Patch:
diff --git a/user.go b/user.go
index 1ba6de9..14b8ef4 100644
--- a/user.go
+++ b/user.go
@@ -17,6 +17,7 @@ func (uID UserID) String() string {
 type UserService interface {
 	Get(context.Context, UserID) (*User, error)
 	List(context.Context, *Pagination) (*UsersListResponse, error)
+	Me(context.Context) (*User, error)
 }
 
 type UserClient struct {
@@ -67,6 +68,28 @@ func (uc *UserClient) List(ctx context.Context, pagination *Pagination) (*UsersL
 	return &response, nil
 }
 
+// Me https://developers.notion.com/reference/get-self
+func (uc *UserClient) Me(ctx context.Context) (*User, error) {
+	res, err := uc.apiClient.request(ctx, http.MethodGet, "users/me", nil, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	defer func() {
+		if errClose := res.Body.Close(); errClose != nil {
+			log.Println("failed to close body, should never happen")
+		}
+	}()
+
+	var response User
+	err = json.NewDecoder(res.Body).Decode(&response)
+	if err != nil {
+		return nil, err
+	}
+
+	return &response, nil
+}
+
 type UserType string
 
 type User struct {
@@ -83,7 +106,15 @@ type Person struct {
 	Email string `json:"email"`
 }
 
-type Bot struct{}
+type Bot struct {
+	Owner         Owner  `json:"owner"`
+	WorkspaceName string `json:"workspace_name"`
+}
+
+type Owner struct {
+	Type      string `json:"type"`
+	Workspace bool   `json:"workspace"`
+}
 
 type UsersListResponse struct {
 	Object     ObjectType `json:"object"`


Test patch:
diff --git a/testdata/user_me.json b/testdata/user_me.json
new file mode 100644
index 0000000..81ffbd6
--- /dev/null
+++ b/testdata/user_me.json
@@ -0,0 +1,14 @@
+{
+  "object": "user",
+  "id": "some_id",
+  "name": "John Doe",
+  "avatar_url": "some.url",
+  "type": "person",
+  "bot": {
+    "owner": {
+      "type": "workspace",
+      "workspace": true
+    },
+    "workspace_name": "John Doe's Workspace"
+  }
+}
diff --git a/user_test.go b/user_test.go
index e5b27a0..a6f81f6 100644
--- a/user_test.go
+++ b/user_test.go
@@ -106,4 +106,49 @@ func TestUserClient(t *testing.T) {
 			})
 		}
 	})
+
+	t.Run("Me", func(t *testing.T) {
+		tests := []struct {
+			name       string
+			filePath   string
+			statusCode int
+			want       *notionapi.User
+			wantErr    bool
+			err        error
+		}{
+			{
+				name:       "returns me-user",
+				filePath:   "testdata/user_me.json",
+				statusCode: http.StatusOK,
+				want: &notionapi.User{
+					Object:    notionapi.ObjectTypeUser,
+					ID:        "some_id",
+					Type:      notionapi.UserTypePerson,
+					Name:      "John Doe",
+					AvatarURL: "some.url",
+					Bot: &notionapi.Bot{Owner: notionapi.Owner{
+						Type:      "workspace",
+						Workspace: true,
+					}, WorkspaceName: "John Doe's Workspace"},
+				},
+			},
+		}
+
+		for _, tt := range tests {
+			t.Run(tt.name, func(t *testing.T) {
+				c := newMockedClient(t, tt.filePath, tt.statusCode)
+				client := notionapi.NewClient("some_token", notionapi.WithHTTPClient(c))
+
+				got, err := client.User.Me(context.Background())
+				if (err != nil) != tt.wantErr {
+					t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
+					return
+				}
+
+				if !reflect.DeepEqual(got, tt.want) {
+					t.Errorf("Get() got = %v, want %v", got, tt.want)
+				}
+			})
+		}
+	})
 }