Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions block.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ type Block interface {
GetArchived() bool
GetParent() *Parent
GetRichTextString() string
GetMeetingNotes() *MeetingNotes
}

type Blocks []Block
Expand Down Expand Up @@ -296,6 +297,11 @@ func (b BasicBlock) GetArchived() bool {
func (b BasicBlock) GetParent() *Parent {
return b.Parent
}

func (b BasicBlock) GetMeetingNotes() *MeetingNotes {
return nil
}

func concatenateRichText(richtext []RichText) string {
var result string
for _, rt := range richtext {
Expand Down Expand Up @@ -380,6 +386,10 @@ func (b LinkPreviewBlock) GetRichTextString() string {
return b.LinkPreview.URL
}

func (b MeetingNotesBlock) GetRichTextString() string {
return concatenateRichText(b.MeetingNotes.Title)
}

func (b EquationBlock) GetRichTextString() string {
return b.Equation.Expression
}
Expand Down Expand Up @@ -738,6 +748,40 @@ type SyncedFrom struct {
BlockID BlockID `json:"block_id"`
}

type MeetingNotesBlock struct {
BasicBlock
MeetingNotes MeetingNotes `json:"meeting_notes"`
}

func (b *MeetingNotesBlock) GetMeetingNotes() *MeetingNotes {
return &b.MeetingNotes
}

type MeetingNotes struct {
Title []RichText `json:"title"`
Status string `json:"status"`
Children *MeetingNotesChildren `json:"children,omitempty"`
CalendarEvent *CalendarEvent `json:"calendar_event,omitempty"`
Recording *Recording `json:"recording,omitempty"`
}

type MeetingNotesChildren struct {
SummaryBlockID BlockID `json:"summary_block_id,omitempty"`
NotesBlockID BlockID `json:"notes_block_id,omitempty"`
TranscriptBlockID BlockID `json:"transcript_block_id,omitempty"`
}

type CalendarEvent struct {
StartTime string `json:"start_time"`
EndTime string `json:"end_time"`
Attendees []string `json:"attendees,omitempty"`
}

type Recording struct {
StartTime string `json:"start_time"`
EndTime string `json:"end_time"`
}

type UnsupportedBlock struct {
BasicBlock
}
Expand Down Expand Up @@ -838,6 +882,13 @@ func decodeBlock(raw map[string]interface{}) (Block, error) {
b = &TableBlock{}
case BlockTypeTableRowBlock:
b = &TableRowBlock{}
case BlockTypeMeetingNotes:
b = &MeetingNotesBlock{}
case BlockTypeTranscription:
raw["type"] = "meeting_notes"
raw["meeting_notes"] = raw["transcription"]
delete(raw, "transcription")
b = &MeetingNotesBlock{}

case BlockTypeUnsupported:
b = &UnsupportedBlock{}
Expand Down
104 changes: 104 additions & 0 deletions block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,110 @@ func TestBlockClient(t *testing.T) {
wantErr: false,
err: nil,
},
{
name: "returns meeting_notes block",
filePath: "testdata/block_get_meeting_notes.json",
statusCode: http.StatusOK,
id: "d7b3c8f4-9e6e-4c1a-b5b8-2c0f4a0c5b8e",
want: &notionapi.MeetingNotesBlock{
BasicBlock: notionapi.BasicBlock{
Object: notionapi.ObjectTypeBlock,
ID: "d7b3c8f4-9e6e-4c1a-b5b8-2c0f4a0c5b8e",
Type: notionapi.BlockTypeMeetingNotes,
CreatedTime: &timestamp,
LastEditedTime: &timestamp,
CreatedBy: &notionapi.User{
Object: "user",
ID: "ee5f0f84-409a-440f-983a-a5315961c6e4",
},
LastEditedBy: &notionapi.User{
Object: "user",
ID: "ee5f0f84-409a-440f-983a-a5315961c6e4",
},
HasChildren: true,
},
MeetingNotes: notionapi.MeetingNotes{
Title: []notionapi.RichText{
{
Type: notionapi.RichTextTypeText,
Text: &notionapi.Text{
Content: "Team Sync",
},
PlainText: "Team Sync",
},
},
Status: "notes_ready",
Children: &notionapi.MeetingNotesChildren{
SummaryBlockID: "a1b2c3d4-5678-9abc-def0-1234567890ab",
NotesBlockID: "b2c3d4e5-6789-abcd-ef01-234567890abc",
TranscriptBlockID: "c3d4e5f6-789a-bcde-f012-34567890abcd",
},
CalendarEvent: &notionapi.CalendarEvent{
Attendees: []string{"ee5f0f84-409a-440f-983a-a5315961c6e4"},
StartTime: "2026-02-24T10:00:00.000Z",
EndTime: "2026-02-24T10:45:00.000Z",
},
Recording: &notionapi.Recording{
StartTime: "2026-02-24T10:00:00.000Z",
EndTime: "2026-02-24T10:45:00.000Z",
},
},
},
wantErr: false,
err: nil,
},
{
name: "returns transcription block (legacy) as meeting_notes",
filePath: "testdata/block_get_transcription.json",
statusCode: http.StatusOK,
id: "d7b3c8f4-9e6e-4c1a-b5b8-2c0f4a0c5b8e",
want: &notionapi.MeetingNotesBlock{
BasicBlock: notionapi.BasicBlock{
Object: notionapi.ObjectTypeBlock,
ID: "d7b3c8f4-9e6e-4c1a-b5b8-2c0f4a0c5b8e",
Type: notionapi.BlockTypeMeetingNotes,
CreatedTime: &timestamp,
LastEditedTime: &timestamp,
CreatedBy: &notionapi.User{
Object: "user",
ID: "ee5f0f84-409a-440f-983a-a5315961c6e4",
},
LastEditedBy: &notionapi.User{
Object: "user",
ID: "ee5f0f84-409a-440f-983a-a5315961c6e4",
},
HasChildren: true,
},
MeetingNotes: notionapi.MeetingNotes{
Title: []notionapi.RichText{
{
Type: notionapi.RichTextTypeText,
Text: &notionapi.Text{
Content: "Sprint Retro",
},
PlainText: "Sprint Retro",
},
},
Status: "notes_ready",
Children: &notionapi.MeetingNotesChildren{
SummaryBlockID: "d1e2f3a4-5678-9abc-def0-1234567890ab",
NotesBlockID: "e2f3a4b5-6789-abcd-ef01-234567890abc",
TranscriptBlockID: "f3a4b5c6-789a-bcde-f012-34567890abcd",
},
CalendarEvent: &notionapi.CalendarEvent{
Attendees: []string{"ee5f0f84-409a-440f-983a-a5315961c6e4"},
StartTime: "2026-02-21T09:00:00.000Z",
EndTime: "2026-02-21T09:30:00.000Z",
},
Recording: &notionapi.Recording{
StartTime: "2026-02-21T09:00:00.000Z",
EndTime: "2026-02-21T09:30:00.000Z",
},
},
},
wantErr: false,
err: nil,
},
}

for _, tt := range tests {
Expand Down
2 changes: 2 additions & 0 deletions const.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ const (
BlockTypeSyncedBlock BlockType = "synced_block"
BlockTypeTableBlock BlockType = "table"
BlockTypeTableRowBlock BlockType = "table_row"
BlockTypeMeetingNotes BlockType = "meeting_notes"
BlockTypeTranscription BlockType = "transcription"
BlockTypeUnsupported BlockType = "unsupported"
)

Expand Down
45 changes: 45 additions & 0 deletions testdata/block_get_meeting_notes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"object": "block",
"id": "d7b3c8f4-9e6e-4c1a-b5b8-2c0f4a0c5b8e",
"created_time": "2021-05-24T05:06:34.827Z",
"last_edited_time": "2021-05-24T05:06:34.827Z",
"created_by": {
"object": "user",
"id": "ee5f0f84-409a-440f-983a-a5315961c6e4"
},
"last_edited_by": {
"object": "user",
"id": "ee5f0f84-409a-440f-983a-a5315961c6e4"
},
"has_children": true,
"archived": false,
"type": "meeting_notes",
"meeting_notes": {
"title": [
{
"type": "text",
"text": {
"content": "Team Sync",
"link": null
},
"plain_text": "Team Sync",
"href": null
}
],
"status": "notes_ready",
"children": {
"summary_block_id": "a1b2c3d4-5678-9abc-def0-1234567890ab",
"notes_block_id": "b2c3d4e5-6789-abcd-ef01-234567890abc",
"transcript_block_id": "c3d4e5f6-789a-bcde-f012-34567890abcd"
},
"calendar_event": {
"attendees": ["ee5f0f84-409a-440f-983a-a5315961c6e4"],
"start_time": "2026-02-24T10:00:00.000Z",
"end_time": "2026-02-24T10:45:00.000Z"
},
"recording": {
"start_time": "2026-02-24T10:00:00.000Z",
"end_time": "2026-02-24T10:45:00.000Z"
}
}
}
45 changes: 45 additions & 0 deletions testdata/block_get_transcription.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"object": "block",
"id": "d7b3c8f4-9e6e-4c1a-b5b8-2c0f4a0c5b8e",
"created_time": "2021-05-24T05:06:34.827Z",
"last_edited_time": "2021-05-24T05:06:34.827Z",
"created_by": {
"object": "user",
"id": "ee5f0f84-409a-440f-983a-a5315961c6e4"
},
"last_edited_by": {
"object": "user",
"id": "ee5f0f84-409a-440f-983a-a5315961c6e4"
},
"has_children": true,
"archived": false,
"type": "transcription",
"transcription": {
"title": [
{
"type": "text",
"text": {
"content": "Sprint Retro",
"link": null
},
"plain_text": "Sprint Retro",
"href": null
}
],
"status": "notes_ready",
"children": {
"summary_block_id": "d1e2f3a4-5678-9abc-def0-1234567890ab",
"notes_block_id": "e2f3a4b5-6789-abcd-ef01-234567890abc",
"transcript_block_id": "f3a4b5c6-789a-bcde-f012-34567890abcd"
},
"calendar_event": {
"attendees": ["ee5f0f84-409a-440f-983a-a5315961c6e4"],
"start_time": "2026-02-21T09:00:00.000Z",
"end_time": "2026-02-21T09:30:00.000Z"
},
"recording": {
"start_time": "2026-02-21T09:00:00.000Z",
"end_time": "2026-02-21T09:30:00.000Z"
}
}
}
Loading