Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b64edb67c7 | |||
| 56acee107e | |||
| 51b1a1dce7 | |||
| 8875a9deb6 | |||
| 9c92fbb8a9 | |||
| 9424e3ed5f | |||
| 12b284d840 | |||
| f2bfb1e998 | |||
| 34d7d38da1 | |||
| 67855d4f80 | |||
| b13c337d99 | |||
| 80c71b77d6 | |||
| 0276c7df60 | |||
| b703449615 | |||
| 3381b85895 | |||
| c581d43f17 | |||
| eea2627a28 | |||
| 6dd4e56c2a | |||
| 20085d0efc | |||
| 2477a6658c | |||
| 38a8802107 | |||
| a5292bb3a3 | |||
| 8c7de0416b | |||
| 275491a1b5 | |||
| c37e0227ff | |||
| bb4cbcbc78 | |||
| bcd5324b48 | |||
| 85614da36f | |||
| 86a325f309 | |||
| 938409b0e4 | |||
| fa1467878b | |||
| 7deb45e35d | |||
| d938754ff6 | |||
| a559bfe323 | |||
| f44a97b8d2 | |||
| 97f4b51874 | |||
| e70695077a | |||
| 0af207b625 | |||
| 1022b297d4 | |||
| 7f6b4da8eb | |||
| 0b06e20464 | |||
| 188507a8ac | |||
| 6f901bc389 | |||
| 27024dfb03 | |||
| f3dfeb3bc4 | |||
| 7110183892 | |||
| 17816053f3 | |||
| 33aa2070c4 | |||
| 9b32c630dc | |||
| 56e6da12c3 | |||
| 4c8fcac9c7 | |||
| 840ddc15fe |
@@ -8,12 +8,12 @@ PROMETHEUS_IMAGE=prom/prometheus:v2.45.6
|
|||||||
ALERTMANAGER_IMAGE=prom/alertmanager:v0.27.0
|
ALERTMANAGER_IMAGE=prom/alertmanager:v0.27.0
|
||||||
GRAFANA_IMAGE=grafana/grafana:11.0.1
|
GRAFANA_IMAGE=grafana/grafana:11.0.1
|
||||||
|
|
||||||
OPENIM_WEB_FRONT_IMAGE=openim/openim-web-front:release-v3.8.1
|
OPENIM_WEB_FRONT_IMAGE=openim/openim-web-front:release-v3.8.0
|
||||||
OPENIM_ADMIN_FRONT_IMAGE=openim/openim-admin-front:release-v1.8.2
|
OPENIM_ADMIN_FRONT_IMAGE=openim/openim-admin-front:release-v1.8.0
|
||||||
|
|
||||||
#FRONT_IMAGE: use aliyun images
|
#FRONT_IMAGE: use aliyun images
|
||||||
#OPENIM_WEB_FRONT_IMAGE=registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web-front:release-v3.8.1
|
#OPENIM_WEB_FRONT_IMAGE=registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-web-front:release-v3.5.1
|
||||||
#OPENIM_ADMIN_FRONT_IMAGE=registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-admin-front:release-v1.8.2
|
#OPENIM_ADMIN_FRONT_IMAGE=registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-admin-front:release-v1.7
|
||||||
|
|
||||||
DATA_DIR=./
|
DATA_DIR=./
|
||||||
|
|
||||||
|
|||||||
@@ -89,65 +89,6 @@ jobs:
|
|||||||
mage start
|
mage start
|
||||||
mage check
|
mage check
|
||||||
|
|
||||||
go-test:
|
|
||||||
name: Benchmark Test with go ${{ matrix.go_version }} on ${{ matrix.os }}
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
env:
|
|
||||||
SDK_DIR: openim-sdk-core
|
|
||||||
CONFIG_PATH: config/notification.yml
|
|
||||||
# pull-requests: write
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ ubuntu-latest ]
|
|
||||||
go_version: [ "1.22.x" ]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout Server repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Checkout SDK repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: 'openimsdk/openim-sdk-core'
|
|
||||||
path: ${{ env.SDK_DIR }}
|
|
||||||
|
|
||||||
- name: Set up Go ${{ matrix.go_version }}
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go_version }}
|
|
||||||
|
|
||||||
- name: Get Server dependencies
|
|
||||||
run: |
|
|
||||||
go install github.com/magefile/mage@latest
|
|
||||||
go mod download
|
|
||||||
|
|
||||||
- name: Install yq
|
|
||||||
run: |
|
|
||||||
sudo wget https://github.com/mikefarah/yq/releases/download/v4.34.1/yq_linux_amd64 -O /usr/bin/yq
|
|
||||||
sudo chmod +x /usr/bin/yq
|
|
||||||
|
|
||||||
- name: Modify Server Configuration
|
|
||||||
run: |
|
|
||||||
yq e '.groupCreated.unreadCount = true' -i ${{ env.CONFIG_PATH }}
|
|
||||||
yq e '.friendApplicationApproved.unreadCount = true' -i ${{ env.CONFIG_PATH }}
|
|
||||||
|
|
||||||
- name: Start Server Services
|
|
||||||
run: |
|
|
||||||
docker compose up -d
|
|
||||||
mage build
|
|
||||||
mage start
|
|
||||||
mage check
|
|
||||||
|
|
||||||
- name: Build test SDK core
|
|
||||||
run: |
|
|
||||||
cd ${{ env.SDK_DIR }}
|
|
||||||
go mod tidy
|
|
||||||
cd integration_test
|
|
||||||
mkdir data
|
|
||||||
go run main.go -lgr 0.8 -imf -crg -ckgn -ckcon -sem -ckmsn -u 20 -su 5 -lg 2 -cg 2 -cgm 3 -sm 10 -gm 10 -reg
|
|
||||||
|
|
||||||
dockerfile-test:
|
dockerfile-test:
|
||||||
name: Build and Test Dockerfile
|
name: Build and Test Dockerfile
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- release-*
|
- release-*
|
||||||
# tags:
|
|
||||||
# - 'v*'
|
|
||||||
|
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
@@ -17,8 +15,11 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
default: "v3.8.0"
|
default: "v3.8.0"
|
||||||
|
|
||||||
|
# env:
|
||||||
|
# GO_VERSION: "1.21"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-test:
|
publish-docker-images:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -27,22 +28,16 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build and push Docker image
|
||||||
id: build
|
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: ./main-repo
|
context: ./main-repo
|
||||||
load: true
|
load: true
|
||||||
tags: "openim/openim-server:local"
|
tags: "openim/openim-server:local"
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
|
|
||||||
- name: Save Docker image to file
|
|
||||||
run: docker save -o image.tar openim/openim-server:local
|
|
||||||
|
|
||||||
- name: Checkout compose repository
|
- name: Checkout compose repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -68,39 +63,38 @@ jobs:
|
|||||||
docker compose up -d
|
docker compose up -d
|
||||||
sleep 60
|
sleep 60
|
||||||
|
|
||||||
# - name: Check openim-server health
|
- name: Check openim-server health
|
||||||
# run: |
|
run: |
|
||||||
# timeout=300
|
timeout=300
|
||||||
# interval=30
|
interval=30
|
||||||
# elapsed=0
|
elapsed=0
|
||||||
# while [[ $elapsed -le $timeout ]]; do
|
while [[ $elapsed -le $timeout ]]; do
|
||||||
# if ! docker exec openim-server mage check; then
|
if ! docker exec openim-server mage check; then
|
||||||
# echo "openim-server is not ready, waiting..."
|
echo "openim-server is not ready, waiting..."
|
||||||
# sleep $interval
|
sleep $interval
|
||||||
# elapsed=$(($elapsed + $interval))
|
elapsed=$(($elapsed + $interval))
|
||||||
# else
|
else
|
||||||
# echo "Health check successful"
|
echo "Health check successful"
|
||||||
# exit 0
|
exit 0
|
||||||
# fi
|
fi
|
||||||
# done
|
done
|
||||||
# echo "Health check failed after 5 minutes"
|
echo "Health check failed after 5 minutes"
|
||||||
# exit 1
|
exit 1
|
||||||
|
|
||||||
# - name: Check openim-chat health
|
- name: Check openim-chat health
|
||||||
# if: success()
|
if: success()
|
||||||
# run: |
|
run: |
|
||||||
# if ! docker exec openim-chat mage check; then
|
if ! docker exec openim-chat mage check; then
|
||||||
# echo "openim-chat check failed"
|
echo "openim-chat check failed"
|
||||||
# exit 1
|
exit 1
|
||||||
# else
|
else
|
||||||
# echo "Health check successful"
|
echo "Health check successful"
|
||||||
# exit 0
|
exit 0
|
||||||
# fi
|
fi
|
||||||
|
|
||||||
- name: Load Docker image from file
|
|
||||||
run: docker load -i image.tar
|
|
||||||
|
|
||||||
- name: Extract metadata for Docker (tags, labels)
|
- name: Extract metadata for Docker # (tags, labels)
|
||||||
|
if: success()
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v5.5.1
|
uses: docker/metadata-action@v5.5.1
|
||||||
with:
|
with:
|
||||||
@@ -108,17 +102,18 @@ jobs:
|
|||||||
openim/openim-server
|
openim/openim-server
|
||||||
ghcr.io/openimsdk/openim-server
|
ghcr.io/openimsdk/openim-server
|
||||||
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server
|
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server
|
||||||
|
|
||||||
|
# generate Docker tags based on the following events/attributes
|
||||||
tags: |
|
tags: |
|
||||||
type=ref,event=tag
|
type=ref,event=tag
|
||||||
type=schedule
|
type=schedule
|
||||||
type=ref,event=branch
|
type=ref,event=branch
|
||||||
|
type=ref,event=pr
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
type=semver,pattern=v{{version}}
|
type=semver,pattern=v{{version}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
type=semver,pattern=release-{{raw}}
|
|
||||||
type=sha
|
type=sha
|
||||||
type=raw,value=${{ github.event.inputs.tag }}
|
|
||||||
|
|
||||||
- name: Log in to Docker Hub
|
- name: Log in to Docker Hub
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
@@ -140,7 +135,7 @@ jobs:
|
|||||||
username: ${{ secrets.ALIREGISTRY_USERNAME }}
|
username: ${{ secrets.ALIREGISTRY_USERNAME }}
|
||||||
password: ${{ secrets.ALIREGISTRY_TOKEN }}
|
password: ${{ secrets.ALIREGISTRY_TOKEN }}
|
||||||
|
|
||||||
- name: Push Docker images
|
- name: Build and push Docker images
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: ./main-repo
|
context: ./main-repo
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# Use Go 1.21 Alpine as the base image for building the application
|
# Use Go 1.21 Alpine as the base image for building the application
|
||||||
FROM golang:1.21-alpine AS builder
|
FROM golang:1.21-alpine as builder
|
||||||
|
|
||||||
# Define the base directory for the application as an environment variable
|
# Define the base directory for the application as an environment variable
|
||||||
ENV SERVER_DIR=/openim-server
|
ENV SERVER_DIR=/openim-server
|
||||||
|
|||||||
@@ -23,4 +23,5 @@ longConnSvr:
|
|||||||
# WebSocket connection handshake timeout in seconds
|
# WebSocket connection handshake timeout in seconds
|
||||||
websocketTimeout: 10
|
websocketTimeout: 10
|
||||||
|
|
||||||
|
# 1: For Android, iOS, Windows, Mac, and web platforms, only one instance can be online at a time
|
||||||
|
multiLoginPolicy: 1
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ prometheus:
|
|||||||
enable: true
|
enable: true
|
||||||
# List of ports that Prometheus listens on; each port corresponds to an instance of monitoring. Ensure these are managed accordingly
|
# List of ports that Prometheus listens on; each port corresponds to an instance of monitoring. Ensure these are managed accordingly
|
||||||
# Because four instances have been launched, four ports need to be specified
|
# Because four instances have been launched, four ports need to be specified
|
||||||
ports: [ 12020, 12021, 12022, 12023, 12024, 12025, 12026, 12027, 12028, 12029, 12030, 12031, 12032, 12033, 12034, 12035 ]
|
ports: [ 12020, 12021, 12022, 12023, 12024, 12025, 12026, 12027 ]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ prometheus:
|
|||||||
# Enable or disable Prometheus monitoring
|
# Enable or disable Prometheus monitoring
|
||||||
enable: true
|
enable: true
|
||||||
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
|
# List of ports that Prometheus listens on; these must match the number of rpc.ports to ensure correct monitoring setup
|
||||||
ports: [ 12170, 12171, 12172, 12173, 12174, 12175, 12176, 12177, 12178, 12179, 12180, 12182, 12183, 12184, 12185, 12186 ]
|
ports: [ 12170, 12171, 12172, 12173, 12174, 12175, 12176, 12177, 12178, 12179, 12180, 12181, 12182, 12183, 12184, 12185 ]
|
||||||
|
|
||||||
maxConcurrentWorkers: 3
|
maxConcurrentWorkers: 3
|
||||||
#Use geTui for offline push notifications, or choose fcm or jpns; corresponding configuration settings must be specified.
|
#Use geTui for offline push notifications, or choose fcm or jpns; corresponding configuration settings must be specified.
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ scrape_configs:
|
|||||||
- job_name: openimserver-openim-push
|
- job_name: openimserver-openim-push
|
||||||
static_configs:
|
static_configs:
|
||||||
- targets: [ internal_ip:12170, internal_ip:12171, internal_ip:12172, internal_ip:12173, internal_ip:12174, internal_ip:12175, internal_ip:12176, internal_ip:12177 ]
|
- targets: [ internal_ip:12170, internal_ip:12171, internal_ip:12172, internal_ip:12173, internal_ip:12174, internal_ip:12175, internal_ip:12176, internal_ip:12177 ]
|
||||||
# - targets: [ internal_ip:12170, internal_ip:12171, internal_ip:12172, internal_ip:12173, internal_ip:12174, internal_ip:12175, internal_ip:12176, internal_ip:12177, internal_ip:12178, internal_ip:12179, internal_ip:12180, internal_ip:12182, internal_ip:12183, internal_ip:12184, internal_ip:12185, internal_ip:12186 ]
|
# - targets: [ internal_ip:12170, internal_ip:12171, internal_ip:12172, internal_ip:12173, internal_ip:12174, internal_ip:12175, internal_ip:12176, internal_ip:12177, internal_ip:12178, internal_ip:12179, internal_ip:12180, internal_ip:12181, internal_ip:12182, internal_ip:12183, internal_ip:12184, internal_ip:12185 ]
|
||||||
labels:
|
labels:
|
||||||
namespace: default
|
namespace: default
|
||||||
- job_name: openimserver-openim-rpc-auth
|
- job_name: openimserver-openim-rpc-auth
|
||||||
|
|||||||
@@ -12,5 +12,3 @@ rpcRegisterName:
|
|||||||
|
|
||||||
imAdminUserID: [ imAdmin ]
|
imAdminUserID: [ imAdmin ]
|
||||||
|
|
||||||
# 1: For Android, iOS, Windows, Mac, and web platforms, only one instance can be online at a time
|
|
||||||
multiLoginPolicy: 1
|
|
||||||
|
|||||||
+1
-26
@@ -1,18 +1,8 @@
|
|||||||
url: http://127.0.0.1:10006/callbackExample
|
url: webhook://127.0.0.1:10008/callbackExample
|
||||||
beforeSendSingleMsg:
|
beforeSendSingleMsg:
|
||||||
enable: false
|
enable: false
|
||||||
timeout: 5
|
timeout: 5
|
||||||
failedContinue: true
|
failedContinue: true
|
||||||
# Only the contentType in allowedTypes will send the callback.
|
|
||||||
# Supports two formats: a single type or a range. The range is defined by the lower and upper bounds connected with a hyphen ("-").
|
|
||||||
# e.g. allowedTypes: [1, 100, 200-500, 600-700] means that only contentType within the range
|
|
||||||
# {1, 100} ∪ [200, 500] ∪ [600, 700] will be allowed through the filter.
|
|
||||||
# If not set, all contentType messages will through this filter.
|
|
||||||
allowedTypes: []
|
|
||||||
# Only the contentType not in deniedTypes will send the callback.
|
|
||||||
# Supports two formats, same as allowedTypes.
|
|
||||||
# If not set, all contentType messages will through this filter.
|
|
||||||
deniedTypes: []
|
|
||||||
beforeUpdateUserInfoEx:
|
beforeUpdateUserInfoEx:
|
||||||
enable: false
|
enable: false
|
||||||
timeout: 5
|
timeout: 5
|
||||||
@@ -26,29 +16,17 @@ afterSendSingleMsg:
|
|||||||
# Only the senID/recvID specified in attentionIds will send the callback
|
# Only the senID/recvID specified in attentionIds will send the callback
|
||||||
# if not set, all user messages will be callback
|
# if not set, all user messages will be callback
|
||||||
attentionIds: []
|
attentionIds: []
|
||||||
# See beforeSendSingleMsg comment.
|
|
||||||
allowedTypes: []
|
|
||||||
deniedTypes: []
|
|
||||||
beforeSendGroupMsg:
|
beforeSendGroupMsg:
|
||||||
enable: false
|
enable: false
|
||||||
timeout: 5
|
timeout: 5
|
||||||
failedContinue: true
|
failedContinue: true
|
||||||
# See beforeSendSingleMsg comment.
|
|
||||||
allowedTypes: []
|
|
||||||
deniedTypes: []
|
|
||||||
beforeMsgModify:
|
beforeMsgModify:
|
||||||
enable: false
|
enable: false
|
||||||
timeout: 5
|
timeout: 5
|
||||||
failedContinue: true
|
failedContinue: true
|
||||||
# See beforeSendSingleMsg comment.
|
|
||||||
allowedTypes: []
|
|
||||||
deniedTypes: []
|
|
||||||
afterSendGroupMsg:
|
afterSendGroupMsg:
|
||||||
enable: false
|
enable: false
|
||||||
timeout: 5
|
timeout: 5
|
||||||
# See beforeSendSingleMsg comment.
|
|
||||||
allowedTypes: []
|
|
||||||
deniedTypes: []
|
|
||||||
afterUserOnline:
|
afterUserOnline:
|
||||||
enable: false
|
enable: false
|
||||||
timeout: 5
|
timeout: 5
|
||||||
@@ -173,9 +151,6 @@ beforeAddFriendAgree:
|
|||||||
enable: false
|
enable: false
|
||||||
timeout: 5
|
timeout: 5
|
||||||
failedContinue: true
|
failedContinue: true
|
||||||
afterAddFriendAgree:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
afterDeleteFriend:
|
afterDeleteFriend:
|
||||||
enable: false
|
enable: false
|
||||||
timeout: 5
|
timeout: 5
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
openim:
|
openim:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module github.com/openimsdk/open-im-server/v3
|
|||||||
go 1.21.2
|
go 1.21.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
firebase.google.com/go/v4 v4.14.1
|
firebase.google.com/go v3.13.0+incompatible
|
||||||
github.com/dtm-labs/rockscache v0.1.1
|
github.com/dtm-labs/rockscache v0.1.1
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
github.com/go-playground/validator/v10 v10.20.0
|
github.com/go-playground/validator/v10 v10.20.0
|
||||||
@@ -12,13 +12,13 @@ require (
|
|||||||
github.com/gorilla/websocket v1.5.1
|
github.com/gorilla/websocket v1.5.1
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/openimsdk/protocol v0.0.72
|
github.com/openimsdk/protocol v0.0.72-alpha.24
|
||||||
github.com/openimsdk/tools v0.0.50-alpha.16
|
github.com/openimsdk/tools v0.0.50-alpha.12
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/prometheus/client_golang v1.18.0
|
github.com/prometheus/client_golang v1.18.0
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
go.mongodb.org/mongo-driver v1.14.0
|
go.mongodb.org/mongo-driver v1.14.0
|
||||||
google.golang.org/api v0.170.0
|
google.golang.org/api v0.165.0
|
||||||
google.golang.org/grpc v1.66.2
|
google.golang.org/grpc v1.66.2
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
@@ -47,13 +47,12 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.112.1 // indirect
|
cloud.google.com/go v0.112.0 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||||
cloud.google.com/go/firestore v1.15.0 // indirect
|
cloud.google.com/go/firestore v1.14.0 // indirect
|
||||||
cloud.google.com/go/iam v1.1.7 // indirect
|
cloud.google.com/go/iam v1.1.5 // indirect
|
||||||
cloud.google.com/go/longrunning v0.5.5 // indirect
|
cloud.google.com/go/longrunning v0.5.4 // indirect
|
||||||
cloud.google.com/go/storage v1.40.0 // indirect
|
cloud.google.com/go/storage v1.36.0 // indirect
|
||||||
github.com/MicahParks/keyfunc v1.9.0 // indirect
|
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible // indirect
|
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible // indirect
|
||||||
github.com/aws/aws-sdk-go-v2 v1.23.1 // indirect
|
github.com/aws/aws-sdk-go-v2 v1.23.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.1 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.1 // indirect
|
||||||
@@ -103,7 +102,7 @@ require (
|
|||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/s2a-go v0.1.7 // indirect
|
github.com/google/s2a-go v0.1.7 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
|
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||||
@@ -165,11 +164,11 @@ require (
|
|||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
|
go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
|
||||||
go.etcd.io/etcd/client/v3 v3.5.13 // indirect
|
go.etcd.io/etcd/client/v3 v3.5.13 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
go.opentelemetry.io/otel v1.23.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
go.opentelemetry.io/otel/metric v1.23.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
go.opentelemetry.io/otel/trace v1.23.0 // indirect
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/arch v0.7.0 // indirect
|
golang.org/x/arch v0.7.0 // indirect
|
||||||
@@ -179,8 +178,8 @@ require (
|
|||||||
golang.org/x/sys v0.25.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
golang.org/x/text v0.18.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
google.golang.org/appengine/v2 v2.0.2 // indirect
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
|
google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||||
gorm.io/gorm v1.25.8 // indirect
|
gorm.io/gorm v1.25.8 // indirect
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
|
cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM=
|
||||||
cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
|
cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4=
|
||||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||||
cloud.google.com/go/firestore v1.15.0 h1:/k8ppuWOtNuDHt2tsRV42yI21uaGnKDEQnRFeBpbFF8=
|
cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw=
|
||||||
cloud.google.com/go/firestore v1.15.0/go.mod h1:GWOxFXcv8GZUtYpWHw/w6IuYNux/BtmeVTMmjrm4yhk=
|
cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=
|
||||||
cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM=
|
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
|
||||||
cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA=
|
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||||
cloud.google.com/go/longrunning v0.5.5 h1:GOE6pZFdSrTb4KAiKnXsJBtlE6mEyaW44oKyMILWnOg=
|
cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg=
|
||||||
cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s=
|
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
|
||||||
cloud.google.com/go/storage v1.40.0 h1:VEpDQV5CJxFmJ6ueWNsKxcr1QAYOXEgxDa+sBbJahPw=
|
cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8=
|
||||||
cloud.google.com/go/storage v1.40.0/go.mod h1:Rrj7/hKlG87BLqDJYtwR0fbPld8uJPbQ2ucUMY7Ir0g=
|
cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
||||||
firebase.google.com/go/v4 v4.14.1 h1:4qiUETaFRWoFGE1XP5VbcEdtPX93Qs+8B/7KvP2825g=
|
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
|
||||||
firebase.google.com/go/v4 v4.14.1/go.mod h1:fgk2XshgNDEKaioKco+AouiegSI9oTWVqRaBdTTGBoM=
|
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/IBM/sarama v1.43.0 h1:YFFDn8mMI2QL0wOrG0J2sFoVIAFl7hS9JQi2YZsXtJc=
|
github.com/IBM/sarama v1.43.0 h1:YFFDn8mMI2QL0wOrG0J2sFoVIAFl7hS9JQi2YZsXtJc=
|
||||||
github.com/IBM/sarama v1.43.0/go.mod h1:zlE6HEbC/SMQ9mhEYaF7nNLYOUyrs0obySKCckWP9BM=
|
github.com/IBM/sarama v1.43.0/go.mod h1:zlE6HEbC/SMQ9mhEYaF7nNLYOUyrs0obySKCckWP9BM=
|
||||||
github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o=
|
|
||||||
github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw=
|
|
||||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
|
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||||
@@ -80,6 +78,8 @@ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJ
|
|||||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
|
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
|
||||||
@@ -107,6 +107,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
|
||||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
||||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
||||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
@@ -157,7 +159,6 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
|
|||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
@@ -166,7 +167,6 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
|
|||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
@@ -175,6 +175,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
@@ -186,6 +188,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
@@ -202,8 +205,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
|||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||||
github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA=
|
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
|
||||||
github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4=
|
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
||||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||||
@@ -319,10 +322,10 @@ github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y=
|
|||||||
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
|
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
|
||||||
github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y=
|
github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y=
|
||||||
github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
|
github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
|
||||||
github.com/openimsdk/protocol v0.0.72 h1:K+vslwaR7lDXyBzb07UuEQITaqsgighz7NyXVIWsu6A=
|
github.com/openimsdk/protocol v0.0.72-alpha.24 h1:1Dl8TEZVXhdmve+ewoLkJa2wbFBIHqPgjvr9u/J66JM=
|
||||||
github.com/openimsdk/protocol v0.0.72/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
|
github.com/openimsdk/protocol v0.0.72-alpha.24/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
|
||||||
github.com/openimsdk/tools v0.0.50-alpha.16 h1:bC1AQvJMuOHtZm8LZRvN8L5mH1Ws2VYdL+TLTs1iGSc=
|
github.com/openimsdk/tools v0.0.50-alpha.12 h1:rV3BxgqN+F79vZvdoQ+97Eob8ScsRVEM8D+Wrcl23uo=
|
||||||
github.com/openimsdk/tools v0.0.50-alpha.16/go.mod h1:h1cYmfyaVtgFbKmb1Cfsl8XwUOMTt8ubVUQrdGtsUh4=
|
github.com/openimsdk/tools v0.0.50-alpha.12/go.mod h1:h1cYmfyaVtgFbKmb1Cfsl8XwUOMTt8ubVUQrdGtsUh4=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||||
@@ -433,18 +436,18 @@ go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd
|
|||||||
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw=
|
||||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
go.opentelemetry.io/otel v1.23.0 h1:Df0pqjqExIywbMCMTxkAwzjLZtRf+bBKLbUcpxO2C9E=
|
||||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0=
|
||||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo=
|
||||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
|
||||||
go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
|
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||||
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
|
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI=
|
||||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
|
||||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
||||||
@@ -489,7 +492,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
@@ -552,19 +554,19 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||||
google.golang.org/api v0.170.0 h1:zMaruDePM88zxZBG+NG8+reALO2rfLhe/JShitLyT48=
|
google.golang.org/api v0.165.0 h1:zd5d4JIIIaYYsfVy1HzoXYZ9rWCSBxxAglbczzo7Bgc=
|
||||||
google.golang.org/api v0.170.0/go.mod h1:/xql9M2btF85xac/VAm4PsLMTLVGUOpq4BE9R8jyNy8=
|
google.golang.org/api v0.165.0/go.mod h1:2OatzO7ZDQsoS7IFf3rvsE17/TldiU3F/zxFHeqUB5o=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine/v2 v2.0.2 h1:MSqyWy2shDLwG7chbwBJ5uMyw6SNqJzhJHNDwYB0Akk=
|
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||||
google.golang.org/appengine/v2 v2.0.2/go.mod h1:PkgRUWz4o1XOvbqtWTkBtCitEJ5Tp4HoVEdMMYQR/8E=
|
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
|
google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe h1:USL2DhxfgRchafRvt/wYyyQNzwgL7ZiURcozOE/Pkvo=
|
||||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
|
google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||||
@@ -585,6 +587,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ func NewAuthApi(client rpcclient.Auth) AuthApi {
|
|||||||
return AuthApi(client)
|
return AuthApi(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *AuthApi) GetAdminToken(c *gin.Context) {
|
func (o *AuthApi) UserToken(c *gin.Context) {
|
||||||
a2r.Call(auth.AuthClient.GetAdminToken, o.Client, c)
|
a2r.Call(auth.AuthClient.UserToken, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *AuthApi) GetUserToken(c *gin.Context) {
|
func (o *AuthApi) GetUserToken(c *gin.Context) {
|
||||||
|
|||||||
@@ -62,11 +62,3 @@ func (o *ConversationApi) GetIncrementalConversation(c *gin.Context) {
|
|||||||
func (o *ConversationApi) GetOwnerConversation(c *gin.Context) {
|
func (o *ConversationApi) GetOwnerConversation(c *gin.Context) {
|
||||||
a2r.Call(conversation.ConversationClient.GetOwnerConversation, o.Client, c)
|
a2r.Call(conversation.ConversationClient.GetOwnerConversation, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ConversationApi) GetNotNotifyConversationIDs(c *gin.Context) {
|
|
||||||
a2r.Call(conversation.ConversationClient.GetNotNotifyConversationIDs, o.Client, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *ConversationApi) GetPinnedConversationIDs(c *gin.Context) {
|
|
||||||
a2r.Call(conversation.ConversationClient.GetPinnedConversationIDs, o.Client, c)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -72,10 +72,6 @@ func (o *FriendApi) GetPaginationBlacks(c *gin.Context) {
|
|||||||
a2r.Call(relation.FriendClient.GetPaginationBlacks, o.Client, c)
|
a2r.Call(relation.FriendClient.GetPaginationBlacks, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *FriendApi) GetSpecifiedBlacks(c *gin.Context) {
|
|
||||||
a2r.Call(relation.FriendClient.GetSpecifiedBlacks, o.Client, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *FriendApi) RemoveBlack(c *gin.Context) {
|
func (o *FriendApi) RemoveBlack(c *gin.Context) {
|
||||||
a2r.Call(relation.FriendClient.RemoveBlack, o.Client, c)
|
a2r.Call(relation.FriendClient.RemoveBlack, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,10 +67,6 @@ func (o *GroupApi) GetGroupUsersReqApplicationList(c *gin.Context) {
|
|||||||
a2r.Call(group.GroupClient.GetGroupUsersReqApplicationList, o.Client, c)
|
a2r.Call(group.GroupClient.GetGroupUsersReqApplicationList, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *GroupApi) GetSpecifiedUserGroupRequestInfo(c *gin.Context) {
|
|
||||||
a2r.Call(group.GroupClient.GetSpecifiedUserGroupRequestInfo, o.Client, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *GroupApi) GetGroupsInfo(c *gin.Context) {
|
func (o *GroupApi) GetGroupsInfo(c *gin.Context) {
|
||||||
a2r.Call(group.GroupClient.GetGroupsInfo, o.Client, c)
|
a2r.Call(group.GroupClient.GetGroupsInfo, o.Client, c)
|
||||||
//a2r.Call(group.GroupClient.GetGroupsInfo, o.Client, c, a2r.NewNilReplaceOption(group.GroupClient.GetGroupsInfo))
|
//a2r.Call(group.GroupClient.GetGroupsInfo, o.Client, c, a2r.NewNilReplaceOption(group.GroupClient.GetGroupsInfo))
|
||||||
|
|||||||
@@ -1,204 +0,0 @@
|
|||||||
package jssdk
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/openimsdk/protocol/conversation"
|
|
||||||
"github.com/openimsdk/protocol/msg"
|
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
|
||||||
"github.com/openimsdk/tools/a2r"
|
|
||||||
"github.com/openimsdk/tools/mcontext"
|
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
maxGetActiveConversation = 500
|
|
||||||
defaultGetActiveConversation = 100
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewJSSdkApi(msg msg.MsgClient, conv conversation.ConversationClient) *JSSdk {
|
|
||||||
return &JSSdk{
|
|
||||||
msg: msg,
|
|
||||||
conv: conv,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type JSSdk struct {
|
|
||||||
msg msg.MsgClient
|
|
||||||
conv conversation.ConversationClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *JSSdk) GetActiveConversations(c *gin.Context) {
|
|
||||||
call(c, x.getActiveConversations)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *JSSdk) GetConversations(c *gin.Context) {
|
|
||||||
call(c, x.getConversations)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *JSSdk) getActiveConversations(ctx *gin.Context) (*ConversationsResp, error) {
|
|
||||||
req, err := a2r.ParseRequest[ActiveConversationsReq](ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if req.Count <= 0 || req.Count > maxGetActiveConversation {
|
|
||||||
req.Count = defaultGetActiveConversation
|
|
||||||
}
|
|
||||||
opUserID := mcontext.GetOpUserID(ctx)
|
|
||||||
conversationIDs, err := field(ctx, x.conv.GetConversationIDs,
|
|
||||||
&conversation.GetConversationIDsReq{UserID: opUserID}, (*conversation.GetConversationIDsResp).GetConversationIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(conversationIDs) == 0 {
|
|
||||||
return &ConversationsResp{}, nil
|
|
||||||
}
|
|
||||||
readSeq, err := field(ctx, x.msg.GetHasReadSeqs,
|
|
||||||
&msg.GetHasReadSeqsReq{UserID: opUserID, ConversationIDs: conversationIDs}, (*msg.SeqsInfoResp).GetMaxSeqs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
activeConversation, err := field(ctx, x.msg.GetActiveConversation,
|
|
||||||
&msg.GetActiveConversationReq{ConversationIDs: conversationIDs}, (*msg.GetActiveConversationResp).GetConversations)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(activeConversation) == 0 {
|
|
||||||
return &ConversationsResp{}, nil
|
|
||||||
}
|
|
||||||
sortConversations := sortActiveConversations{
|
|
||||||
Conversation: activeConversation,
|
|
||||||
}
|
|
||||||
if len(activeConversation) > 1 {
|
|
||||||
pinnedConversationIDs, err := field(ctx, x.conv.GetPinnedConversationIDs,
|
|
||||||
&conversation.GetPinnedConversationIDsReq{UserID: opUserID}, (*conversation.GetPinnedConversationIDsResp).GetConversationIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
sortConversations.PinnedConversationIDs = datautil.SliceSet(pinnedConversationIDs)
|
|
||||||
}
|
|
||||||
sort.Sort(&sortConversations)
|
|
||||||
sortList := sortConversations.Top(req.Count)
|
|
||||||
conversations, err := field(ctx, x.conv.GetConversations,
|
|
||||||
&conversation.GetConversationsReq{
|
|
||||||
OwnerUserID: opUserID,
|
|
||||||
ConversationIDs: datautil.Slice(sortList, func(c *msg.ActiveConversation) string {
|
|
||||||
return c.ConversationID
|
|
||||||
})}, (*conversation.GetConversationsResp).GetConversations)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
msgs, err := field(ctx, x.msg.GetSeqMessage,
|
|
||||||
&msg.GetSeqMessageReq{
|
|
||||||
UserID: opUserID,
|
|
||||||
Conversations: datautil.Slice(sortList, func(c *msg.ActiveConversation) *msg.ConversationSeqs {
|
|
||||||
return &msg.ConversationSeqs{
|
|
||||||
ConversationID: c.ConversationID,
|
|
||||||
Seqs: []int64{c.MaxSeq},
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}, (*msg.GetSeqMessageResp).GetMsgs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
conversationMap := datautil.SliceToMap(conversations, func(c *conversation.Conversation) string {
|
|
||||||
return c.ConversationID
|
|
||||||
})
|
|
||||||
resp := make([]ConversationMsg, 0, len(sortList))
|
|
||||||
for _, c := range sortList {
|
|
||||||
conv, ok := conversationMap[c.ConversationID]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var lastMsg *sdkws.MsgData
|
|
||||||
if msgList, ok := msgs[c.ConversationID]; ok && len(msgList.Msgs) > 0 {
|
|
||||||
lastMsg = msgList.Msgs[0]
|
|
||||||
}
|
|
||||||
resp = append(resp, ConversationMsg{
|
|
||||||
Conversation: conv,
|
|
||||||
LastMsg: lastMsg,
|
|
||||||
MaxSeq: c.MaxSeq,
|
|
||||||
ReadSeq: readSeq[c.ConversationID],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
var unreadCount int64
|
|
||||||
for _, c := range activeConversation {
|
|
||||||
count := c.MaxSeq - readSeq[c.ConversationID]
|
|
||||||
if count > 0 {
|
|
||||||
unreadCount += count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &ConversationsResp{
|
|
||||||
Conversations: resp,
|
|
||||||
UnreadCount: unreadCount,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *JSSdk) getConversations(ctx *gin.Context) (*ConversationsResp, error) {
|
|
||||||
req, err := a2r.ParseRequest[conversation.GetConversationsReq](ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.OwnerUserID = mcontext.GetOpUserID(ctx)
|
|
||||||
conversations, err := field(ctx, x.conv.GetConversations, req, (*conversation.GetConversationsResp).GetConversations)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(conversations) == 0 {
|
|
||||||
return &ConversationsResp{}, nil
|
|
||||||
}
|
|
||||||
req.ConversationIDs = datautil.Slice(conversations, func(c *conversation.Conversation) string {
|
|
||||||
return c.ConversationID
|
|
||||||
})
|
|
||||||
maxSeqs, err := field(ctx, x.msg.GetMaxSeqs,
|
|
||||||
&msg.GetMaxSeqsReq{ConversationIDs: req.ConversationIDs}, (*msg.SeqsInfoResp).GetMaxSeqs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
readSeqs, err := field(ctx, x.msg.GetHasReadSeqs,
|
|
||||||
&msg.GetHasReadSeqsReq{UserID: req.OwnerUserID, ConversationIDs: req.ConversationIDs}, (*msg.SeqsInfoResp).GetMaxSeqs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
conversationSeqs := make([]*msg.ConversationSeqs, 0, len(conversations))
|
|
||||||
for _, c := range conversations {
|
|
||||||
if seq := maxSeqs[c.ConversationID]; seq > 0 {
|
|
||||||
conversationSeqs = append(conversationSeqs, &msg.ConversationSeqs{
|
|
||||||
ConversationID: c.ConversationID,
|
|
||||||
Seqs: []int64{seq},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var msgs map[string]*sdkws.PullMsgs
|
|
||||||
if len(conversationSeqs) > 0 {
|
|
||||||
msgs, err = field(ctx, x.msg.GetSeqMessage,
|
|
||||||
&msg.GetSeqMessageReq{UserID: req.OwnerUserID, Conversations: conversationSeqs}, (*msg.GetSeqMessageResp).GetMsgs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resp := make([]ConversationMsg, 0, len(conversations))
|
|
||||||
for _, c := range conversations {
|
|
||||||
var lastMsg *sdkws.MsgData
|
|
||||||
if msgList, ok := msgs[c.ConversationID]; ok && len(msgList.Msgs) > 0 {
|
|
||||||
lastMsg = msgList.Msgs[0]
|
|
||||||
}
|
|
||||||
resp = append(resp, ConversationMsg{
|
|
||||||
Conversation: c,
|
|
||||||
LastMsg: lastMsg,
|
|
||||||
MaxSeq: maxSeqs[c.ConversationID],
|
|
||||||
ReadSeq: readSeqs[c.ConversationID],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
var unreadCount int64
|
|
||||||
for conversationID, maxSeq := range maxSeqs {
|
|
||||||
count := maxSeq - readSeqs[conversationID]
|
|
||||||
if count > 0 {
|
|
||||||
unreadCount += count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &ConversationsResp{
|
|
||||||
Conversations: resp,
|
|
||||||
UnreadCount: unreadCount,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package jssdk
|
|
||||||
|
|
||||||
import "github.com/openimsdk/protocol/msg"
|
|
||||||
|
|
||||||
type sortActiveConversations struct {
|
|
||||||
Conversation []*msg.ActiveConversation
|
|
||||||
PinnedConversationIDs map[string]struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s sortActiveConversations) Top(limit int) []*msg.ActiveConversation {
|
|
||||||
if limit > 0 && len(s.Conversation) > limit {
|
|
||||||
return s.Conversation[:limit]
|
|
||||||
}
|
|
||||||
return s.Conversation
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s sortActiveConversations) Len() int {
|
|
||||||
return len(s.Conversation)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s sortActiveConversations) Less(i, j int) bool {
|
|
||||||
iv, jv := s.Conversation[i], s.Conversation[j]
|
|
||||||
_, ip := s.PinnedConversationIDs[iv.ConversationID]
|
|
||||||
_, jp := s.PinnedConversationIDs[jv.ConversationID]
|
|
||||||
if ip != jp {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
return iv.LastTime > jv.LastTime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s sortActiveConversations) Swap(i, j int) {
|
|
||||||
s.Conversation[i], s.Conversation[j] = s.Conversation[j], s.Conversation[i]
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package jssdk
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/openimsdk/protocol/conversation"
|
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ActiveConversationsReq struct {
|
|
||||||
Count int `json:"count"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ConversationMsg struct {
|
|
||||||
Conversation *conversation.Conversation `json:"conversation"`
|
|
||||||
LastMsg *sdkws.MsgData `json:"lastMsg"`
|
|
||||||
MaxSeq int64 `json:"maxSeq"`
|
|
||||||
ReadSeq int64 `json:"readSeq"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ConversationsResp struct {
|
|
||||||
UnreadCount int64 `json:"unreadCount"`
|
|
||||||
Conversations []ConversationMsg `json:"conversations"`
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package jssdk
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/openimsdk/tools/apiresp"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func field[A, B, C any](ctx context.Context, fn func(ctx context.Context, req *A, opts ...grpc.CallOption) (*B, error), req *A, get func(*B) C) (C, error) {
|
|
||||||
resp, err := fn(ctx, req)
|
|
||||||
if err != nil {
|
|
||||||
var c C
|
|
||||||
return c, err
|
|
||||||
}
|
|
||||||
return get(resp), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func call[R any](c *gin.Context, fn func(ctx *gin.Context) (R, error)) {
|
|
||||||
resp, err := fn(c)
|
|
||||||
if err != nil {
|
|
||||||
apiresp.GinError(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
apiresp.GinSuccess(c, resp)
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/openimsdk/protocol/msg"
|
|
||||||
"sort"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestName(t *testing.T) {
|
|
||||||
val := sortActiveConversations{
|
|
||||||
Conversation: []*msg.ActiveConversation{
|
|
||||||
{
|
|
||||||
ConversationID: "100",
|
|
||||||
LastTime: 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ConversationID: "200",
|
|
||||||
LastTime: 200,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ConversationID: "300",
|
|
||||||
LastTime: 300,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ConversationID: "400",
|
|
||||||
LastTime: 400,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
//PinnedConversationIDs: map[string]struct{}{
|
|
||||||
// "100": {},
|
|
||||||
// "300": {},
|
|
||||||
//},
|
|
||||||
}
|
|
||||||
sort.Sort(&val)
|
|
||||||
t.Log(val)
|
|
||||||
|
|
||||||
}
|
|
||||||
+3
-15
@@ -2,9 +2,6 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/api/jssdk"
|
|
||||||
|
|
||||||
"github.com/gin-contrib/gzip"
|
"github.com/gin-contrib/gzip"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -77,7 +74,6 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
|||||||
r.Use(prommetricsGin(), gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID(), GinParseToken(authRpc))
|
r.Use(prommetricsGin(), gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID(), GinParseToken(authRpc))
|
||||||
u := NewUserApi(*userRpc)
|
u := NewUserApi(*userRpc)
|
||||||
m := NewMessageApi(messageRpc, userRpc, config.Share.IMAdminUserID)
|
m := NewMessageApi(messageRpc, userRpc, config.Share.IMAdminUserID)
|
||||||
j := jssdk.NewJSSdkApi(messageRpc.Client, conversationRpc.Client)
|
|
||||||
userRouterGroup := r.Group("/user")
|
userRouterGroup := r.Group("/user")
|
||||||
{
|
{
|
||||||
userRouterGroup.POST("/user_register", u.UserRegister)
|
userRouterGroup.POST("/user_register", u.UserRegister)
|
||||||
@@ -119,7 +115,6 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
|||||||
friendRouterGroup.POST("/set_friend_remark", f.SetFriendRemark)
|
friendRouterGroup.POST("/set_friend_remark", f.SetFriendRemark)
|
||||||
friendRouterGroup.POST("/add_black", f.AddBlack)
|
friendRouterGroup.POST("/add_black", f.AddBlack)
|
||||||
friendRouterGroup.POST("/get_black_list", f.GetPaginationBlacks)
|
friendRouterGroup.POST("/get_black_list", f.GetPaginationBlacks)
|
||||||
friendRouterGroup.POST("/get_specified_blacks", f.GetSpecifiedBlacks)
|
|
||||||
friendRouterGroup.POST("/remove_black", f.RemoveBlack)
|
friendRouterGroup.POST("/remove_black", f.RemoveBlack)
|
||||||
friendRouterGroup.POST("/get_incremental_blacks", f.GetIncrementalBlacks)
|
friendRouterGroup.POST("/get_incremental_blacks", f.GetIncrementalBlacks)
|
||||||
friendRouterGroup.POST("/import_friend", f.ImportFriends)
|
friendRouterGroup.POST("/import_friend", f.ImportFriends)
|
||||||
@@ -143,7 +138,6 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
|||||||
groupRouterGroup.POST("/get_recv_group_applicationList", g.GetRecvGroupApplicationList)
|
groupRouterGroup.POST("/get_recv_group_applicationList", g.GetRecvGroupApplicationList)
|
||||||
groupRouterGroup.POST("/get_user_req_group_applicationList", g.GetUserReqGroupApplicationList)
|
groupRouterGroup.POST("/get_user_req_group_applicationList", g.GetUserReqGroupApplicationList)
|
||||||
groupRouterGroup.POST("/get_group_users_req_application_list", g.GetGroupUsersReqApplicationList)
|
groupRouterGroup.POST("/get_group_users_req_application_list", g.GetGroupUsersReqApplicationList)
|
||||||
groupRouterGroup.POST("/get_specified_user_group_request_info", g.GetSpecifiedUserGroupRequestInfo)
|
|
||||||
groupRouterGroup.POST("/get_groups_info", g.GetGroupsInfo)
|
groupRouterGroup.POST("/get_groups_info", g.GetGroupsInfo)
|
||||||
groupRouterGroup.POST("/kick_group", g.KickGroupMember)
|
groupRouterGroup.POST("/kick_group", g.KickGroupMember)
|
||||||
groupRouterGroup.POST("/get_group_members_info", g.GetGroupMembersInfo)
|
groupRouterGroup.POST("/get_group_members_info", g.GetGroupMembersInfo)
|
||||||
@@ -169,7 +163,7 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
|||||||
authRouterGroup := r.Group("/auth")
|
authRouterGroup := r.Group("/auth")
|
||||||
{
|
{
|
||||||
a := NewAuthApi(*authRpc)
|
a := NewAuthApi(*authRpc)
|
||||||
authRouterGroup.POST("/get_admin_token", a.GetAdminToken)
|
authRouterGroup.POST("/user_token", a.UserToken)
|
||||||
authRouterGroup.POST("/get_user_token", a.GetUserToken)
|
authRouterGroup.POST("/get_user_token", a.GetUserToken)
|
||||||
authRouterGroup.POST("/parse_token", a.ParseToken)
|
authRouterGroup.POST("/parse_token", a.ParseToken)
|
||||||
authRouterGroup.POST("/force_logout", a.ForceLogout)
|
authRouterGroup.POST("/force_logout", a.ForceLogout)
|
||||||
@@ -236,8 +230,6 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
|||||||
conversationGroup.POST("/get_full_conversation_ids", c.GetFullOwnerConversationIDs)
|
conversationGroup.POST("/get_full_conversation_ids", c.GetFullOwnerConversationIDs)
|
||||||
conversationGroup.POST("/get_incremental_conversations", c.GetIncrementalConversation)
|
conversationGroup.POST("/get_incremental_conversations", c.GetIncrementalConversation)
|
||||||
conversationGroup.POST("/get_owner_conversation", c.GetOwnerConversation)
|
conversationGroup.POST("/get_owner_conversation", c.GetOwnerConversation)
|
||||||
conversationGroup.POST("/get_not_notify_conversation_ids", c.GetNotNotifyConversationIDs)
|
|
||||||
conversationGroup.POST("/get_pinned_conversation_ids", c.GetPinnedConversationIDs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
statisticsGroup := r.Group("/statistics")
|
statisticsGroup := r.Group("/statistics")
|
||||||
@@ -247,11 +239,6 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
|||||||
statisticsGroup.POST("/group/create", g.GroupCreateCount)
|
statisticsGroup.POST("/group/create", g.GroupCreateCount)
|
||||||
statisticsGroup.POST("/group/active", m.GetActiveGroup)
|
statisticsGroup.POST("/group/active", m.GetActiveGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
jssdk := r.Group("/jssdk")
|
|
||||||
jssdk.POST("/get_conversations", j.GetConversations)
|
|
||||||
jssdk.POST("/get_active_conversations", j.GetActiveConversations)
|
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +275,7 @@ func GinParseToken(authRPC *rpcclient.Auth) gin.HandlerFunc {
|
|||||||
|
|
||||||
// Whitelist api not parse token
|
// Whitelist api not parse token
|
||||||
var Whitelist = []string{
|
var Whitelist = []string{
|
||||||
"/auth/get_admin_token",
|
"/user/user_register",
|
||||||
|
"/auth/user_token",
|
||||||
"/auth/parse_token",
|
"/auth/parse_token",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,14 +107,14 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
|||||||
if v2.UserID == v1 {
|
if v2.UserID == v1 {
|
||||||
flag = true
|
flag = true
|
||||||
res.UserID = v1
|
res.UserID = v1
|
||||||
res.Status = constant.Online
|
res.Status = constant.OnlineStatus
|
||||||
res.DetailPlatformStatus = append(res.DetailPlatformStatus, v2.DetailPlatformStatus...)
|
res.DetailPlatformStatus = append(res.DetailPlatformStatus, v2.DetailPlatformStatus...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !flag {
|
if !flag {
|
||||||
res.UserID = v1
|
res.UserID = v1
|
||||||
res.Status = constant.Offline
|
res.Status = constant.OfflineStatus
|
||||||
}
|
}
|
||||||
respResult = append(respResult, res)
|
respResult = append(respResult, res)
|
||||||
}
|
}
|
||||||
@@ -153,26 +153,26 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, v1 := range req.UserIDs {
|
for _, v1 := range req.UserIDs {
|
||||||
m := make(map[int32][]string, 10)
|
m := make(map[string][]string, 10)
|
||||||
flag = false
|
flag = false
|
||||||
temp := new(msggateway.SingleDetail)
|
temp := new(msggateway.SingleDetail)
|
||||||
for _, v2 := range wsResult {
|
for _, v2 := range wsResult {
|
||||||
if v2.UserID == v1 {
|
if v2.UserID == v1 {
|
||||||
flag = true
|
flag = true
|
||||||
temp.UserID = v1
|
temp.UserID = v1
|
||||||
temp.Status = constant.Online
|
temp.Status = constant.OnlineStatus
|
||||||
for _, status := range v2.DetailPlatformStatus {
|
for _, status := range v2.DetailPlatformStatus {
|
||||||
if v, ok := m[status.PlatformID]; ok {
|
if v, ok := m[status.Platform]; ok {
|
||||||
m[status.PlatformID] = append(v, status.Token)
|
m[status.Platform] = append(v, status.Token)
|
||||||
} else {
|
} else {
|
||||||
m[status.PlatformID] = []string{status.Token}
|
m[status.Platform] = []string{status.Token}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for p, tokens := range m {
|
for p, tokens := range m {
|
||||||
t := new(msggateway.SinglePlatformToken)
|
t := new(msggateway.SinglePlatformToken)
|
||||||
t.PlatformID = p
|
t.Platform = p
|
||||||
t.Token = tokens
|
t.Token = tokens
|
||||||
t.Total = int32(len(tokens))
|
t.Total = int32(len(tokens))
|
||||||
temp.SinglePlatformToken = append(temp.SinglePlatformToken, t)
|
temp.SinglePlatformToken = append(temp.SinglePlatformToken, t)
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ package msggateway
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
||||||
@@ -32,6 +30,7 @@ import (
|
|||||||
"github.com/openimsdk/tools/mq/memamq"
|
"github.com/openimsdk/tools/mq/memamq"
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) InitServer(ctx context.Context, config *Config, disCov discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func (s *Server) InitServer(ctx context.Context, config *Config, disCov discovery.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
@@ -112,14 +111,15 @@ func (s *Server) GetUsersOnlineStatus(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ps := new(msggateway.GetUsersOnlineStatusResp_SuccessDetail)
|
ps := new(msggateway.GetUsersOnlineStatusResp_SuccessDetail)
|
||||||
ps.PlatformID = int32(client.PlatformID)
|
ps.Platform = constant.PlatformIDToName(client.PlatformID)
|
||||||
|
ps.Status = constant.OnlineStatus
|
||||||
ps.ConnID = client.ctx.GetConnID()
|
ps.ConnID = client.ctx.GetConnID()
|
||||||
ps.Token = client.token
|
ps.Token = client.token
|
||||||
ps.IsBackground = client.IsBackground
|
ps.IsBackground = client.IsBackground
|
||||||
uresp.Status = constant.Online
|
uresp.Status = constant.OnlineStatus
|
||||||
uresp.DetailPlatformStatus = append(uresp.DetailPlatformStatus, ps)
|
uresp.DetailPlatformStatus = append(uresp.DetailPlatformStatus, ps)
|
||||||
}
|
}
|
||||||
if uresp.Status == constant.Online {
|
if uresp.Status == constant.OnlineStatus {
|
||||||
resp.SuccessResult = append(resp.SuccessResult, uresp)
|
resp.SuccessResult = append(resp.SuccessResult, uresp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ func (ws *WsServer) KickUserConn(client *Client) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) {
|
func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) {
|
||||||
switch ws.msgGatewayConfig.Share.MultiLoginPolicy {
|
switch ws.msgGatewayConfig.MsgGateway.MultiLoginPolicy {
|
||||||
case constant.DefalutNotKick:
|
case constant.DefalutNotKick:
|
||||||
case constant.PCAndOther:
|
case constant.PCAndOther:
|
||||||
if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC {
|
if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC {
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
firebase "firebase.google.com/go/v4"
|
firebase "firebase.google.com/go"
|
||||||
"firebase.google.com/go/v4/messaging"
|
"firebase.google.com/go/messaging"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
@@ -99,7 +99,7 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
|
|||||||
apns := &messaging.APNSConfig{Payload: &messaging.APNSPayload{Aps: &messaging.Aps{Sound: opts.IOSPushSound}}}
|
apns := &messaging.APNSConfig{Payload: &messaging.APNSPayload{Aps: &messaging.Aps{Sound: opts.IOSPushSound}}}
|
||||||
messageCount := len(messages)
|
messageCount := len(messages)
|
||||||
if messageCount >= SinglePushCountLimit {
|
if messageCount >= SinglePushCountLimit {
|
||||||
response, err := f.fcmMsgCli.SendEach(ctx, messages)
|
response, err := f.fcmMsgCli.SendAll(ctx, messages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail = Fail + messageCount
|
Fail = Fail + messageCount
|
||||||
// Record push error
|
// Record push error
|
||||||
@@ -154,7 +154,7 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
|
|||||||
}
|
}
|
||||||
messageCount := len(messages)
|
messageCount := len(messages)
|
||||||
if messageCount > 0 {
|
if messageCount > 0 {
|
||||||
response, err := f.fcmMsgCli.SendEach(ctx, messages)
|
response, err := f.fcmMsgCli.SendAll(ctx, messages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail = Fail + messageCount
|
Fail = Fail + messageCount
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
redis2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
|
redis2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
|
||||||
"github.com/openimsdk/tools/db/redisutil"
|
"github.com/openimsdk/tools/db/redisutil"
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
@@ -65,33 +64,24 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
|||||||
redis2.NewTokenCacheModel(rdb, config.RpcConfig.TokenPolicy.Expire),
|
redis2.NewTokenCacheModel(rdb, config.RpcConfig.TokenPolicy.Expire),
|
||||||
config.Share.Secret,
|
config.Share.Secret,
|
||||||
config.RpcConfig.TokenPolicy.Expire,
|
config.RpcConfig.TokenPolicy.Expire,
|
||||||
config.Share.MultiLoginPolicy,
|
|
||||||
),
|
),
|
||||||
config: config,
|
config: config,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) GetAdminToken(ctx context.Context, req *pbauth.GetAdminTokenReq) (*pbauth.GetAdminTokenResp, error) {
|
func (s *authServer) UserToken(ctx context.Context, req *pbauth.UserTokenReq) (*pbauth.UserTokenResp, error) {
|
||||||
resp := pbauth.GetAdminTokenResp{}
|
resp := pbauth.UserTokenResp{}
|
||||||
if req.Secret != s.config.Share.Secret {
|
if req.Secret != s.config.Share.Secret {
|
||||||
return nil, errs.ErrNoPermission.WrapMsg("secret invalid")
|
return nil, errs.ErrNoPermission.WrapMsg("secret invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !datautil.Contain(req.UserID, s.config.Share.IMAdminUserID...) {
|
|
||||||
return nil, errs.ErrArgs.WrapMsg("userID is error.", "userID", req.UserID, "adminUserID", s.config.Share.IMAdminUserID)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := s.userRpcClient.GetUserInfo(ctx, req.UserID); err != nil {
|
if _, err := s.userRpcClient.GetUserInfo(ctx, req.UserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
token, err := s.authDatabase.CreateToken(ctx, req.UserID, int(req.PlatformID))
|
||||||
token, err := s.authDatabase.CreateToken(ctx, req.UserID, int(constant.AdminPlatformID))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
prommetrics.UserLoginCounter.Inc()
|
prommetrics.UserLoginCounter.Inc()
|
||||||
resp.Token = token
|
resp.Token = token
|
||||||
resp.ExpireTimeSeconds = s.config.RpcConfig.TokenPolicy.Expire * 24 * 60 * 60
|
resp.ExpireTimeSeconds = s.config.RpcConfig.TokenPolicy.Expire * 24 * 60 * 60
|
||||||
@@ -102,11 +92,6 @@ func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenR
|
|||||||
if err := authverify.CheckAdmin(ctx, s.config.Share.IMAdminUserID); err != nil {
|
if err := authverify.CheckAdmin(ctx, s.config.Share.IMAdminUserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.PlatformID == constant.AdminPlatformID {
|
|
||||||
return nil, errs.ErrNoPermission.WrapMsg("platformID invalid. platformID must not be adminPlatformID")
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := pbauth.GetUserTokenResp{}
|
resp := pbauth.GetUserTokenResp{}
|
||||||
|
|
||||||
if authverify.IsManagerUserID(req.UserID, s.config.Share.IMAdminUserID) {
|
if authverify.IsManagerUserID(req.UserID, s.config.Share.IMAdminUserID) {
|
||||||
|
|||||||
+2
-18
@@ -278,8 +278,8 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver
|
|||||||
if req.Conversation.MsgDestructTime != nil {
|
if req.Conversation.MsgDestructTime != nil {
|
||||||
m["msg_destruct_time"] = req.Conversation.MsgDestructTime.Value
|
m["msg_destruct_time"] = req.Conversation.MsgDestructTime.Value
|
||||||
}
|
}
|
||||||
if req.Conversation.IsMsgDestruct != nil {
|
if req.Conversation.MsgDestructTime != nil {
|
||||||
m["is_msg_destruct"] = req.Conversation.IsMsgDestruct.Value
|
m["msg_destruct_time"] = req.Conversation.MsgDestructTime.Value
|
||||||
}
|
}
|
||||||
if req.Conversation.BurnDuration != nil {
|
if req.Conversation.BurnDuration != nil {
|
||||||
m["burn_duration"] = req.Conversation.BurnDuration.Value
|
m["burn_duration"] = req.Conversation.BurnDuration.Value
|
||||||
@@ -710,19 +710,3 @@ func (c *conversationServer) GetConversationsNeedDestructMsgs(ctx context.Contex
|
|||||||
|
|
||||||
return &pbconversation.GetConversationsNeedDestructMsgsResp{Conversations: convert.ConversationsDB2Pb(temp)}, nil
|
return &pbconversation.GetConversationsNeedDestructMsgsResp{Conversations: convert.ConversationsDB2Pb(temp)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conversationServer) GetNotNotifyConversationIDs(ctx context.Context, req *pbconversation.GetNotNotifyConversationIDsReq) (*pbconversation.GetNotNotifyConversationIDsResp, error) {
|
|
||||||
conversationIDs, err := c.conversationDatabase.GetNotNotifyConversationIDs(ctx, req.UserID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &pbconversation.GetNotNotifyConversationIDsResp{ConversationIDs: conversationIDs}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *conversationServer) GetPinnedConversationIDs(ctx context.Context, req *pbconversation.GetPinnedConversationIDsReq) (*pbconversation.GetPinnedConversationIDsResp, error) {
|
|
||||||
conversationIDs, err := c.conversationDatabase.GetPinnedConversationIDs(ctx, req.UserID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &pbconversation.GetPinnedConversationIDsResp{ConversationIDs: conversationIDs}, nil
|
|
||||||
}
|
|
||||||
@@ -218,7 +218,6 @@ func (s *groupServer) webhookAfterKickGroupMember(ctx context.Context, after *co
|
|||||||
CallbackCommand: callbackstruct.CallbackAfterKickGroupCommand,
|
CallbackCommand: callbackstruct.CallbackAfterKickGroupCommand,
|
||||||
GroupID: req.GroupID,
|
GroupID: req.GroupID,
|
||||||
KickedUserIDs: req.KickedUserIDs,
|
KickedUserIDs: req.KickedUserIDs,
|
||||||
Reason: req.Reason,
|
|
||||||
}
|
}
|
||||||
s.webhookClient.AsyncPost(ctx, cbReq.GetCallbackCommand(), cbReq, &callbackstruct.CallbackKillGroupMemberResp{}, after)
|
s.webhookClient.AsyncPost(ctx, cbReq.GetCallbackCommand(), cbReq, &callbackstruct.CallbackKillGroupMemberResp{}, after)
|
||||||
}
|
}
|
||||||
@@ -374,7 +373,7 @@ func (s *groupServer) webhookBeforeSetGroupInfoEx(ctx context.Context, before *c
|
|||||||
if req.Ex != nil {
|
if req.Ex != nil {
|
||||||
cbReq.Ex = req.Ex
|
cbReq.Ex = req.Ex
|
||||||
}
|
}
|
||||||
log.ZDebug(ctx, "debug CallbackBeforeSetGroupInfoEx", "ex", cbReq.Ex)
|
log.ZDebug(ctx, "debug CallbackBeforeSetGroupInfoEX", "ex", cbReq.Ex)
|
||||||
|
|
||||||
if req.NeedVerification != nil {
|
if req.NeedVerification != nil {
|
||||||
cbReq.NeedVerification = req.NeedVerification
|
cbReq.NeedVerification = req.NeedVerification
|
||||||
|
|||||||
@@ -58,12 +58,8 @@ func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[s
|
|||||||
func UpdateGroupInfoExMap(ctx context.Context, group *pbgroup.SetGroupInfoExReq) (map[string]any, error) {
|
func UpdateGroupInfoExMap(ctx context.Context, group *pbgroup.SetGroupInfoExReq) (map[string]any, error) {
|
||||||
m := make(map[string]any)
|
m := make(map[string]any)
|
||||||
|
|
||||||
if group.GroupName != nil {
|
if group.GroupName != nil && group.GroupName.Value != "" {
|
||||||
if group.GroupName.Value != "" {
|
return nil, errs.ErrArgs.WrapMsg("group name is empty")
|
||||||
m["group_name"] = group.GroupName.Value
|
|
||||||
} else {
|
|
||||||
return nil, errs.ErrArgs.WrapMsg("group name is empty")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if group.Notification != nil {
|
if group.Notification != nil {
|
||||||
m["notification"] = group.Notification.Value
|
m["notification"] = group.Notification.Value
|
||||||
|
|||||||
@@ -167,11 +167,11 @@ func (g *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupServer) GetPublicUserInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.PublicUserInfo, error) {
|
func (g *groupServer) GetPublicUserInfoMap(ctx context.Context, userIDs []string, complete bool) (map[string]*sdkws.PublicUserInfo, error) {
|
||||||
if len(userIDs) == 0 {
|
if len(userIDs) == 0 {
|
||||||
return map[string]*sdkws.PublicUserInfo{}, nil
|
return map[string]*sdkws.PublicUserInfo{}, nil
|
||||||
}
|
}
|
||||||
users, err := g.user.GetPublicUserInfos(ctx, userIDs)
|
users, err := g.user.GetPublicUserInfos(ctx, userIDs, complete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -696,7 +696,7 @@ func (g *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup.
|
|||||||
userIDs = append(userIDs, gr.UserID)
|
userIDs = append(userIDs, gr.UserID)
|
||||||
}
|
}
|
||||||
userIDs = datautil.Distinct(userIDs)
|
userIDs = datautil.Distinct(userIDs)
|
||||||
userMap, err := g.user.GetPublicUserInfoMap(ctx, userIDs)
|
userMap, err := g.user.GetPublicUserInfoMap(ctx, userIDs, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1685,51 +1685,36 @@ func (g *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req *
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(requests) == 0 {
|
if len(requests) == 0 {
|
||||||
return &pbgroup.GetGroupUsersReqApplicationListResp{}, nil
|
return &pbgroup.GetGroupUsersReqApplicationListResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
groupIDs := datautil.Distinct(datautil.Slice(requests, func(e *model.GroupRequest) string {
|
groupIDs := datautil.Distinct(datautil.Slice(requests, func(e *model.GroupRequest) string {
|
||||||
return e.GroupID
|
return e.GroupID
|
||||||
}))
|
}))
|
||||||
|
|
||||||
groups, err := g.db.FindGroup(ctx, groupIDs)
|
groups, err := g.db.FindGroup(ctx, groupIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
groupMap := datautil.SliceToMap(groups, func(e *model.Group) string {
|
groupMap := datautil.SliceToMap(groups, func(e *model.Group) string {
|
||||||
return e.GroupID
|
return e.GroupID
|
||||||
})
|
})
|
||||||
|
|
||||||
if ids := datautil.Single(groupIDs, datautil.Keys(groupMap)); len(ids) > 0 {
|
if ids := datautil.Single(groupIDs, datautil.Keys(groupMap)); len(ids) > 0 {
|
||||||
return nil, servererrs.ErrGroupIDNotFound.WrapMsg(strings.Join(ids, ","))
|
return nil, servererrs.ErrGroupIDNotFound.WrapMsg(strings.Join(ids, ","))
|
||||||
}
|
}
|
||||||
|
|
||||||
userMap, err := g.user.GetPublicUserInfoMap(ctx, req.UserIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
owners, err := g.db.FindGroupsOwner(ctx, groupIDs)
|
owners, err := g.db.FindGroupsOwner(ctx, groupIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := g.PopulateGroupMember(ctx, owners...); err != nil {
|
if err := g.PopulateGroupMember(ctx, owners...); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ownerMap := datautil.SliceToMap(owners, func(e *model.GroupMember) string {
|
ownerMap := datautil.SliceToMap(owners, func(e *model.GroupMember) string {
|
||||||
return e.GroupID
|
return e.GroupID
|
||||||
})
|
})
|
||||||
|
|
||||||
groupMemberNum, err := g.db.MapGroupMemberNum(ctx, groupIDs)
|
groupMemberNum, err := g.db.MapGroupMemberNum(ctx, groupIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pbgroup.GetGroupUsersReqApplicationListResp{
|
return &pbgroup.GetGroupUsersReqApplicationListResp{
|
||||||
Total: int64(len(requests)),
|
Total: int64(len(requests)),
|
||||||
GroupRequests: datautil.Slice(requests, func(e *model.GroupRequest) *sdkws.GroupRequest {
|
GroupRequests: datautil.Slice(requests, func(e *model.GroupRequest) *sdkws.GroupRequest {
|
||||||
@@ -1737,72 +1722,7 @@ func (g *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req *
|
|||||||
if owner, ok := ownerMap[e.GroupID]; ok {
|
if owner, ok := ownerMap[e.GroupID]; ok {
|
||||||
ownerUserID = owner.UserID
|
ownerUserID = owner.UserID
|
||||||
}
|
}
|
||||||
|
return convert.Db2PbGroupRequest(e, nil, convert.Db2PbGroupInfo(groupMap[e.GroupID], ownerUserID, groupMemberNum[e.GroupID]))
|
||||||
var userInfo *sdkws.PublicUserInfo
|
|
||||||
if user, ok := userMap[e.UserID]; !ok {
|
|
||||||
userInfo = user
|
|
||||||
}
|
|
||||||
|
|
||||||
return convert.Db2PbGroupRequest(e, userInfo, convert.Db2PbGroupInfo(groupMap[e.GroupID], ownerUserID, groupMemberNum[e.GroupID]))
|
|
||||||
}),
|
}),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupServer) GetSpecifiedUserGroupRequestInfo(ctx context.Context, req *pbgroup.GetSpecifiedUserGroupRequestInfoReq) (*pbgroup.GetSpecifiedUserGroupRequestInfoResp, error) {
|
|
||||||
opUserID := mcontext.GetOpUserID(ctx)
|
|
||||||
|
|
||||||
owners, err := g.db.FindGroupsOwner(ctx, []string{req.GroupID})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.UserID != opUserID {
|
|
||||||
req.UserID = mcontext.GetOpUserID(ctx)
|
|
||||||
adminIDs, err := g.db.GetGroupRoleLevelMemberIDs(ctx, req.GroupID, constant.GroupAdmin)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
adminIDs = append(adminIDs, owners[0].UserID)
|
|
||||||
adminIDs = append(adminIDs, g.config.Share.IMAdminUserID...)
|
|
||||||
|
|
||||||
if !datautil.Contain(req.UserID, adminIDs...) {
|
|
||||||
return nil, errs.ErrNoPermission.WrapMsg("opUser no permission")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requests, err := g.db.FindGroupRequests(ctx, req.GroupID, []string{req.UserID})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(requests) == 0 {
|
|
||||||
return &pbgroup.GetSpecifiedUserGroupRequestInfoResp{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
groups, err := g.db.FindGroup(ctx, []string{req.GroupID})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
userInfos, err := g.user.GetPublicUserInfos(ctx, []string{req.UserID})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
groupMemberNum, err := g.db.MapGroupMemberNum(ctx, []string{req.GroupID})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := &pbgroup.GetSpecifiedUserGroupRequestInfoResp{
|
|
||||||
GroupRequests: make([]*sdkws.GroupRequest, 0, len(requests)),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, request := range requests {
|
|
||||||
resp.GroupRequests = append(resp.GroupRequests, convert.Db2PbGroupRequest(request, userInfos[0], convert.Db2PbGroupInfo(groups[0], owners[0].UserID, groupMemberNum[groups[0].GroupID])))
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Total = uint32(len(requests))
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *m
|
|||||||
conversationMaxSeqMap[conversation.ConversationID] = conversation.MaxSeq
|
conversationMaxSeqMap[conversation.ConversationID] = conversation.MaxSeq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maxSeqs, err := m.MsgDatabase.GetMaxSeqsWithTime(ctx, conversationIDs)
|
maxSeqs, err := m.MsgDatabase.GetMaxSeqs(ctx, conversationIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -63,8 +63,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *m
|
|||||||
for conversationID, maxSeq := range maxSeqs {
|
for conversationID, maxSeq := range maxSeqs {
|
||||||
resp.Seqs[conversationID] = &msg.Seqs{
|
resp.Seqs[conversationID] = &msg.Seqs{
|
||||||
HasReadSeq: hasReadSeqs[conversationID],
|
HasReadSeq: hasReadSeqs[conversationID],
|
||||||
MaxSeq: maxSeq.Seq,
|
MaxSeq: maxSeq,
|
||||||
MaxSeqTime: maxSeq.Time,
|
|
||||||
}
|
}
|
||||||
if v, ok := conversationMaxSeqMap[conversationID]; ok {
|
if v, ok := conversationMaxSeqMap[conversationID]; ok {
|
||||||
resp.Seqs[conversationID].MaxSeq = v
|
resp.Seqs[conversationID].MaxSeq = v
|
||||||
|
|||||||
@@ -67,9 +67,6 @@ func (m *msgServer) webhookBeforeSendSingleMsg(ctx context.Context, before *conf
|
|||||||
if msg.MsgData.ContentType == constant.Typing {
|
if msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !filterBeforeMsg(msg, before) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
cbReq := &cbapi.CallbackBeforeSendSingleMsgReq{
|
cbReq := &cbapi.CallbackBeforeSendSingleMsgReq{
|
||||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackBeforeSendSingleMsgCommand),
|
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackBeforeSendSingleMsgCommand),
|
||||||
RecvID: msg.MsgData.RecvID,
|
RecvID: msg.MsgData.RecvID,
|
||||||
@@ -87,7 +84,9 @@ func (m *msgServer) webhookAfterSendSingleMsg(ctx context.Context, after *config
|
|||||||
if msg.MsgData.ContentType == constant.Typing {
|
if msg.MsgData.ContentType == constant.Typing {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !filterAfterMsg(msg, after) {
|
// According to the attentionIds configuration, only some users are sent
|
||||||
|
attentionIds := after.AttentionIds
|
||||||
|
if attentionIds != nil && !datautil.Contain(msg.MsgData.RecvID, attentionIds...) && !datautil.Contain(msg.MsgData.SendID, attentionIds...) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterSendSingleMsgReq{
|
cbReq := &cbapi.CallbackAfterSendSingleMsgReq{
|
||||||
@@ -99,9 +98,6 @@ func (m *msgServer) webhookAfterSendSingleMsg(ctx context.Context, after *config
|
|||||||
|
|
||||||
func (m *msgServer) webhookBeforeSendGroupMsg(ctx context.Context, before *config.BeforeConfig, msg *pbchat.SendMsgReq) error {
|
func (m *msgServer) webhookBeforeSendGroupMsg(ctx context.Context, before *config.BeforeConfig, msg *pbchat.SendMsgReq) error {
|
||||||
return webhook.WithCondition(ctx, before, func(ctx context.Context) error {
|
return webhook.WithCondition(ctx, before, func(ctx context.Context) error {
|
||||||
if !filterBeforeMsg(msg, before) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if msg.MsgData.ContentType == constant.Typing {
|
if msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -121,9 +117,6 @@ func (m *msgServer) webhookAfterSendGroupMsg(ctx context.Context, after *config.
|
|||||||
if msg.MsgData.ContentType == constant.Typing {
|
if msg.MsgData.ContentType == constant.Typing {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !filterAfterMsg(msg, after) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cbReq := &cbapi.CallbackAfterSendGroupMsgReq{
|
cbReq := &cbapi.CallbackAfterSendGroupMsgReq{
|
||||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackAfterSendGroupMsgCommand),
|
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackAfterSendGroupMsgCommand),
|
||||||
GroupID: msg.MsgData.GroupID,
|
GroupID: msg.MsgData.GroupID,
|
||||||
@@ -136,9 +129,6 @@ func (m *msgServer) webhookBeforeMsgModify(ctx context.Context, before *config.B
|
|||||||
if msg.MsgData.ContentType != constant.Text {
|
if msg.MsgData.ContentType != constant.Text {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !filterBeforeMsg(msg, before) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
cbReq := &cbapi.CallbackMsgModifyCommandReq{
|
cbReq := &cbapi.CallbackMsgModifyCommandReq{
|
||||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackBeforeMsgModifyCommand),
|
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackBeforeMsgModifyCommand),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
package msg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
pbchat "github.com/openimsdk/protocol/msg"
|
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
separator = "-"
|
|
||||||
)
|
|
||||||
|
|
||||||
func filterAfterMsg(msg *pbchat.SendMsgReq, after *config.AfterConfig) bool {
|
|
||||||
return filterMsg(msg, after.AttentionIds, after.AllowedTypes, after.DeniedTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func filterBeforeMsg(msg *pbchat.SendMsgReq, before *config.BeforeConfig) bool {
|
|
||||||
return filterMsg(msg, nil, before.AllowedTypes, before.DeniedTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func filterMsg(msg *pbchat.SendMsgReq, attentionIds, allowedTypes, deniedTypes []string) bool {
|
|
||||||
// According to the attentionIds configuration, only some users are sent
|
|
||||||
if len(attentionIds) != 0 && !datautil.Contains([]string{msg.MsgData.SendID, msg.MsgData.RecvID}, attentionIds...) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func isInInterval(contentType int32, interval []string) bool {
|
|
||||||
for _, v := range interval {
|
|
||||||
if strings.Contains(v, separator) {
|
|
||||||
// is interval
|
|
||||||
bounds := strings.Split(v, separator)
|
|
||||||
if len(bounds) != 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
bottom, err := strconv.Atoi(bounds[0])
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
top, err := strconv.Atoi(bounds[1])
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if datautil.BetweenEq(int(contentType), bottom, top) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
iv, err := strconv.Atoi(v)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if int(contentType) == iv {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
+2
-24
@@ -16,10 +16,10 @@ package msg
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
pbmsg "github.com/openimsdk/protocol/msg"
|
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"sort"
|
|
||||||
|
pbmsg "github.com/openimsdk/protocol/msg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *msgServer) GetConversationMaxSeq(ctx context.Context, req *pbmsg.GetConversationMaxSeqReq) (*pbmsg.GetConversationMaxSeqResp, error) {
|
func (m *msgServer) GetConversationMaxSeq(ctx context.Context, req *pbmsg.GetConversationMaxSeqReq) (*pbmsg.GetConversationMaxSeqResp, error) {
|
||||||
@@ -62,25 +62,3 @@ func (m *msgServer) SetUserConversationsMinSeq(ctx context.Context, req *pbmsg.S
|
|||||||
}
|
}
|
||||||
return &pbmsg.SetUserConversationsMinSeqResp{}, nil
|
return &pbmsg.SetUserConversationsMinSeqResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *msgServer) GetActiveConversation(ctx context.Context, req *pbmsg.GetActiveConversationReq) (*pbmsg.GetActiveConversationResp, error) {
|
|
||||||
res, err := m.MsgDatabase.GetCacheMaxSeqWithTime(ctx, req.ConversationIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
conversations := make([]*pbmsg.ActiveConversation, 0, len(res))
|
|
||||||
for conversationID, val := range res {
|
|
||||||
conversations = append(conversations, &pbmsg.ActiveConversation{
|
|
||||||
MaxSeq: val.Seq,
|
|
||||||
LastTime: val.Time,
|
|
||||||
ConversationID: conversationID,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if req.Limit > 0 {
|
|
||||||
sort.Sort(activeConversations(conversations))
|
|
||||||
if len(conversations) > int(req.Limit) {
|
|
||||||
conversations = conversations[:req.Limit]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &pbmsg.GetActiveConversationResp{Conversations: conversations}, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
package msg
|
package msg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/openimsdk/protocol/msg"
|
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
@@ -29,63 +28,3 @@ func IsNotFound(err error) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type activeConversations []*msg.ActiveConversation
|
|
||||||
|
|
||||||
func (s activeConversations) Len() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s activeConversations) Less(i, j int) bool {
|
|
||||||
return s[i].LastTime > s[j].LastTime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s activeConversations) Swap(i, j int) {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
//type seqTime struct {
|
|
||||||
// ConversationID string
|
|
||||||
// Seq int64
|
|
||||||
// Time int64
|
|
||||||
// Unread int64
|
|
||||||
// Pinned bool
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func (s seqTime) String() string {
|
|
||||||
// return fmt.Sprintf("<Time_%d,Unread_%d,Pinned_%t>", s.Time, s.Unread, s.Pinned)
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//type seqTimes []seqTime
|
|
||||||
//
|
|
||||||
//func (s seqTimes) Len() int {
|
|
||||||
// return len(s)
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// Less sticky priority, unread priority, time descending
|
|
||||||
//func (s seqTimes) Less(i, j int) bool {
|
|
||||||
// iv, jv := s[i], s[j]
|
|
||||||
// if iv.Pinned && (!jv.Pinned) {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// if jv.Pinned && (!iv.Pinned) {
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// if iv.Unread > 0 && jv.Unread == 0 {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// if jv.Unread > 0 && iv.Unread == 0 {
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// return iv.Time > jv.Time
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func (s seqTimes) Swap(i, j int) {
|
|
||||||
// s[i], s[j] = s[j], s[i]
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//type conversationStatus struct {
|
|
||||||
// ConversationID string
|
|
||||||
// Pinned bool
|
|
||||||
// Recv bool
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -23,17 +23,13 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
"github.com/openimsdk/protocol/relation"
|
"github.com/openimsdk/protocol/relation"
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
|
||||||
"github.com/openimsdk/tools/errs"
|
|
||||||
"github.com/openimsdk/tools/mcontext"
|
"github.com/openimsdk/tools/mcontext"
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *friendServer) GetPaginationBlacks(ctx context.Context, req *relation.GetPaginationBlacksReq) (resp *relation.GetPaginationBlacksResp, err error) {
|
func (s *friendServer) GetPaginationBlacks(ctx context.Context, req *relation.GetPaginationBlacksReq) (resp *relation.GetPaginationBlacksResp, err error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
total, blacks, err := s.blackDatabase.FindOwnerBlacks(ctx, req.UserID, req.Pagination)
|
total, blacks, err := s.blackDatabase.FindOwnerBlacks(ctx, req.UserID, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -59,7 +55,7 @@ func (s *friendServer) IsBlack(ctx context.Context, req *relation.IsBlackReq) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) RemoveBlack(ctx context.Context, req *relation.RemoveBlackReq) (*relation.RemoveBlackResp, error) {
|
func (s *friendServer) RemoveBlack(ctx context.Context, req *relation.RemoveBlackReq) (*relation.RemoveBlackResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +64,6 @@ func (s *friendServer) RemoveBlack(ctx context.Context, req *relation.RemoveBlac
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.notificationSender.BlackDeletedNotification(ctx, req)
|
s.notificationSender.BlackDeletedNotification(ctx, req)
|
||||||
s.webhookAfterRemoveBlack(ctx, &s.config.WebhooksConfig.AfterRemoveBlack, req)
|
|
||||||
|
|
||||||
return &relation.RemoveBlackResp{}, nil
|
return &relation.RemoveBlackResp{}, nil
|
||||||
}
|
}
|
||||||
@@ -77,11 +72,6 @@ func (s *friendServer) AddBlack(ctx context.Context, req *relation.AddBlackReq)
|
|||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.webhookBeforeAddBlack(ctx, &s.config.WebhooksConfig.BeforeAddBlack, req); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := s.userRpcClient.GetUsersInfo(ctx, []string{req.OwnerUserID, req.BlackUserID})
|
_, err := s.userRpcClient.GetUsersInfo(ctx, []string{req.OwnerUserID, req.BlackUserID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -100,53 +90,3 @@ func (s *friendServer) AddBlack(ctx context.Context, req *relation.AddBlackReq)
|
|||||||
s.notificationSender.BlackAddedNotification(ctx, req)
|
s.notificationSender.BlackAddedNotification(ctx, req)
|
||||||
return &relation.AddBlackResp{}, nil
|
return &relation.AddBlackResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) GetSpecifiedBlacks(ctx context.Context, req *relation.GetSpecifiedBlacksReq) (*relation.GetSpecifiedBlacksResp, error) {
|
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(req.UserIDList) == 0 {
|
|
||||||
return nil, errs.ErrArgs.WrapMsg("userIDList is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if datautil.Duplicate(req.UserIDList) {
|
|
||||||
return nil, errs.ErrArgs.WrapMsg("userIDList repeated")
|
|
||||||
}
|
|
||||||
|
|
||||||
userMap, err := s.userRpcClient.GetPublicUserInfoMap(ctx, req.UserIDList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
blacks, err := s.blackDatabase.FindBlackInfos(ctx, req.OwnerUserID, req.UserIDList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
blackMap := datautil.SliceToMap(blacks, func(e *model.Black) string {
|
|
||||||
return e.BlockUserID
|
|
||||||
})
|
|
||||||
|
|
||||||
resp := &relation.GetSpecifiedBlacksResp{
|
|
||||||
Blacks: make([]*sdkws.BlackInfo, 0, len(req.UserIDList)),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, userID := range req.UserIDList {
|
|
||||||
if black := blackMap[userID]; black != nil {
|
|
||||||
resp.Blacks = append(resp.Blacks,
|
|
||||||
&sdkws.BlackInfo{
|
|
||||||
OwnerUserID: black.OwnerUserID,
|
|
||||||
CreateTime: black.CreateTime.UnixMilli(),
|
|
||||||
BlackUserInfo: userMap[userID],
|
|
||||||
AddSource: black.AddSource,
|
|
||||||
OperatorUserID: black.OperatorUserID,
|
|
||||||
Ex: black.Ex,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Total = int32(len(resp.Blacks))
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -138,18 +138,6 @@ func (s *friendServer) webhookBeforeAddFriendAgree(ctx context.Context, before *
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) webhookAfterAddFriendAgree(ctx context.Context, after *config.AfterConfig, req *relation.RespondFriendApplyReq) {
|
|
||||||
cbReq := &cbapi.CallbackAfterAddFriendAgreeReq{
|
|
||||||
CallbackCommand: cbapi.CallbackAfterAddFriendAgreeCommand,
|
|
||||||
FromUserID: req.FromUserID,
|
|
||||||
ToUserID: req.ToUserID,
|
|
||||||
HandleMsg: req.HandleMsg,
|
|
||||||
HandleResult: req.HandleResult,
|
|
||||||
}
|
|
||||||
resp := &cbapi.CallbackAfterAddFriendAgreeResp{}
|
|
||||||
s.webhookClient.AsyncPost(ctx, cbReq.GetCallbackCommand(), cbReq, resp, after)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *friendServer) webhookBeforeImportFriends(ctx context.Context, before *config.BeforeConfig, req *relation.ImportFriendReq) error {
|
func (s *friendServer) webhookBeforeImportFriends(ctx context.Context, before *config.BeforeConfig, req *relation.ImportFriendReq) error {
|
||||||
return webhook.WithCondition(ctx, before, func(ctx context.Context) error {
|
return webhook.WithCondition(ctx, before, func(ctx context.Context) error {
|
||||||
cbReq := &cbapi.CallbackBeforeImportFriendsReq{
|
cbReq := &cbapi.CallbackBeforeImportFriendsReq{
|
||||||
|
|||||||
@@ -212,7 +212,6 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *relation.Res
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.webhookAfterAddFriendAgree(ctx, &s.config.WebhooksConfig.AfterAddFriendAgree, req)
|
|
||||||
s.notificationSender.FriendApplicationAgreedNotification(ctx, req)
|
s.notificationSender.FriendApplicationAgreedNotification(ctx, req)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
@@ -229,23 +228,20 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *relation.Res
|
|||||||
|
|
||||||
// ok.
|
// ok.
|
||||||
func (s *friendServer) DeleteFriend(ctx context.Context, req *relation.DeleteFriendReq) (resp *relation.DeleteFriendResp, err error) {
|
func (s *friendServer) DeleteFriend(ctx context.Context, req *relation.DeleteFriendReq) (resp *relation.DeleteFriendResp, err error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
resp = &relation.DeleteFriendResp{}
|
||||||
|
if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.db.FindFriendsWithError(ctx, req.OwnerUserID, []string{req.FriendUserID})
|
_, err = s.db.FindFriendsWithError(ctx, req.OwnerUserID, []string{req.FriendUserID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.db.Delete(ctx, req.OwnerUserID, []string{req.FriendUserID}); err != nil {
|
if err := s.db.Delete(ctx, req.OwnerUserID, []string{req.FriendUserID}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.notificationSender.FriendDeletedNotification(ctx, req)
|
s.notificationSender.FriendDeletedNotification(ctx, req)
|
||||||
s.webhookAfterDeleteFriend(ctx, &s.config.WebhooksConfig.AfterDeleteFriend, req)
|
s.webhookAfterDeleteFriend(ctx, &s.config.WebhooksConfig.AfterDeleteFriend, req)
|
||||||
|
return resp, nil
|
||||||
return &relation.DeleteFriendResp{}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok.
|
// ok.
|
||||||
@@ -253,24 +249,20 @@ func (s *friendServer) SetFriendRemark(ctx context.Context, req *relation.SetFri
|
|||||||
if err = s.webhookBeforeSetFriendRemark(ctx, &s.config.WebhooksConfig.BeforeSetFriendRemark, req); err != nil && err != servererrs.ErrCallbackContinue {
|
if err = s.webhookBeforeSetFriendRemark(ctx, &s.config.WebhooksConfig.BeforeSetFriendRemark, req); err != nil && err != servererrs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
resp = &relation.SetFriendRemarkResp{}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.db.FindFriendsWithError(ctx, req.OwnerUserID, []string{req.FriendUserID})
|
_, err = s.db.FindFriendsWithError(ctx, req.OwnerUserID, []string{req.FriendUserID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.db.UpdateRemark(ctx, req.OwnerUserID, req.FriendUserID, req.Remark); err != nil {
|
if err := s.db.UpdateRemark(ctx, req.OwnerUserID, req.FriendUserID, req.Remark); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.webhookAfterSetFriendRemark(ctx, &s.config.WebhooksConfig.AfterSetFriendRemark, req)
|
s.webhookAfterSetFriendRemark(ctx, &s.config.WebhooksConfig.AfterSetFriendRemark, req)
|
||||||
s.notificationSender.FriendRemarkSetNotification(ctx, req.OwnerUserID, req.FriendUserID)
|
s.notificationSender.FriendRemarkSetNotification(ctx, req.OwnerUserID, req.FriendUserID)
|
||||||
|
return resp, nil
|
||||||
return &relation.SetFriendRemarkResp{}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok.
|
// ok.
|
||||||
@@ -317,7 +309,7 @@ func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context,
|
|||||||
|
|
||||||
// Get received friend requests (i.e., those initiated by others).
|
// Get received friend requests (i.e., those initiated by others).
|
||||||
func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *relation.GetPaginationFriendsApplyToReq) (resp *relation.GetPaginationFriendsApplyToResp, err error) {
|
func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *relation.GetPaginationFriendsApplyToReq) (resp *relation.GetPaginationFriendsApplyToResp, err error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,23 +331,18 @@ func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *rel
|
|||||||
|
|
||||||
func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *relation.GetPaginationFriendsApplyFromReq) (resp *relation.GetPaginationFriendsApplyFromResp, err error) {
|
func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *relation.GetPaginationFriendsApplyFromReq) (resp *relation.GetPaginationFriendsApplyFromResp, err error) {
|
||||||
resp = &relation.GetPaginationFriendsApplyFromResp{}
|
resp = &relation.GetPaginationFriendsApplyFromResp{}
|
||||||
|
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
total, friendRequests, err := s.db.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination)
|
total, friendRequests, err := s.db.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userRpcClient.GetUsersInfoMap)
|
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userRpcClient.GetUsersInfoMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.Total = int32(total)
|
resp.Total = int32(total)
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,37 +357,31 @@ func (s *friendServer) IsFriend(ctx context.Context, req *relation.IsFriendReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) GetPaginationFriends(ctx context.Context, req *relation.GetPaginationFriendsReq) (resp *relation.GetPaginationFriendsResp, err error) {
|
func (s *friendServer) GetPaginationFriends(ctx context.Context, req *relation.GetPaginationFriendsReq) (resp *relation.GetPaginationFriendsResp, err error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
total, friends, err := s.db.PageOwnerFriends(ctx, req.UserID, req.Pagination)
|
total, friends, err := s.db.PageOwnerFriends(ctx, req.UserID, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = &relation.GetPaginationFriendsResp{}
|
resp = &relation.GetPaginationFriendsResp{}
|
||||||
resp.FriendsInfo, err = convert.FriendsDB2Pb(ctx, friends, s.userRpcClient.GetUsersInfoMap)
|
resp.FriendsInfo, err = convert.FriendsDB2Pb(ctx, friends, s.userRpcClient.GetUsersInfoMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.Total = int32(total)
|
resp.Total = int32(total)
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) GetFriendIDs(ctx context.Context, req *relation.GetFriendIDsReq) (resp *relation.GetFriendIDsResp, err error) {
|
func (s *friendServer) GetFriendIDs(ctx context.Context, req *relation.GetFriendIDsReq) (resp *relation.GetFriendIDsResp, err error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
if err := s.userRpcClient.Access(ctx, req.UserID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = &relation.GetFriendIDsResp{}
|
resp = &relation.GetFriendIDsResp{}
|
||||||
resp.FriendIDs, err = s.db.FindFriendUserIDs(ctx, req.UserID)
|
resp.FriendIDs, err = s.db.FindFriendUserIDs(ctx, req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,45 +389,35 @@ func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, req *relatio
|
|||||||
if len(req.UserIDList) == 0 {
|
if len(req.UserIDList) == 0 {
|
||||||
return nil, errs.ErrArgs.WrapMsg("userIDList is empty")
|
return nil, errs.ErrArgs.WrapMsg("userIDList is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
if datautil.Duplicate(req.UserIDList) {
|
if datautil.Duplicate(req.UserIDList) {
|
||||||
return nil, errs.ErrArgs.WrapMsg("userIDList repeated")
|
return nil, errs.ErrArgs.WrapMsg("userIDList repeated")
|
||||||
}
|
}
|
||||||
|
|
||||||
userMap, err := s.userRpcClient.GetUsersInfoMap(ctx, req.UserIDList)
|
userMap, err := s.userRpcClient.GetUsersInfoMap(ctx, req.UserIDList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
friends, err := s.db.FindFriendsWithError(ctx, req.OwnerUserID, req.UserIDList)
|
friends, err := s.db.FindFriendsWithError(ctx, req.OwnerUserID, req.UserIDList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
blacks, err := s.blackDatabase.FindBlackInfos(ctx, req.OwnerUserID, req.UserIDList)
|
blacks, err := s.blackDatabase.FindBlackInfos(ctx, req.OwnerUserID, req.UserIDList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
friendMap := datautil.SliceToMap(friends, func(e *model.Friend) string {
|
friendMap := datautil.SliceToMap(friends, func(e *model.Friend) string {
|
||||||
return e.FriendUserID
|
return e.FriendUserID
|
||||||
})
|
})
|
||||||
|
|
||||||
blackMap := datautil.SliceToMap(blacks, func(e *model.Black) string {
|
blackMap := datautil.SliceToMap(blacks, func(e *model.Black) string {
|
||||||
return e.BlockUserID
|
return e.BlockUserID
|
||||||
})
|
})
|
||||||
|
|
||||||
resp := &relation.GetSpecifiedFriendsInfoResp{
|
resp := &relation.GetSpecifiedFriendsInfoResp{
|
||||||
Infos: make([]*relation.GetSpecifiedFriendsInfoInfo, 0, len(req.UserIDList)),
|
Infos: make([]*relation.GetSpecifiedFriendsInfoInfo, 0, len(req.UserIDList)),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, userID := range req.UserIDList {
|
for _, userID := range req.UserIDList {
|
||||||
user := userMap[userID]
|
user := userMap[userID]
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var friendInfo *sdkws.FriendInfo
|
var friendInfo *sdkws.FriendInfo
|
||||||
if friend := friendMap[userID]; friend != nil {
|
if friend := friendMap[userID]; friend != nil {
|
||||||
friendInfo = &sdkws.FriendInfo{
|
friendInfo = &sdkws.FriendInfo{
|
||||||
@@ -459,7 +430,6 @@ func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, req *relatio
|
|||||||
IsPinned: friend.IsPinned,
|
IsPinned: friend.IsPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var blackInfo *sdkws.BlackInfo
|
var blackInfo *sdkws.BlackInfo
|
||||||
if black := blackMap[userID]; black != nil {
|
if black := blackMap[userID]; black != nil {
|
||||||
blackInfo = &sdkws.BlackInfo{
|
blackInfo = &sdkws.BlackInfo{
|
||||||
@@ -470,14 +440,12 @@ func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, req *relatio
|
|||||||
Ex: black.Ex,
|
Ex: black.Ex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.Infos = append(resp.Infos, &relation.GetSpecifiedFriendsInfoInfo{
|
resp.Infos = append(resp.Infos, &relation.GetSpecifiedFriendsInfoInfo{
|
||||||
UserInfo: user,
|
UserInfo: user,
|
||||||
FriendInfo: friendInfo,
|
FriendInfo: friendInfo,
|
||||||
BlackInfo: blackInfo,
|
BlackInfo: blackInfo,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/webhook"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/webhook"
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
|
|
||||||
@@ -89,6 +88,7 @@ func (s *userServer) webhookBeforeUserRegister(ctx context.Context, before *conf
|
|||||||
return webhook.WithCondition(ctx, before, func(ctx context.Context) error {
|
return webhook.WithCondition(ctx, before, func(ctx context.Context) error {
|
||||||
cbReq := &cbapi.CallbackBeforeUserRegisterReq{
|
cbReq := &cbapi.CallbackBeforeUserRegisterReq{
|
||||||
CallbackCommand: cbapi.CallbackBeforeUserRegisterCommand,
|
CallbackCommand: cbapi.CallbackBeforeUserRegisterCommand,
|
||||||
|
Secret: req.Secret,
|
||||||
Users: req.Users,
|
Users: req.Users,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +108,7 @@ func (s *userServer) webhookBeforeUserRegister(ctx context.Context, before *conf
|
|||||||
func (s *userServer) webhookAfterUserRegister(ctx context.Context, after *config.AfterConfig, req *pbuser.UserRegisterReq) {
|
func (s *userServer) webhookAfterUserRegister(ctx context.Context, after *config.AfterConfig, req *pbuser.UserRegisterReq) {
|
||||||
cbReq := &cbapi.CallbackAfterUserRegisterReq{
|
cbReq := &cbapi.CallbackAfterUserRegisterReq{
|
||||||
CallbackCommand: cbapi.CallbackAfterUserRegisterCommand,
|
CallbackCommand: cbapi.CallbackAfterUserRegisterCommand,
|
||||||
|
Secret: req.Secret,
|
||||||
Users: req.Users,
|
Users: req.Users,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
|
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
@@ -62,7 +61,7 @@ func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatu
|
|||||||
case constant.Online:
|
case constant.Online:
|
||||||
online = []int32{req.PlatformID}
|
online = []int32{req.PlatformID}
|
||||||
case constant.Offline:
|
case constant.Offline:
|
||||||
offline = []int32{req.PlatformID}
|
online = []int32{req.PlatformID}
|
||||||
}
|
}
|
||||||
if err := s.online.SetUserOnline(ctx, req.UserID, online, offline); err != nil {
|
if err := s.online.SetUserOnline(ctx, req.UserID, online, offline); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import (
|
|||||||
"github.com/openimsdk/tools/db/pagination"
|
"github.com/openimsdk/tools/db/pagination"
|
||||||
registry "github.com/openimsdk/tools/discovery"
|
registry "github.com/openimsdk/tools/discovery"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
@@ -262,11 +263,10 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
|||||||
if len(req.Users) == 0 {
|
if len(req.Users) == 0 {
|
||||||
return nil, errs.ErrArgs.WrapMsg("users is empty")
|
return nil, errs.ErrArgs.WrapMsg("users is empty")
|
||||||
}
|
}
|
||||||
|
if req.Secret != s.config.Share.Secret {
|
||||||
if err = authverify.CheckAdmin(ctx, s.config.Share.IMAdminUserID); err != nil {
|
log.ZDebug(ctx, "UserRegister", s.config.Share.Secret, req.Secret)
|
||||||
return nil, err
|
return nil, errs.ErrNoPermission.WrapMsg("secret invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
if datautil.DuplicateAny(req.Users, func(e *sdkws.UserInfo) string { return e.UserID }) {
|
if datautil.DuplicateAny(req.Users, func(e *sdkws.UserInfo) string { return e.UserID }) {
|
||||||
return nil, errs.ErrArgs.WrapMsg("userID repeated")
|
return nil, errs.ErrArgs.WrapMsg("userID repeated")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ const (
|
|||||||
CallbackBeforeAddBlackCommand = "callbackBeforeAddBlackCommand"
|
CallbackBeforeAddBlackCommand = "callbackBeforeAddBlackCommand"
|
||||||
CallbackAfterAddFriendCommand = "callbackAfterAddFriendCommand"
|
CallbackAfterAddFriendCommand = "callbackAfterAddFriendCommand"
|
||||||
CallbackBeforeAddFriendAgreeCommand = "callbackBeforeAddFriendAgreeCommand"
|
CallbackBeforeAddFriendAgreeCommand = "callbackBeforeAddFriendAgreeCommand"
|
||||||
CallbackAfterAddFriendAgreeCommand = "callbackAfterAddFriendAgreeCommand"
|
|
||||||
CallbackAfterDeleteFriendCommand = "callbackAfterDeleteFriendCommand"
|
CallbackAfterDeleteFriendCommand = "callbackAfterDeleteFriendCommand"
|
||||||
CallbackBeforeImportFriendsCommand = "callbackBeforeImportFriendsCommand"
|
CallbackBeforeImportFriendsCommand = "callbackBeforeImportFriendsCommand"
|
||||||
CallbackAfterImportFriendsCommand = "callbackAfterImportFriendsCommand"
|
CallbackAfterImportFriendsCommand = "callbackAfterImportFriendsCommand"
|
||||||
|
|||||||
@@ -90,18 +90,6 @@ type CallbackBeforeAddFriendAgreeResp struct {
|
|||||||
CommonCallbackResp
|
CommonCallbackResp
|
||||||
}
|
}
|
||||||
|
|
||||||
type CallbackAfterAddFriendAgreeReq struct {
|
|
||||||
CallbackCommand `json:"callbackCommand"`
|
|
||||||
FromUserID string `json:"fromUserID" `
|
|
||||||
ToUserID string `json:"blackUserID"`
|
|
||||||
HandleResult int32 `json:"HandleResult"`
|
|
||||||
HandleMsg string `json:"HandleMsg"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CallbackAfterAddFriendAgreeResp struct {
|
|
||||||
CommonCallbackResp
|
|
||||||
}
|
|
||||||
|
|
||||||
type CallbackAfterDeleteFriendReq struct {
|
type CallbackAfterDeleteFriendReq struct {
|
||||||
CallbackCommand `json:"callbackCommand"`
|
CallbackCommand `json:"callbackCommand"`
|
||||||
OwnerUserID string `json:"ownerUserID" `
|
OwnerUserID string `json:"ownerUserID" `
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ type CallbackAfterUpdateUserInfoExResp struct {
|
|||||||
|
|
||||||
type CallbackBeforeUserRegisterReq struct {
|
type CallbackBeforeUserRegisterReq struct {
|
||||||
CallbackCommand `json:"callbackCommand"`
|
CallbackCommand `json:"callbackCommand"`
|
||||||
|
Secret string `json:"secret"`
|
||||||
Users []*sdkws.UserInfo `json:"users"`
|
Users []*sdkws.UserInfo `json:"users"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +83,7 @@ type CallbackBeforeUserRegisterResp struct {
|
|||||||
|
|
||||||
type CallbackAfterUserRegisterReq struct {
|
type CallbackAfterUserRegisterReq struct {
|
||||||
CallbackCommand `json:"callbackCommand"`
|
CallbackCommand `json:"callbackCommand"`
|
||||||
|
Secret string `json:"secret"`
|
||||||
Users []*sdkws.UserInfo `json:"users"`
|
Users []*sdkws.UserInfo `json:"users"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,13 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/openimsdk/protocol/auth"
|
"github.com/openimsdk/protocol/auth"
|
||||||
"github.com/openimsdk/tools/apiresp"
|
"github.com/openimsdk/tools/apiresp"
|
||||||
"github.com/openimsdk/tools/utils/jsonutil"
|
"github.com/openimsdk/tools/utils/jsonutil"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
"math"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockRootCmd is a mock type for the RootCmd type
|
// MockRootCmd is a mock type for the RootCmd type
|
||||||
@@ -40,7 +39,7 @@ func TestName(t *testing.T) {
|
|||||||
ErrCode: 1234,
|
ErrCode: 1234,
|
||||||
ErrMsg: "test",
|
ErrMsg: "test",
|
||||||
ErrDlt: "4567",
|
ErrDlt: "4567",
|
||||||
Data: &auth.GetUserTokenResp{
|
Data: &auth.UserTokenResp{
|
||||||
Token: "1234567",
|
Token: "1234567",
|
||||||
ExpireTimeSeconds: math.MaxInt64,
|
ExpireTimeSeconds: math.MaxInt64,
|
||||||
},
|
},
|
||||||
@@ -52,7 +51,7 @@ func TestName(t *testing.T) {
|
|||||||
t.Log(string(data))
|
t.Log(string(data))
|
||||||
|
|
||||||
var rReso apiresp.ApiResponse
|
var rReso apiresp.ApiResponse
|
||||||
rReso.Data = &auth.GetUserTokenResp{}
|
rReso.Data = &auth.UserTokenResp{}
|
||||||
|
|
||||||
if err := jsonutil.JsonUnmarshal(data, &rReso); err != nil {
|
if err := jsonutil.JsonUnmarshal(data, &rReso); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ type MsgGateway struct {
|
|||||||
WebsocketMaxMsgLen int `mapstructure:"websocketMaxMsgLen"`
|
WebsocketMaxMsgLen int `mapstructure:"websocketMaxMsgLen"`
|
||||||
WebsocketTimeout int `mapstructure:"websocketTimeout"`
|
WebsocketTimeout int `mapstructure:"websocketTimeout"`
|
||||||
} `mapstructure:"longConnSvr"`
|
} `mapstructure:"longConnSvr"`
|
||||||
|
MultiLoginPolicy int `mapstructure:"multiLoginPolicy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MsgTransfer struct {
|
type MsgTransfer struct {
|
||||||
@@ -345,26 +346,21 @@ type Redis struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BeforeConfig struct {
|
type BeforeConfig struct {
|
||||||
Enable bool `mapstructure:"enable"`
|
Enable bool `mapstructure:"enable"`
|
||||||
Timeout int `mapstructure:"timeout"`
|
Timeout int `mapstructure:"timeout"`
|
||||||
FailedContinue bool `mapstructure:"failedContinue"`
|
FailedContinue bool `mapstructure:"failedContinue"`
|
||||||
AllowedTypes []string `mapstructure:"allowedTypes"`
|
|
||||||
DeniedTypes []string `mapstructure:"deniedTypes"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AfterConfig struct {
|
type AfterConfig struct {
|
||||||
Enable bool `mapstructure:"enable"`
|
Enable bool `mapstructure:"enable"`
|
||||||
Timeout int `mapstructure:"timeout"`
|
Timeout int `mapstructure:"timeout"`
|
||||||
AttentionIds []string `mapstructure:"attentionIds"`
|
AttentionIds []string `mapstructure:"attentionIds"`
|
||||||
AllowedTypes []string `mapstructure:"allowedTypes"`
|
|
||||||
DeniedTypes []string `mapstructure:"deniedTypes"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Share struct {
|
type Share struct {
|
||||||
Secret string `mapstructure:"secret"`
|
Secret string `mapstructure:"secret"`
|
||||||
RpcRegisterName RpcRegisterName `mapstructure:"rpcRegisterName"`
|
RpcRegisterName RpcRegisterName `mapstructure:"rpcRegisterName"`
|
||||||
IMAdminUserID []string `mapstructure:"imAdminUserID"`
|
IMAdminUserID []string `mapstructure:"imAdminUserID"`
|
||||||
MultiLoginPolicy int `mapstructure:"multiLoginPolicy"`
|
|
||||||
}
|
}
|
||||||
type RpcRegisterName struct {
|
type RpcRegisterName struct {
|
||||||
User string `mapstructure:"user"`
|
User string `mapstructure:"user"`
|
||||||
@@ -438,7 +434,6 @@ type Webhooks struct {
|
|||||||
BeforeAddBlack BeforeConfig `mapstructure:"beforeAddBlack"`
|
BeforeAddBlack BeforeConfig `mapstructure:"beforeAddBlack"`
|
||||||
AfterAddFriend AfterConfig `mapstructure:"afterAddFriend"`
|
AfterAddFriend AfterConfig `mapstructure:"afterAddFriend"`
|
||||||
BeforeAddFriendAgree BeforeConfig `mapstructure:"beforeAddFriendAgree"`
|
BeforeAddFriendAgree BeforeConfig `mapstructure:"beforeAddFriendAgree"`
|
||||||
AfterAddFriendAgree AfterConfig `mapstructure:"afterAddFriendAgree"`
|
|
||||||
AfterDeleteFriend AfterConfig `mapstructure:"afterDeleteFriend"`
|
AfterDeleteFriend AfterConfig `mapstructure:"afterDeleteFriend"`
|
||||||
BeforeImportFriends BeforeConfig `mapstructure:"beforeImportFriends"`
|
BeforeImportFriends BeforeConfig `mapstructure:"beforeImportFriends"`
|
||||||
AfterImportFriends AfterConfig `mapstructure:"afterImportFriends"`
|
AfterImportFriends AfterConfig `mapstructure:"afterImportFriends"`
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ package cachekey
|
|||||||
const (
|
const (
|
||||||
ConversationKey = "CONVERSATION:"
|
ConversationKey = "CONVERSATION:"
|
||||||
ConversationIDsKey = "CONVERSATION_IDS:"
|
ConversationIDsKey = "CONVERSATION_IDS:"
|
||||||
NotNotifyConversationIDsKey = "NOT_NOTIFY_CONVERSATION_IDS:"
|
|
||||||
PinnedConversationIDsKey = "PINNED_CONVERSATION_IDS:"
|
|
||||||
ConversationIDsHashKey = "CONVERSATION_IDS_HASH:"
|
ConversationIDsHashKey = "CONVERSATION_IDS_HASH:"
|
||||||
ConversationHasReadSeqKey = "CONVERSATION_HAS_READ_SEQ:"
|
ConversationHasReadSeqKey = "CONVERSATION_HAS_READ_SEQ:"
|
||||||
RecvMsgOptKey = "RECV_MSG_OPT:"
|
RecvMsgOptKey = "RECV_MSG_OPT:"
|
||||||
@@ -36,14 +34,6 @@ func GetConversationIDsKey(ownerUserID string) string {
|
|||||||
return ConversationIDsKey + ownerUserID
|
return ConversationIDsKey + ownerUserID
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetNotNotifyConversationIDsKey(ownerUserID string) string {
|
|
||||||
return NotNotifyConversationIDsKey + ownerUserID
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPinnedConversationIDs(ownerUserID string) string {
|
|
||||||
return PinnedConversationIDsKey + ownerUserID
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetSuperGroupRecvNotNotifyUserIDsKey(groupID string) string {
|
func GetSuperGroupRecvNotNotifyUserIDsKey(groupID string) string {
|
||||||
return SuperGroupRecvMsgNotNotifyUserIDsKey + groupID
|
return SuperGroupRecvMsgNotNotifyUserIDsKey + groupID
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-11
@@ -20,17 +20,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
groupExpireTime = time.Second * 60 * 60 * 12
|
groupExpireTime = time.Second * 60 * 60 * 12
|
||||||
GroupInfoKey = "GROUP_INFO:"
|
GroupInfoKey = "GROUP_INFO:"
|
||||||
GroupMemberIDsKey = "GROUP_MEMBER_IDS:"
|
GroupMemberIDsKey = "GROUP_MEMBER_IDS:"
|
||||||
GroupMembersHashKey = "GROUP_MEMBERS_HASH2:"
|
GroupMembersHashKey = "GROUP_MEMBERS_HASH2:"
|
||||||
GroupMemberInfoKey = "GROUP_MEMBER_INFO:"
|
GroupMemberInfoKey = "GROUP_MEMBER_INFO:"
|
||||||
JoinedGroupsKey = "JOIN_GROUPS_KEY:"
|
JoinedGroupsKey = "JOIN_GROUPS_KEY:"
|
||||||
GroupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
|
GroupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
|
||||||
GroupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:"
|
GroupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:"
|
||||||
GroupAdminLevelMemberIDsKey = "GROUP_ADMIN_LEVEL_MEMBER_IDS:"
|
GroupMemberMaxVersionKey = "GROUP_MEMBER_MAX_VERSION:"
|
||||||
GroupMemberMaxVersionKey = "GROUP_MEMBER_MAX_VERSION:"
|
GroupJoinMaxVersionKey = "GROUP_JOIN_MAX_VERSION:"
|
||||||
GroupJoinMaxVersionKey = "GROUP_JOIN_MAX_VERSION:"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetGroupInfoKey(groupID string) string {
|
func GetGroupInfoKey(groupID string) string {
|
||||||
|
|||||||
+1
-4
@@ -25,8 +25,6 @@ type ConversationCache interface {
|
|||||||
CloneConversationCache() ConversationCache
|
CloneConversationCache() ConversationCache
|
||||||
// get user's conversationIDs from msgCache
|
// get user's conversationIDs from msgCache
|
||||||
GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error)
|
GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error)
|
||||||
GetUserNotNotifyConversationIDs(ctx context.Context, userID string) ([]string, error)
|
|
||||||
GetPinnedConversationIDs(ctx context.Context, userID string) ([]string, error)
|
|
||||||
DelConversationIDs(userIDs ...string) ConversationCache
|
DelConversationIDs(userIDs ...string) ConversationCache
|
||||||
|
|
||||||
GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error)
|
GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error)
|
||||||
@@ -56,8 +54,7 @@ type ConversationCache interface {
|
|||||||
|
|
||||||
GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error)
|
GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error)
|
||||||
DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache
|
DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache
|
||||||
DelConversationNotNotifyMessageUserIDs(userIDs ...string) ConversationCache
|
|
||||||
DelConversationPinnedMessageUserIDs(userIDs ...string) ConversationCache
|
|
||||||
DelConversationVersionUserIDs(userIDs ...string) ConversationCache
|
DelConversationVersionUserIDs(userIDs ...string) ConversationCache
|
||||||
|
|
||||||
FindMaxConversationUserVersion(ctx context.Context, userID string) (*relationtb.VersionLog, error)
|
FindMaxConversationUserVersion(ctx context.Context, userID string) (*relationtb.VersionLog, error)
|
||||||
|
|||||||
Vendored
-1
@@ -16,7 +16,6 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/common"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/common"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
)
|
)
|
||||||
|
|||||||
-36
@@ -71,14 +71,6 @@ func (c *ConversationRedisCache) getConversationIDsKey(ownerUserID string) strin
|
|||||||
return cachekey.GetConversationIDsKey(ownerUserID)
|
return cachekey.GetConversationIDsKey(ownerUserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConversationRedisCache) getNotNotifyConversationIDsKey(ownerUserID string) string {
|
|
||||||
return cachekey.GetNotNotifyConversationIDsKey(ownerUserID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ConversationRedisCache) getPinnedConversationIDsKey(ownerUserID string) string {
|
|
||||||
return cachekey.GetPinnedConversationIDs(ownerUserID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsKey(groupID string) string {
|
func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsKey(groupID string) string {
|
||||||
return cachekey.GetSuperGroupRecvNotNotifyUserIDsKey(groupID)
|
return cachekey.GetSuperGroupRecvNotNotifyUserIDsKey(groupID)
|
||||||
}
|
}
|
||||||
@@ -113,18 +105,6 @@ func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Context, own
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConversationRedisCache) GetUserNotNotifyConversationIDs(ctx context.Context, userID string) ([]string, error) {
|
|
||||||
return getCache(ctx, c.rcClient, c.getNotNotifyConversationIDsKey(userID), c.expireTime, func(ctx context.Context) ([]string, error) {
|
|
||||||
return c.conversationDB.FindUserIDAllNotNotifyConversationID(ctx, userID)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ConversationRedisCache) GetPinnedConversationIDs(ctx context.Context, userID string) ([]string, error) {
|
|
||||||
return getCache(ctx, c.rcClient, c.getPinnedConversationIDsKey(userID), c.expireTime, func(ctx context.Context) ([]string, error) {
|
|
||||||
return c.conversationDB.FindUserIDAllPinnedConversationID(ctx, userID)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ConversationRedisCache) DelConversationIDs(userIDs ...string) cache.ConversationCache {
|
func (c *ConversationRedisCache) DelConversationIDs(userIDs ...string) cache.ConversationCache {
|
||||||
keys := make([]string, 0, len(userIDs))
|
keys := make([]string, 0, len(userIDs))
|
||||||
for _, userID := range userIDs {
|
for _, userID := range userIDs {
|
||||||
@@ -262,22 +242,6 @@ func (c *ConversationRedisCache) DelConversationNotReceiveMessageUserIDs(convers
|
|||||||
return cache
|
return cache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConversationRedisCache) DelConversationNotNotifyMessageUserIDs(userIDs ...string) cache.ConversationCache {
|
|
||||||
cache := c.CloneConversationCache()
|
|
||||||
for _, userID := range userIDs {
|
|
||||||
cache.AddKeys(c.getNotNotifyConversationIDsKey(userID))
|
|
||||||
}
|
|
||||||
return cache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ConversationRedisCache) DelConversationPinnedMessageUserIDs(userIDs ...string) cache.ConversationCache {
|
|
||||||
cache := c.CloneConversationCache()
|
|
||||||
for _, userID := range userIDs {
|
|
||||||
cache.AddKeys(c.getPinnedConversationIDsKey(userID))
|
|
||||||
}
|
|
||||||
return cache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ConversationRedisCache) DelConversationVersionUserIDs(userIDs ...string) cache.ConversationCache {
|
func (c *ConversationRedisCache) DelConversationVersionUserIDs(userIDs ...string) cache.ConversationCache {
|
||||||
cache := c.CloneConversationCache()
|
cache := c.CloneConversationCache()
|
||||||
for _, userID := range userIDs {
|
for _, userID := range userIDs {
|
||||||
|
|||||||
+21
-207
@@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -58,14 +57,6 @@ func (s *seqConversationCacheRedis) getSingleMaxSeq(ctx context.Context, convers
|
|||||||
return map[string]int64{conversationID: seq}, nil
|
return map[string]int64{conversationID: seq}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) getSingleMaxSeqWithTime(ctx context.Context, conversationID string) (map[string]database.SeqTime, error) {
|
|
||||||
seq, err := s.GetMaxSeqWithTime(ctx, conversationID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return map[string]database.SeqTime{conversationID: seq}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) batchGetMaxSeq(ctx context.Context, keys []string, keyConversationID map[string]string, seqs map[string]int64) error {
|
func (s *seqConversationCacheRedis) batchGetMaxSeq(ctx context.Context, keys []string, keyConversationID map[string]string, seqs map[string]int64) error {
|
||||||
result := make([]*redis.StringCmd, len(keys))
|
result := make([]*redis.StringCmd, len(keys))
|
||||||
pipe := s.rdb.Pipeline()
|
pipe := s.rdb.Pipeline()
|
||||||
@@ -97,46 +88,6 @@ func (s *seqConversationCacheRedis) batchGetMaxSeq(ctx context.Context, keys []s
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) batchGetMaxSeqWithTime(ctx context.Context, keys []string, keyConversationID map[string]string, seqs map[string]database.SeqTime) error {
|
|
||||||
result := make([]*redis.SliceCmd, len(keys))
|
|
||||||
pipe := s.rdb.Pipeline()
|
|
||||||
for i, key := range keys {
|
|
||||||
result[i] = pipe.HMGet(ctx, key, "CURR", "TIME")
|
|
||||||
}
|
|
||||||
if _, err := pipe.Exec(ctx); err != nil && !errors.Is(err, redis.Nil) {
|
|
||||||
return errs.Wrap(err)
|
|
||||||
}
|
|
||||||
var notFoundKey []string
|
|
||||||
for i, r := range result {
|
|
||||||
val, err := r.Result()
|
|
||||||
if len(val) != 2 {
|
|
||||||
return errs.WrapMsg(err, "batchGetMaxSeqWithTime invalid result", "key", keys[i], "res", val)
|
|
||||||
}
|
|
||||||
if val[0] == nil {
|
|
||||||
notFoundKey = append(notFoundKey, keys[i])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seq, err := s.parseInt64(val[0])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
mill, err := s.parseInt64(val[1])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
seqs[keyConversationID[keys[i]]] = database.SeqTime{Seq: seq, Time: mill}
|
|
||||||
}
|
|
||||||
for _, key := range notFoundKey {
|
|
||||||
conversationID := keyConversationID[key]
|
|
||||||
seq, err := s.GetMaxSeqWithTime(ctx, conversationID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
seqs[conversationID] = seq
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) {
|
func (s *seqConversationCacheRedis) GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) {
|
||||||
switch len(conversationIDs) {
|
switch len(conversationIDs) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -170,44 +121,11 @@ func (s *seqConversationCacheRedis) GetMaxSeqs(ctx context.Context, conversation
|
|||||||
return seqs, nil
|
return seqs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) GetMaxSeqsWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error) {
|
|
||||||
switch len(conversationIDs) {
|
|
||||||
case 0:
|
|
||||||
return map[string]database.SeqTime{}, nil
|
|
||||||
case 1:
|
|
||||||
return s.getSingleMaxSeqWithTime(ctx, conversationIDs[0])
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, len(conversationIDs))
|
|
||||||
keyConversationID := make(map[string]string, len(conversationIDs))
|
|
||||||
for _, conversationID := range conversationIDs {
|
|
||||||
key := s.getSeqMallocKey(conversationID)
|
|
||||||
if _, ok := keyConversationID[key]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
keys = append(keys, key)
|
|
||||||
keyConversationID[key] = conversationID
|
|
||||||
}
|
|
||||||
if len(keys) == 1 {
|
|
||||||
return s.getSingleMaxSeqWithTime(ctx, conversationIDs[0])
|
|
||||||
}
|
|
||||||
slotKeys, err := groupKeysBySlot(ctx, s.rdb, keys)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
seqs := make(map[string]database.SeqTime, len(conversationIDs))
|
|
||||||
for _, keys := range slotKeys {
|
|
||||||
if err := s.batchGetMaxSeqWithTime(ctx, keys, keyConversationID, seqs); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return seqs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) getSeqMallocKey(conversationID string) string {
|
func (s *seqConversationCacheRedis) getSeqMallocKey(conversationID string) string {
|
||||||
return cachekey.GetMallocSeqKey(conversationID)
|
return cachekey.GetMallocSeqKey(conversationID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) setSeq(ctx context.Context, key string, owner int64, currSeq int64, lastSeq int64, mill int64) (int64, error) {
|
func (s *seqConversationCacheRedis) setSeq(ctx context.Context, key string, owner int64, currSeq int64, lastSeq int64) (int64, error) {
|
||||||
if lastSeq < currSeq {
|
if lastSeq < currSeq {
|
||||||
return 0, errs.New("lastSeq must be greater than currSeq")
|
return 0, errs.New("lastSeq must be greater than currSeq")
|
||||||
}
|
}
|
||||||
@@ -220,9 +138,8 @@ local lockValue = ARGV[1]
|
|||||||
local dataSecond = ARGV[2]
|
local dataSecond = ARGV[2]
|
||||||
local curr_seq = tonumber(ARGV[3])
|
local curr_seq = tonumber(ARGV[3])
|
||||||
local last_seq = tonumber(ARGV[4])
|
local last_seq = tonumber(ARGV[4])
|
||||||
local mallocTime = ARGV[5]
|
|
||||||
if redis.call("EXISTS", key) == 0 then
|
if redis.call("EXISTS", key) == 0 then
|
||||||
redis.call("HSET", key, "CURR", curr_seq, "LAST", last_seq, "TIME", mallocTime)
|
redis.call("HSET", key, "CURR", curr_seq, "LAST", last_seq)
|
||||||
redis.call("EXPIRE", key, dataSecond)
|
redis.call("EXPIRE", key, dataSecond)
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
@@ -230,11 +147,11 @@ if redis.call("HGET", key, "LOCK") ~= lockValue then
|
|||||||
return 2
|
return 2
|
||||||
end
|
end
|
||||||
redis.call("HDEL", key, "LOCK")
|
redis.call("HDEL", key, "LOCK")
|
||||||
redis.call("HSET", key, "CURR", curr_seq, "LAST", last_seq, "TIME", mallocTime)
|
redis.call("HSET", key, "CURR", curr_seq, "LAST", last_seq)
|
||||||
redis.call("EXPIRE", key, dataSecond)
|
redis.call("EXPIRE", key, dataSecond)
|
||||||
return 0
|
return 0
|
||||||
`
|
`
|
||||||
result, err := s.rdb.Eval(ctx, script, []string{key}, owner, int64(s.dataTime/time.Second), currSeq, lastSeq, mill).Int64()
|
result, err := s.rdb.Eval(ctx, script, []string{key}, owner, int64(s.dataTime/time.Second), currSeq, lastSeq).Int64()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errs.Wrap(err)
|
return 0, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
@@ -252,7 +169,6 @@ local key = KEYS[1]
|
|||||||
local size = tonumber(ARGV[1])
|
local size = tonumber(ARGV[1])
|
||||||
local lockSecond = ARGV[2]
|
local lockSecond = ARGV[2]
|
||||||
local dataSecond = ARGV[3]
|
local dataSecond = ARGV[3]
|
||||||
local mallocTime = ARGV[4]
|
|
||||||
local result = {}
|
local result = {}
|
||||||
if redis.call("EXISTS", key) == 0 then
|
if redis.call("EXISTS", key) == 0 then
|
||||||
local lockValue = math.random(0, 999999999)
|
local lockValue = math.random(0, 999999999)
|
||||||
@@ -260,7 +176,6 @@ if redis.call("EXISTS", key) == 0 then
|
|||||||
redis.call("EXPIRE", key, lockSecond)
|
redis.call("EXPIRE", key, lockSecond)
|
||||||
table.insert(result, 1)
|
table.insert(result, 1)
|
||||||
table.insert(result, lockValue)
|
table.insert(result, lockValue)
|
||||||
table.insert(result, mallocTime)
|
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
if redis.call("HEXISTS", key, "LOCK") == 1 then
|
if redis.call("HEXISTS", key, "LOCK") == 1 then
|
||||||
@@ -274,12 +189,6 @@ if size == 0 then
|
|||||||
table.insert(result, 0)
|
table.insert(result, 0)
|
||||||
table.insert(result, curr_seq)
|
table.insert(result, curr_seq)
|
||||||
table.insert(result, last_seq)
|
table.insert(result, last_seq)
|
||||||
local setTime = redis.call("HGET", key, "TIME")
|
|
||||||
if setTime then
|
|
||||||
table.insert(result, setTime)
|
|
||||||
else
|
|
||||||
table.insert(result, 0)
|
|
||||||
end
|
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
local max_seq = curr_seq + size
|
local max_seq = curr_seq + size
|
||||||
@@ -287,25 +196,21 @@ if max_seq > last_seq then
|
|||||||
local lockValue = math.random(0, 999999999)
|
local lockValue = math.random(0, 999999999)
|
||||||
redis.call("HSET", key, "LOCK", lockValue)
|
redis.call("HSET", key, "LOCK", lockValue)
|
||||||
redis.call("HSET", key, "CURR", last_seq)
|
redis.call("HSET", key, "CURR", last_seq)
|
||||||
redis.call("HSET", key, "TIME", mallocTime)
|
|
||||||
redis.call("EXPIRE", key, lockSecond)
|
redis.call("EXPIRE", key, lockSecond)
|
||||||
table.insert(result, 3)
|
table.insert(result, 3)
|
||||||
table.insert(result, curr_seq)
|
table.insert(result, curr_seq)
|
||||||
table.insert(result, last_seq)
|
table.insert(result, last_seq)
|
||||||
table.insert(result, lockValue)
|
table.insert(result, lockValue)
|
||||||
table.insert(result, mallocTime)
|
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
redis.call("HSET", key, "CURR", max_seq)
|
redis.call("HSET", key, "CURR", max_seq)
|
||||||
redis.call("HSET", key, "TIME", ARGV[4])
|
|
||||||
redis.call("EXPIRE", key, dataSecond)
|
redis.call("EXPIRE", key, dataSecond)
|
||||||
table.insert(result, 0)
|
table.insert(result, 0)
|
||||||
table.insert(result, curr_seq)
|
table.insert(result, curr_seq)
|
||||||
table.insert(result, last_seq)
|
table.insert(result, last_seq)
|
||||||
table.insert(result, mallocTime)
|
|
||||||
return result
|
return result
|
||||||
`
|
`
|
||||||
result, err := s.rdb.Eval(ctx, script, []string{key}, size, int64(s.lockTime/time.Second), int64(s.dataTime/time.Second), time.Now().UnixMilli()).Int64Slice()
|
result, err := s.rdb.Eval(ctx, script, []string{key}, size, int64(s.lockTime/time.Second), int64(s.dataTime/time.Second)).Int64Slice()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err)
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
@@ -323,9 +228,9 @@ func (s *seqConversationCacheRedis) wait(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) setSeqRetry(ctx context.Context, key string, owner int64, currSeq int64, lastSeq int64, mill int64) {
|
func (s *seqConversationCacheRedis) setSeqRetry(ctx context.Context, key string, owner int64, currSeq int64, lastSeq int64) {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
state, err := s.setSeq(ctx, key, owner, currSeq, lastSeq, mill)
|
state, err := s.setSeq(ctx, key, owner, currSeq, lastSeq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZError(ctx, "set seq cache failed", err, "key", key, "owner", owner, "currSeq", currSeq, "lastSeq", lastSeq, "count", i+1)
|
log.ZError(ctx, "set seq cache failed", err, "key", key, "owner", owner, "currSeq", currSeq, "lastSeq", lastSeq, "count", i+1)
|
||||||
if err := s.wait(ctx); err != nil {
|
if err := s.wait(ctx); err != nil {
|
||||||
@@ -362,74 +267,60 @@ func (s *seqConversationCacheRedis) getMallocSize(conversationID string, size in
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) Malloc(ctx context.Context, conversationID string, size int64) (int64, error) {
|
func (s *seqConversationCacheRedis) Malloc(ctx context.Context, conversationID string, size int64) (int64, error) {
|
||||||
seq, _, err := s.mallocTime(ctx, conversationID, size)
|
|
||||||
return seq, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) mallocTime(ctx context.Context, conversationID string, size int64) (int64, int64, error) {
|
|
||||||
if size < 0 {
|
if size < 0 {
|
||||||
return 0, 0, errs.New("size must be greater than 0")
|
return 0, errs.New("size must be greater than 0")
|
||||||
}
|
}
|
||||||
key := s.getSeqMallocKey(conversationID)
|
key := s.getSeqMallocKey(conversationID)
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
states, err := s.malloc(ctx, key, size)
|
states, err := s.malloc(ctx, key, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
switch states[0] {
|
switch states[0] {
|
||||||
case 0: // success
|
case 0: // success
|
||||||
return states[1], states[3], nil
|
return states[1], nil
|
||||||
case 1: // not found
|
case 1: // not found
|
||||||
mallocSize := s.getMallocSize(conversationID, size)
|
mallocSize := s.getMallocSize(conversationID, size)
|
||||||
seq, err := s.mgo.Malloc(ctx, conversationID, mallocSize)
|
seq, err := s.mgo.Malloc(ctx, conversationID, mallocSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
s.setSeqRetry(ctx, key, states[1], seq+size, seq+mallocSize, states[2])
|
s.setSeqRetry(ctx, key, states[1], seq+size, seq+mallocSize)
|
||||||
return seq, 0, nil
|
return seq, nil
|
||||||
case 2: // locked
|
case 2: // locked
|
||||||
if err := s.wait(ctx); err != nil {
|
if err := s.wait(ctx); err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
case 3: // exceeded cache max value
|
case 3: // exceeded cache max value
|
||||||
currSeq := states[1]
|
currSeq := states[1]
|
||||||
lastSeq := states[2]
|
lastSeq := states[2]
|
||||||
mill := states[4]
|
|
||||||
mallocSize := s.getMallocSize(conversationID, size)
|
mallocSize := s.getMallocSize(conversationID, size)
|
||||||
seq, err := s.mgo.Malloc(ctx, conversationID, mallocSize)
|
seq, err := s.mgo.Malloc(ctx, conversationID, mallocSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if lastSeq == seq {
|
if lastSeq == seq {
|
||||||
s.setSeqRetry(ctx, key, states[3], currSeq+size, seq+mallocSize, mill)
|
s.setSeqRetry(ctx, key, states[3], currSeq+size, seq+mallocSize)
|
||||||
return currSeq, states[4], nil
|
return currSeq, nil
|
||||||
} else {
|
} else {
|
||||||
log.ZWarn(ctx, "malloc seq not equal cache last seq", nil, "conversationID", conversationID, "currSeq", currSeq, "lastSeq", lastSeq, "mallocSeq", seq)
|
log.ZWarn(ctx, "malloc seq not equal cache last seq", nil, "conversationID", conversationID, "currSeq", currSeq, "lastSeq", lastSeq, "mallocSeq", seq)
|
||||||
s.setSeqRetry(ctx, key, states[3], seq+size, seq+mallocSize, mill)
|
s.setSeqRetry(ctx, key, states[3], seq+size, seq+mallocSize)
|
||||||
return seq, mill, nil
|
return seq, nil
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
log.ZError(ctx, "malloc seq unknown state", nil, "state", states[0], "conversationID", conversationID, "size", size)
|
log.ZError(ctx, "malloc seq unknown state", nil, "state", states[0], "conversationID", conversationID, "size", size)
|
||||||
return 0, 0, errs.New(fmt.Sprintf("unknown state: %d", states[0]))
|
return 0, errs.New(fmt.Sprintf("unknown state: %d", states[0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.ZError(ctx, "malloc seq retrying still failed", nil, "conversationID", conversationID, "size", size)
|
log.ZError(ctx, "malloc seq retrying still failed", nil, "conversationID", conversationID, "size", size)
|
||||||
return 0, 0, errs.New("malloc seq waiting for lock timeout", "conversationID", conversationID, "size", size)
|
return 0, errs.New("malloc seq waiting for lock timeout", "conversationID", conversationID, "size", size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) GetMaxSeq(ctx context.Context, conversationID string) (int64, error) {
|
func (s *seqConversationCacheRedis) GetMaxSeq(ctx context.Context, conversationID string) (int64, error) {
|
||||||
return s.Malloc(ctx, conversationID, 0)
|
return s.Malloc(ctx, conversationID, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) GetMaxSeqWithTime(ctx context.Context, conversationID string) (database.SeqTime, error) {
|
|
||||||
seq, mill, err := s.mallocTime(ctx, conversationID, 0)
|
|
||||||
if err != nil {
|
|
||||||
return database.SeqTime{}, err
|
|
||||||
}
|
|
||||||
return database.SeqTime{Seq: seq, Time: mill}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) SetMinSeqs(ctx context.Context, seqs map[string]int64) error {
|
func (s *seqConversationCacheRedis) SetMinSeqs(ctx context.Context, seqs map[string]int64) error {
|
||||||
keys := make([]string, 0, len(seqs))
|
keys := make([]string, 0, len(seqs))
|
||||||
for conversationID, seq := range seqs {
|
for conversationID, seq := range seqs {
|
||||||
@@ -440,80 +331,3 @@ func (s *seqConversationCacheRedis) SetMinSeqs(ctx context.Context, seqs map[str
|
|||||||
}
|
}
|
||||||
return DeleteCacheBySlot(ctx, s.rocks, keys)
|
return DeleteCacheBySlot(ctx, s.rocks, keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCacheMaxSeqWithTime only get the existing cache, if there is no cache, no cache will be generated
|
|
||||||
func (s *seqConversationCacheRedis) GetCacheMaxSeqWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error) {
|
|
||||||
if len(conversationIDs) == 0 {
|
|
||||||
return map[string]database.SeqTime{}, nil
|
|
||||||
}
|
|
||||||
key2conversationID := make(map[string]string)
|
|
||||||
keys := make([]string, 0, len(conversationIDs))
|
|
||||||
for _, conversationID := range conversationIDs {
|
|
||||||
key := s.getSeqMallocKey(conversationID)
|
|
||||||
if _, ok := key2conversationID[key]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
key2conversationID[key] = conversationID
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
slotKeys, err := groupKeysBySlot(ctx, s.rdb, keys)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
res := make(map[string]database.SeqTime)
|
|
||||||
for _, keys := range slotKeys {
|
|
||||||
if len(keys) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pipe := s.rdb.Pipeline()
|
|
||||||
cmds := make([]*redis.SliceCmd, 0, len(keys))
|
|
||||||
for _, key := range keys {
|
|
||||||
cmds = append(cmds, pipe.HMGet(ctx, key, "CURR", "TIME"))
|
|
||||||
}
|
|
||||||
if _, err := pipe.Exec(ctx); err != nil {
|
|
||||||
return nil, errs.Wrap(err)
|
|
||||||
}
|
|
||||||
for i, cmd := range cmds {
|
|
||||||
val, err := cmd.Result()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(val) != 2 {
|
|
||||||
return nil, errs.WrapMsg(err, "GetCacheMaxSeqWithTime invalid result", "key", keys[i], "res", val)
|
|
||||||
}
|
|
||||||
if val[0] == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seq, err := s.parseInt64(val[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mill, err := s.parseInt64(val[1])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
conversationID := key2conversationID[keys[i]]
|
|
||||||
res[conversationID] = database.SeqTime{Seq: seq, Time: mill}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *seqConversationCacheRedis) parseInt64(val any) (int64, error) {
|
|
||||||
switch v := val.(type) {
|
|
||||||
case nil:
|
|
||||||
return 0, nil
|
|
||||||
case int:
|
|
||||||
return int64(v), nil
|
|
||||||
case int64:
|
|
||||||
return v, nil
|
|
||||||
case string:
|
|
||||||
res, err := strconv.ParseInt(v, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errs.WrapMsg(err, "invalid string not int64", "value", v)
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
default:
|
|
||||||
return 0, errs.New("invalid result not int64", "resType", fmt.Sprintf("%T", v), "value", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-36
@@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func newTestSeq() *seqConversationCacheRedis {
|
func newTestSeq() *seqConversationCacheRedis {
|
||||||
mgocli, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://openIM:openIM123@127.0.0.1:37017/openim_v3?maxPoolSize=100").SetConnectTimeout(5*time.Second))
|
mgocli, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://openIM:openIM123@172.16.8.48:37017/openim_v3?maxPoolSize=100").SetConnectTimeout(5*time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ func newTestSeq() *seqConversationCacheRedis {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
opt := &redis.Options{
|
opt := &redis.Options{
|
||||||
Addr: "127.0.0.1:16379",
|
Addr: "172.16.8.48:16379",
|
||||||
Password: "openIM123",
|
Password: "openIM123",
|
||||||
DB: 1,
|
DB: 1,
|
||||||
}
|
}
|
||||||
@@ -107,37 +107,3 @@ func TestMinSeq(t *testing.T) {
|
|||||||
ts := newTestSeq()
|
ts := newTestSeq()
|
||||||
t.Log(ts.GetMinSeq(context.Background(), "10000000"))
|
t.Log(ts.GetMinSeq(context.Background(), "10000000"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMalloc(t *testing.T) {
|
|
||||||
ts := newTestSeq()
|
|
||||||
t.Log(ts.mallocTime(context.Background(), "10000000", 100))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHMGET(t *testing.T) {
|
|
||||||
ts := newTestSeq()
|
|
||||||
res, err := ts.GetCacheMaxSeqWithTime(context.Background(), []string{"10000000", "123456"})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
t.Log(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetMaxSeqWithTime(t *testing.T) {
|
|
||||||
ts := newTestSeq()
|
|
||||||
t.Log(ts.GetMaxSeqWithTime(context.Background(), "10000000"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetMaxSeqWithTime1(t *testing.T) {
|
|
||||||
ts := newTestSeq()
|
|
||||||
t.Log(ts.GetMaxSeqsWithTime(context.Background(), []string{"10000000", "12345", "111"}))
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
//func TestHMGET(t *testing.T) {
|
|
||||||
// ts := newTestSeq()
|
|
||||||
// res, err := ts.rdb.HMGet(context.Background(), "MALLOC_SEQ:1", "CURR", "TIME1").Result()
|
|
||||||
// if err != nil {
|
|
||||||
// panic(err)
|
|
||||||
// }
|
|
||||||
// t.Log(res)
|
|
||||||
//}
|
|
||||||
|
|||||||
+3
-6
@@ -19,8 +19,8 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
|
"github.com/openimsdk/tools/utils/stringutil"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -58,12 +58,9 @@ func (c *tokenCache) GetTokensWithoutError(ctx context.Context, userID string, p
|
|||||||
}
|
}
|
||||||
mm := make(map[string]int)
|
mm := make(map[string]int)
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
state, err := strconv.Atoi(v)
|
mm[k] = stringutil.StringToInt(v)
|
||||||
if err != nil {
|
|
||||||
return nil, errs.WrapMsg(err, "redis token value is not int", "value", v, "userID", userID, "platformID", platformID)
|
|
||||||
}
|
|
||||||
mm[k] = state
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mm, nil
|
return mm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-7
@@ -1,9 +1,6 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import "context"
|
||||||
"context"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SeqConversationCache interface {
|
type SeqConversationCache interface {
|
||||||
Malloc(ctx context.Context, conversationID string, size int64) (int64, error)
|
Malloc(ctx context.Context, conversationID string, size int64) (int64, error)
|
||||||
@@ -12,7 +9,4 @@ type SeqConversationCache interface {
|
|||||||
GetMinSeq(ctx context.Context, conversationID string) (int64, error)
|
GetMinSeq(ctx context.Context, conversationID string) (int64, error)
|
||||||
GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error)
|
GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error)
|
||||||
SetMinSeqs(ctx context.Context, seqs map[string]int64) error
|
SetMinSeqs(ctx context.Context, seqs map[string]int64) error
|
||||||
GetCacheMaxSeqWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error)
|
|
||||||
GetMaxSeqsWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error)
|
|
||||||
GetMaxSeqWithTime(ctx context.Context, conversationID string) (database.SeqTime, error)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/openimsdk/tools/log"
|
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
@@ -36,14 +35,13 @@ type AuthDatabase interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type authDatabase struct {
|
type authDatabase struct {
|
||||||
cache cache.TokenModel
|
cache cache.TokenModel
|
||||||
accessSecret string
|
accessSecret string
|
||||||
accessExpire int64
|
accessExpire int64
|
||||||
multiLoginPolicy int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthDatabase(cache cache.TokenModel, accessSecret string, accessExpire int64, policy int) AuthDatabase {
|
func NewAuthDatabase(cache cache.TokenModel, accessSecret string, accessExpire int64) AuthDatabase {
|
||||||
return &authDatabase{cache: cache, accessSecret: accessSecret, accessExpire: accessExpire, multiLoginPolicy: policy}
|
return &authDatabase{cache: cache, accessSecret: accessSecret, accessExpire: accessExpire}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the result is empty.
|
// If the result is empty.
|
||||||
@@ -57,19 +55,15 @@ func (a *authDatabase) SetTokenMapByUidPid(ctx context.Context, userID string, p
|
|||||||
|
|
||||||
// Create Token.
|
// Create Token.
|
||||||
func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformID int) (string, error) {
|
func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformID int) (string, error) {
|
||||||
// todo: get all platform token
|
|
||||||
tokens, err := a.cache.GetTokensWithoutError(ctx, userID, platformID)
|
tokens, err := a.cache.GetTokensWithoutError(ctx, userID, platformID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
var deleteTokenKey []string
|
var deleteTokenKey []string
|
||||||
var kickedTokenKey []string
|
|
||||||
for k, v := range tokens {
|
for k, v := range tokens {
|
||||||
t, err := tokenverify.GetClaimFromToken(k, authverify.Secret(a.accessSecret))
|
_, err = tokenverify.GetClaimFromToken(k, authverify.Secret(a.accessSecret))
|
||||||
if err != nil || v != constant.NormalToken {
|
if err != nil || v != constant.NormalToken {
|
||||||
deleteTokenKey = append(deleteTokenKey, k)
|
deleteTokenKey = append(deleteTokenKey, k)
|
||||||
} else if a.checkKickToken(ctx, platformID, t) {
|
|
||||||
kickedTokenKey = append(kickedTokenKey, k)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(deleteTokenKey) != 0 {
|
if len(deleteTokenKey) != 0 {
|
||||||
@@ -79,25 +73,6 @@ func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const adminTokenMaxNum = 30
|
|
||||||
if platformID == constant.AdminPlatformID {
|
|
||||||
if len(kickedTokenKey) > adminTokenMaxNum {
|
|
||||||
kickedTokenKey = kickedTokenKey[:len(kickedTokenKey)-adminTokenMaxNum]
|
|
||||||
} else {
|
|
||||||
kickedTokenKey = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(kickedTokenKey) != 0 {
|
|
||||||
for _, k := range kickedTokenKey {
|
|
||||||
err := a.cache.SetTokenFlagEx(ctx, userID, platformID, k, constant.KickedToken)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
log.ZDebug(ctx, "kicked token in create token", "token", k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
claims := tokenverify.BuildClaims(userID, platformID, a.accessExpire)
|
claims := tokenverify.BuildClaims(userID, platformID, a.accessExpire)
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
tokenString, err := token.SignedString([]byte(a.accessSecret))
|
tokenString, err := token.SignedString([]byte(a.accessSecret))
|
||||||
@@ -110,23 +85,3 @@ func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformI
|
|||||||
}
|
}
|
||||||
return tokenString, nil
|
return tokenString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *authDatabase) checkKickToken(ctx context.Context, platformID int, token *tokenverify.Claims) bool {
|
|
||||||
switch a.multiLoginPolicy {
|
|
||||||
case constant.DefalutNotKick:
|
|
||||||
return false
|
|
||||||
case constant.PCAndOther:
|
|
||||||
if constant.PlatformIDToClass(platformID) == constant.TerminalPC ||
|
|
||||||
constant.PlatformIDToClass(token.PlatformID) == constant.TerminalPC {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
case constant.AllLoginButSameTermKick:
|
|
||||||
if platformID == token.PlatformID {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -69,10 +69,6 @@ type ConversationDatabase interface {
|
|||||||
FindConversationUserVersion(ctx context.Context, userID string, version uint, limit int) (*relationtb.VersionLog, error)
|
FindConversationUserVersion(ctx context.Context, userID string, version uint, limit int) (*relationtb.VersionLog, error)
|
||||||
FindMaxConversationUserVersionCache(ctx context.Context, userID string) (*relationtb.VersionLog, error)
|
FindMaxConversationUserVersionCache(ctx context.Context, userID string) (*relationtb.VersionLog, error)
|
||||||
GetOwnerConversation(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (int64, []*relationtb.Conversation, error)
|
GetOwnerConversation(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (int64, []*relationtb.Conversation, error)
|
||||||
// GetNotNotifyConversationIDs gets not notify conversationIDs by userID
|
|
||||||
GetNotNotifyConversationIDs(ctx context.Context, userID string) ([]string, error)
|
|
||||||
// GetPinnedConversationIDs gets pinned conversationIDs by userID
|
|
||||||
GetPinnedConversationIDs(ctx context.Context, userID string) ([]string, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConversationDatabase(conversation database.Conversation, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase {
|
func NewConversationDatabase(conversation database.Conversation, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase {
|
||||||
@@ -112,10 +108,6 @@ func (c *conversationDatabase) SetUsersConversationFieldTx(ctx context.Context,
|
|||||||
}
|
}
|
||||||
if _, ok := fieldMap["recv_msg_opt"]; ok {
|
if _, ok := fieldMap["recv_msg_opt"]; ok {
|
||||||
cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID)
|
cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID)
|
||||||
cache = cache.DelConversationNotNotifyMessageUserIDs(userIDs...)
|
|
||||||
}
|
|
||||||
if _, ok := fieldMap["is_pinned"]; ok {
|
|
||||||
cache = cache.DelConversationPinnedMessageUserIDs(userIDs...)
|
|
||||||
}
|
}
|
||||||
cache = cache.DelConversationVersionUserIDs(haveUserIDs...)
|
cache = cache.DelConversationVersionUserIDs(haveUserIDs...)
|
||||||
}
|
}
|
||||||
@@ -152,10 +144,6 @@ func (c *conversationDatabase) UpdateUsersConversationField(ctx context.Context,
|
|||||||
cache = cache.DelUsersConversation(conversationID, userIDs...).DelConversationVersionUserIDs(userIDs...)
|
cache = cache.DelUsersConversation(conversationID, userIDs...).DelConversationVersionUserIDs(userIDs...)
|
||||||
if _, ok := args["recv_msg_opt"]; ok {
|
if _, ok := args["recv_msg_opt"]; ok {
|
||||||
cache = cache.DelConversationNotReceiveMessageUserIDs(conversationID)
|
cache = cache.DelConversationNotReceiveMessageUserIDs(conversationID)
|
||||||
cache = cache.DelConversationNotNotifyMessageUserIDs(userIDs...)
|
|
||||||
}
|
|
||||||
if _, ok := args["is_pinned"]; ok {
|
|
||||||
cache = cache.DelConversationPinnedMessageUserIDs(userIDs...)
|
|
||||||
}
|
}
|
||||||
return cache.ChainExecDel(ctx)
|
return cache.ChainExecDel(ctx)
|
||||||
}
|
}
|
||||||
@@ -164,30 +152,14 @@ func (c *conversationDatabase) CreateConversation(ctx context.Context, conversat
|
|||||||
if err := c.conversationDB.Create(ctx, conversations); err != nil {
|
if err := c.conversationDB.Create(ctx, conversations); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var (
|
var userIDs []string
|
||||||
userIDs []string
|
|
||||||
notNotifyUserIDs []string
|
|
||||||
pinnedUserIDs []string
|
|
||||||
)
|
|
||||||
|
|
||||||
cache := c.cache.CloneConversationCache()
|
cache := c.cache.CloneConversationCache()
|
||||||
for _, conversation := range conversations {
|
for _, conversation := range conversations {
|
||||||
cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID)
|
cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID)
|
||||||
cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID)
|
cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID)
|
||||||
userIDs = append(userIDs, conversation.OwnerUserID)
|
userIDs = append(userIDs, conversation.OwnerUserID)
|
||||||
if conversation.RecvMsgOpt == constant.ReceiveNotNotifyMessage {
|
|
||||||
notNotifyUserIDs = append(notNotifyUserIDs, conversation.OwnerUserID)
|
|
||||||
}
|
|
||||||
if conversation.IsPinned == true {
|
|
||||||
pinnedUserIDs = append(pinnedUserIDs, conversation.OwnerUserID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return cache.DelConversationIDs(userIDs...).
|
return cache.DelConversationIDs(userIDs...).DelUserConversationIDsHash(userIDs...).DelConversationVersionUserIDs(userIDs...).ChainExecDel(ctx)
|
||||||
DelUserConversationIDsHash(userIDs...).
|
|
||||||
DelConversationVersionUserIDs(userIDs...).
|
|
||||||
DelConversationNotNotifyMessageUserIDs(notNotifyUserIDs...).
|
|
||||||
DelConversationPinnedMessageUserIDs(pinnedUserIDs...).
|
|
||||||
ChainExecDel(ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Context, conversations []*relationtb.Conversation) error {
|
func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Context, conversations []*relationtb.Conversation) error {
|
||||||
@@ -240,10 +212,7 @@ func (c *conversationDatabase) GetUserAllConversation(ctx context.Context, owner
|
|||||||
func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.Conversation) error {
|
func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.Conversation) error {
|
||||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||||
cache := c.cache.CloneConversationCache()
|
cache := c.cache.CloneConversationCache()
|
||||||
cache = cache.DelConversationVersionUserIDs(ownerUserID).
|
cache = cache.DelConversationVersionUserIDs(ownerUserID)
|
||||||
DelConversationNotNotifyMessageUserIDs(ownerUserID).
|
|
||||||
DelConversationPinnedMessageUserIDs(ownerUserID)
|
|
||||||
|
|
||||||
groupIDs := datautil.Distinct(datautil.Filter(conversations, func(e *relationtb.Conversation) (string, bool) {
|
groupIDs := datautil.Distinct(datautil.Filter(conversations, func(e *relationtb.Conversation) (string, bool) {
|
||||||
return e.GroupID, e.GroupID != ""
|
return e.GroupID, e.GroupID != ""
|
||||||
}))
|
}))
|
||||||
@@ -384,19 +353,3 @@ func (c *conversationDatabase) GetOwnerConversation(ctx context.Context, ownerUs
|
|||||||
}
|
}
|
||||||
return int64(len(conversationIDs)), conversations, nil
|
return int64(len(conversationIDs)), conversations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conversationDatabase) GetNotNotifyConversationIDs(ctx context.Context, userID string) ([]string, error) {
|
|
||||||
conversationIDs, err := c.cache.GetUserNotNotifyConversationIDs(ctx, userID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return conversationIDs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *conversationDatabase) GetPinnedConversationIDs(ctx context.Context, userID string) ([]string, error) {
|
|
||||||
conversationIDs, err := c.cache.GetPinnedConversationIDs(ctx, userID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return conversationIDs, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -74,10 +74,6 @@ type CommonMsgDatabase interface {
|
|||||||
GetHasReadSeq(ctx context.Context, userID string, conversationID string) (int64, error)
|
GetHasReadSeq(ctx context.Context, userID string, conversationID string) (int64, error)
|
||||||
UserSetHasReadSeqs(ctx context.Context, userID string, hasReadSeqs map[string]int64) error
|
UserSetHasReadSeqs(ctx context.Context, userID string, hasReadSeqs map[string]int64) error
|
||||||
|
|
||||||
GetMaxSeqsWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error)
|
|
||||||
GetMaxSeqWithTime(ctx context.Context, conversationID string) (database.SeqTime, error)
|
|
||||||
GetCacheMaxSeqWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error)
|
|
||||||
|
|
||||||
//GetMongoMaxAndMinSeq(ctx context.Context, conversationID string) (minSeqMongo, maxSeqMongo int64, err error)
|
//GetMongoMaxAndMinSeq(ctx context.Context, conversationID string) (minSeqMongo, maxSeqMongo int64, err error)
|
||||||
//GetConversationMinMaxSeqInMongoAndCache(ctx context.Context, conversationID string) (minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache int64, err error)
|
//GetConversationMinMaxSeqInMongoAndCache(ctx context.Context, conversationID string) (minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache int64, err error)
|
||||||
SetSendMsgStatus(ctx context.Context, id string, status int32) error
|
SetSendMsgStatus(ctx context.Context, id string, status int32) error
|
||||||
@@ -450,7 +446,7 @@ func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID strin
|
|||||||
|
|
||||||
func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, conversationID string, seqs []int64) (int64, int64, []*sdkws.MsgData, error) {
|
func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, conversationID string, seqs []int64) (int64, int64, []*sdkws.MsgData, error) {
|
||||||
userMinSeq, err := db.seqUser.GetUserMinSeq(ctx, conversationID, userID)
|
userMinSeq, err := db.seqUser.GetUserMinSeq(ctx, conversationID, userID)
|
||||||
if err != nil {
|
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||||
return 0, 0, nil, err
|
return 0, 0, nil, err
|
||||||
}
|
}
|
||||||
minSeq, err := db.seqConversation.GetMinSeq(ctx, conversationID)
|
minSeq, err := db.seqConversation.GetMinSeq(ctx, conversationID)
|
||||||
@@ -461,28 +457,15 @@ func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, co
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, nil, err
|
return 0, 0, nil, err
|
||||||
}
|
}
|
||||||
userMaxSeq, err := db.seqUser.GetUserMaxSeq(ctx, conversationID, userID)
|
if userMinSeq < minSeq {
|
||||||
if err != nil {
|
|
||||||
return 0, 0, nil, err
|
|
||||||
}
|
|
||||||
if userMinSeq > minSeq {
|
|
||||||
minSeq = userMinSeq
|
minSeq = userMinSeq
|
||||||
}
|
}
|
||||||
if userMaxSeq > 0 && userMaxSeq < maxSeq {
|
var newSeqs []int64
|
||||||
maxSeq = userMaxSeq
|
|
||||||
}
|
|
||||||
newSeqs := make([]int64, 0, len(seqs))
|
|
||||||
for _, seq := range seqs {
|
for _, seq := range seqs {
|
||||||
if seq <= 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if seq >= minSeq && seq <= maxSeq {
|
if seq >= minSeq && seq <= maxSeq {
|
||||||
newSeqs = append(newSeqs, seq)
|
newSeqs = append(newSeqs, seq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(newSeqs) == 0 {
|
|
||||||
return minSeq, maxSeq, nil, nil
|
|
||||||
}
|
|
||||||
successMsgs, failedSeqs, err := db.msg.GetMessagesBySeq(ctx, conversationID, newSeqs)
|
successMsgs, failedSeqs, err := db.msg.GetMessagesBySeq(ctx, conversationID, newSeqs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != redis.Nil {
|
if err != redis.Nil {
|
||||||
@@ -870,16 +853,3 @@ func (db *commonMsgDatabase) setMinSeq(ctx context.Context, conversationID strin
|
|||||||
func (db *commonMsgDatabase) GetDocIDs(ctx context.Context) ([]string, error) {
|
func (db *commonMsgDatabase) GetDocIDs(ctx context.Context) ([]string, error) {
|
||||||
return db.msgDocDatabase.GetDocIDs(ctx)
|
return db.msgDocDatabase.GetDocIDs(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *commonMsgDatabase) GetCacheMaxSeqWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error) {
|
|
||||||
return db.seqConversation.GetCacheMaxSeqWithTime(ctx, conversationIDs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *commonMsgDatabase) GetMaxSeqWithTime(ctx context.Context, conversationID string) (database.SeqTime, error) {
|
|
||||||
return db.seqConversation.GetMaxSeqWithTime(ctx, conversationID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *commonMsgDatabase) GetMaxSeqsWithTime(ctx context.Context, conversationIDs []string) (map[string]database.SeqTime, error) {
|
|
||||||
// todo: only the time in the redis cache will be taken, not the message time
|
|
||||||
return db.seqConversation.GetMaxSeqsWithTime(ctx, conversationIDs)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ type Conversation interface {
|
|||||||
Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*model.Conversation, err error)
|
Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*model.Conversation, err error)
|
||||||
FindUserID(ctx context.Context, userIDs []string, conversationIDs []string) ([]string, error)
|
FindUserID(ctx context.Context, userIDs []string, conversationIDs []string) ([]string, error)
|
||||||
FindUserIDAllConversationID(ctx context.Context, userID string) ([]string, error)
|
FindUserIDAllConversationID(ctx context.Context, userID string) ([]string, error)
|
||||||
FindUserIDAllNotNotifyConversationID(ctx context.Context, userID string) ([]string, error)
|
|
||||||
FindUserIDAllPinnedConversationID(ctx context.Context, userID string) ([]string, error)
|
|
||||||
Take(ctx context.Context, userID, conversationID string) (conversation *model.Conversation, err error)
|
Take(ctx context.Context, userID, conversationID string) (conversation *model.Conversation, err error)
|
||||||
FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error)
|
FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error)
|
||||||
FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*model.Conversation, err error)
|
FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*model.Conversation, err error)
|
||||||
|
|||||||
@@ -124,20 +124,6 @@ func (c *ConversationMgo) FindUserIDAllConversationID(ctx context.Context, userI
|
|||||||
return mongoutil.Find[string](ctx, c.coll, bson.M{"owner_user_id": userID}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1}))
|
return mongoutil.Find[string](ctx, c.coll, bson.M{"owner_user_id": userID}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConversationMgo) FindUserIDAllNotNotifyConversationID(ctx context.Context, userID string) ([]string, error) {
|
|
||||||
return mongoutil.Find[string](ctx, c.coll, bson.M{
|
|
||||||
"owner_user_id": userID,
|
|
||||||
"recv_msg_opt": constant.ReceiveNotNotifyMessage,
|
|
||||||
}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ConversationMgo) FindUserIDAllPinnedConversationID(ctx context.Context, userID string) ([]string, error) {
|
|
||||||
return mongoutil.Find[string](ctx, c.coll, bson.M{
|
|
||||||
"owner_user_id": userID,
|
|
||||||
"is_pinned": true,
|
|
||||||
}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ConversationMgo) Take(ctx context.Context, userID, conversationID string) (conversation *model.Conversation, err error) {
|
func (c *ConversationMgo) Take(ctx context.Context, userID, conversationID string) (conversation *model.Conversation, err error) {
|
||||||
return mongoutil.FindOne[*model.Conversation](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": conversationID})
|
return mongoutil.FindOne[*model.Conversation](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": conversationID})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,6 @@ package database
|
|||||||
|
|
||||||
import "context"
|
import "context"
|
||||||
|
|
||||||
type SeqTime struct {
|
|
||||||
Seq int64
|
|
||||||
Time int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type SeqConversation interface {
|
type SeqConversation interface {
|
||||||
Malloc(ctx context.Context, conversationID string, size int64) (int64, error)
|
Malloc(ctx context.Context, conversationID string, size int64) (int64, error)
|
||||||
GetMaxSeq(ctx context.Context, conversationID string) (int64, error)
|
GetMaxSeq(ctx context.Context, conversationID string) (int64, error)
|
||||||
|
|||||||
@@ -39,9 +39,7 @@ func GetNotificationConversationIDByMsg(msg *sdkws.MsgData) string {
|
|||||||
case constant.ReadGroupChatType:
|
case constant.ReadGroupChatType:
|
||||||
return "n_" + msg.GroupID
|
return "n_" + msg.GroupID
|
||||||
case constant.NotificationChatType:
|
case constant.NotificationChatType:
|
||||||
l := []string{msg.SendID, msg.RecvID}
|
return "n_" + msg.SendID + "_" + msg.RecvID
|
||||||
sort.Strings(l)
|
|
||||||
return "n_" + strings.Join(l, "_")
|
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -57,14 +55,24 @@ func GetChatConversationIDByMsg(msg *sdkws.MsgData) string {
|
|||||||
case constant.ReadGroupChatType:
|
case constant.ReadGroupChatType:
|
||||||
return "sg_" + msg.GroupID
|
return "sg_" + msg.GroupID
|
||||||
case constant.NotificationChatType:
|
case constant.NotificationChatType:
|
||||||
l := []string{msg.SendID, msg.RecvID}
|
return "sn_" + msg.SendID + "_" + msg.RecvID
|
||||||
sort.Strings(l)
|
|
||||||
return "sn_" + strings.Join(l, "_")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenConversationUniqueKey(msg *sdkws.MsgData) string {
|
||||||
|
switch msg.SessionType {
|
||||||
|
case constant.SingleChatType, constant.NotificationChatType:
|
||||||
|
l := []string{msg.SendID, msg.RecvID}
|
||||||
|
sort.Strings(l)
|
||||||
|
return strings.Join(l, "_")
|
||||||
|
case constant.ReadGroupChatType:
|
||||||
|
return msg.GroupID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func GetConversationIDByMsg(msg *sdkws.MsgData) string {
|
func GetConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||||
options := Options(msg.Options)
|
options := Options(msg.Options)
|
||||||
switch msg.SessionType {
|
switch msg.SessionType {
|
||||||
@@ -86,12 +94,10 @@ func GetConversationIDByMsg(msg *sdkws.MsgData) string {
|
|||||||
}
|
}
|
||||||
return "sg_" + msg.GroupID // super group chat
|
return "sg_" + msg.GroupID // super group chat
|
||||||
case constant.NotificationChatType:
|
case constant.NotificationChatType:
|
||||||
l := []string{msg.SendID, msg.RecvID}
|
|
||||||
sort.Strings(l)
|
|
||||||
if !options.IsNotNotification() {
|
if !options.IsNotNotification() {
|
||||||
return "n_" + strings.Join(l, "_")
|
return "n_" + msg.SendID + "_" + msg.RecvID // super group chat
|
||||||
}
|
}
|
||||||
return "sn_" + strings.Join(l, "_")
|
return "sn_" + msg.SendID + "_" + msg.RecvID // server notification chat
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -114,6 +120,30 @@ func GetConversationIDBySessionType(sessionType int, ids ...string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetNotificationConversationIDByConversationID(conversationID string) string {
|
||||||
|
l := strings.Split(conversationID, "_")
|
||||||
|
if len(l) > 1 {
|
||||||
|
l[0] = "n"
|
||||||
|
return strings.Join(l, "_")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetNotificationConversationID(sessionType int, ids ...string) string {
|
||||||
|
sort.Strings(ids)
|
||||||
|
if len(ids) > 2 || len(ids) < 1 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
switch sessionType {
|
||||||
|
case constant.SingleChatType:
|
||||||
|
return "n_" + strings.Join(ids, "_") // single chat
|
||||||
|
case constant.ReadGroupChatType:
|
||||||
|
return "n_" + ids[0] // super group chat
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func IsNotification(conversationID string) bool {
|
func IsNotification(conversationID string) bool {
|
||||||
return strings.HasPrefix(conversationID, "n_")
|
return strings.HasPrefix(conversationID, "n_")
|
||||||
}
|
}
|
||||||
@@ -122,6 +152,30 @@ func IsNotificationByMsg(msg *sdkws.MsgData) bool {
|
|||||||
return !Options(msg.Options).IsNotNotification()
|
return !Options(msg.Options).IsNotNotification()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ParseConversationID(msg *sdkws.MsgData) (isNotification bool, conversationID string) {
|
||||||
|
options := Options(msg.Options)
|
||||||
|
switch msg.SessionType {
|
||||||
|
case constant.SingleChatType:
|
||||||
|
l := []string{msg.SendID, msg.RecvID}
|
||||||
|
sort.Strings(l)
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return true, "n_" + strings.Join(l, "_")
|
||||||
|
}
|
||||||
|
return false, "si_" + strings.Join(l, "_") // single chat
|
||||||
|
case constant.ReadGroupChatType:
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return true, "n_" + msg.GroupID // super group chat
|
||||||
|
}
|
||||||
|
return false, "sg_" + msg.GroupID // super group chat
|
||||||
|
case constant.NotificationChatType:
|
||||||
|
if !options.IsNotNotification() {
|
||||||
|
return true, "n_" + msg.SendID + "_" + msg.RecvID // super group chat
|
||||||
|
}
|
||||||
|
return false, "sn_" + msg.SendID + "_" + msg.RecvID // server notification chat
|
||||||
|
}
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
type MsgBySeq []*sdkws.MsgData
|
type MsgBySeq []*sdkws.MsgData
|
||||||
|
|
||||||
func (s MsgBySeq) Len() int {
|
func (s MsgBySeq) Len() int {
|
||||||
|
|||||||
@@ -0,0 +1,334 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package msgprocessor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetNotificationConversationIDByMsg(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
msg *sdkws.MsgData
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := GetNotificationConversationIDByMsg(tt.args.msg); got != tt.want {
|
||||||
|
t.Errorf("GetNotificationConversationIDByMsg() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetChatConversationIDByMsg(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
msg *sdkws.MsgData
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := GetChatConversationIDByMsg(tt.args.msg); got != tt.want {
|
||||||
|
t.Errorf("GetChatConversationIDByMsg() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenConversationUniqueKey(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
msg *sdkws.MsgData
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := GenConversationUniqueKey(tt.args.msg); got != tt.want {
|
||||||
|
t.Errorf("GenConversationUniqueKey() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetConversationIDByMsg(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
msg *sdkws.MsgData
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := GetConversationIDByMsg(tt.args.msg); got != tt.want {
|
||||||
|
t.Errorf("GetConversationIDByMsg() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetConversationIDBySessionType(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
sessionType int
|
||||||
|
ids []string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := GetConversationIDBySessionType(tt.args.sessionType, tt.args.ids...); got != tt.want {
|
||||||
|
t.Errorf("GetConversationIDBySessionType() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetNotificationConversationIDByConversationID(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
conversationID string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := GetNotificationConversationIDByConversationID(tt.args.conversationID); got != tt.want {
|
||||||
|
t.Errorf("GetNotificationConversationIDByConversationID() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetNotificationConversationID(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
sessionType int
|
||||||
|
ids []string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := GetNotificationConversationID(tt.args.sessionType, tt.args.ids...); got != tt.want {
|
||||||
|
t.Errorf("GetNotificationConversationID() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsNotification(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
conversationID string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := IsNotification(tt.args.conversationID); got != tt.want {
|
||||||
|
t.Errorf("IsNotification() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsNotificationByMsg(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
msg *sdkws.MsgData
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := IsNotificationByMsg(tt.args.msg); got != tt.want {
|
||||||
|
t.Errorf("IsNotificationByMsg() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseConversationID(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
msg *sdkws.MsgData
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantIsNotification bool
|
||||||
|
wantConversationID string
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
gotIsNotification, gotConversationID := ParseConversationID(tt.args.msg)
|
||||||
|
if gotIsNotification != tt.wantIsNotification {
|
||||||
|
t.Errorf("ParseConversationID() gotIsNotification = %v, want %v", gotIsNotification, tt.wantIsNotification)
|
||||||
|
}
|
||||||
|
if gotConversationID != tt.wantConversationID {
|
||||||
|
t.Errorf("ParseConversationID() gotConversationID = %v, want %v", gotConversationID, tt.wantConversationID)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMsgBySeq_Len(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
s MsgBySeq
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := tt.s.Len(); got != tt.want {
|
||||||
|
t.Errorf("MsgBySeq.Len() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMsgBySeq_Less(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
i int
|
||||||
|
j int
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
s MsgBySeq
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := tt.s.Less(tt.args.i, tt.args.j); got != tt.want {
|
||||||
|
t.Errorf("MsgBySeq.Less() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMsgBySeq_Swap(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
i int
|
||||||
|
j int
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
s MsgBySeq
|
||||||
|
args args
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tt.s.Swap(tt.args.i, tt.args.j)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPb2String(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
pb proto.Message
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := Pb2String(tt.args.pb)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Pb2String() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("Pb2String() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestString2Pb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
s string
|
||||||
|
pb proto.Message
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if err := String2Pb(tt.args.s, tt.args.pb); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("String2Pb() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -109,12 +109,12 @@ func (u *UserRpcClient) GetUsersInfoMap(ctx context.Context, userIDs []string) (
|
|||||||
func (u *UserRpcClient) GetPublicUserInfos(
|
func (u *UserRpcClient) GetPublicUserInfos(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
userIDs []string,
|
userIDs []string,
|
||||||
|
complete bool,
|
||||||
) ([]*sdkws.PublicUserInfo, error) {
|
) ([]*sdkws.PublicUserInfo, error) {
|
||||||
users, err := u.GetUsersInfo(ctx, userIDs)
|
users, err := u.GetUsersInfo(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return datautil.Slice(users, func(e *sdkws.UserInfo) *sdkws.PublicUserInfo {
|
return datautil.Slice(users, func(e *sdkws.UserInfo) *sdkws.PublicUserInfo {
|
||||||
return &sdkws.PublicUserInfo{
|
return &sdkws.PublicUserInfo{
|
||||||
UserID: e.UserID,
|
UserID: e.UserID,
|
||||||
@@ -127,11 +127,10 @@ func (u *UserRpcClient) GetPublicUserInfos(
|
|||||||
|
|
||||||
// GetPublicUserInfo retrieves public information for a single user based on the provided user ID.
|
// GetPublicUserInfo retrieves public information for a single user based on the provided user ID.
|
||||||
func (u *UserRpcClient) GetPublicUserInfo(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) {
|
func (u *UserRpcClient) GetPublicUserInfo(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) {
|
||||||
users, err := u.GetPublicUserInfos(ctx, []string{userID})
|
users, err := u.GetPublicUserInfos(ctx, []string{userID}, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return users[0], nil
|
return users[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,12 +138,12 @@ func (u *UserRpcClient) GetPublicUserInfo(ctx context.Context, userID string) (*
|
|||||||
func (u *UserRpcClient) GetPublicUserInfoMap(
|
func (u *UserRpcClient) GetPublicUserInfoMap(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
userIDs []string,
|
userIDs []string,
|
||||||
|
complete bool,
|
||||||
) (map[string]*sdkws.PublicUserInfo, error) {
|
) (map[string]*sdkws.PublicUserInfo, error) {
|
||||||
users, err := u.GetPublicUserInfos(ctx, userIDs)
|
users, err := u.GetPublicUserInfos(ctx, userIDs, complete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return datautil.SliceToMap(users, func(e *sdkws.PublicUserInfo) string {
|
return datautil.SliceToMap(users, func(e *sdkws.PublicUserInfo) string {
|
||||||
return e.UserID
|
return e.UserID
|
||||||
}), nil
|
}), nil
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ type User struct {
|
|||||||
|
|
||||||
// UserRegisterRequest represents a request to register a user.
|
// UserRegisterRequest represents a request to register a user.
|
||||||
type UserRegisterRequest struct {
|
type UserRegisterRequest struct {
|
||||||
Users []User `json:"users"`
|
Secret string `json:"secret"`
|
||||||
|
Users []User `json:"users"`
|
||||||
}
|
}
|
||||||
|
|
||||||
/* func main() {
|
/* func main() {
|
||||||
@@ -108,7 +109,8 @@ func RegisterUser(token, userID, nickname, faceURL string) error {
|
|||||||
FaceURL: faceURL,
|
FaceURL: faceURL,
|
||||||
}
|
}
|
||||||
reqBody := UserRegisterRequest{
|
reqBody := UserRegisterRequest{
|
||||||
Users: []User{user},
|
Secret: SecretKey,
|
||||||
|
Users: []User{user},
|
||||||
}
|
}
|
||||||
reqBytes, err := json.Marshal(reqBody)
|
reqBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/openimsdk/protocol/auth"
|
"github.com/openimsdk/protocol/auth"
|
||||||
|
"github.com/openimsdk/protocol/constant"
|
||||||
"github.com/openimsdk/protocol/third"
|
"github.com/openimsdk/protocol/third"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
)
|
)
|
||||||
@@ -87,13 +88,14 @@ func (a *Api) apiPost(ctx context.Context, path string, req any, resp any) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Api) GetAdminToken(ctx context.Context) (string, error) {
|
func (a *Api) GetToken(ctx context.Context) (string, error) {
|
||||||
req := auth.GetAdminTokenReq{
|
req := auth.UserTokenReq{
|
||||||
UserID: a.UserID,
|
UserID: a.UserID,
|
||||||
Secret: a.Secret,
|
Secret: a.Secret,
|
||||||
|
PlatformID: constant.AdminPlatformID,
|
||||||
}
|
}
|
||||||
var resp auth.GetAdminTokenResp
|
var resp auth.UserTokenResp
|
||||||
if err := a.apiPost(ctx, "/auth/get_admin_token", &req, &resp); err != nil {
|
if err := a.apiPost(ctx, "/auth/user_token", &req, &resp); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return resp.Token, nil
|
return resp.Token, nil
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/openimsdk/tools/errs"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -33,8 +34,6 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/tools/errs"
|
|
||||||
|
|
||||||
"github.com/openimsdk/protocol/third"
|
"github.com/openimsdk/protocol/third"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -96,7 +95,7 @@ func (m *Manage) Run() error {
|
|||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
ctx := context.WithValue(m.ctx, "operationID", fmt.Sprintf("%s_init", m.prefix))
|
ctx := context.WithValue(m.ctx, "operationID", fmt.Sprintf("%s_init", m.prefix))
|
||||||
m.api.Token, err = m.api.GetAdminToken(ctx)
|
m.api.Token, err = m.api.GetToken(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
3.8.1
|
3.8.0
|
||||||
Reference in New Issue
Block a user