Skip to content

Commit 3104c7e

Browse files
authored
feat: add message history (#278)
* feat: add message history * fix: check length of map instead of nil equality
1 parent 7307355 commit 3104c7e

File tree

2 files changed

+158
-0
lines changed

2 files changed

+158
-0
lines changed

message_history.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package stream_chat
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"errors"
7+
"net/http"
8+
"time"
9+
)
10+
11+
type QueryMessageHistoryRequest struct {
12+
Filter map[string]any `json:"filter"`
13+
Sort []*SortOption `json:"sort,omitempty"`
14+
15+
Limit int `json:"limit,omitempty"`
16+
Next string `json:"next,omitempty"`
17+
Prev string `json:"prev,omitempty"`
18+
}
19+
20+
type MessageHistoryEntry struct {
21+
MessageID string `json:"message_id"`
22+
MessageUpdatedByID string `json:"message_updated_by_id"`
23+
MessageUpdatedAt time.Time `json:"message_updated_at"`
24+
25+
Text string `json:"text"`
26+
Attachments []*Attachment `json:"attachments"`
27+
ExtraData map[string]interface{} `json:"-"`
28+
}
29+
30+
var _ json.Unmarshaler = (*MessageHistoryEntry)(nil)
31+
var _ json.Marshaler = (*MessageHistoryEntry)(nil)
32+
33+
type messageHistoryJson MessageHistoryEntry
34+
35+
func (m *MessageHistoryEntry) UnmarshalJSON(data []byte) error {
36+
var m2 messageHistoryJson
37+
if err := json.Unmarshal(data, &m2); err != nil {
38+
return err
39+
}
40+
*m = MessageHistoryEntry(m2)
41+
42+
if err := json.Unmarshal(data, &m.ExtraData); err != nil {
43+
return err
44+
}
45+
removeFromMap(m.ExtraData, *m)
46+
return nil
47+
}
48+
49+
func (m MessageHistoryEntry) MarshalJSON() ([]byte, error) {
50+
return addToMapAndMarshal(m.ExtraData, messageHistoryJson(m))
51+
}
52+
53+
type QueryMessageHistoryResponse struct {
54+
MessageHistory []*MessageHistoryEntry `json:"message_history"`
55+
56+
Next *string `json:"next,omitempty"`
57+
Prev *string `json:"prev,omitempty"`
58+
Response
59+
}
60+
61+
func (c *Client) QueryMessageHistory(ctx context.Context, request QueryMessageHistoryRequest) (*QueryMessageHistoryResponse, error) {
62+
if len(request.Filter) == 0 {
63+
return nil, errors.New("you need specify one filter at least")
64+
}
65+
var resp QueryMessageHistoryResponse
66+
err := c.makeRequest(ctx, http.MethodPost, "messages/history", nil, request, &resp)
67+
return &resp, err
68+
}

message_history_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package stream_chat
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestMessageHistory(t *testing.T) {
12+
client := initClient(t)
13+
users := randomUsers(t, client, 2)
14+
user1 := users[0]
15+
user2 := users[1]
16+
17+
ch := initChannel(t, client, user1.ID)
18+
19+
ctx := context.Background()
20+
initialText := "initial text"
21+
customField := "custom_field"
22+
initialCustomFieldValue := "custom value"
23+
// send a message with initial text
24+
response, err := ch.SendMessage(ctx, &Message{Text: initialText, ExtraData: map[string]interface{}{customField: initialCustomFieldValue}}, user1.ID)
25+
require.NoError(t, err)
26+
message := response.Message
27+
28+
updatedText1 := "updated text"
29+
updatedCustomFieldValue := "updated custom value"
30+
// update the message by user1
31+
_, err = client.UpdateMessage(ctx, &Message{Text: updatedText1, ExtraData: map[string]interface{}{customField: updatedCustomFieldValue}, UserID: user1.ID}, message.ID)
32+
assert.NoError(t, err)
33+
34+
updatedText2 := "updated text 2"
35+
// update the message by user2
36+
_, err = client.UpdateMessage(ctx, &Message{Text: updatedText2, UserID: user2.ID}, message.ID)
37+
assert.NoError(t, err)
38+
39+
t.Run("test query", func(t *testing.T) {
40+
req := QueryMessageHistoryRequest{
41+
Filter: map[string]interface{}{
42+
"message_id": message.ID,
43+
},
44+
}
45+
messageHistoryResponse, err := client.QueryMessageHistory(ctx, req)
46+
assert.NoError(t, err)
47+
assert.NotNil(t, messageHistoryResponse)
48+
49+
history := messageHistoryResponse.MessageHistory
50+
assert.Equal(t, 2, len(history))
51+
52+
firstUpdate := history[1]
53+
assert.Equal(t, initialText, firstUpdate.Text)
54+
assert.Equal(t, user1.ID, firstUpdate.MessageUpdatedByID)
55+
assert.Equal(t, initialCustomFieldValue, firstUpdate.ExtraData[customField].(string))
56+
57+
secondUpdate := history[0]
58+
assert.Equal(t, updatedText1, secondUpdate.Text)
59+
assert.Equal(t, user2.ID, secondUpdate.MessageUpdatedByID)
60+
assert.Equal(t, updatedCustomFieldValue, secondUpdate.ExtraData[customField].(string))
61+
})
62+
63+
t.Run("test sorting", func(t *testing.T) {
64+
sortedHistoryQueryRequest := QueryMessageHistoryRequest{
65+
Filter: map[string]interface{}{
66+
"message_id": message.ID,
67+
},
68+
Sort: []*SortOption{
69+
{
70+
Field: "message_updated_at",
71+
Direction: 1,
72+
},
73+
},
74+
}
75+
sortedHistoryResponse, err := client.QueryMessageHistory(ctx, sortedHistoryQueryRequest)
76+
assert.NoError(t, err)
77+
assert.NotNil(t, sortedHistoryResponse)
78+
79+
sortedHistory := sortedHistoryResponse.MessageHistory
80+
assert.Equal(t, 2, len(sortedHistory))
81+
82+
firstUpdate := sortedHistory[0]
83+
assert.Equal(t, initialText, firstUpdate.Text)
84+
assert.Equal(t, user1.ID, firstUpdate.MessageUpdatedByID)
85+
86+
secondUpdate := sortedHistory[1]
87+
assert.Equal(t, updatedText1, secondUpdate.Text)
88+
assert.Equal(t, user2.ID, secondUpdate.MessageUpdatedByID)
89+
})
90+
}

0 commit comments

Comments
 (0)