HTTP API: a chat's recent messages, and sending a message (closes #5)
check / check (push) Successful in 1m5s
check / check (push) Successful in 1m5s
`GET /api/v1/chats/{id}/messages?count=N` returns a chat's recent messages, oldest first (`count` 1 to 100, default 20), and `POST` to the same path sends a text message and returns it once the chat client has taken it. Both answer `404` for any id the chats list does not show, looked up in the same contact list. The message record is defined once, for the webhooks to reuse.
Disclosures: items are read five at a time, because one item can be many times its text and 100 at once could pass the 16 MiB read limit; text too long gets `413`, a contact who deleted the chat `409` (unverified for one still connecting); a query the server cannot read gets its own `400`.
Model: opus-5-5
This commit was merged in pull request #15.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Response and event types this package and the bot act on. The chat
|
||||
@@ -15,6 +16,7 @@ const (
|
||||
TypeUserContactLinkCreated = "userContactLinkCreated"
|
||||
TypeUserContactLinkUpdated = "userContactLinkUpdated"
|
||||
TypeContactsList = "contactsList"
|
||||
TypeAPIChat = "apiChat"
|
||||
TypeNewChatItems = "newChatItems"
|
||||
TypeContactConnected = "contactConnected"
|
||||
TypeChatCmdError = "chatCmdError"
|
||||
@@ -71,8 +73,9 @@ type (
|
||||
Status string `json:"contactStatus"`
|
||||
}
|
||||
|
||||
// NewChatItems is the record of a newChatItems event: messages
|
||||
// received, or sent from this profile elsewhere.
|
||||
// NewChatItems is the record of a newChatItems event, messages
|
||||
// received or sent from this profile elsewhere, and of the answer
|
||||
// to sending a message.
|
||||
NewChatItems struct {
|
||||
ChatItems []AChatItem `json:"chatItems"`
|
||||
}
|
||||
@@ -82,25 +85,36 @@ type (
|
||||
Contact Contact `json:"contact"`
|
||||
}
|
||||
|
||||
// AChatItem is one message together with the chat it belongs to.
|
||||
// AChatItem is one chat item together with the chat it belongs to.
|
||||
AChatItem struct {
|
||||
ChatInfo struct {
|
||||
Type string `json:"type"`
|
||||
Contact *Contact `json:"contact,omitempty"`
|
||||
} `json:"chatInfo"`
|
||||
ChatItem struct {
|
||||
ChatDir tagged `json:"chatDir"`
|
||||
Meta struct {
|
||||
ItemID int64 `json:"itemId"`
|
||||
} `json:"meta"`
|
||||
Content struct {
|
||||
Type string `json:"type"`
|
||||
MsgContent *MsgContent `json:"msgContent,omitempty"`
|
||||
} `json:"content"`
|
||||
} `json:"chatItem"`
|
||||
ChatItem ChatItem `json:"chatItem"`
|
||||
}
|
||||
|
||||
// MsgContent is a message body. Only "text" is sent or read here.
|
||||
// ChatItem is one item in a chat: a message, or an event the chat
|
||||
// client records there, such as the contact connecting. Content.Type
|
||||
// tells them apart: "rcvMsgContent" and "sndMsgContent" are messages
|
||||
// received and sent.
|
||||
ChatItem struct {
|
||||
ChatDir tagged `json:"chatDir"`
|
||||
Meta struct {
|
||||
ItemID int64 `json:"itemId"`
|
||||
// ItemTs is when a received message reached the SimpleX
|
||||
// relay, and when a sent one was sent.
|
||||
ItemTs time.Time `json:"itemTs"`
|
||||
} `json:"meta"`
|
||||
Content struct {
|
||||
Type string `json:"type"`
|
||||
MsgContent *MsgContent `json:"msgContent,omitempty"`
|
||||
} `json:"content"`
|
||||
}
|
||||
|
||||
// MsgContent is a message body: its type, such as "text", "image"
|
||||
// or "file", and its text, which for anything but "text" is the
|
||||
// caption. Only "text" is sent here.
|
||||
MsgContent struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text"`
|
||||
@@ -208,6 +222,20 @@ func cmdListContacts(userID int64) string {
|
||||
return "/_contacts " + strconv.FormatInt(userID, 10)
|
||||
}
|
||||
|
||||
// cmdGetChat asks for the last count items of the chat with a contact,
|
||||
// or, unless beforeItemID is 0, the last count before that item. It is
|
||||
// missing from COMMANDS.md; its syntax is the client's parser's, in
|
||||
// src/Simplex/Chat/Library/Commands.hs.
|
||||
func cmdGetChat(contactID, beforeItemID int64, count int) string {
|
||||
cmd := "/_get chat @" + strconv.FormatInt(contactID, 10)
|
||||
|
||||
if beforeItemID != 0 {
|
||||
cmd += " before=" + strconv.FormatInt(beforeItemID, 10)
|
||||
}
|
||||
|
||||
return cmd + " count=" + strconv.Itoa(count)
|
||||
}
|
||||
|
||||
func cmdSendText(contactID, quotedItemID int64, text string) (string, error) {
|
||||
b, err := json.Marshal([]composedMessage{{
|
||||
QuotedItemID: quotedItemID,
|
||||
|
||||
Reference in New Issue
Block a user