Skip to content

Commit 7a3c813

Browse files
committed
fix: restore fetch message output format
It must match Acrobits specs
1 parent c225e60 commit 7a3c813

File tree

6 files changed

+90
-56
lines changed

6 files changed

+90
-56
lines changed

api/routes.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func (h handler) fetchMessages(c echo.Context) error {
6969
return mapServiceError(err)
7070
}
7171

72-
logger.Info().Str("endpoint", "fetch_messages").Str("username", req.Username).Int("received", len(resp.ReceivedMessages)).Int("sent", len(resp.SentMessages)).Msg("messages fetched successfully")
72+
logger.Info().Str("endpoint", "fetch_messages").Str("username", req.Username).Int("received", len(resp.ReceivedSMSs)).Int("sent", len(resp.SentSMSs)).Msg("messages fetched successfully")
7373
return c.JSON(http.StatusOK, resp)
7474
}
7575

docs/openapi.yaml

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -268,46 +268,56 @@ paths:
268268

269269
components:
270270
schemas:
271-
Message:
271+
SMS:
272272
type: object
273+
description: A message following the Acrobits Modern API format.
273274
properties:
274-
id:
275+
sms_id:
275276
type: string
276277
description: Unique identifier (Matrix Event ID).
277278
sending_date:
278279
type: string
279280
format: date-time
280-
description: RFC 3339 timestamp.
281+
description: RFC 3339 timestamp when the message was sent.
281282
sender:
282283
type: string
283-
description: Sender address/ID.
284+
description: Sender identifier (phone number or user name). Only present in received messages.
284285
recipient:
285286
type: string
286-
description: Recipient address/ID (Room ID).
287-
text:
287+
description: Recipient identifier (phone number or user name). Only present in sent messages.
288+
sms_text:
288289
type: string
289-
description: Message body.
290+
description: Message body (UTF-8 encoded).
290291
content_type:
291292
type: string
292-
description: MIME type.
293+
description: MIME content-type. Defaults to text/plain if omitted.
294+
disposition_notification:
295+
type: string
296+
description: Opaque string from Send Message request. Can be omitted if empty.
297+
displayed:
298+
type: boolean
299+
description: True if message has already been displayed on another device. Only in received messages.
293300
stream_id:
294301
type: string
295-
description: Identifier for the conversation stream (Room ID).
302+
description: Identifier for the conversation stream (Room ID or identifier).
296303
FetchMessagesResponse:
297304
type: object
305+
description: Response from the fetch_messages endpoint following Acrobits Modern API specification.
298306
properties:
299307
date:
300308
type: string
301309
format: date-time
302-
description: Current server time in RFC 3339.
303-
received_messages:
310+
description: Current server time in RFC 3339 format (used to synchronize timestamps).
311+
received_smss:
304312
type: array
305313
items:
306-
$ref: '#/components/schemas/Message'
307-
sent_messages:
314+
$ref: '#/components/schemas/SMS'
315+
description: Array of received messages. Sorted by sending_date in ascending order (oldest first).
316+
sent_smss:
308317
type: array
309318
items:
310-
$ref: '#/components/schemas/Message'
319+
$ref: '#/components/schemas/SMS'
320+
description: Array of sent messages. Sorted by sending_date in ascending order (oldest first).
311321
MappingRequest:
312322
type: object
313323
required:
@@ -316,7 +326,7 @@ components:
316326
properties:
317327
number:
318328
type: string
319-
description: number or bridged identifier to map.
329+
description: Phone number or bridged identifier to map.
320330
matrix_id:
321331
type: string
322332
description: Optional Matrix user to use when auto-creating DMs.

main_test.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,8 @@ func TestIntegration_SendAndFetchMessages(t *testing.T) {
407407
}
408408

409409
found := false
410-
for _, msg := range fetchResp.ReceivedMessages {
411-
if strings.Contains(msg.Text, "Hello from integration test") && msg.Sender == user1MatrixID {
410+
for _, msg := range fetchResp.ReceivedSMSs {
411+
if strings.Contains(msg.SMSText, "Hello from integration test") && msg.Sender == user1MatrixID {
412412
found = true
413413
t.Logf("Found test message from %s", msg.Sender)
414414
break
@@ -703,10 +703,10 @@ func TestIntegration_SendMessageWithPhoneNumberMapping(t *testing.T) {
703703
}
704704

705705
foundPhoneMessage := false
706-
for _, msg := range fetchResp.ReceivedMessages {
707-
if strings.Contains(msg.Text, "Message from phone number") && msg.Sender == user1MatrixID {
706+
for _, msg := range fetchResp.ReceivedSMSs {
707+
if strings.Contains(msg.SMSText, "Message from phone number") && msg.Sender == user1MatrixID {
708708
foundPhoneMessage = true
709-
t.Logf("User2 received message from phone-mapped user: sender=%s, text=%s", msg.Sender, msg.Text)
709+
t.Logf("User2 received message from phone-mapped user: sender=%s, text=%s", msg.Sender, msg.SMSText)
710710
break
711711
}
712712
}
@@ -823,10 +823,10 @@ func TestIntegration_RoomMessaging(t *testing.T) {
823823

824824
// Check that user1 sees the message from user2
825825
foundUser2Message := false
826-
for _, msg := range fetchResp1.ReceivedMessages {
827-
if strings.Contains(msg.Text, "Hello from user2") && msg.Sender == user2MatrixID {
826+
for _, msg := range fetchResp1.ReceivedSMSs {
827+
if strings.Contains(msg.SMSText, "Hello from user2") && msg.Sender == user2MatrixID {
828828
foundUser2Message = true
829-
t.Logf("User1 received message from user2: %s", msg.Text)
829+
t.Logf("User1 received message from user2: %s", msg.SMSText)
830830
break
831831
}
832832
}
@@ -842,10 +842,10 @@ func TestIntegration_RoomMessaging(t *testing.T) {
842842

843843
// Check that user2 sees the message from user1
844844
foundUser1Message := false
845-
for _, msg := range fetchResp2.ReceivedMessages {
846-
if strings.Contains(msg.Text, "Hello from user1") && msg.Sender == user1MatrixID {
845+
for _, msg := range fetchResp2.ReceivedSMSs {
846+
if strings.Contains(msg.SMSText, "Hello from user1") && msg.Sender == user1MatrixID {
847847
foundUser1Message = true
848-
t.Logf("User2 received message from user1: %s", msg.Text)
848+
t.Logf("User2 received message from user1: %s", msg.SMSText)
849849
break
850850
}
851851
}
@@ -855,10 +855,10 @@ func TestIntegration_RoomMessaging(t *testing.T) {
855855

856856
// Check that user2 also sees their own message in sent messages
857857
foundOwnMessage := false
858-
for _, msg := range fetchResp2.SentMessages {
859-
if strings.Contains(msg.Text, "Hello from user2") && msg.Sender == user2MatrixID {
858+
for _, msg := range fetchResp2.SentSMSs {
859+
if strings.Contains(msg.SMSText, "Hello from user2") && msg.Recipient == user2MatrixID {
860860
foundOwnMessage = true
861-
t.Logf("User2 sees their own sent message: %s", msg.Text)
861+
t.Logf("User2 sees their own sent message: %s", msg.SMSText)
862862
break
863863
}
864864
}

models/messages.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,35 @@ type FetchMessagesRequest struct {
2424
Device string `json:"device"`
2525
}
2626

27-
// FetchMessagesResponse is the payload returned from the fetch_messages endpoint.
27+
// FetchMessagesResponse matches Acrobits Modern API specification.
2828
type FetchMessagesResponse struct {
29-
Date string `json:"date"`
30-
ReceivedMessages []Message `json:"received_messages"`
31-
SentMessages []Message `json:"sent_messages"`
29+
Date string `json:"date"`
30+
ReceivedSMSs []SMS `json:"received_smss"`
31+
SentSMSs []SMS `json:"sent_smss"`
3232
}
3333

34-
// Message represents the shared schema used in both fetch and send responses.
34+
// SMS represents a message in the Acrobits Modern API format.
35+
type SMS struct {
36+
SMSID string `json:"sms_id"`
37+
SendingDate string `json:"sending_date"`
38+
Sender string `json:"sender,omitempty"`
39+
Recipient string `json:"recipient,omitempty"`
40+
SMSText string `json:"sms_text"`
41+
ContentType string `json:"content_type,omitempty"`
42+
DispositionNotification string `json:"disposition_notification,omitempty"`
43+
Displayed bool `json:"displayed,omitempty"`
44+
StreamID string `json:"stream_id"`
45+
}
46+
47+
// Message is a helper struct for internal use.
3548
type Message struct {
36-
ID string `json:"message_id"`
37-
SendingDate string `json:"sending_date"`
38-
Sender string `json:"sender"`
39-
Recipient string `json:"recipient"`
40-
Text string `json:"message_text"`
41-
ContentType string `json:"content_type"`
42-
StreamID string `json:"stream_id"`
49+
ID string
50+
SendingDate string
51+
Sender string
52+
Recipient string
53+
Text string
54+
ContentType string
55+
StreamID string
4356
}
4457

4558
// PushTokenReportRequest mirrors the Acrobits push token reporter POST JSON schema.

models/models_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,16 @@ func TestSendMessageResponse_Marshal(t *testing.T) {
110110
func TestFetchMessagesResponse_Marshal(t *testing.T) {
111111
resp := FetchMessagesResponse{
112112
Date: "2025-01-01T00:00:00Z",
113-
ReceivedMessages: []Message{
113+
ReceivedSMSs: []SMS{
114114
{
115-
ID: "$event1",
116-
Text: "Received message",
115+
SMSID: "$event1",
116+
SMSText: "Received message",
117117
},
118118
},
119-
SentMessages: []Message{
119+
SentSMSs: []SMS{
120120
{
121-
ID: "$event2",
122-
Text: "Sent message",
121+
SMSID: "$event2",
122+
SMSText: "Sent message",
123123
},
124124
},
125125
}
@@ -131,8 +131,8 @@ func TestFetchMessagesResponse_Marshal(t *testing.T) {
131131
err = json.Unmarshal(data, &resp2)
132132
assert.NoError(t, err)
133133
assert.Equal(t, resp.Date, resp2.Date)
134-
assert.Len(t, resp2.ReceivedMessages, 1)
135-
assert.Len(t, resp2.SentMessages, 1)
134+
assert.Len(t, resp2.ReceivedSMSs, 1)
135+
assert.Len(t, resp2.SentSMSs, 1)
136136
}
137137

138138
func TestMappingResponse_Marshal(t *testing.T) {

service/messages.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func (s *MessageService) FetchMessages(ctx context.Context, req *models.FetchMes
158158
return nil, fmt.Errorf("sync messages: %w", mapAuthErr(err))
159159
}
160160

161-
received, sent := make([]models.Message, 0, 8), make([]models.Message, 0, 8)
161+
received, sent := make([]models.SMS, 0, 8), make([]models.SMS, 0, 8)
162162

163163
// Resolve the caller's identifier (e.g. "91201")
164164
callerIdentifier := s.resolveMatrixIDToIdentifier(string(userID))
@@ -204,20 +204,31 @@ func (s *MessageService) FetchMessages(ctx context.Context, req *models.FetchMes
204204
msg.Recipient = callerIdentifier
205205
}
206206

207+
// Convert internal Message to SMS
208+
sms := models.SMS{
209+
SMSID: msg.ID,
210+
SendingDate: msg.SendingDate,
211+
SMSText: msg.Text,
212+
ContentType: msg.ContentType,
213+
StreamID: msg.StreamID,
214+
}
215+
207216
if isSent {
208-
sent = append(sent, msg)
217+
sms.Recipient = msg.Recipient
218+
sent = append(sent, sms)
209219
} else {
210-
received = append(received, msg)
220+
sms.Sender = msg.Sender
221+
received = append(received, sms)
211222
}
212223
}
213224
}
214225

215226
logger.Debug().Str("user_id", string(userID)).Int("received_count", len(received)).Int("sent_count", len(sent)).Msg("processed sync messages")
216227

217228
return &models.FetchMessagesResponse{
218-
Date: s.now().UTC().Format(time.RFC3339),
219-
ReceivedMessages: received,
220-
SentMessages: sent,
229+
Date: s.now().UTC().Format(time.RFC3339),
230+
ReceivedSMSs: received,
231+
SentSMSs: sent,
221232
}, nil
222233
}
223234

0 commit comments

Comments
 (0)