Commit d07bcee4 authored by Andrei Mihu's avatar Andrei Mihu
Browse files

Add ChannelMessagesList function to all runtimes.

parent 6e878aba
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr
## [Unreleased]
### Added
- Add "FriendsBlock" function to all runtimes.
- Add "ChannelMessagesList" function to all runtimes.

### Changed
- Ensure storage write ops return acks in the same order as inputs.
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ require (
	github.com/gorilla/mux v1.8.0
	github.com/gorilla/websocket v1.4.2
	github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0
	github.com/heroiclabs/nakama-common v1.22.1-0.20220521150612-11ae5d0b3b0d
	github.com/heroiclabs/nakama-common v1.22.1-0.20220521170538-e804a8eeaa39
	github.com/jackc/pgconn v1.10.0
	github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451
	github.com/jackc/pgtype v1.8.1
+2 −2
Original line number Diff line number Diff line
@@ -290,8 +290,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/heroiclabs/nakama-common v1.22.1-0.20220521150612-11ae5d0b3b0d h1:2pdN0sSZmdTwCOKhep4F3OeW36ODuhW76mLnZUCKsNM=
github.com/heroiclabs/nakama-common v1.22.1-0.20220521150612-11ae5d0b3b0d/go.mod h1:WF4YG46afwY3ibzsXnkt3zvhQ3tBY03IYeU7xSLr8HE=
github.com/heroiclabs/nakama-common v1.22.1-0.20220521170538-e804a8eeaa39 h1:eRkiuBT6jFJbNcaiS1O/wbYlmyfmc5TcKn7s5eJgNV4=
github.com/heroiclabs/nakama-common v1.22.1-0.20220521170538-e804a8eeaa39/go.mod h1:WF4YG46afwY3ibzsXnkt3zvhQ3tBY03IYeU7xSLr8HE=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+30 −1
Original line number Diff line number Diff line
@@ -3669,7 +3669,7 @@ func (n *RuntimeGoNakamaModule) ChannelMessageSend(ctx context.Context, channelI
// @param senderId(type=string, optional=true) The UUID for the sender of this message. If left empty, it will be assumed that it is a system message.
// @param senderUsername(type=string, optional=true) The username of the user to send this message as. If left empty, it will be assumed that it is a system message.
// @param persist(type=bool, optional=true, default=true) Whether to record this message in the channel history.
// @return channelMessageSend(*rtapi.ChannelMessageAck) Message updated ack.
// @return channelMessageUpdate(*rtapi.ChannelMessageAck) Message updated ack.
// @return error(error) An optional error value if an error occurred.
func (n *RuntimeGoNakamaModule) ChannelMessageUpdate(ctx context.Context, channelId, messageId string, content map[string]interface{}, senderId, senderUsername string, persist bool) (*rtapi.ChannelMessageAck, error) {
	channelIdToStreamResult, err := ChannelIdToStream(channelId)
@@ -3689,6 +3689,35 @@ func (n *RuntimeGoNakamaModule) ChannelMessageUpdate(ctx context.Context, channe
	return ChannelMessageUpdate(ctx, n.logger, n.db, n.router, channelIdToStreamResult.Stream, channelId, messageId, contentStr, senderId, senderUsername, persist)
}

// @group chat
// @summary List messages from a realtime chat channel.
// @param ctx(type=context.Context) The context object represents information about the server and requester.
// @param channelId(type=string) The ID of the channel to list messages from.
// @param limit(type=int) The number of messages to return per page.
// @param forward(type=bool) Whether to list messages from oldest to newest, or newest to oldest.
// @param cursor(type=string, optional=true) A pagination cursor to use for retrieving a next page of messages.
// @return channelMessageList([]*rtapi.ChannelMessage) Messages from the specified channel.
// @return nextCursor(string) Cursor for the next page of messages, if any.
// @return prevCursor(string) Cursor for the previous page of messages, if any.
// @return error(error) An optional error value if an error occurred.
func (n *RuntimeGoNakamaModule) ChannelMessagesList(ctx context.Context, channelId string, limit int, forward bool, cursor string) ([]*api.ChannelMessage, string, string, error) {
	channelIdToStreamResult, err := ChannelIdToStream(channelId)
	if err != nil {
		return nil, "", "", err
	}

	if limit < 1 || limit > 100 {
		return nil, "", "", errors.New("limit must be 1-100")
	}

	list, err := ChannelMessagesList(ctx, n.logger, n.db, uuid.Nil, channelIdToStreamResult.Stream, channelId, limit, forward, cursor)
	if err != nil {
		return nil, "", "", err
	}

	return list.Messages, list.NextCursor, list.PrevCursor, nil
}

// @group chat
// @summary Create a channel identifier to be used in other runtime calls. Does not create a channel.
// @param ctx(type=context.Context) The context object represents information about the server and requester.
+71 −1
Original line number Diff line number Diff line
@@ -263,6 +263,7 @@ func (n *runtimeJavascriptNakamaModule) mappings(r *goja.Runtime) map[string]fun
		"localcacheDelete":                n.localcacheDelete(r),
		"channelMessageSend":              n.channelMessageSend(r),
		"channelMessageUpdate":            n.channelMessageUpdate(r),
		"channelMessagesList":             n.channelMessagesList(r),
		"channelIdBuild":                  n.channelIdBuild(r),
		"binaryToString":                  n.binaryToString(r),
		"stringToBinary":                  n.stringToBinary(r),
@@ -7499,7 +7500,7 @@ func (n *runtimeJavascriptNakamaModule) channelMessageSend(r *goja.Runtime) func
// @param senderId(type=string) The UUID for the sender of this message. If left empty, it will be assumed that it is a system message.
// @param senderUsername(type=string) The username of the user to send this message as. If left empty, it will be assumed that it is a system message.
// @param persist(type=bool, optional=true, default=true) Whether to record this message in the channel history.
// @return channelMessageSend(nkruntime.ChannelMessageAck) Message updated ack.
// @return channelMessageUpdate(nkruntime.ChannelMessageAck) Message updated ack.
// @return error(error) An optional error value if an error occurred.
func (n *runtimeJavascriptNakamaModule) channelMessageUpdate(r *goja.Runtime) func(goja.FunctionCall) goja.Value {
	return func(f goja.FunctionCall) goja.Value {
@@ -7563,6 +7564,75 @@ func (n *runtimeJavascriptNakamaModule) channelMessageUpdate(r *goja.Runtime) fu
	}
}

// @group chat
// @summary List messages from a realtime chat channel.
// @param channelId(type=string) The ID of the channel to list messages from.
// @param limit(type=number, optional=true, default=100) The number of messages to return per page.
// @param forward(type=bool, optional=true, default=true) Whether to list messages from oldest to newest, or newest to oldest.
// @param cursor(type=string, optional=true) A pagination cursor to use for retrieving a next page of messages.
// @return channelMessagesList(nkruntime.ChannelMessageList) Messages from the specified channel.
// @return error(error) An optional error value if an error occurred.
func (n *runtimeJavascriptNakamaModule) channelMessagesList(r *goja.Runtime) func(goja.FunctionCall) goja.Value {
	return func(f goja.FunctionCall) goja.Value {
		channelId := getJsString(r, f.Argument(0))

		limit := 100
		if f.Argument(1) != goja.Undefined() && f.Argument(1) != goja.Null() {
			limit = int(getJsInt(r, f.Argument(1)))
			if limit < 1 || limit > 100 {
				panic(r.NewTypeError("limit must be 1-100"))
			}
		}

		forward := true
		if f.Argument(2) != goja.Undefined() && f.Argument(2) != goja.Null() {
			forward = getJsBool(r, f.Argument(2))
		}

		var cursor string
		if f.Argument(3) != goja.Undefined() && f.Argument(3) != goja.Null() {
			cursor = getJsString(r, f.Argument(3))
		}

		channelIdToStreamResult, err := ChannelIdToStream(channelId)
		if err != nil {
			panic(r.NewTypeError(err.Error()))
		}

		list, err := ChannelMessagesList(context.Background(), n.logger, n.db, uuid.Nil, channelIdToStreamResult.Stream, channelId, limit, forward, cursor)
		if err != nil {
			panic(r.NewGoError(fmt.Errorf("failed to list channel messages: %s", err.Error())))
		}

		messages := make([]interface{}, 0, len(list.Messages))
		for _, message := range list.Messages {
			messages = append(messages, map[string]interface{}{
				"channelId":  message.ChannelId,
				"messageId":  message.MessageId,
				"code":       message.Code.Value,
				"senderId":   message.SenderId,
				"username":   message.Username,
				"content":    message.Content,
				"createTime": message.CreateTime.Seconds,
				"updateTime": message.UpdateTime.Seconds,
				"persistent": message.Persistent.Value,
				"roomName":   message.RoomName,
				"groupId":    message.GroupId,
				"userIdOne":  message.UserIdOne,
				"userIdTwo":  message.UserIdTwo,
			})
		}

		result := map[string]interface{}{
			"messages":   messages,
			"nextCursor": list.NextCursor,
			"prevCursor": list.PrevCursor,
		}

		return r.ToValue(result)
	}
}

// @group chat
// @summary Create a channel identifier to be used in other runtime calls. Does not create a channel.
// @param senderId(type=string) UserID of the message sender (when applicable). Defaults to the system user if void.
Loading