Skip to content

Commit 63b6b82

Browse files
fix: add user to RESERVED_UPDATED_MESSAGE_FIELDS (#1526)
## Description of the changes, What, Why and How? Update fails if the payload contains both `user` object and `user_id`property. ``` StreamChat error code 4: UpdateMessage failed with error: "cannot set both message.user and message.user_id." ```
1 parent be89a9e commit 63b6b82

File tree

4 files changed

+48
-60
lines changed

4 files changed

+48
-60
lines changed

src/client.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,28 +2860,28 @@ export class StreamChat {
28602860
* updateMessage - Update the given message
28612861
*
28622862
* @param {Omit<MessageResponse, 'mentioned_users'> & { mentioned_users?: string[] }} message object, id needs to be specified
2863-
* @param {string | { id: string }} [userId]
2863+
* @param {string | { id: string }} [partialUserOrUserId]
28642864
* @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message
28652865
*
28662866
* @return {{ message: LocalMessage | MessageResponse }} Response that includes the message
28672867
*/
28682868
async updateMessage(
28692869
message: LocalMessage | Partial<MessageResponse>,
2870-
userId?: string | { id: string },
2870+
partialUserOrUserId?: string | { id: string },
28712871
options?: UpdateMessageOptions,
28722872
) {
28732873
if (!message.id) {
2874-
throw Error('Please specify the message id when calling updateMessage');
2874+
throw Error('Please specify the message.id when calling updateMessage');
28752875
}
2876+
2877+
// should not include user object
28762878
const payload = toUpdatedMessagePayload(message);
2877-
if (userId != null) {
2878-
if (isString(userId)) {
2879-
payload.user_id = userId;
2880-
} else {
2881-
payload.user = {
2882-
id: userId.id,
2883-
};
2884-
}
2879+
2880+
// add user_id (if exists)
2881+
if (typeof partialUserOrUserId === 'string') {
2882+
payload.user_id = partialUserOrUserId;
2883+
} else if (typeof partialUserOrUserId?.id === 'string') {
2884+
payload.user_id = partialUserOrUserId.id;
28852885
}
28862886

28872887
return await this.post<UpdateMessageAPIResponse>(
@@ -2909,16 +2909,21 @@ export class StreamChat {
29092909
async partialUpdateMessage(
29102910
id: string,
29112911
partialMessageObject: PartialMessageUpdate,
2912-
userId?: string | { id: string },
2912+
partialUserOrUserId?: string | { id: string },
29132913
options?: UpdateMessageOptions,
29142914
) {
29152915
if (!id) {
2916-
throw Error('Please specify the message id when calling partialUpdateMessage');
2916+
throw Error('Please specify the message.id when calling partialUpdateMessage');
29172917
}
2918-
let user = userId;
2919-
if (userId != null && isString(userId)) {
2920-
user = { id: userId };
2918+
2919+
let user: { id: string } | undefined = undefined;
2920+
2921+
if (typeof partialUserOrUserId === 'string') {
2922+
user = { id: partialUserOrUserId };
2923+
} else if (typeof partialUserOrUserId?.id === 'string') {
2924+
user = { id: partialUserOrUserId.id };
29212925
}
2926+
29222927
return await this.put<UpdateMessageAPIResponse>(
29232928
this.baseURL + `/messages/${encodeURIComponent(id)}`,
29242929
{

src/constants.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
1-
import type { ReservedUpdatedMessageFields } from './types';
2-
31
export const DEFAULT_QUERY_CHANNELS_MESSAGE_LIST_PAGE_SIZE = 25;
42
export const DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE = 100;
53
export const DEFAULT_MESSAGE_SET_PAGINATION = { hasNext: false, hasPrev: false };
64
export const DEFAULT_UPLOAD_SIZE_LIMIT_BYTES = 100 * 1024 * 1024; // 100 MB
75
export const API_MAX_FILES_ALLOWED_PER_MESSAGE = 10;
86
export const MAX_CHANNEL_MEMBER_COUNT_IN_CHANNEL_QUERY = 100;
9-
export const RESERVED_UPDATED_MESSAGE_FIELDS: Array<ReservedUpdatedMessageFields> = [
7+
export const RESERVED_UPDATED_MESSAGE_FIELDS = {
108
// Dates should not be converted back to ISO strings as JS looses precision on them (milliseconds)
11-
'created_at',
12-
'deleted_at',
13-
'pinned_at',
14-
'updated_at',
15-
'command',
9+
created_at: true,
10+
deleted_at: true,
11+
pinned_at: true,
12+
updated_at: true,
13+
command: true,
1614
// Back-end enriches these fields
17-
'mentioned_users',
18-
'quoted_message',
15+
mentioned_users: true,
16+
quoted_message: true,
1917
// Client-specific fields
20-
'latest_reactions',
21-
'own_reactions',
22-
'reaction_counts',
23-
'reply_count',
18+
latest_reactions: true,
19+
own_reactions: true,
20+
reaction_counts: true,
21+
reply_count: true,
2422
// Message text related fields that shouldn't be in update
25-
'i18n',
26-
'type',
27-
'html',
28-
'__html',
29-
] as const;
23+
i18n: true,
24+
type: true,
25+
html: true,
26+
__html: true,
27+
user: true,
28+
} as const;
3029

31-
export const LOCAL_MESSAGE_FIELDS = ['error'] as const;
30+
export const LOCAL_MESSAGE_FIELDS = { error: true } as const;

src/types.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type {
1717
CustomUserData,
1818
} from './custom_types';
1919
import type { NotificationManager } from './notifications';
20+
import type { RESERVED_UPDATED_MESSAGE_FIELDS } from './constants';
2021

2122
/**
2223
* Utility Types
@@ -2945,23 +2946,7 @@ export type TranslationLanguages =
29452946

29462947
export type TypingStartEvent = Event;
29472948

2948-
export type ReservedUpdatedMessageFields =
2949-
| 'command'
2950-
| 'created_at'
2951-
| 'deleted_at'
2952-
| 'html'
2953-
| 'i18n'
2954-
| 'latest_reactions'
2955-
// the the original array of UserResponse object is converted to array of user ids and re-inserted before sending the update request
2956-
| 'mentioned_users'
2957-
| 'own_reactions'
2958-
| 'pinned_at'
2959-
| 'quoted_message'
2960-
| 'reaction_counts'
2961-
| 'reply_count'
2962-
| 'type'
2963-
| 'updated_at'
2964-
| '__html';
2949+
export type ReservedUpdatedMessageFields = keyof typeof RESERVED_UPDATED_MESSAGE_FIELDS;
29652950

29662951
export type UpdatedMessage = Omit<MessageResponse, ReservedUpdatedMessageFields> & {
29672952
mentioned_users?: string[];

src/utils.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,14 @@ export const localMessageToNewMessagePayload = (localMessage: LocalMessage): Mes
367367
export const toUpdatedMessagePayload = (
368368
message: LocalMessage | Partial<MessageResponse>,
369369
): UpdatedMessage => {
370+
const reservedKeys = {
371+
...RESERVED_UPDATED_MESSAGE_FIELDS,
372+
...LOCAL_MESSAGE_FIELDS,
373+
} as const;
374+
370375
const messageFields = Object.fromEntries(
371376
Object.entries(message).filter(
372-
([key]) =>
373-
![...RESERVED_UPDATED_MESSAGE_FIELDS, ...LOCAL_MESSAGE_FIELDS].includes(
374-
key as
375-
| (typeof RESERVED_UPDATED_MESSAGE_FIELDS)[number]
376-
| (typeof LOCAL_MESSAGE_FIELDS)[number],
377-
),
377+
([key]) => !reservedKeys[key as keyof typeof reservedKeys],
378378
),
379379
) as UpdatedMessage;
380380

@@ -384,7 +384,6 @@ export const toUpdatedMessagePayload = (
384384
mentioned_users: message.mentioned_users?.map((user) =>
385385
typeof user === 'string' ? user : user.id,
386386
),
387-
user_id: message.user?.id ?? message.user_id,
388387
};
389388
};
390389

0 commit comments

Comments
 (0)