Showing preview only (2,942K chars total). Download the full file or copy to clipboard to get everything.
Repository: openimsdk/open-im-server
Branch: main
Commit: d16a617ba8ff
Files: 667
Total size: 2.7 MB
Directory structure:
gitextract_q8p9a5l9/
├── .dockerignore
├── .gitattributes
├── .github/
│ ├── .codecov.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.yml
│ │ ├── config.yml
│ │ ├── deployment.yml
│ │ ├── documentation.md
│ │ ├── feature-request.yml
│ │ ├── other.yml
│ │ └── rfc.md
│ ├── sync-release.yml
│ └── workflows/
│ ├── auto-assign-issue.yml
│ ├── auto-invite-comment.yml
│ ├── changelog.yml
│ ├── cla-assistant.yml
│ ├── cleanup-after-milestone-prs-merged.yml
│ ├── codeql-analysis.yml
│ ├── comment-check.yml
│ ├── docker-build-and-release-services-images.yml
│ ├── go-build-test.yml
│ ├── help-comment-issue.yml
│ ├── issue-translator.yml
│ ├── merge-from-milestone.yml
│ ├── publish-docker-image.yml
│ ├── remove-unused-labels.yml
│ ├── reopen-issue.yml
│ ├── update-version-file-on-release.yml
│ └── user-first-interaction.yml
├── .gitignore
├── .golangci.yml
├── CHANGELOG/
│ ├── CHANGELOG-3.8.md
│ └── README.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING-zh_CN.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── README_zh_CN.md
├── assets/
│ ├── README.md
│ ├── colors.md
│ ├── demo/
│ │ └── README.md
│ ├── logo/
│ │ └── LICENSE
│ └── logo-gif/
│ └── LICENSE
├── bootstrap.bat
├── bootstrap.sh
├── build/
│ ├── README.md
│ ├── goreleaser.yaml
│ └── images/
│ ├── Dockerfile
│ ├── openim-api/
│ │ └── Dockerfile
│ ├── openim-crontask/
│ │ └── Dockerfile
│ ├── openim-msggateway/
│ │ └── Dockerfile
│ ├── openim-msgtransfer/
│ │ └── Dockerfile
│ ├── openim-push/
│ │ └── Dockerfile
│ ├── openim-rpc-auth/
│ │ └── Dockerfile
│ ├── openim-rpc-conversation/
│ │ └── Dockerfile
│ ├── openim-rpc-friend/
│ │ └── Dockerfile
│ ├── openim-rpc-group/
│ │ └── Dockerfile
│ ├── openim-rpc-msg/
│ │ └── Dockerfile
│ ├── openim-rpc-third/
│ │ └── Dockerfile
│ ├── openim-rpc-user/
│ │ └── Dockerfile
│ └── openim-tools/
│ └── component/
│ └── Dockerfile
├── cmd/
│ ├── main.go
│ ├── openim-api/
│ │ └── main.go
│ ├── openim-cmdutils/
│ │ └── main.go
│ ├── openim-crontask/
│ │ └── main.go
│ ├── openim-msggateway/
│ │ └── main.go
│ ├── openim-msgtransfer/
│ │ └── main.go
│ ├── openim-push/
│ │ └── main.go
│ └── openim-rpc/
│ ├── openim-rpc-auth/
│ │ └── main.go
│ ├── openim-rpc-conversation/
│ │ └── main.go
│ ├── openim-rpc-friend/
│ │ └── main.go
│ ├── openim-rpc-group/
│ │ └── main.go
│ ├── openim-rpc-msg/
│ │ └── main.go
│ ├── openim-rpc-third/
│ │ └── main.go
│ └── openim-rpc-user/
│ └── main.go
├── config/
│ ├── README.md
│ ├── README_zh_CN.md
│ ├── alertmanager.yml
│ ├── discovery.yml
│ ├── email.tmpl
│ ├── grafana-template/
│ │ └── Demo.json
│ ├── instance-down-rules.yml
│ ├── kafka.yml
│ ├── local-cache.yml
│ ├── log.yml
│ ├── minio.yml
│ ├── mongodb.yml
│ ├── notification.yml
│ ├── openim-api.yml
│ ├── openim-crontask.yml
│ ├── openim-msggateway.yml
│ ├── openim-msgtransfer.yml
│ ├── openim-push.yml
│ ├── openim-rpc-auth.yml
│ ├── openim-rpc-conversation.yml
│ ├── openim-rpc-friend.yml
│ ├── openim-rpc-group.yml
│ ├── openim-rpc-msg.yml
│ ├── openim-rpc-third.yml
│ ├── openim-rpc-user.yml
│ ├── prometheus.yml
│ ├── redis.yml
│ ├── share.yml
│ └── webhooks.yml
├── deployments/
│ ├── Readme.md
│ └── deploy/
│ ├── clusterRole.yml
│ ├── ingress.yml
│ ├── kafka-secret.yml
│ ├── kafka-service.yml
│ ├── kafka-statefulset.yml
│ ├── minio-secret.yml
│ ├── minio-service.yml
│ ├── minio-statefulset.yml
│ ├── mongo-secret.yml
│ ├── mongo-service.yml
│ ├── mongo-statefulset.yml
│ ├── openim-api-deployment.yml
│ ├── openim-api-service.yml
│ ├── openim-config.yml
│ ├── openim-crontask-deployment.yml
│ ├── openim-msggateway-deployment.yml
│ ├── openim-msggateway-service.yml
│ ├── openim-msgtransfer-deployment.yml
│ ├── openim-msgtransfer-service.yml
│ ├── openim-push-deployment.yml
│ ├── openim-push-service.yml
│ ├── openim-rpc-auth-deployment.yml
│ ├── openim-rpc-auth-service.yml
│ ├── openim-rpc-conversation-deployment.yml
│ ├── openim-rpc-conversation-service.yml
│ ├── openim-rpc-friend-deployment.yml
│ ├── openim-rpc-friend-service.yml
│ ├── openim-rpc-group-deployment.yml
│ ├── openim-rpc-group-service.yml
│ ├── openim-rpc-msg-deployment.yml
│ ├── openim-rpc-msg-service.yml
│ ├── openim-rpc-third-deployment.yml
│ ├── openim-rpc-third-service.yml
│ ├── openim-rpc-user-deployment.yml
│ ├── openim-rpc-user-service.yml
│ ├── redis-secret.yml
│ ├── redis-service.yml
│ └── redis-statefulset.yml
├── docker-compose.yml
├── docs/
│ ├── .generated_docs
│ ├── CODEOWNERS
│ ├── README.md
│ ├── contrib/
│ │ ├── README.md
│ │ ├── api.md
│ │ ├── bash-log.md
│ │ ├── cicd-actions.md
│ │ ├── code-conventions.md
│ │ ├── commit.md
│ │ ├── development.md
│ │ ├── directory.md
│ │ ├── environment.md
│ │ ├── error-code.md
│ │ ├── git-workflow.md
│ │ ├── gitcherry-pick.md
│ │ ├── github-workflow.md
│ │ ├── go-code.md
│ │ ├── go-code1.md
│ │ ├── go-doc.md
│ │ ├── images.md
│ │ ├── init-config.md
│ │ ├── install-docker.md
│ │ ├── install-openim-linux-system.md
│ │ ├── kafka.md
│ │ ├── linux-development.md
│ │ ├── local-actions.md
│ │ ├── logging.md
│ │ ├── mac-developer-deployment-guide.md
│ │ ├── offline-deployment.md
│ │ ├── prometheus-grafana.md
│ │ ├── protoc-tools.md
│ │ ├── release.md
│ │ ├── test.md
│ │ ├── util-go.md
│ │ ├── util-makefile.md
│ │ ├── util-scripts.md
│ │ └── version.md
│ ├── contributing/
│ │ ├── CONTRIBUTING-JP.md
│ │ └── CONTRIBUTING-PL.md
│ └── readme/
│ ├── README_cs.md
│ ├── README_da.md
│ ├── README_el.md
│ ├── README_es.md
│ ├── README_fa.md
│ ├── README_fr.md
│ ├── README_hu.md
│ ├── README_ja.md
│ ├── README_ko.md
│ ├── README_tr.md
│ ├── README_uk.md
│ └── README_vi.md
├── go.mod
├── go.sum
├── install.sh
├── internal/
│ ├── api/
│ │ ├── auth.go
│ │ ├── config_manager.go
│ │ ├── conversation.go
│ │ ├── custom_validator.go
│ │ ├── friend.go
│ │ ├── group.go
│ │ ├── init.go
│ │ ├── jssdk/
│ │ │ ├── jssdk.go
│ │ │ ├── sort.go
│ │ │ └── tools.go
│ │ ├── msg.go
│ │ ├── prometheus_discovery.go
│ │ ├── ratelimit.go
│ │ ├── router.go
│ │ ├── third.go
│ │ └── user.go
│ ├── msggateway/
│ │ ├── callback.go
│ │ ├── client.go
│ │ ├── client_conn.go
│ │ ├── compressor.go
│ │ ├── compressor_test.go
│ │ ├── constant.go
│ │ ├── context.go
│ │ ├── encoder.go
│ │ ├── http_error.go
│ │ ├── hub_server.go
│ │ ├── init.go
│ │ ├── message_handler.go
│ │ ├── online.go
│ │ ├── options.go
│ │ ├── subscription.go
│ │ ├── user_map.go
│ │ └── ws_server.go
│ ├── msgtransfer/
│ │ ├── callback.go
│ │ ├── init.go
│ │ ├── online_history_msg_handler.go
│ │ └── online_msg_to_mongo_handler.go
│ ├── push/
│ │ ├── callback.go
│ │ ├── offlinepush/
│ │ │ ├── dummy/
│ │ │ │ └── push.go
│ │ │ ├── fcm/
│ │ │ │ └── push.go
│ │ │ ├── getui/
│ │ │ │ ├── body.go
│ │ │ │ └── push.go
│ │ │ ├── jpush/
│ │ │ │ ├── body/
│ │ │ │ │ ├── audience.go
│ │ │ │ │ ├── message.go
│ │ │ │ │ ├── notification.go
│ │ │ │ │ ├── options.go
│ │ │ │ │ ├── platform.go
│ │ │ │ │ └── pushobj.go
│ │ │ │ └── push.go
│ │ │ ├── offlinepusher.go
│ │ │ └── options/
│ │ │ └── options.go
│ │ ├── offlinepush_handler.go
│ │ ├── onlinepusher.go
│ │ ├── push.go
│ │ └── push_handler.go
│ ├── rpc/
│ │ ├── auth/
│ │ │ └── auth.go
│ │ ├── conversation/
│ │ │ ├── callback.go
│ │ │ ├── conversation.go
│ │ │ ├── db_map.go
│ │ │ ├── notification.go
│ │ │ └── sync.go
│ │ ├── group/
│ │ │ ├── cache.go
│ │ │ ├── callback.go
│ │ │ ├── convert.go
│ │ │ ├── db_map.go
│ │ │ ├── fill.go
│ │ │ ├── group.go
│ │ │ ├── notification.go
│ │ │ ├── statistics.go
│ │ │ └── sync.go
│ │ ├── incrversion/
│ │ │ ├── batch_option.go
│ │ │ └── option.go
│ │ ├── msg/
│ │ │ ├── as_read.go
│ │ │ ├── callback.go
│ │ │ ├── clear.go
│ │ │ ├── delete.go
│ │ │ ├── filter.go
│ │ │ ├── msg_status.go
│ │ │ ├── notification.go
│ │ │ ├── revoke.go
│ │ │ ├── send.go
│ │ │ ├── seq.go
│ │ │ ├── server.go
│ │ │ ├── statistics.go
│ │ │ ├── sync_msg.go
│ │ │ ├── utils.go
│ │ │ └── verify.go
│ │ ├── relation/
│ │ │ ├── black.go
│ │ │ ├── callback.go
│ │ │ ├── friend.go
│ │ │ ├── notification.go
│ │ │ └── sync.go
│ │ ├── third/
│ │ │ ├── log.go
│ │ │ ├── s3.go
│ │ │ ├── third.go
│ │ │ └── tool.go
│ │ └── user/
│ │ ├── callback.go
│ │ ├── config.go
│ │ ├── notification.go
│ │ ├── online.go
│ │ ├── statistics.go
│ │ └── user.go
│ └── tools/
│ └── cron/
│ ├── cron_task.go
│ ├── cron_test.go
│ ├── dist_look.go
│ ├── msg.go
│ ├── s3.go
│ └── user_msg.go
├── magefile.go
├── magefile_unix.go
├── magefile_windows.go
├── pkg/
│ ├── apistruct/
│ │ ├── config_manager.go
│ │ ├── doc.go
│ │ ├── manage.go
│ │ ├── msg.go
│ │ └── public.go
│ ├── authverify/
│ │ ├── doc.go
│ │ └── token.go
│ ├── callbackstruct/
│ │ ├── common.go
│ │ ├── constant.go
│ │ ├── conversation.go
│ │ ├── doc.go
│ │ ├── friend.go
│ │ ├── group.go
│ │ ├── message.go
│ │ ├── msg_gateway.go
│ │ ├── push.go
│ │ ├── revoke.go
│ │ └── user.go
│ ├── common/
│ │ ├── cmd/
│ │ │ ├── api.go
│ │ │ ├── auth.go
│ │ │ ├── conversation.go
│ │ │ ├── cron_task.go
│ │ │ ├── doc.go
│ │ │ ├── friend.go
│ │ │ ├── group.go
│ │ │ ├── msg.go
│ │ │ ├── msg_gateway.go
│ │ │ ├── msg_gateway_test.go
│ │ │ ├── msg_transfer.go
│ │ │ ├── msg_utils.go
│ │ │ ├── push.go
│ │ │ ├── root.go
│ │ │ ├── third.go
│ │ │ └── user.go
│ │ ├── config/
│ │ │ ├── config.go
│ │ │ ├── constant.go
│ │ │ ├── doc.go
│ │ │ ├── env.go
│ │ │ ├── global.go
│ │ │ ├── load_config.go
│ │ │ ├── load_config_test.go
│ │ │ └── parse.go
│ │ ├── convert/
│ │ │ ├── auth.go
│ │ │ ├── black.go
│ │ │ ├── conversation.go
│ │ │ ├── doc.go
│ │ │ ├── friend.go
│ │ │ ├── group.go
│ │ │ ├── msg.go
│ │ │ ├── user.go
│ │ │ └── user_test.go
│ │ ├── discovery/
│ │ │ ├── direct/
│ │ │ │ ├── direct_resolver.go
│ │ │ │ ├── directconn.go
│ │ │ │ └── doc.go
│ │ │ ├── discoveryregister.go
│ │ │ ├── discoveryregister_test.go
│ │ │ ├── doc.go
│ │ │ ├── etcd/
│ │ │ │ ├── config_manager.go
│ │ │ │ └── const.go
│ │ │ └── kubernetes/
│ │ │ ├── doc.go
│ │ │ └── kubernetes.go
│ │ ├── ginprometheus/
│ │ │ ├── doc.go
│ │ │ └── ginprometheus.go
│ │ ├── prommetrics/
│ │ │ ├── api.go
│ │ │ ├── grpc_auth.go
│ │ │ ├── grpc_msg.go
│ │ │ ├── grpc_msggateway.go
│ │ │ ├── grpc_push.go
│ │ │ ├── grpc_user.go
│ │ │ ├── prommetrics.go
│ │ │ ├── prommetrics_test.go
│ │ │ ├── rpc.go
│ │ │ └── transfer.go
│ │ ├── servererrs/
│ │ │ ├── code.go
│ │ │ ├── doc.go
│ │ │ ├── predefine.go
│ │ │ └── relation.go
│ │ ├── startrpc/
│ │ │ ├── circuitbreaker.go
│ │ │ ├── mw.go
│ │ │ ├── ratelimit.go
│ │ │ ├── start.go
│ │ │ └── tools.go
│ │ ├── storage/
│ │ │ ├── cache/
│ │ │ │ ├── batch_handler.go
│ │ │ │ ├── black.go
│ │ │ │ ├── cachekey/
│ │ │ │ │ ├── black.go
│ │ │ │ │ ├── client_config.go
│ │ │ │ │ ├── conversation.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── friend.go
│ │ │ │ │ ├── group.go
│ │ │ │ │ ├── msg.go
│ │ │ │ │ ├── online.go
│ │ │ │ │ ├── s3.go
│ │ │ │ │ ├── seq.go
│ │ │ │ │ ├── third.go
│ │ │ │ │ ├── token.go
│ │ │ │ │ └── user.go
│ │ │ │ ├── client_config.go
│ │ │ │ ├── conversation.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── friend.go
│ │ │ │ ├── group.go
│ │ │ │ ├── mcache/
│ │ │ │ │ ├── minio.go
│ │ │ │ │ ├── msg_cache.go
│ │ │ │ │ ├── online.go
│ │ │ │ │ ├── seq_conversation.go
│ │ │ │ │ ├── third.go
│ │ │ │ │ ├── token.go
│ │ │ │ │ └── tools.go
│ │ │ │ ├── msg.go
│ │ │ │ ├── online.go
│ │ │ │ ├── redis/
│ │ │ │ │ ├── batch.go
│ │ │ │ │ ├── batch_handler.go
│ │ │ │ │ ├── batch_test.go
│ │ │ │ │ ├── black.go
│ │ │ │ │ ├── client_config.go
│ │ │ │ │ ├── conversation.go
│ │ │ │ │ ├── friend.go
│ │ │ │ │ ├── group.go
│ │ │ │ │ ├── lua_script.go
│ │ │ │ │ ├── lua_script_test.go
│ │ │ │ │ ├── minio.go
│ │ │ │ │ ├── msg.go
│ │ │ │ │ ├── online.go
│ │ │ │ │ ├── online_test.go
│ │ │ │ │ ├── redis_shard_manager.go
│ │ │ │ │ ├── s3.go
│ │ │ │ │ ├── seq_conversation.go
│ │ │ │ │ ├── seq_conversation_test.go
│ │ │ │ │ ├── seq_user.go
│ │ │ │ │ ├── seq_user_test.go
│ │ │ │ │ ├── third.go
│ │ │ │ │ ├── token.go
│ │ │ │ │ └── user.go
│ │ │ │ ├── s3.go
│ │ │ │ ├── seq_conversation.go
│ │ │ │ ├── seq_user.go
│ │ │ │ ├── third.go
│ │ │ │ ├── token.go
│ │ │ │ └── user.go
│ │ │ ├── common/
│ │ │ │ └── types.go
│ │ │ ├── controller/
│ │ │ │ ├── auth.go
│ │ │ │ ├── black.go
│ │ │ │ ├── client_config.go
│ │ │ │ ├── conversation.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── friend.go
│ │ │ │ ├── group.go
│ │ │ │ ├── msg.go
│ │ │ │ ├── msg_transfer.go
│ │ │ │ ├── push.go
│ │ │ │ ├── s3.go
│ │ │ │ ├── third.go
│ │ │ │ └── user.go
│ │ │ ├── database/
│ │ │ │ ├── black.go
│ │ │ │ ├── cache.go
│ │ │ │ ├── client_config.go
│ │ │ │ ├── conversation.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── friend.go
│ │ │ │ ├── friend_request.go
│ │ │ │ ├── group.go
│ │ │ │ ├── group_member.go
│ │ │ │ ├── group_request.go
│ │ │ │ ├── log.go
│ │ │ │ ├── mgo/
│ │ │ │ │ ├── black.go
│ │ │ │ │ ├── cache.go
│ │ │ │ │ ├── cache_test.go
│ │ │ │ │ ├── client_config.go
│ │ │ │ │ ├── conversation.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── friend.go
│ │ │ │ │ ├── friend_request.go
│ │ │ │ │ ├── group.go
│ │ │ │ │ ├── group_member.go
│ │ │ │ │ ├── group_request.go
│ │ │ │ │ ├── helpers.go
│ │ │ │ │ ├── log.go
│ │ │ │ │ ├── msg.go
│ │ │ │ │ ├── msg_test.go
│ │ │ │ │ ├── object.go
│ │ │ │ │ ├── seq_conversation.go
│ │ │ │ │ ├── seq_conversation_test.go
│ │ │ │ │ ├── seq_user.go
│ │ │ │ │ ├── user.go
│ │ │ │ │ ├── version_log.go
│ │ │ │ │ └── version_test.go
│ │ │ │ ├── msg.go
│ │ │ │ ├── name.go
│ │ │ │ ├── object.go
│ │ │ │ ├── seq.go
│ │ │ │ ├── seq_user.go
│ │ │ │ ├── user.go
│ │ │ │ └── version_log.go
│ │ │ ├── kafka/
│ │ │ │ ├── config.go
│ │ │ │ ├── consumer_group.go
│ │ │ │ ├── producer.go
│ │ │ │ ├── sarama.go
│ │ │ │ ├── tls.go
│ │ │ │ ├── util.go
│ │ │ │ └── verify.go
│ │ │ ├── model/
│ │ │ │ ├── application.go
│ │ │ │ ├── black.go
│ │ │ │ ├── cache.go
│ │ │ │ ├── client_config.go
│ │ │ │ ├── conversation.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── friend.go
│ │ │ │ ├── friend_request.go
│ │ │ │ ├── group.go
│ │ │ │ ├── group_member.go
│ │ │ │ ├── group_request.go
│ │ │ │ ├── log.go
│ │ │ │ ├── msg.go
│ │ │ │ ├── object.go
│ │ │ │ ├── seq.go
│ │ │ │ ├── seq_user.go
│ │ │ │ ├── subscribe.go
│ │ │ │ ├── user.go
│ │ │ │ └── version_log.go
│ │ │ └── versionctx/
│ │ │ ├── rpc.go
│ │ │ └── version.go
│ │ └── webhook/
│ │ ├── condition.go
│ │ ├── doc.go
│ │ ├── http_client.go
│ │ └── http_client_test.go
│ ├── dbbuild/
│ │ ├── builder.go
│ │ ├── microservices.go
│ │ └── standalone.go
│ ├── localcache/
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ ├── doc.go
│ │ ├── init.go
│ │ ├── link/
│ │ │ ├── doc.go
│ │ │ ├── link.go
│ │ │ └── link_test.go
│ │ ├── lru/
│ │ │ ├── doc.go
│ │ │ ├── lru.go
│ │ │ ├── lru_expiration.go
│ │ │ ├── lru_lazy.go
│ │ │ ├── lru_lazy_test.go
│ │ │ └── lru_slot.go
│ │ ├── option.go
│ │ └── tool.go
│ ├── mqbuild/
│ │ └── builder.go
│ ├── msgprocessor/
│ │ ├── conversation.go
│ │ ├── doc.go
│ │ └── options.go
│ ├── notification/
│ │ ├── common_user/
│ │ │ └── common.go
│ │ ├── grouphash/
│ │ │ └── grouphash.go
│ │ └── msg.go
│ ├── rpccache/
│ │ ├── auth.go
│ │ ├── common.go
│ │ ├── conversation.go
│ │ ├── doc.go
│ │ ├── friend.go
│ │ ├── group.go
│ │ ├── online.go
│ │ ├── subscriber.go
│ │ └── user.go
│ ├── rpcli/
│ │ ├── auth.go
│ │ ├── conversation.go
│ │ ├── group.go
│ │ ├── msg.go
│ │ ├── msggateway.go
│ │ ├── push.go
│ │ ├── relation.go
│ │ ├── rtc.go
│ │ ├── third.go
│ │ ├── tool.go
│ │ └── user.go
│ ├── statistics/
│ │ ├── doc.go
│ │ └── statistics.go
│ ├── tools/
│ │ └── batcher/
│ │ ├── batcher.go
│ │ └── batcher_test.go
│ └── util/
│ ├── conversationutil/
│ │ ├── conversationutil.go
│ │ └── doc.go
│ ├── hashutil/
│ │ └── id.go
│ └── useronline/
│ └── split.go
├── scripts/
│ └── template/
│ ├── LICENSE
│ ├── LICENSE_TEMPLATES
│ ├── boilerplate.txt
│ ├── footer.md.tmpl
│ ├── head.md.tmpl
│ └── project_README.md
├── start-config.yml
├── test/
│ ├── e2e/
│ │ ├── README.md
│ │ ├── api/
│ │ │ ├── token/
│ │ │ │ └── token.go
│ │ │ └── user/
│ │ │ ├── curd.go
│ │ │ └── user.go
│ │ ├── conformance/
│ │ │ └── .keep
│ │ ├── e2e.go
│ │ ├── e2e_test.go
│ │ ├── framework/
│ │ │ ├── config/
│ │ │ │ ├── config.go
│ │ │ │ └── config_test.go
│ │ │ ├── ginkgowrapper/
│ │ │ │ ├── .keep
│ │ │ │ ├── ginkgowrapper.go
│ │ │ │ └── ginkgowrapper_test.go
│ │ │ └── helpers/
│ │ │ ├── .keep
│ │ │ └── chat/
│ │ │ └── chat.go
│ │ ├── page/
│ │ │ ├── chat_page.go
│ │ │ └── login_page.go
│ │ ├── performance/
│ │ │ └── .keep
│ │ ├── rpc/
│ │ │ ├── auth/
│ │ │ │ └── .keep
│ │ │ ├── conversation/
│ │ │ │ └── .keep
│ │ │ ├── friend/
│ │ │ │ └── .keep
│ │ │ ├── group/
│ │ │ │ └── .keep
│ │ │ └── message/
│ │ │ └── .keep
│ │ ├── scalability/
│ │ │ └── .keep
│ │ ├── upgrade/
│ │ │ └── .keep
│ │ └── web/
│ │ └── Readme.md
│ ├── jwt/
│ │ └── main.go
│ ├── readme
│ ├── stress-test/
│ │ ├── README.md
│ │ └── main.go
│ ├── stress-test-v2/
│ │ ├── README.md
│ │ └── main.go
│ ├── testdata/
│ │ ├── README.md
│ │ ├── db/
│ │ │ ├── messages.json
│ │ │ └── users.json
│ │ ├── requests/
│ │ │ ├── login.json
│ │ │ ├── register.json
│ │ │ └── send-message.json
│ │ └── responses/
│ │ ├── login.json
│ │ ├── register.json
│ │ └── sendMessage.json
│ └── webhook/
│ └── msgmodify/
│ └── main.go
├── tools/
│ ├── README.md
│ ├── changelog/
│ │ └── changelog.go
│ ├── check-component/
│ │ └── main.go
│ ├── check-free-memory/
│ │ └── main.go
│ ├── imctl/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ └── main.go
│ ├── infra/
│ │ └── main.go
│ ├── ncpu/
│ │ ├── README.md
│ │ ├── main.go
│ │ └── main_test.go
│ ├── s3/
│ │ ├── README.md
│ │ ├── internal/
│ │ │ └── conversion.go
│ │ └── main.go
│ ├── seq/
│ │ ├── internal/
│ │ │ └── seq.go
│ │ └── main.go
│ ├── stress-test-v2/
│ │ └── main.go
│ ├── url2im/
│ │ ├── main.go
│ │ └── pkg/
│ │ ├── api.go
│ │ ├── buffer.go
│ │ ├── config.go
│ │ ├── http.go
│ │ ├── manage.go
│ │ ├── md5.go
│ │ └── progress.go
│ ├── versionchecker/
│ │ └── main.go
│ └── yamlfmt/
│ ├── main.go
│ └── main_test.go
└── version/
├── version
└── version.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
# Ignore files and directories starting with a dot
# Ignore specific files
.dockerignore
.git
# Ignore build artifacts
logs/
_output/
# Ignore non-essential documentation
README.md
README-zh_CN.md
CONTRIBUTING.md
CHANGELOG/
# LICENSE
# Ignore testing and linting configuration
.golangci.yml
# Ignore assets
assets/
# Ignore components
components/
# Ignore tools and scripts
.github/
================================================
FILE: .gitattributes
================================================
*.sh text eol=lf
================================================
FILE: .github/.codecov.yml
================================================
coverage:
status:
project:
default: false # disable the default status that measures entire project
pkg: # declare a new status context "pkg"
paths:
- pkg/* # only include coverage in "pkg/" folder
informational: true # Always pass check
tools: # declare a new status context "tools"
paths:
- tools/* # only include coverage in "tools/" folder
informational: true # Always pass check
test: # declare a new status context "test"
paths:
- test/* # only include coverage in "test/" folder
informational: true # Always pass check
# internal: # declare a new status context "internal"
# paths:
# - internal/* # only include coverage in "internal/" folder
# informational: true # Always pass check
# cmd: # declare a new status context "cmd"
# paths:
# - cmd/* # only include coverage in "cmd/" folder
# informational: true # Always pass check
patch: off # disable the commit only checks
================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.yml
================================================
name: Bug Report
title: "[BUG] "
labels: ["bug"]
description: "Create a detailed report to help us identify and resolve issues."
# assignees: []
body:
- type: markdown
attributes:
value: "Thank you for taking the time to fill out the bug report. Please provide as much information as possible to help us understand and replicate the bug."
- type: input
id: openim-server-version
attributes:
label: OpenIM Server Version
description: "Please provide the version number of OpenIM Server you are using."
placeholder: "e.g., 3.8.0"
validations:
required: true
- type: dropdown
id: operating-system
attributes:
label: Operating System and CPU Architecture
description: "Please select the operating system and describe the CPU architecture."
options:
- Linux (AMD)
- Linux (ARM)
- Windows (AMD)
- Windows (ARM)
- macOS (AMD)
- macOS (ARM)
validations:
required: true
- type: dropdown
id: deployment-method
attributes:
label: Deployment Method
description: "Please specify how OpenIM Server was deployed."
options:
- Source Code Deployment
- Docker Deployment
validations:
required: true
- type: textarea
id: bug-description-reproduction
attributes:
label: Bug Description and Steps to Reproduce
description: "Provide a detailed description of the bug and a step-by-step guide on how to reproduce it."
placeholder: "Describe the bug in detail here...\n\nSteps to reproduce the bug on the server:\n1. Start the server with specific configurations (mention any relevant config details).\n2. Make an API call to '...' endpoint with the following payload '...'.\n3. Observe the behavior and note any error messages or logs.\n4. Mention any additional setup relevant to the bug (e.g., database version, external service dependencies)."
validations:
required: true
- type: markdown
attributes:
value: "If possible, please add screenshots to help explain your problem."
- type: textarea
id: screenshots-link
attributes:
label: Screenshots Link
description: "If applicable, please provide any links to screenshots here."
placeholder: "Paste your screenshot URL here, e.g., http://imgur.com/example"
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
# - name: "Bug Report"
# description: "Report a bug in the project"
# file: "bug-report.yml"
- name: 📢 Connect on slack
url: https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A
about: Support OpenIM-related requests or issues, get in touch with developers and help on slack
- name: 🌐 OpenIM Blog
url: https://www.openim.io/
about: Open the OpenIM community blog
================================================
FILE: .github/ISSUE_TEMPLATE/deployment.yml
================================================
name: Deployment issue
title: "[Deployment] "
labels: ["deployment"]
description: "Create a detailed report to help us identify and resolve deployment issues."
# assignees: []
body:
- type: markdown
attributes:
value: "Thank you for taking the time to fill out the deployment issue report. Please provide as much information as possible to help us understand and resolve the issue."
- type: input
id: openim-server-version
attributes:
label: OpenIM Server Version
description: "Please provide the version number of OpenIM Server you are using."
placeholder: "e.g., 3.8.0"
validations:
required: true
- type: dropdown
id: operating-system
attributes:
label: Operating System and CPU Architecture
description: "Please select the operating system and describe the CPU architecture."
options:
- Linux (AMD)
- Linux (ARM)
- Windows (AMD)
- Windows (ARM)
- macOS (AMD)
- macOS (ARM)
validations:
required: true
- type: dropdown
id: deployment-method
attributes:
label: Deployment Method
description: "Please specify how OpenIM Server was deployed."
options:
- Source Code Deployment
- Docker Deployment
validations:
required: true
- type: textarea
id: issue-description-reproduction
attributes:
label: Issue Description and Steps to Reproduce
description: "Provide a detailed description of the issue and a step-by-step guide on how to reproduce it."
placeholder: "Describe the issue in detail here...\n\nSteps to reproduce the issue on the server:\n1. Start the server with specific configurations (mention any relevant config details).\n2. Make an API call to '...' endpoint with the following payload '...'.\n3. Observe the behavior and note any error messages or logs.\n4. Mention any additional setup relevant to the bug (e.g., database version, external service dependencies)."
validations:
required: true
- type: markdown
attributes:
value: "If possible, please add screenshots to help explain your problem."
- type: textarea
id: screenshots-link
attributes:
label: Screenshots Link
description: "If applicable, please provide any links to screenshots here."
placeholder: "Paste your screenshot URL here, e.g., http://imgur.com/example"
================================================
FILE: .github/ISSUE_TEMPLATE/documentation.md
================================================
---
name: Documentation Update
about: Propose updates to documentation, including README files and other docs.
title: "[DOC]: " # Prefix for the title to help identify documentation issues
labels: documentation # Labels to be automatically added
assignees: '' # Optionally, specify maintainers or teams to be auto-assigned
---
## Documentation Updates
Describe the documentation that needs to be updated or corrected. Please specify the files and sections if possible.
## Motivation
Explain why these updates are necessary. What is missing, misleading, or outdated?
## Suggested Changes
Detail the changes that you propose. If you are suggesting large changes, include examples or mockups of what the updated documentation should look like.
## Additional Information
Include any other information that might be relevant, such as links to discussions or related issues in the repository.
================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.yml
================================================
name: Feature Request
title: "[FEATURE REQUEST] "
labels: ["feature request","enhancement"]
description: "Propose a new feature or improvement that you believe will help enhance the project."
# assignees: []
body:
- type: markdown
attributes:
value: "Thank you for taking the time to propose a feature request. Please fill in as much detail as possible to help us understand why this feature is necessary and how it should work."
- type: textarea
id: feature-reason
attributes:
label: Why this feature?
description: "Explain why this feature is needed. What problem does it solve? How does it benefit the project and its users?"
placeholder: "Describe the need for this feature..."
validations:
required: true
- type: textarea
id: solution-proposal
attributes:
label: Suggested Solution
description: "Describe your proposed solution for this feature. How do you envision it working?"
placeholder: "Detail your solution here..."
validations:
required: true
- type: markdown
attributes:
value: "Please provide any other relevant information or screenshots that could help illustrate your idea."
- type: textarea
id: additional-info
attributes:
label: Additional Information
description: "Include any additional information, links, or screenshots that might be relevant to your feature request."
placeholder: "Add more context or links to relevant resources..."
- type: markdown
attributes:
value: "Thank you for contributing to the project! We appreciate your input and will review your suggestion as soon as possible."
================================================
FILE: .github/ISSUE_TEMPLATE/other.yml
================================================
name: 🐧 Other
description: Use this for any other issues. Please do NOT create blank issues
title: "[Other]: <give this problem a name>"
labels: ["other"]
# assignees: []
body:
- type: markdown
attributes:
value: "# Other issue"
- type: textarea
id: issuedescription
attributes:
label: What would you like to share?
description: Provide a clear and concise explanation of your issue.
validations:
required: true
- type: textarea
id: extrainfo
attributes:
label: Additional information
description: Is there anything else we should know about this issue?
validations:
required: false
- type: markdown
attributes:
value: |
You can also join our Discord community [here](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A)
Feel free to check out other cool repositories of the openim Community [here](https://github.com/openimsdk)
================================================
FILE: .github/ISSUE_TEMPLATE/rfc.md
================================================
---
name: RFC - Feature Proposal
about: Submit a proposal for a significant feature to invite community discussion.
title: "[RFC]: " # Prefix for the title to help identify RFC proposals
labels: rfc, proposal # Labels to be automatically added
assignees: '' # Optionally, specify maintainers or teams to be auto-assigned
---
## Proposal Overview
Briefly describe the content and objectives of your proposal.
## Motivation
Why is this new feature necessary? What is the background of this problem?
## Detailed Design
Describe the technical details of the proposal, including implementation steps, code snippets, or architecture diagrams.
## Alternatives Considered
Have other alternatives been considered? Why is this approach preferred over others?
## Impact
How will this proposal affect existing practices and community users?
## Additional Information
Include any other relevant information such as related discussions, prior related work, etc.
================================================
FILE: .github/sync-release.yml
================================================
openimsdk/openim-docker:
- source: ./config
dest: ./openim-server/release/config
replace: true
- source: ./docs
dest: ./openim-server/release/docs
replace: true
- source: ./scripts
dest: ./openim-server/release/scripts
replace: true
- source: ./scripts
dest: ./scripts
replace: false
- source: ./Makefile
dest: ./Makefile
replace: false
================================================
FILE: .github/workflows/auto-assign-issue.yml
================================================
name: Assign issue to comment author
on:
issue_comment:
types: [created]
jobs:
assign-issue:
if: |
contains(github.event.comment.body, '/assign') || contains(github.event.comment.body, '/accept') &&
!contains(github.event.comment.user.login, 'openim-robot')
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Assign the issue
run: |
export LETASE_MILESTONES=$(curl 'https://api.github.com/repos/$OWNER/$PEPO/milestones' | jq -r 'last(.[]).title')
gh issue edit ${{ github.event.issue.number }} --add-assignee "${{ github.event.comment.user.login }}"
gh issue edit ${{ github.event.issue.number }} --add-label "accepted"
gh issue comment $ISSUE --body "@${{ github.event.comment.user.login }} Glad to see you accepted this issue🤲, this issue has been assigned to you. I set the milestones for this issue to [$LETASE_MILESTONES](https://github.com/$OWNER/$PEPO/milestones), We are looking forward to your PR!"
# gh issue edit ${{ github.event.issue.number }} --milestone "$LETASE_MILESTONES"
env:
GH_TOKEN: ${{ secrets.BOT_TOKEN }}
ISSUE: ${{ github.event.issue.html_url }}
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
================================================
FILE: .github/workflows/auto-invite-comment.yml
================================================
name: Invite users to join OpenIM Community.
on:
issue_comment:
types:
- created
jobs:
issue_comment:
name: Invite users to join OpenIM Community
if: ${{ github.event.comment.body == '/invite' || github.event.comment.body == '/close' || github.event.comment.body == '/comment' }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Invite user to join OpenIM Community
uses: peter-evans/create-or-update-comment@v4
with:
token: ${{ secrets.BOT_GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
We value close connections with our users, developers, and contributors here at Open-IM-Server. With a large community and maintainer team, we're always here to help and support you. Whether you're looking to join our community or have any questions or suggestions, we welcome you to get in touch with us.
Our most recommended way to get in touch is through [Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A). Even if you're in China, Slack is usually not blocked by firewalls, making it an easy way to connect with us. Our Slack community is the ideal place to discuss and share ideas and suggestions with other users and developers of Open-IM-Server. You can ask technical questions, seek help, or share your experiences with other users of Open-IM-Server.
In addition to Slack, we also offer the following ways to get in touch:
+ <a href="https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A" target="_blank"><img src="https://img.shields.io/badge/Slack-OpenIM%2B-blueviolet?logo=slack&logoColor=white"></a> We also have Slack channels for you to communicate and discuss. To join, visit https://slack.com/ and join our [👀 Open-IM-Server slack](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A) team channel.
+ <a href="https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=info@openim.io" target="_blank"><img src="https://img.shields.io/badge/gmail-%40OOpenIMSDKCore?style=social&logo=gmail"></a> Get in touch with us on [Gmail](https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=winxu81@gmail.com). If you have any questions or issues that need resolving, or any suggestions and feedback for our open source projects, please feel free to contact us via email.
+ <a href="https://doc.rentsoft.cn/" target="_blank"><img src="https://img.shields.io/badge/%E5%8D%9A%E5%AE%A2-%40OpenIMSDKCore-blue?style=social&logo=Octopus%20Deploy"></a> Read our [blog](https://doc.rentsoft.cn/). Our blog is a great place to stay up-to-date with Open-IM-Server projects and trends. On the blog, we share our latest developments, tech trends, and other interesting information.
+ <a href="https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg" target="_blank"><img src="https://img.shields.io/badge/%E5%BE%AE%E4%BF%A1-OpenIMSDKCore-brightgreen?logo=wechat&style=flat-square"></a> Add [Wechat](https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of Open-IM-Server. We will process your request as soon as possible.
# - name: Close Issue
# uses: peter-evans/close-issue@v3
# with:
# token: ${{ secrets.BOT_GITHUB_TOKEN }}
# issue-number: ${{ github.event.issue.number }}
# comment: 🤖 Auto-closing issue, if you still need help please reopen the issue or ask for help in the community above
# labels: |
# accepted
================================================
FILE: .github/workflows/changelog.yml
================================================
name: Release Changelog
on:
release:
types: [released]
permissions:
contents: write
pull-requests: write
jobs:
update-changelog:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Go Changelog Generator
run: |
# Run the Go changelog generator, passing the release tag if available
if [ "${{ github.event.release.tag_name }}" = "latest" ]; then
go run tools/changelog/changelog.go > "${{ github.event.release.tag_name }}-changelog.md"
else
go run tools/changelog/changelog.go "${{ github.event.release.tag_name }}" > "${{ github.event.release.tag_name }}-changelog.md"
fi
- name: Handle changelog files
run: |
# Ensure that the CHANGELOG directory exists
mkdir -p CHANGELOG
# Extract Major.Minor version by removing the 'v' prefix from the tag name
TAG_NAME=${{ github.event.release.tag_name }}
CHANGELOG_VERSION_NUMBER=$(echo "$TAG_NAME" | sed 's/^v//' | grep -oP '^\d+\.\d+')
# Define the new changelog file path
CHANGELOG_FILENAME="CHANGELOG-$CHANGELOG_VERSION_NUMBER.md"
CHANGELOG_PATH="CHANGELOG/$CHANGELOG_FILENAME"
# Check if the changelog file for the current release already exists
if [ -f "$CHANGELOG_PATH" ]; then
# If the file exists, append the new changelog to the existing one
cat "$CHANGELOG_PATH" >> "${TAG_NAME}-changelog.md"
# Overwrite the existing changelog with the updated content
mv "${TAG_NAME}-changelog.md" "$CHANGELOG_PATH"
else
# If the changelog file doesn't exist, rename the temp changelog file to the new changelog file
mv "${TAG_NAME}-changelog.md" "$CHANGELOG_PATH"
# Ensure that README.md exists
if [ ! -f "CHANGELOG/README.md" ]; then
echo -e "# CHANGELOGs\n\n" > CHANGELOG/README.md
fi
# Add the new changelog entry at the top of the README.md
if ! grep -q "\[$CHANGELOG_FILENAME\]" CHANGELOG/README.md; then
sed -i "3i- [$CHANGELOG_FILENAME](./$CHANGELOG_FILENAME)" CHANGELOG/README.md
# Remove the extra newline character added by sed
# sed -i '4d' CHANGELOG/README.md
fi
fi
- name: Clean up
run: |
# Remove any temporary files that were created during the process
rm -f "${{ github.event.release.tag_name }}-changelog.md"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7.0.5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Update CHANGELOG for release ${{ github.event.release.tag_name }}"
title: "Update CHANGELOG for release ${{ github.event.release.tag_name }}"
body: "This PR updates the CHANGELOG files for release ${{ github.event.release.tag_name }}"
branch: changelog-${{ github.event.release.tag_name }}
base: main
delete-branch: true
labels: changelog
================================================
FILE: .github/workflows/cla-assistant.yml
================================================
name: CLA Assistant
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened,closed,synchronize]
# explicitly configure permissions, in case your GITHUB_TOKEN workflow permissions are set to read-only in repository settings
permissions:
actions: write
contents: write # this can be 'read' if the signatures are in remote repository
pull-requests: write
statuses: write
jobs:
CLA-Assistant:
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
uses: contributor-assistant/github-action@v2.4.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN: ${{ secrets.BOT_TOKEN }}
with:
path-to-signatures: 'signatures/cla.json'
path-to-document: 'https://github.com/OpenIM-Robot/cla/blob/main/README.md' # e.g. a CLA or a DCO document
branch: 'main'
allowlist: 'bot*,*bot,OpenIM-Robot'
# the followings are the optional inputs - If the optional inputs are not given, then default values will be taken
remote-organization-name: OpenIM-Robot
remote-repository-name: cla
create-file-commit-message: 'Creating file for storing CLA Signatures'
# signed-commit-message: '$contributorName has signed the CLA in $owner/$repo#$pullRequestNo'
custom-notsigned-prcomment: '💕 Thank you for your contribution and please kindly read and sign our CLA. [CLA Docs](https://github.com/OpenIM-Robot/cla/blob/main/README.md)'
custom-pr-sign-comment: 'I have read the CLA Document and I hereby sign the CLA'
custom-allsigned-prcomment: '🤖 All Contributors have signed the [CLA](https://github.com/OpenIM-Robot/cla/blob/main/README.md).<br> The signed information is recorded [**here**](https://github.com/OpenIM-Robot/cla/blob/main/signatures/cla.json)'
#lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true)
#use-dco-flag: true - If you are using DCO instead of CLA
================================================
FILE: .github/workflows/cleanup-after-milestone-prs-merged.yml
================================================
name: Cleanup After Milestone PRs Merged
on:
pull_request:
types:
- closed
jobs:
handle_pr:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4.2.0
- name: Get the PR title and extract PR numbers
id: extract_pr_numbers
run: |
# Get the PR title
PR_TITLE="${{ github.event.pull_request.title }}"
echo "PR Title: $PR_TITLE"
# Extract PR numbers from the title
PR_NUMBERS=$(echo "$PR_TITLE" | grep -oE "#[0-9]+" | tr -d '#' | tr '\n' ' ')
echo "Extracted PR Numbers: $PR_NUMBERS"
# Save PR numbers to a file
echo "$PR_NUMBERS" > pr_numbers.txt
echo "Saved PR Numbers to pr_numbers.txt"
# Check if the title matches a specific pattern
if echo "$PR_TITLE" | grep -qE "^deps: Merge( #[0-9]+)+ PRs into .+"; then
echo "proceed=true" >> $GITHUB_OUTPUT
else
echo "proceed=false" >> $GITHUB_OUTPUT
fi
- name: Use extracted PR numbers and label PRs
if: (steps.extract_pr_numbers.outputs.proceed == 'true' || contains(github.event.pull_request.labels.*.name, 'milestone-merge')) && github.event.pull_request.merged == true
run: |
# Read the previously saved PR numbers
PR_NUMBERS=$(cat pr_numbers.txt)
echo "Using extracted PR Numbers: $PR_NUMBERS"
# Loop through each PR number and add label
for PR_NUMBER in $PR_NUMBERS; do
echo "Adding 'cherry-picked' label to PR #$PR_NUMBER"
curl -X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/${{ github.repository }}/issues/$PR_NUMBER/labels \
-d '{"labels":["cherry-picked"]}'
done
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Delete branch after PR close
if: steps.extract_pr_numbers.outputs.proceed == 'true' || contains(github.event.pull_request.labels.*.name, 'milestone-merge')
run: |
BRANCH_NAME="${{ github.event.pull_request.head.ref }}"
echo "Branch to delete: $BRANCH_NAME"
git push origin --delete "$BRANCH_NAME"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '18 19 * * 6'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
================================================
FILE: .github/workflows/comment-check.yml
================================================
name: Non-English Comments Check
on:
pull_request:
branches:
- main
workflow_dispatch:
jobs:
non-english-comments-check:
runs-on: ubuntu-latest
env:
# need ignore Dirs
EXCLUDE_DIRS: ".git docs tests scripts assets node_modules build"
# need ignore Files
EXCLUDE_FILES: "*.md *.txt *.html *.css *.min.js *.mdx"
steps:
- uses: actions/checkout@v4
- name: Search for Non-English comments
run: |
set -e
# Define the regex pattern to match Chinese characters
pattern='[\p{Han}]'
# Process the directories to be excluded
exclude_dirs=""
for dir in $EXCLUDE_DIRS; do
exclude_dirs="$exclude_dirs --exclude-dir=$dir"
done
# Process the file types to be excluded
exclude_files=""
for file in $EXCLUDE_FILES; do
exclude_files="$exclude_files --exclude=$file"
done
# Use grep to find all comments containing Non-English characters and save to file
grep -Pnr "$pattern" . $exclude_dirs $exclude_files > non_english_comments.txt || true
- name: Output non-English comments are found
run: |
if [ -s non_english_comments.txt ]; then
echo "Non-English comments found in the following locations:"
cat non_english_comments.txt
exit 1 # terminate the workflow
else
echo "No Non_English comments found."
fi
================================================
FILE: .github/workflows/docker-build-and-release-services-images.yml
================================================
name: Build and release services Docker Images
on:
push:
branches:
- release-*
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Tag version to be used for Docker image"
required: true
default: "v3.8.3"
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.8.0
- name: Log in to Docker Hub
uses: docker/login-action@v3.3.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3.3.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Aliyun Container Registry
uses: docker/login-action@v3.3.0
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALIREGISTRY_USERNAME }}
password: ${{ secrets.ALIREGISTRY_TOKEN }}
- name: Extract metadata for Docker (tags, labels)
id: meta
uses: docker/metadata-action@v5.6.0
with:
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern=release-{{raw}}
type=sha
type=raw,value=${{ github.event.inputs.tag }}
- name: Build and push Docker images
run: |
IMG_DIR="build/images"
for dir in "$IMG_DIR"/*/; do
# Find Dockerfile or *.dockerfile in a case-insensitive manner
dockerfile=$(find "$dir" -maxdepth 1 -type f \( -iname 'dockerfile' -o -iname '*.dockerfile' \) | head -n 1)
if [ -n "$dockerfile" ] && [ -f "$dockerfile" ]; then
IMAGE_NAME=$(basename "$dir")
echo "Building Docker image for $IMAGE_NAME with tags:"
# Initialize tag arguments
tag_args=()
# Read each tag and append --tag arguments
while IFS= read -r tag; do
tag_args+=(--tag "${{ secrets.DOCKER_USERNAME }}/$IMAGE_NAME:$tag")
tag_args+=(--tag "ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME:$tag")
tag_args+=(--tag "registry.cn-hangzhou.aliyuncs.com/openimsdk/$IMAGE_NAME:$tag")
done <<< "${{ steps.meta.outputs.tags }}"
# Build and push the Docker image with all tags
docker buildx build --platform linux/amd64,linux/arm64 \
--file "$dockerfile" \
"${tag_args[@]}" \
--push \
"."
else
echo "No valid Dockerfile found in $dir"
fi
done
================================================
FILE: .github/workflows/go-build-test.yml
================================================
name: Go Build Test
on:
push:
pull_request:
paths-ignore:
- "**/*.md"
workflow_dispatch:
jobs:
go-build:
name: Test with go ${{ matrix.go_version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
env:
SHARE_CONFIG_PATH: config/share.yml
permissions:
contents: write
pull-requests: write
strategy:
matrix:
os: [ubuntu-latest]
go_version: ["1.22.x"]
steps:
- name: Checkout Server repository
uses: actions/checkout@v4
- 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 tidy
go mod download
- name: Set up infra services
uses: hoverkraft-tech/compose-action@v2.0.1
with:
compose-file: "./docker-compose.yml"
- name: Modify Server Configuration
run: |
yq e '.secret = 123456' -i ${{ env.SHARE_CONFIG_PATH }}
# - name: Get Internal IP Address
# id: get-ip
# run: |
# IP=$(hostname -I | awk '{print $1}')
# echo "The IP Address is: $IP"
# echo "::set-output name=ip::$IP"
# - name: Update .env
# run: |
# sed -i 's|externalAddress:.*|externalAddress: "http://${{ steps.get-ip.outputs.ip }}:10005"|' config/minio.yml
# cat config/minio.yml
- name: Build and test Server Services
run: |
mage build
mage start
mage check
- name: Checkout Chat repository
uses: actions/checkout@v4
with:
repository: "openimsdk/chat"
path: "chat-repo"
- name: Get Chat dependencies
run: |
cd ${{ github.workspace }}/chat-repo
go mod tidy
go mod download
go install github.com/magefile/mage@latest
- name: Modify Chat Configuration
run: |
cd ${{ github.workspace }}/chat-repo
yq e '.openIM.secret = 123456' -i ${{ env.SHARE_CONFIG_PATH }}
- name: Build and test Chat Services
run: |
cd ${{ github.workspace }}/chat-repo
mage build
mage start
mage check
- name: Test Server and Chat
run: |
check_error() {
echo "Response: $1"
errCode=$(echo $1 | jq -r '.errCode')
if [ "$errCode" != "0" ]; then
errMsg=$(echo $1 | jq -r '.errMsg')
echo "Error: $errMsg"
exit 1
fi
}
# Test register
response1=$(curl -X POST -H "Content-Type: application/json" -H "operationID: imAdmin" -d '{
"verifyCode": "666666",
"platform": 3,
"autoLogin": true,
"user":{
"nickname": "test12312",
"areaCode":"+86",
"phoneNumber": "12345678190",
"password":"test123456"
}
}' http://127.0.0.1:10008/account/register)
check_error "$response1"
userID1=$(echo $response1 | jq -r '.data.userID')
echo "userID1: $userID1"
response2=$(curl -X POST -H "Content-Type: application/json" -H "operationID: imAdmin" -d '{
"verifyCode": "666666",
"platform": 3,
"autoLogin": true,
"user":{
"nickname": "test22312",
"areaCode":"+86",
"phoneNumber": "12345678290",
"password":"test123456"
}
}' http://127.0.0.1:10008/account/register)
check_error "$response2"
userID2=$(echo $response2 | jq -r '.data.userID')
echo "userID2: $userID2"
# Test login
login_response=$(curl -X POST -H "Content-Type: application/json" -H "operationID: imAdmin" -d '{
"platform": 3,
"areaCode":"+86",
"phoneNumber": "12345678190",
"password":"test123456"
}' http://localhost:10008/account/login)
check_error "$login_response"
# Test get admin token
get_admin_token_response=$(curl -X POST -H "Content-Type: application/json" -H "operationID: imAdmin" -d '{
"secret": "123456",
"platformID": 2,
"userID": "imAdmin"
}' http://127.0.0.1:10002/auth/get_admin_token)
check_error "$get_admin_token_response"
adminToken=$(echo $get_admin_token_response | jq -r '.data.token')
echo "adminToken: $adminToken"
# Test send message
send_msg_response=$(curl -X POST -H "Content-Type: application/json" -H "operationID: imAdmin" -H "token: $adminToken" -d '{
"sendID": "'$userID1'",
"recvID": "'$userID2'",
"senderPlatformID": 3,
"content": {
"content": "hello!!"
},
"contentType": 101,
"sessionType": 1
}' http://127.0.0.1:10002/msg/send_msg)
check_error "$send_msg_response"
# Test get users
get_users_response=$(curl -X POST -H "Content-Type: application/json" -H "operationID: imAdmin" -H "token: $adminToken" -d '{
"pagination": {
"pageNumber": 1,
"showNumber": 100
}
}' http://127.0.0.1:10002/user/get_users)
check_error "$get_users_response"
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
NOTIFICATION_CONFIG_PATH: config/notification.yml
SHARE_CONFIG_PATH: config/share.yml
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"
ref: "main"
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: Modify Server Configuration
run: |
yq e '.groupCreated.isSendMsg = true' -i ${{ env.NOTIFICATION_CONFIG_PATH }}
yq e '.friendApplicationApproved.isSendMsg = true' -i ${{ env.NOTIFICATION_CONFIG_PATH }}
yq e '.secret = 123456' -i ${{ env.SHARE_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:
name: Build and Test Dockerfile
runs-on: ubuntu-latest
strategy:
matrix:
go_version: ["1.22"]
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up Go ${{ matrix.go_version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go_version }}
- name: Get dependencies
run: |
go mod tidy
go mod download
go install github.com/magefile/mage@latest
- name: Build Docker Image
run: |
IMAGE_NAME="${{ github.event.repository.name }}-test"
CONTAINER_NAME="${{ github.event.repository.name }}-container"
docker build -t $IMAGE_NAME .
- name: Run Docker Container
run: |
IMAGE_NAME="${{ github.event.repository.name }}-test"
CONTAINER_NAME="${{ github.event.repository.name }}-container"
docker run --name $CONTAINER_NAME -d $IMAGE_NAME
docker ps -a
- name: Test Docker Container Logs
run: |
CONTAINER_NAME="${{ github.event.repository.name }}-container"
docker logs $CONTAINER_NAME
================================================
FILE: .github/workflows/help-comment-issue.yml
================================================
# 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.
name: Good frist issue add comment
on:
issues:
types:
- labeled
jobs:
add-comment:
if: github.event.label.name == 'help wanted' || github.event.label.name == 'good first issue'
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Add comment
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.issue.number }}
token: ${{ secrets.BOT_TOKEN }}
body: |
This issue is available for anyone to work on. **Make sure to reference this issue in your pull request.** :sparkles: Thank you for your contribution! :sparkles:
[Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A) to connect and communicate with our developers.
If you wish to accept this assignment, please leave a comment in the comments section: `/accept`.🎯
================================================
FILE: .github/workflows/issue-translator.yml
================================================
name: 'issue-translator'
on:
issue_comment:
types: [created]
issues:
types: [opened]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: usthe/issues-translate-action@v2.7
with:
BOT_GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
IS_MODIFY_TITLE: true
# not require, default false, . Decide whether to modify the issue title
# if true, the robot account @Issues-translate-bot must have modification permissions, invite @Issues-translate-bot to your project or use your custom bot.
CUSTOM_BOT_NOTE: Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
# not require. Customize the translation robot prefix message.
================================================
FILE: .github/workflows/merge-from-milestone.yml
================================================
name: Create Individual PRs from Milestone
permissions:
contents: write
pull-requests: write
issues: write
on:
workflow_dispatch:
inputs:
milestone_name:
description: "Milestone name to collect closed PRs from"
required: true
default: "v3.8.4"
target_branch:
description: "Target branch to merge the consolidated PR"
required: true
default: "pre-release-v3.8.4"
env:
MILESTONE_NAME: ${{ github.event.inputs.milestone_name || 'v3.8.4' }}
TARGET_BRANCH: ${{ github.event.inputs.target_branch || 'pre-release-v3.8.4' }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
LABEL_NAME: cherry-picked
TEMP_DIR: /tmp
jobs:
merge_milestone_prs:
runs-on: ubuntu-latest
steps:
- name: Setup temp directory
run: |
# Create the temporary directory and initialize necessary files
mkdir -p ${{ env.TEMP_DIR }}
touch ${{ env.TEMP_DIR }}/pr_numbers.txt
touch ${{ env.TEMP_DIR }}/commit_hashes.txt
touch ${{ env.TEMP_DIR }}/pr_title.txt
touch ${{ env.TEMP_DIR }}/pr_body.txt
touch ${{ env.TEMP_DIR }}/created_pr_number.txt
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.BOT_TOKEN }}
- name: Setup Git User for OpenIM-Robot
run: |
git config --global user.email "OpenIM-Robot@users.noreply.github.com"
git config --global user.name "OpenIM-Robot"
- name: Fetch Milestone ID and Filter PR Numbers
env:
MILESTONE_NAME: ${{ env.MILESTONE_NAME }}
run: |
# Fetch milestone details and extract milestone ID
milestones=$(curl -s -H "Authorization: token $BOT_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/milestones")
milestone_id=$(echo "$milestones" | grep -B3 "\"title\": \"$MILESTONE_NAME\"" | grep '"number":' | head -n1 | grep -o '[0-9]\+')
if [ -z "$milestone_id" ]; then
echo "Milestone '$MILESTONE_NAME' not found. Exiting."
exit 1
fi
echo "Milestone ID: $milestone_id"
echo "MILESTONE_ID=$milestone_id" >> $GITHUB_ENV
# Fetch issues for the milestone
issues=$(curl -s -H "Authorization: token $BOT_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/issues?milestone=$milestone_id&state=closed&per_page=100")
> ${{ env.TEMP_DIR }}/pr_numbers.txt
# Filter PRs that do not have the 'cherry-picked' label
for pr_number in $(echo "$issues" | jq -r '.[] | select(.pull_request != null) | .number'); do
labels=$(curl -s -H "Authorization: token $BOT_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/issues/$pr_number/labels" | jq -r '.[].name')
if ! echo "$labels" | grep -q "${LABEL_NAME}"; then
echo "PR #$pr_number does not have the 'cherry-picked' label. Adding to the list."
echo "$pr_number" >> ${{ env.TEMP_DIR }}/pr_numbers.txt
fi
done
sort -n ${{ env.TEMP_DIR }}/pr_numbers.txt -o ${{ env.TEMP_DIR }}/pr_numbers.txt
- name: Create Individual PRs
run: |
for pr_number in $(cat ${{ env.TEMP_DIR }}/pr_numbers.txt); do
pr_details=$(curl -s -H "Authorization: token $BOT_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/pulls/$pr_number")
pr_title=$(echo "$pr_details" | jq -r '.title')
pr_body=$(echo "$pr_details" | jq -r '.body')
pr_creator=$(echo "$pr_details" | jq -r '.user.login')
merge_commit=$(echo "$pr_details" | jq -r '.merge_commit_sha')
short_commit_hash=$(echo "$merge_commit" | cut -c 1-7)
if [ "$merge_commit" != "null" ]; then
git fetch origin
echo "Checking out target branch: $TARGET_BRANCH"
git checkout $TARGET_BRANCH
echo "Pulling latest changes from target branch: $TARGET_BRANCH"
git pull origin $TARGET_BRANCH
cherry_pick_branch="cherry-pick-${short_commit_hash}"
git checkout -b $cherry_pick_branch
echo "Cherry-picking commit: $merge_commit"
if ! git cherry-pick "$merge_commit" --strategy=recursive -X theirs; then
echo "Conflict detected for $merge_commit. Resolving with incoming changes."
conflict_files=$(git diff --name-only --diff-filter=U)
echo "Conflicting files:"
echo "$conflict_files"
for file in $conflict_files; do
if [ -f "$file" ]; then
echo "Resolving conflict for $file"
git add "$file"
else
echo "File $file has been deleted. Skipping."
git rm "$file"
fi
done
echo "Conflicts resolved. Continuing cherry-pick."
git cherry-pick --continue || { echo "Cherry-pick failed, but continuing to create PR."; }
else
echo "Cherry-pick successful for commit $merge_commit."
fi
git remote set-url origin "https://${BOT_TOKEN}@github.com/${{ github.repository }}.git"
echo "Pushing branch: $cherry_pick_branch"
if ! git push origin $cherry_pick_branch --force; then
echo "Push failed, but continuing to create PR..."
fi
new_pr_title="$pr_title [Created by @$pr_creator from #$pr_number]"
new_pr_body="$pr_body
> This PR is created from original PR #$pr_number."
response=$(curl -s -X POST -H "Authorization: token $BOT_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/${{ github.repository }}/pulls \
-d "$(jq -n --arg title "$new_pr_title" \
--arg head "$cherry_pick_branch" \
--arg base "$TARGET_BRANCH" \
--arg body "$new_pr_body" \
'{title: $title, head: $head, base: $base, body: $body}')")
new_pr_number=$(echo "$response" | jq -r '.number')
if [[ "$new_pr_number" == "null" || -z "$new_pr_number" ]]; then
echo "Failed to create PR. Response: $response"
git checkout $TARGET_BRANCH
git branch -D $cherry_pick_branch
echo "Deleted branch: $cherry_pick_branch"
git push origin --delete $cherry_pick_branch
else
echo "Created PR #$new_pr_number"
curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
-d '{"labels": ["milestone-merge"]}' \
"https://api.github.com/repos/${{ github.repository }}/issues/$new_pr_number/labels"
fi
echo ""
echo "----------------------------------------"
echo ""
fi
done
================================================
FILE: .github/workflows/publish-docker-image.yml
================================================
name: Publish Docker image to registries
on:
push:
branches:
- release-*
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Tag version to be used for Docker image"
required: true
default: "v3.8.3"
env:
GO_VERSION: "1.22"
IMAGE_NAME: "openim-server"
# IMAGE_NAME: ${{ github.event.repository.name }}
DOCKER_BUILDKIT: 1
jobs:
publish-docker-images:
runs-on: ubuntu-latest
if: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.merged == false) }}
steps:
- name: Checkout main repository
uses: actions/checkout@v4
with:
path: main-repo
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.3.0
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5.6.0
with:
images: |
${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}
ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
registry.cn-hangzhou.aliyuncs.com/openimsdk/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Install skopeo
run: |
sudo apt-get update && sudo apt-get install -y skopeo
- name: Build multi-arch images as OCI
run: |
mkdir -p /tmp/oci-image /tmp/docker-cache
# Build multi-architecture image and save in OCI format
docker buildx build \
--platform linux/amd64,linux/arm64 \
--output type=oci,dest=/tmp/oci-image/multi-arch.tar \
--cache-to type=local,dest=/tmp/docker-cache \
--cache-from type=gha \
./main-repo
# Use skopeo to convert the amd64 image from OCI format to Docker format and load it
skopeo copy --override-arch amd64 oci-archive:/tmp/oci-image/multi-arch.tar docker-daemon:${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:local
# check image
docker image ls | grep openim
- name: Checkout compose repository
uses: actions/checkout@v4
with:
repository: "openimsdk/openim-docker"
path: "compose-repo"
- name: Get Internal IP Address
id: get-ip
run: |
IP=$(hostname -I | awk '{print $1}')
echo "The IP Address is: $IP"
echo "ip=$IP" >> $GITHUB_OUTPUT
- name: Update .env to use the local image
run: |
sed -i 's|OPENIM_SERVER_IMAGE=.*|OPENIM_SERVER_IMAGE=${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:local|' ${{ github.workspace }}/compose-repo/.env
sed -i 's|MINIO_EXTERNAL_ADDRESS=.*|MINIO_EXTERNAL_ADDRESS=http://${{ steps.get-ip.outputs.ip }}:10005|' ${{ github.workspace }}/compose-repo/.env
- name: Start services using Docker Compose
run: |
cd ${{ github.workspace }}/compose-repo
docker compose up -d
docker compose ps
# - name: Check openim-server health
# run: |
# timeout=300
# interval=30
# elapsed=0
# while [[ $elapsed -le $timeout ]]; do
# if ! docker exec openim-server mage check; then
# echo "openim-server is not ready, waiting..."
# sleep $interval
# elapsed=$(($elapsed + $interval))
# else
# echo "Health check successful"
# exit 0
# fi
# done
# echo "Health check failed after 5 minutes"
# exit 1
# - name: Check openim-chat health
# if: success()
# run: |
# if ! docker exec openim-chat mage check; then
# echo "openim-chat check failed"
# exit 1
# else
# echo "Health check successful"
# exit 0
# fi
- name: Log in to Docker Hub
uses: docker/login-action@v3.3.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3.3.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Aliyun Container Registry
uses: docker/login-action@v3.3.0
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALIREGISTRY_USERNAME }}
password: ${{ secrets.ALIREGISTRY_TOKEN }}
- name: Push multi-architecture images
if: success()
run: |
docker buildx build \
--platform linux/amd64,linux/arm64 \
$(echo "${{ steps.meta.outputs.tags }}" | sed 's/,/ --tag /g' | sed 's/^/--tag /') \
--cache-from type=local,src=/tmp/docker-cache \
--push \
./main-repo
- name: Verify multi-platform support
run: |
images=(
"${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}"
"ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}"
"registry.cn-hangzhou.aliyuncs.com/openimsdk/${{ env.IMAGE_NAME }}"
)
for image in "${images[@]}"; do
for tag in $(echo "${{ steps.meta.outputs.tags }}" | tr ',' '\n' | cut -d':' -f2); do
echo "Verifying multi-arch support for $image:$tag"
manifest=$(docker manifest inspect "$image:$tag" || echo "error")
if [[ "$manifest" == "error" ]]; then
echo "Manifest not found for $image:$tag"
exit 1
fi
amd64_found=$(echo "$manifest" | jq '.manifests[] | select(.platform.architecture == "amd64")')
arm64_found=$(echo "$manifest" | jq '.manifests[] | select(.platform.architecture == "arm64")')
if [[ -z "$amd64_found" ]]; then
echo "Multi-platform support check failed for $image:$tag - missing amd64"
exit 1
fi
if [[ -z "$arm64_found" ]]; then
echo "Multi-platform support check failed for $image:$tag - missing arm64"
exit 1
fi
echo "✅ $image:$tag supports both amd64 and arm64 architectures"
done
done
================================================
FILE: .github/workflows/remove-unused-labels.yml
================================================
name: Remove Unused Labels
on:
workflow_dispatch:
jobs:
cleanup:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
contents: read
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Fetch All Issues and PRs
id: fetch_issues_prs
uses: actions/github-script@v7.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issues = await github.paginate(github.rest.issues.listForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'all',
per_page: 100
});
const labelsInUse = new Set();
issues.forEach(issue => {
issue.labels.forEach(label => {
labelsInUse.add(label.name);
});
});
return JSON.stringify(Array.from(labelsInUse));
result-encoding: string
- name: Fetch All Labels
id: fetch_labels
uses: actions/github-script@v7.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const labels = await github.paginate(github.rest.issues.listLabelsForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
});
return JSON.stringify(labels.map(label => label.name));
result-encoding: string
- name: Remove Unused Labels
uses: actions/github-script@v7.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const labelsInUse = new Set(JSON.parse(process.env.LABELS_IN_USE));
const allLabels = JSON.parse(process.env.ALL_LABELS);
const unusedLabels = allLabels.filter(label => !labelsInUse.has(label));
for (const label of unusedLabels) {
await github.rest.issues.deleteLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label
});
console.log(`Deleted label: ${label}`);
}
env:
LABELS_IN_USE: ${{ steps.fetch_issues_prs.outputs.result }}
ALL_LABELS: ${{ steps.fetch_labels.outputs.result }}
================================================
FILE: .github/workflows/reopen-issue.yml
================================================
name: Reopen and Update Stale Issues
on:
workflow_dispatch:
jobs:
reopen_stale_issues:
runs-on: ubuntu-latest
permissions:
issues: write
contents: read
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Fetch Closed Issues with lifecycle/stale Label
id: fetch_issues
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issues = await github.paginate(github.rest.issues.listForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'closed',
labels: 'lifecycle/stale',
per_page: 100
});
const issueNumbers = issues
.filter(issue => !issue.pull_request) // exclude PR
.map(issue => issue.number);
console.log(`Fetched issues: ${issueNumbers}`);
return issueNumbers;
- name: Set issue numbers
id: set_issue_numbers
run: |
echo "ISSUE_NUMBERS=${{ steps.fetch_issues.outputs.result }}" >> $GITHUB_ENV
echo "Issue numbers: ${{ steps.fetch_issues.outputs.result }}"
- name: Reopen Issues
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issueNumbers = JSON.parse(process.env.ISSUE_NUMBERS);
console.log(`Reopening issues: ${issueNumbers}`);
for (const issue_number of issueNumbers) {
// Reopen the issue
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue_number,
state: 'open'
});
console.log(`Reopened issue #${issue_number}`);
}
- name: Remove lifecycle/stale Label
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issueNumbers = JSON.parse(process.env.ISSUE_NUMBERS);
console.log(`Removing 'lifecycle/stale' label from issues: ${issueNumbers}`);
for (const issue_number of issueNumbers) {
// Remove the lifecycle/stale label
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue_number,
name: 'lifecycle/stale'
});
console.log(`Removed label 'lifecycle/stale' from issue #${issue_number}`);
}
================================================
FILE: .github/workflows/update-version-file-on-release.yml
================================================
name: Update Version File on Release
on:
release:
types: [created]
jobs:
update-version:
runs-on: ubuntu-latest
env:
TAG_VERSION: ${{ github.event.release.tag_name }}
steps:
# Step 1: Checkout the original repository's code
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
# submodules: "recursive"
- name: Safe submodule initialization
run: |
echo "Checking for submodules..."
if [ -f .gitmodules ]; then
if [ -s .gitmodules ]; then
echo "Initializing submodules..."
if git submodule sync --recursive 2>/dev/null; then
git submodule update --init --force --recursive || {
echo "Warning: Some submodules failed to initialize, continuing anyway..."
}
else
echo "Warning: Submodule sync failed, continuing without submodules..."
fi
else
echo ".gitmodules exists but is empty, skipping submodule initialization"
fi
else
echo "No .gitmodules file found, no submodules to initialize"
fi
# Step 2: Set up Git with official account
- name: Set up Git
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
# Step 3: Check and delete existing tag
- name: Check and delete existing tag
run: |
if git rev-parse ${{ env.TAG_VERSION }} >/dev/null 2>&1; then
git tag -d ${{ env.TAG_VERSION }}
git push --delete origin ${{ env.TAG_VERSION }}
fi
# Step 4: Update version file
- name: Update version file
run: |
mkdir -p version
echo -n "${{ env.TAG_VERSION }}" > version/version
# Step 5: Commit and push changes
- name: Commit and push changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git add version/version
git commit -m "Update version to ${{ env.TAG_VERSION }}"
# Step 6: Update tag
- name: Update tag
run: |
git tag -fa ${{ env.TAG_VERSION }} -m "Update version to ${{ env.TAG_VERSION }}"
git push origin ${{ env.TAG_VERSION }} --force
# Step 7: Find and Publish Draft Release
- name: Find and Publish Draft Release
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo } = context.repo;
const tagName = process.env.TAG_VERSION;
try {
let release;
try {
const response = await github.rest.repos.getReleaseByTag({
owner,
repo,
tag: tagName
});
release = response.data;
} catch (tagError) {
core.info(`Release not found by tag, searching all releases...`);
const releases = await github.rest.repos.listReleases({
owner,
repo,
per_page: 100
});
release = releases.data.find(r => r.draft && r.tag_name === tagName);
if (!release) {
throw new Error(`No release found with tag ${tagName}`);
}
}
await github.rest.repos.updateRelease({
owner,
repo,
release_id: release.id,
draft: false,
prerelease: release.prerelease
});
const status = release.draft ? "was draft" : "was already published";
core.info(`Release ${tagName} ensured to be published (${status}).`);
} catch (error) {
core.warning(`Could not find or update release for tag ${tagName}: ${error.message}`);
}
================================================
FILE: .github/workflows/user-first-interaction.yml
================================================
name: User First Interaction
on:
issues:
types: [opened]
pull_request:
branches: [main]
types: [opened]
jobs:
check_for_first_interaction:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/first-interaction@v1.3.0
with:
repo-token: ${{ secrets.BOT_TOKEN }}
pr-message: |
Hello! Thank you for your contribution.
If you are fixing a bug, please reference the issue number in the description.
If you are implementing a feature request, please check with the maintainers that the feature will be accepted first.
[Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A) to connect and communicate with our developers.
Please leave your information in the [✨ discussions](https://github.com/orgs/OpenIMSDK/discussions/426), we expect anyone to join OpenIM developer community.
issue-message: |
Hello! Thank you for filing an issue.
If this is a bug report, please include relevant logs to help us debug the problem.
[Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A) to connect and communicate with our developers.
continue-on-error: true
================================================
FILE: .gitignore
================================================
# Copyright © 2023 OpenIMSDK.
#
# 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.
# ==============================================================================
# For the entire design of.gitignore, ignore git commits and ignore files
#===============================================================================
#
### OpenIM developer supplement ###
logs
.devcontainer
components
out-test
Dockerfile.cross
### Makefile ###
tmp/
bin/
output/
_output/
deployments/charts/generated-configs/
### OpenIM Config ###
.env
config/config.yaml
config/notification.yaml
### OpenIM deploy ###
deployments/openim-server/charts
# files used by the developer
.idea.md
.todo.md
.note.md
# ==============================================================================
# Created by https://www.toptal.com/developers/gitignore/api/go,git,vim,tags,test,emacs,backup,jetbrains
# Edit at https://www.toptal.com/developers/gitignore?templates=go,git,vim,tags,test,emacs,backup,jetbrains
### Backup ###
*.bak
*.gho
*.ori
*.orig
*.tmp
### Emacs ###
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
dist/
# Flycheck
flycheck_*.el
# server auth directory
/server/
# projectiles files
.projectile
# directory configuration
.dir-locals.el
# network security
/network-security.data
### vscode ###
.vscode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# End of https://www.toptal.com/developers/gitignore/api/vim,jetbrains,vscode,git,go,tags,backup,test
### Git ###
# Created by git for backups. To disable backups in Git:
# $ git config --global mergetool.keepBackup false
# Created by git when using merge tools for conflicts
*.BACKUP.*
*.BASE.*
*.LOCAL.*
*.REMOTE.*
*_BACKUP_*.txt
*_BASE_*.txt
*_LOCAL_*.txt
*_REMOTE_*.txt
### Go ###
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
vendor/
# Go workspace file
# go.work
go.work.sum
### JetBrains ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### JetBrains Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### Tags ###
# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
TAGS
.TAGS
!TAGS/
tags
.tags
!tags/
gtags.files
GTAGS
GRTAGS
GPATH
GSYMS
cscope.files
cscope.out
cscope.in.out
cscope.po.out
### Test ###
### Ignore all files that could be used to test your code and
### you wouldn't want to push
# Reference https://en.wikipedia.org/wiki/Metasyntactic_variable
# Most common
*foo
*bar
*fubar
*foobar
*baz
# Less common
*qux
*quux
*bongo
*bazola
*ztesch
# UK, Australia
*wibble
*wobble
*wubble
*flob
*blep
*blah
*boop
*beep
# Japanese
*hoge
*piyo
*fuga
*hogera
*hogehoge
# Portugal, Spain
*fulano
*sicrano
*beltrano
*mengano
*perengano
*zutano
# France, Italy, the Netherlands
*toto
*titi
*tata
*tutu
*pipppo
*pluto
*paperino
*aap
*noot
*mies
# Other names that would make sense
*tests
*testsdir
*testsfile
*testsfiles
*testdir
*testfile
*testfiles
*testing
*testingdir
*testingfile
*testingfiles
*temp
*tempdir
*tempfile
*tempfiles
*tmp
*tmpdir
*tmpfile
*tmpfiles
*lol
### Vim ###
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
# Auto-generated tag files
# Persistent undo
[._]*.un~
# End of https://www.toptal.com/developers/gitignore/api/go,git,vim,tags,test,emacs,backup,jetbrains
.idea
dist/
================================================
FILE: .golangci.yml
================================================
# options for analysis running
run:
# default concurrency is a available CPU number
concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 5m
# exit code when at least one issue was found, default is 1
issues-exit-code: 1
# include test files or not, default is true
tests: true
# list of build tags, all linters use it. Default is empty list.
build-tags:
- mytag
# which dirs to skip: issues from them won't be reported;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but default dirs are skipped independently
# from this option's value (see skip-dirs-use-default).
# "/" will be replaced by current OS file path separator to properly work
# on Windows.
# skip-dirs:
# - components
# - docs
# - util
# - .*~
# - api/swagger/docs
# - server/docs
# - components/mnt/config/certs
# - logs
# default is true. Enables skipping of directories:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
# skip-dirs-use-default: true
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
# "/" will be replaced by current OS file path separator to properly work
# on Windows.
# skip-files:
# - ".*\\.my\\.go$"
# - _test.go
# - ".*_test.go"
# - "mocks/"
# - ".github/"
# - "logs/"
# - "_output/"
# - "components/"
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
# If invoked with -mod=readonly, the go command is disallowed from the implicit
# automatic updating of go.mod described above. Instead, it fails when any changes
# to go.mod are needed. This setting is most useful to check that go.mod does
# not need updates, such as in a continuous integration and testing system.
# If invoked with -mod=vendor, the go command assumes that the vendor
# directory holds the correct copies of dependencies and ignores
# the dependency descriptions in go.mod.
#modules-download-mode: release|readonly|vendor
# Allow multiple parallel golangci-lint instances running.
# If false (default) - golangci-lint acquires file lock on start.
allow-parallel-runners: true
# output configuration options
output:
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
# format: colored-line-number
# print lines of code with issue, default is true
print-issued-lines: true
# print linter name in the end of issue text, default is true
print-linter-name: true
# make issues output unique by line, default is true
uniq-by-line: true
# add a prefix to the output file references; default is no prefix
path-prefix: ""
# sorts results by: filepath, line and column
sort-results: true
# all available settings of specific linters
linters-settings:
bidichk:
# The following configurations check for all mentioned invisible unicode
# runes. It can be omitted because all runes are enabled by default.
left-to-right-embedding: true
right-to-left-embedding: true
pop-directional-formatting: true
left-to-right-override: true
right-to-left-override: true
left-to-right-isolate: true
right-to-left-isolate: true
first-strong-isolate: true
pop-directional-isolate: true
dupl:
# tokens count to trigger issue, 150 by default
threshold: 200
errcheck:
# report about not checking of errors in type assertions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: false
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: false
# [deprecated] comma-separated list of pairs of the form pkg:regex
# the regex is used to ignore names within pkg. (default "fmt:.*").
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
#ignore: GenMarkdownTree,os:.*,BindPFlags,WriteTo,Help
#ignore: (os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv
# path to a file containing a list of functions to exclude from checking
# see https://github.com/kisielk/errcheck#excluding-functions for details
# exclude: errcheck.txt
errorlint:
# Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats
errorf: true
# Check for plain type assertions and type switches
asserts: true
# Check for plain error comparisons
comparison: true
exhaustive:
# Program elements to check for exhaustiveness.
# Default: [ switch ]
check:
- switch
- map
# check switch statements in generated files also
check-generated: false
# indicates that switch statements are to be considered exhaustive if a
# 'default' case is present, even if all enum members aren't listed in the
# switch
default-signifies-exhaustive: false
# enum members matching the supplied regex do not have to be listed in
# switch statements to satisfy exhaustiveness
ignore-enum-members: ""
# consider enums only in package scopes, not in inner scopes
package-scope-only: false
forbidigo:
# # Forbid the following identifiers (identifiers are written using regexp):
forbid:
# - ^print.*$
- 'fmt\.Print.*'
- fmt.Println.* # too much log noise
- ^unsafe\..*$
- ^init$
- ^os.Exit$
- ^fmt.Print.*$
- errors.New.*$
- ^fmt.Println.*$
- ^panic$
- painc
# - ginkgo\\.F.* # these are used just for local development
# # Exclude godoc examples from forbidigo checks. Default is true.
# exclude_godoc_examples: false
funlen:
lines: 220
statements: 80
gocognit:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30
goconst:
# minimal length of string constant, 3 by default
min-len: 3
# minimal occurrences count to trigger, 3 by default
min-occurrences: 3
# ignore test files, false by default
ignore-tests: false
# look for existing constants matching the values, true by default
match-constant: true
# search also for duplicated numbers, false by default
numbers: false
# minimum value, only works with goconst.numbers, 3 by default
min: 3
# maximum value, only works with goconst.numbers, 3 by default
max: 3
# ignore when constant is not used as function argument, true by default
ignore-calls: true
gocritic:
# Which checks should be enabled; can't be combined with 'disabled-checks';
# See https://go-critic.github.io/overview#checks-overview
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
# By default list of stable checks is used.
enabled-checks:
#- rangeValCopy
- ruleguard
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
disabled-checks:
- regexpMust
- ifElseChain
#- exitAfterDefer
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
enabled-tags:
- performance
disabled-tags:
- experimental
# Settings passed to gocritic.
# The settings key is the name of a supported gocritic checker.
# The list of supported checkers can be find in https://go-critic.github.io/overview.
settings:
captLocal: # must be valid enabled check name
# whether to restrict checker to params only (default true)
paramsOnly: true
elseif:
# whether to skip balanced if-else pairs (default true)
skipBalanced: true
hugeParam:
# size in bytes that makes the warning trigger (default 80)
sizeThreshold: 80
rangeExprCopy:
# size in bytes that makes the warning trigger (default 512)
sizeThreshold: 512
# whether to check test functions (default true)
skipTestFuncs: true
rangeValCopy:
# size in bytes that makes the warning trigger (default 128)
sizeThreshold: 32
# whether to check test functions (default true)
skipTestFuncs: true
ruleguard:
# path to a gorules file for the ruleguard checker
rules: ''
underef:
# whether to skip (*x).method() calls where x is a pointer receiver (default true)
skipRecvDeref: true
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30
cyclop:
# the maximal code complexity to report
max-complexity: 50
# the maximal average package complexity. If it's higher than 0.0 (float) the check is enabled (default 0.0)
package-average: 0.0
# should ignore tests (default false)
skip-tests: false
godot:
# comments to be checked: `declarations`, `toplevel`, or `all`
scope: declarations
# list of regexps for excluding particular comment lines from check
exclude:
# example: exclude comments which contain numbers
- '[0-9]+'
- 'func\s+\w+'
- 'FIXME:'
- '.*func.*'
# check that each sentence starts with a capital letter
capital: true
godox:
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
# might be left in the code accidentally and should be resolved before merging
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
#- TODO
- BUG
- FIXME
#- NOTE
- OPTIMIZE # marks code that should be optimized before merging
- HACK # marks hack-arounds that should be removed before merging
gofmt:
# simplify code: gofmt with `-s` option, true by default
simplify: true
gofumpt:
# Select the Go version to target. The default is `1.18`.
go-version: "1.21"
# Choose whether or not to use the extra rules that are disabled
# by default
extra-rules: false
# goheader:
# values:
# const:
# define here const type values in format k:v, for example:
# COMPANY: MY COMPANY
# regexp:
# define here regexp type values, for example
# AUTHOR: .*@mycompany\.com
# template: # |-
# put here copyright header template for source code files, for example:
# Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
#
# {{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
# SPDX-License-Identifier: Apache-2.0
# 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.
# template-path:
# also as alternative of directive 'template' you may put the path to file with the template source
goimports:
# put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes
local-prefixes: github.com/openimsdk/open-im-server
gomnd:
# List of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
# Default: ["argument", "case", "condition", "operation", "return", "assign"]
checks:
- argument
- case
- condition
- operation
- return
- assign
# List of numbers to exclude from analysis.
# The numbers should be written as string.
# Values always ignored: "1", "1.0", "0" and "0.0"
# Default: []
ignored-numbers:
- '0666'
- '0755'
- '42'
# List of file patterns to exclude from analysis.
# Values always ignored: `.+_test.go`
# Default: []
ignored-files:
- 'magic1_.+\.go$'
# List of function patterns to exclude from analysis.
# Following functions are always ignored: `time.Date`,
# `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`,
# `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`.
# Default: []
ignored-functions:
- '^math\.'
- '^webhook\.StatusText$'
gomoddirectives:
# Allow local `replace` directives. Default is false.
replace-local: true
# List of allowed `replace` directives. Default is empty.
replace-allow-list:
- google.golang.org/grpc
# Allow to not explain why the version has been retracted in the `retract` directives. Default is false.
retract-allow-no-explanation: false
# Forbid the use of the `exclude` directives. Default is false.
exclude-forbidden: false
gomodguard:
allowed:
modules:
- gorm.io/gen # List of allowed modules
- gorm.io/gorm
- gorm.io/driver/mysql
- k8s.io/klog
- github.com/allowed/module
- go.mongodb.org/mongo-driver/mongo
# - gopkg.in/yaml.v2
domains: # List of allowed module domains
- google.golang.org
- gopkg.in
- golang.org
- github.com
- go.mongodb.org
- go.uber.org
- openim.io
- go.etcd.io
blocked:
versions:
- github.com/MakeNowJust/heredoc:
version: "> 2.0.9"
reason: "use the latest version"
local_replace_directives: false # Set to true to raise lint issues for packages that are loaded from a local path via replace directive
gosec:
# To select a subset of rules to run.
# Available rules: https://github.com/securego/gosec#available-rules
includes:
- G401
- G306
- G101
# To specify a set of rules to explicitly exclude.
# Available rules: https://github.com/securego/gosec#available-rules
excludes:
- G204
# Exclude generated files
exclude-generated: true
# Filter out the issues with a lower severity than the given value. Valid options are: low, medium, high.
severity: "low"
# Filter out the issues with a lower confidence than the given value. Valid options are: low, medium, high.
confidence: "low"
# To specify the configuration of rules.
# The configuration of rules is not fully documented by gosec:
# https://github.com/securego/gosec#configuration
# https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/rules/rulelist.go#L60-L102
config:
G306: "0600"
G101:
pattern: "(?i)example"
ignore_entropy: false
entropy_threshold: "80.0"
per_char_threshold: "3.0"
truncate: "32"
gosimple:
# Select the Go version to target. The default is '1.13'.
go: "1.20"
# https://staticcheck.io/docs/options#checks
checks: [ "all" ]
govet:
# settings per analyzer
settings:
printf: # analyzer name, run `go tool vet help` to see all analyzers
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
# enable or disable analyzers by name
enable:
- atomicalign
enable-all: false
disable:
- shadow
disable-all: false
depguard:
rules:
prevent_unmaintained_packages:
list-mode: lax # allow unless explicitely denied
files:
- $all
- "!$test"
allow:
- $gostd
deny:
- pkg: io/ioutil
desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil"
- pkg: github.com/OpenIMSDK
desc: "The OpenIM organization has been replaced with lowercase, please do not use uppercase organization name, you will use openimsdk"
- pkg: log
desc: "We have a wrapped log package at openim, we recommend you to use our wrapped log package, https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/logging.md"
- pkg: errors
desc: "We have a wrapped errors package at openim, we recommend you to use our wrapped errors package, https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/error-code.md"
importas:
# if set to `true`, force to use alias.
no-unaliased: true
# List of aliases
alias:
# using `servingv1` alias for `knative.dev/serving/pkg/apis/serving/v1` package
- pkg: knative.dev/serving/pkg/apis/serving/v1
alias: servingv1
- pkg: gopkg.in/yaml.v2
alias: yaml
# using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package
- pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
alias: autoscalingv1alpha1
# You can specify the package path by regular expression,
# and alias by regular expression expansion syntax like below.
# see https://github.com/julz/importas#use-regular-expression for details
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
alias: $1$2
ireturn:
# ireturn allows using `allow` and `reject` settings at the same time.
# Both settings are lists of the keywords and regular expressions matched to interface or package names.
# keywords:
# - `empty` for `interface{}`
# - `error` for errors
# - `stdlib` for standard library
# - `anon` for anonymous interfaces
# By default, it allows using errors, empty interfaces, anonymous interfaces,
# and interfaces provided by the standard library.
allow:
- anon
- error
- empty
- stdlib
# You can specify idiomatic endings for interface
- (or|er)$
# Reject patterns
reject:
- github.com\/user\/package\/v4\.Type
lll:
# max line length, lines longer will be reported. Default is 250.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 250
# tab width in spaces. Default to 1.
tab-width: 4
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
ignore-words:
- someword
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 30
nestif:
# minimal complexity of if statements to report, 5 by default
min-complexity: 4
nilnil:
# By default, nilnil checks all returned types below.
checked-types:
- ptr
- func
- iface
- map
- chan
nlreturn:
# size of the block (including return statement that is still "OK")
# so no return split required.
block-size: 1
nolintlint:
# Disable to ensure that all nolint directives actually have an effect. Default is true.
allow-unused: false
# Exclude following linters from requiring an explanation. Default is [].
allow-no-explanation: [ ]
# Enable to require an explanation of nonzero length after each nolint directive. Default is false.
require-explanation: false
# Enable to require nolint directives to mention the specific linter being suppressed. Default is false.
require-specific: true
prealloc:
# XXX: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization.
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# True by default.
simple: true
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
promlinter:
# Promlinter cannot infer all metrics name in static analysis.
# Enable strict mode will also include the errors caused by failing to parse the args.
strict: false
# Please refer to https://github.com/yeya24/promlinter#usage for detailed usage.
disabled-linters:
- "Help"
- "MetricUnits"
- "Counter"
- "HistogramSummaryReserved"
- "MetricTypeInName"
- "ReservedChars"
- "CamelCase"
predeclared:
# comma-separated list of predeclared identifiers to not report on
ignore: ""
# include method names and field names (i.e., qualified names) in checks
q: false
rowserrcheck:
packages:
- github.com/jmoiron/sqlx
revive:
# see https://github.com/mgechev/revive#available-rules for details.
ignore-generated-header: true
severity: warning
rules:
- name: indent-error-flow
severity: warning
- name: exported
severity: warning
- name: var-naming
arguments: [ [ "OpenIM"] ]
# arguments: [ ["ID", "HTTP", "URL", "URI", "API", "APIKey", "Token", "TokenID", "TokenSecret", "TokenKey", "TokenSecret", "JWT", "JWTToken", "JWTTokenID", "JWTTokenSecret", "JWTTokenKey", "JWTTokenSecret", "OAuth", "OAuthToken", "RPC" ] ]
- name: atomic
- name: line-length-limit
severity: error
arguments: [200]
- name: unhandled-error
arguments : ["fmt.Printf", "myFunction"]
staticcheck:
# Select the Go version to target. The default is '1.13'.
go: "1.20"
# https://staticcheck.io/docs/options#checks
checks: [ "all" ]
stylecheck:
# Select the Go version to target. The default is '1.13'.
go: "1.20"
# https://staticcheck.io/docs/options#checks
checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ]
# https://staticcheck.io/docs/options#dot_import_whitelist
dot-import-whitelist:
- fmt
# https://staticcheck.io/docs/options#initialisms
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" ]
# https://staticcheck.io/docs/options#http_status_code_whitelist
http-status-code-whitelist: [ "200", "400", "404", "500" ]
tagliatelle:
# check the struck tag name case
case:
# use the struct field name to check the name of the struct tag
use-field-name: true
rules:
# any struct tag type can be used.
# support string case: `camel`, `pascal`, `kebab`, `snake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`
json: camel
yaml: camel
xml: camel
bson: camel
avro: snake
mapstructure: kebab
testpackage:
# regexp pattern to skip files
skip-regexp: (id|export|internal)_test\.go
thelper:
# The following configurations enable all checks. It can be omitted because all checks are enabled by default.
# You can enable only required checks deleting unnecessary checks.
test:
first: true
name: true
begin: true
benchmark:
first: true
name: true
begin: true
tb:
first: true
name: true
begin: true
tenv:
# The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
# By default, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
all: false
unparam:
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
# unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
whitespace:
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
wrapcheck:
# An array of strings that specify substrings of signatures to ignore.
# If this set, it will override the default set of ignored signatures.
# See https://github.com/tomarrell/wrapcheck#configuration for more information.
ignoreSigs:
- .Errorf(
- errors.New(
- errors.Unwrap(
- .Wrap(
- .WrapMsg(
- .Wrapf(
- .WithMessage(
- .WithMessagef(
- .WithStack(
ignorePackageGlobs:
- encoding/*
- github.com/pkg/*
- github.com/openimsdk/*
- github.com/OpenIMSDK/*
wsl:
# If true append is only allowed to be cuddled if appending value is
# matching variables, fields or types on line above. Default is true.
strict-append: true
# Allow calls and assignments to be cuddled as long as the lines have any
# matching variables, fields or types. Default is true.
allow-assign-and-call: true
# Allow assignments to be cuddled with anything. Default is false.
allow-assign-and-anything: false
# Allow multiline assignments to be cuddled. Default is true.
allow-multiline-assign: true
# Allow declarations (var) to be cuddled.
allow-cuddle-declarations: false
# Allow trailing comments in ending of blocks
allow-trailing-comment: false
# Force newlines in end of case at this limit (0 = never).
force-case-trailing-whitespace: 0
# Force cuddling of err checks with err var assignment
force-err-cuddling: false
# Allow leading comments to be separated with empty liens
allow-separated-leading-comment: false
makezero:
# Allow only slices initialized with a length of zero. Default is false.
always: false
# The custom section can be used to define linter plugins to be loaded at runtime. See README doc
# for more info.
#custom:
# Each custom linter should have a unique name.
#example:
# The path to the plugin *.so. Can be absolute or local. Required for each custom linter
#path: /path/to/example.so
# The description of the linter. Optional, just for documentation purposes.
#description: This is an example usage of a plugin linter.
# Intended to point to the repo location of the linter. Optional, just for documentation purposes.
#original-url: github.com/golangci/example-linter
linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
# enable-all: true
disable-all: true
enable:
- typecheck # Basic type checking
- gofmt # Format check
- govet # Go's standard linting tool
- gosimple # Suggestions for simplifying code
- errcheck
- decorder
- ineffassign
- forbidigo
- revive
- reassign
- tparallel
- unconvert
- fieldalignment
- dupl
- dupword
- errname
- gci
- exhaustive
- gocritic
- goprintffuncname
- gomnd
- goconst
- gosec
- misspell # Spelling mistakes
- staticcheck # Static analysis
- unused # Checks for unused code
# - goimports # Checks if imports are correctly sorted and formatted
- godot # Checks for comment punctuation
- bodyclose # Ensures HTTP response body is closed
- stylecheck # Style checker for Go code
- unused # Checks for unused code
- errcheck # Checks for missed error returns
fast: true
issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
exclude:
- tools/.*
- test/.*
- components/*
- third_party/.*
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- linters:
- revive
path: (log/.*)\.go
- linters:
- wrapcheck
path: (cmd/.*|pkg/.*)\.go
- linters:
- typecheck
#path: (pkg/storage/.*)\.go
path: (internal/.*|pkg/.*)\.go
- path: (cmd/.*|test/.*|tools/.*|internal/pump/pumps/.*)\.go
linters:
- forbidigo
- path: (cmd/[a-z]*/.*|store/.*)\.go
linters:
- dupl
- linters:
- gocritic
text: (hugeParam:|rangeValCopy:)
- path: (cmd/[a-z]*/.*)\.go
linters:
- lll
- path: (validator/.*|code/.*|validator/.*|watcher/watcher/.*)
linters:
- gochecknoinits
- path: (internal/.*/options|internal/pump|pkg/log/options.go|internal/authzserver|tools/)
linters:
- tagliatelle
- path: (pkg/app/.*)\.go
linters:
- unused
- forbidigo
# Exclude some staticcheck messages
- linters:
- staticcheck
text: "SA9003:"
# Exclude lll issues for long lines with go:generate
- linters:
- lll
source: "^//go:generate "
- text: ".*[\u4e00-\u9fa5]+.*"
linters:
- golint
source: "^//.*$"
# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
# Default value for this option is true.
exclude-use-default: true
# The default value is false. If set to true exclude and exclude-rules
# regular expressions become case sensitive.
exclude-case-sensitive: false
# The list of ids of default excludes to include or disable. By default it's empty.
include:
- EXC0002 # disable excluding of issues about comments from golint
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing
# large codebase. It's not practical to fix all existing issues at the moment
# of integration: much better don't allow issues in new code.
# Default is false.
new: false
# Show only new issues created after git revision `REV`
# new-from-rev: REV
# Show only new issues created in git patch with set file path.
#new-from-patch: path/to/patch/file
# Fix found issues (if it's supported by the linter)
fix: true
severity:
# Default value is empty string.
# Set the default severity for issues. If severity rules are defined and the issues
# do not match or no severity is provided to the rule this will be the default
# severity applied. Severities should match the supported severity names of the
# selected out format.
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
# - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
default-severity: error
# The default value is false.
# If set to true severity-rules regular expressions become case sensitive.
case-sensitive: false
# Default value is empty list.
# When a list of severity rules are provided, severity information will be added to lint
# issues. Severity rules have the same filtering capability as exclude rules except you
# are allowed to specify one matcher per severity rule.
# Only affects out formats that support setting severity information.
rules:
- linters:
- dupl
severity: info
================================================
FILE: CHANGELOG/CHANGELOG-3.8.md
================================================
## [v3.8.3-patch.6](https://github.com/openimsdk/open-im-server/releases/tag/v3.8.3-patch.6) (2025-07-23)
### Bug Fixes
* fix: Add friend DB in notification sender [#3438](https://github.com/openimsdk/open-im-server/pull/3438)
* fix: remove update version file workflows have new line in 3.8.3-patch branch. [#3452](https://github.com/openimsdk/open-im-server/pull/3452)
* fix: s3 aws init [#3454](https://github.com/openimsdk/open-im-server/pull/3454)
* fix: use safe submodule init in workflows in v3.8.3-patch. [#3469](https://github.com/openimsdk/open-im-server/pull/3469)
**Full Changelog**: [v3.8.3-patch.5...v3.8.3-patch.6](https://github.com/openimsdk/open-im-server/compare/v3.8.3-patch.5...v3.8.3-patch.6)
## [v3.8.3-patch.5](https://github.com/openimsdk/open-im-server/releases/tag/v3.8.3-patch.5) (2025-06-10)
### New Features
* feat: optimize friend and group applications [#3396](https://github.com/openimsdk/open-im-server/pull/3396)
### Bug Fixes
* fix: solve unocrrect invite notification [Created [#3219](https://github.com/openimsdk/open-im-server/pull/3219)
### Builds
* build: update gomake version in dockerfile.[Patch branch] [#3416](https://github.com/openimsdk/open-im-server/pull/3416)
**Full Changelog**: [v3.8.3...v3.8.3-patch.5](https://github.com/openimsdk/open-im-server/compare/v3.8.3...v3.8.3-patch.5)
## [v3.8.3-patch.4](https://github.com/openimsdk/open-im-server/releases/tag/v3.8.3-patch.4) (2025-03-13)
### Bug Fixes
* fix: solve unocrrect invite notificationfrom #3213
**Full Changelog**: [v3.8.3-patch.3...v3.8.3-patch.4](https://github.com/openimsdk/open-im-server/compare/v3.8.3-patch.3...v3.8.3-patch.4)
## [v3.8.3-patch.3](https://github.com/openimsdk/open-im-server/releases/tag/v3.8.3-patch.3) (2025-03-07)
### New Features
* feat: optimizing BatchGetIncrementalGroupMember #3180
### Bug Fixes
* fix: solve uncorrect notification when set group info #3172
* fix: the sorting is wrong after canceling the administrator in group settings #3185
* fix: solve uncorrect GroupMember enter group notification type. #3188
### Refactors
* refactor: change sendNotification to sendMessage to avoid ambiguity regarding message sending behavior. #3173
**Full Changelog**: [v3.8.3-patch.2...v3.8.3-patch.3](https://github.com/openimsdk/open-im-server/compare/v3.8.3-patch.2...v3.8.3-patch.3)
## [v3.8.3-patch.2](https://github.com/openimsdk/open-im-server/releases/tag/v3.8.3-patch.2) (2025-02-28)
### Bug Fixes
* fix: Offline push does not have a badge && Android offline push (#3146) [#3174](https://github.com/openimsdk/open-im-server/pull/3174)
**Full Changelog**: [v3.8.3-patch.1...v3.8.3-patch.2](https://github.com/openimsdk/open-im-server/compare/v3.8.3-patch.1...v3.8.3-patch.2)
## [v3.8.3-patch.1](https://github.com/openimsdk/open-im-server/releases/tag/v3.8.3-patch.1) (2025-02-25)
### New Features
* feat: add backup volume && optimize log print [Created [#3121](https://github.com/openimsdk/open-im-server/pull/3121)
### Bug Fixes
* fix: seq conversion failed without exiting [Created [#3120](https://github.com/openimsdk/open-im-server/pull/3120)
* fix: check error in BatchSetTokenMapByUidPid [Created [#3123](https://github.com/openimsdk/open-im-server/pull/3123)
* fix: DeleteDoc crash [Created [#3124](https://github.com/openimsdk/open-im-server/pull/3124)
* fix: the abnormal message has no sending time, causing the SDK to be abnormal [Created [#3126](https://github.com/openimsdk/open-im-server/pull/3126)
* fix: crash caused [#3127](https://github.com/openimsdk/open-im-server/pull/3127)
* fix: the user sets the conversation timer cleanup timestamp unit incorrectly [Created [#3128](https://github.com/openimsdk/open-im-server/pull/3128)
* fix: seq conversion not reading env in docker environment [Created [#3131](https://github.com/openimsdk/open-im-server/pull/3131)
### Builds
* build: improve workflows contents. [Created [#3125](https://github.com/openimsdk/open-im-server/pull/3125)
**Full Changelog**: [v3.8.3-e-v1.1.5...v3.8.3-patch.1-e-v1.1.5](https://github.com/openimsdk/open-im-server-enterprise/compare/v3.8.3-e-v1.1.5...v3.8.3-patch.1-e-v1.1.5)
================================================
FILE: CHANGELOG/README.md
================================================
# CHANGELOGs
- [CHANGELOG-3.8.md](./CHANGELOG-3.8.md)
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
`security@openim.io`.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: CONTRIBUTING-zh_CN.md
================================================
# 如何给 OpenIM 贡献代码(提交 Pull Request)
<p align="center">
<a href="./CONTRIBUTING.md">English</a> ·
<a href="./CONTRIBUTING-zh_CN.md">中文</a> ·
<a href="docs/contributing/CONTRIBUTING-UA.md">Українська</a> ·
<a href="docs/contributing/CONTRIBUTING-CS.md">Česky</a> ·
<a href="docs/contributing/CONTRIBUTING-HU.md">Magyar</a> ·
<a href="docs/contributing/CONTRIBUTING-ES.md">Español</a> ·
<a href="docs/contributing/CONTRIBUTING-FA.md">فارسی</a> ·
<a href="docs/contributing/CONTRIBUTING-FR.md">Français</a> ·
<a href="docs/contributing/CONTRIBUTING-DE.md">Deutsch</a> ·
<a href="docs/contributing/CONTRIBUTING-PL.md">Polski</a> ·
<a href="docs/contributing/CONTRIBUTING-ID.md">Indonesian</a> ·
<a href="docs/contributing/CONTRIBUTING-FI.md">Suomi</a> ·
<a href="docs/contributing/CONTRIBUTING-ML.md">മലയാളം</a> ·
<a href="docs/contributing/CONTRIBUTING-JP.md">日本語</a> ·
<a href="docs/contributing/CONTRIBUTING-NL.md">Nederlands</a> ·
<a href="docs/contributing/CONTRIBUTING-IT.md">Italiano</a> ·
<a href="docs/contributing/CONTRIBUTING-RU.md">Русский</a> ·
<a href="docs/contributing/CONTRIBUTING-PTBR.md">Português (Brasil)</a> ·
<a href="docs/contributing/CONTRIBUTING-EO.md">Esperanto</a> ·
<a href="docs/contributing/CONTRIBUTING-KR.md">한국어</a> ·
<a href="docs/contributing/CONTRIBUTING-AR.md">العربي</a> ·
<a href="docs/contributing/CONTRIBUTING-VN.md">Tiếng Việt</a> ·
<a href="docs/contributing/CONTRIBUTING-DA.md">Dansk</a> ·
<a href="docs/contributing/CONTRIBUTING-GR.md">Ελληνικά</a> ·
<a href="docs/contributing/CONTRIBUTING-TR.md">Türkçe</a>
</p>
本指南将以 [openimsdk/open-im-server](https://github.com/openimsdk/open-im-server) 为例,详细说明如何为 OpenIM 项目贡献代码。我们采用“一问题一分支”的策略,确保每个 Issue 都对应一个专门的分支,以便有效管理代码变更。
### 1. Fork 仓库
前往 [openimsdk/open-im-server](https://github.com/openimsdk/open-im-server) GitHub 页面,点击右上角的 "Fork" 按钮,将仓库 Fork 到你的 GitHub 账户下。
### 2. 克隆仓库
将你 Fork 的仓库克隆到本地:
```bash
git clone https://github.com/your-username/open-im-server.git
```
### 3. 设置远程上游
添加原始仓库为远程上游以便跟踪其更新:
```bash
git remote add upstream https://github.com/openimsdk/open-im-server.git
```
### 4. 创建 Issue
在原始仓库中创建一个新的 Issue,详细描述你遇到的问题或希望添加
的新功能。
### 5. 创建新分支
基于主分支创建一个新分支,并使用描述性的名称与 Issue ID,例如:
```bash
git checkout -b fix-bug-123
```
### 6. 提交更改
在你的本地分支上进行更改后,提交这些更改:
```bash
git add .
git commit -m "Describe your changes in detail"
```
### 7. 推送分支
将你的分支推送回你的 GitHub Fork:
```bash
git push origin fix-bug-123
```
### 8. 创建 Pull Request
在 GitHub 上转到你的 Fork 仓库,点击 "Pull Request" 按钮。确保 PR 描述清楚,并链接到相关的 Issue。
### 9. 签署 CLA
如果这是你第一次提交 PR,你需要在 PR 的评论中回复:
```
I have read the CLA Document and I hereby sign the CLA
```
### 编程规范
请参考以下文档以了解关于 Go 语言编程规范的详细信息:
- [Go 编码规范](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/go-code.md)
- [代码约定](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/code-conventions.md)
### 日志规范
- **禁止使用标准的 `log` 包**。
- 应使用 `"github.com/openimsdk/tools/log"` 包来打印日志,该包支持多种日志级别:`debug`、`info`、`warn`、`error`。
- **错误日志应仅在首次调用的函数中打印**,以防止日志重复,并确保错误的上下文清晰。
### 异常及错误处理
- **禁止使用 `panic`**:程序中不应使用 `panic`,以避免在遇到不可恢复的错误时突然终止。
- **错误包裹**:使用 `"github.com/openimsdk/tools/errs"` 来包裹错误,保持错误信息的完整性并增加调试便利。
- **错误传递**:如果函数本身不能处理错误,应将错误返回给调用者,而不是隐藏或忽略这些错误。
================================================
FILE: CONTRIBUTING.md
================================================
# How to Contribute to OpenIM (Submitting Pull Requests)
<p align="center">
<a href="./CONTRIBUTING.md">English</a> ·
<a href="./CONTRIBUTING-zh_CN.md">中文</a> ·
<a href="docs/contributing/CONTRIBUTING-UA.md">Українська</a> ·
<a href="docs/contributing/CONTRIBUTING-CS.md">Česky</a> ·
<a href="docs/contributing/CONTRIBUTING-HU.md">Magyar</a> ·
<a href="docs/contributing/CONTRIBUTING-ES.md">Español</a> ·
<a href="docs/contributing/CONTRIBUTING-FA.md">فارسی</a> ·
<a href="docs/contributing/CONTRIBUTING-FR.md">Français</a> ·
<a href="docs/contributing/CONTRIBUTING-DE.md">Deutsch</a> ·
<a href="docs/contributing/CONTRIBUTING-PL.md">Polski</a> ·
<a href="docs/contributing/CONTRIBUTING-ID.md">Indonesian</a> ·
<a href="docs/contributing/CONTRIBUTING-FI.md">Suomi</a> ·
<a href="docs/contributing/CONTRIBUTING-ML.md">മലയാളം</a> ·
<a href="docs/contributing/CONTRIBUTING-JP.md">日本語</a> ·
<a href="docs/contributing/CONTRIBUTING-NL.md">Nederlands</a> ·
<a href="docs/contributing/CONTRIBUTING-IT.md">Italiano</a> ·
<a href="docs/contributing/CONTRIBUTING-RU.md">Русский</a> ·
<a href="docs/contributing/CONTRIBUTING-PTBR.md">Português (Brasil)</a> ·
<a href="docs/contributing/CONTRIBUTING-EO.md">Esperanto</a> ·
<a href="docs/contributing/CONTRIBUTING-KR.md">한국어</a> ·
<a href="docs/contributing/CONTRIBUTING-AR.md">العربي</a> ·
<a href="docs/contributing/CONTRIBUTING-VN.md">Tiếng Việt</a> ·
<a href="docs/contributing/CONTRIBUTING-DA.md">Dansk</a> ·
<a href="docs/contributing/CONTRIBUTING-GR.md">Ελληνικά</a> ·
<a href="docs/contributing/CONTRIBUTING-TR.md">Türkçe</a>
</p>
This guide will use [openimsdk/open-im-server](https://github.com/openimsdk/open-im-server) as an example to explain in detail how to contribute code to the OpenIM project. We adopt a "one issue, one branch" strategy to ensure each issue corresponds to a dedicated branch for effective code change management.
### 1. Fork the Repository
Go to the [openimsdk/open-im-server](https://github.com/openimsdk/open-im-server) GitHub page, click the "Fork" button in the upper right corner to fork the repository to your GitHub account.
### 2. Clone the Repository
Clone the repository you forked to your local machine:
```bash
git clone https://github.com/your-username/open-im-server.git
```
### 3. Set Upstream Remote
Add the original repository as a remote upstream to track updates:
```bash
git remote add upstream https://github.com/openimsdk/open-im-server.git
```
### 4. Create an Issue
Create a new issue in the original repository detailing the problem you encountered or the new feature you wish to add.
### 5. Create a New Branch
Create a new branch off the main branch with a descriptive name and Issue ID, for example:
```bash
git checkout -b fix-bug-123
```
### 6. Commit Changes
After making changes on your local branch, commit these changes:
```bash
git add .
git commit -m "Describe your changes
in detail"
```
### 7. Push the Branch
Push your branch back to your GitHub fork:
```bash
git push origin fix-bug-123
```
### 8. Create a Pull Request
Go to your fork on GitHub and click the "Pull Request" button. Ensure the PR description is clear and links to the related issue.
### 9. Sign the CLA
If this is your first time submitting a PR, you will need to reply in the comments of the PR:
```
I have read the CLA Document and I hereby sign the CLA
```
### Programming Standards
Please refer to the following documents for detailed information on Go language programming standards:
- [Go Coding Standards](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/go-code.md)
- [Code Conventions](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/code-conventions.md)
### Logging Standards
- **Do not use the standard `log` package**.
- Use the `"github.com/openimsdk/tools/log"` package for logging, which supports multiple log levels: `debug`, `info`, `warn`, `error`.
- **Error logs should only be printed in the function where they are first actively called** to prevent log duplication and ensure clear error context.
### Exception and Error Handling
- **Prohibit the use of `panic`**: The code should not use `panic` to avoid abrupt termination when encountering unrecoverable errors.
- **Error Wrapping**: Use `"github.com/openimsdk/tools/errs"` to wrap errors, maintaining the integrity of error information and facilitating debugging.
- **Error Propagation**: If a function cannot handle an error itself, it should return the error to the caller, rather than hiding or ignoring it.
================================================
FILE: Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
# ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod download
# Install Mage to use for building the application
RUN go install github.com/magefile/mage@v1.15.0
# Optionally build your application if needed
RUN mage build
# Using Alpine Linux with Go environment for the final image
FROM golang:1.22-alpine
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
COPY --from=builder /go/bin/mage /usr/local/bin/mage
COPY --from=builder $SERVER_DIR/magefile_windows.go $SERVER_DIR/
COPY --from=builder $SERVER_DIR/magefile_unix.go $SERVER_DIR/
COPY --from=builder $SERVER_DIR/magefile.go $SERVER_DIR/
COPY --from=builder $SERVER_DIR/start-config.yml $SERVER_DIR/
COPY --from=builder $SERVER_DIR/go.mod $SERVER_DIR/
COPY --from=builder $SERVER_DIR/go.sum $SERVER_DIR/
RUN go get github.com/openimsdk/gomake@v0.0.15-alpha.1
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "mage start && tail -f /dev/null"]
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
================================================
FILE: README.md
================================================
<p align="center">
<a href="https://openim.io">
<img src="./assets/logo-gif/openim-logo.gif" width="60%" height="30%"/>
</a>
</p>
<div align="center">
[](https://github.com/openimsdk/open-im-server/stargazers)
[](https://github.com/openimsdk/open-im-server/network/members)
[](https://app.codecov.io/gh/openimsdk/open-im-server)
[](https://goreportcard.com/report/github.com/openimsdk/open-im-server)
[](https://pkg.go.dev/github.com/openimsdk/open-im-server/v3)
[](https://github.com/openimsdk/open-im-server/blob/main/LICENSE)
[](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A)
[](https://www.bestpractices.dev/projects/8045)
[](https://github.com/openimsdk/open-im-server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22)
[](https://golang.org/)
[](https://gurubase.io/g/openim)
<p align="center">
<a href="./README.md">English</a> ·
<a href="./README_zh_CN.md">中文</a> ·
<a href="./docs/readme/README_uk.md">Українська</a> ·
<a href="./docs/readme/README_cs.md">Česky</a> ·
<a href="./docs/readme/README_hu.md">Magyar</a> ·
<a href="./docs/readme/README_es.md">Español</a> ·
<a href="./docs/readme/README_fa.md">فارسی</a> ·
<a href="./docs/readme/README_fr.md">Français</a> ·
<a href="./docs/readme/README_de.md">Deutsch</a> ·
<a href="./docs/readme/README_pl.md">Polski</a> ·
<a href="./docs/readme/README_id.md">Indonesian</a> ·
<a href="./docs/readme/README_fi.md">Suomi</a> ·
<a href="./docs/readme/README_ml.md">മലയാളം</a> ·
<a href="./docs/readme/README_ja.md">日本語</a> ·
<a href="./docs/readme/README_nl.md">Nederlands</a> ·
<a href="./docs/readme/README_it.md">Italiano</a> ·
<a href="./docs/readme/README_ru.md">Русский</a> ·
<a href="./docs/readme/README_pt_BR.md">Português (Brasil)</a> ·
<a href="./docs/readme/README_eo.md">Esperanto</a> ·
<a href="./docs/readme/README_ko.md">한국어</a> ·
<a href="./docs/readme/README_ar.md">العربي</a> ·
<a href="./docs/readme/README_vi.md">Tiếng Việt</a> ·
<a href="./docs/readme/README_da.md">Dansk</a> ·
<a href="./docs/readme/README_el.md">Ελληνικά</a> ·
<a href="./docs/readme/README_tr.md">Türkçe</a>
</p>
</div>
</p>
## :busts_in_silhouette: Join Our Community
- 💬 [Follow us on Twitter](https://twitter.com/founder_im63606)
- 🚀 [Join our Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A)
- :eyes: [Join our WeChat Group](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
## Ⓜ️ About OpenIM
Unlike standalone chat applications such as Telegram, Signal, and Rocket.Chat, OpenIM offers an open-source instant messaging solution designed specifically for developers rather than as a directly installable standalone chat app. Comprising OpenIM SDK and OpenIM Server, it provides developers with a complete set of tools and services to integrate instant messaging functions into their applications, including message sending and receiving, user management, and group management. Overall, OpenIM aims to provide developers with the necessary tools and framework to implement efficient instant messaging solutions in their applications.

## 🚀 Introduction to OpenIMSDK
**OpenIMSDK**, designed for **OpenIMServer**, is an IM SDK created specifically for integration into client applications. It supports various functionalities and modules:
- 🌟 Main Features:
- 📦 Local Storage
- 🔔 Listener Callbacks
- 🛡️ API Wrapping
- 🌐 Connection Management
- 📚 Main Modules:
1. 🚀 Initialization and Login
2. 👤 User Management
3. 👫 Friends Management
4. 🤖 Group Functions
5. 💬 Session Handling
Built with Golang and supports cross-platform deployment to ensure a consistent integration experience across all platforms.
👉 **[Explore the GO SDK](https://github.com/openimsdk/openim-sdk-core)**
## 🌐 Introduction to OpenIMServer
- **OpenIMServer** features include:
- 🌐 Microservices Architecture: Supports cluster mode, including a gateway and multiple rpc services.
- 🚀 Diverse Deployment Options: Supports source code, Kubernetes, or Docker deployment.
- Massive User Support: Supports large-scale groups with hundreds of thousands, millions of users, and billions of messages.
### Enhanced Business Functions:
- **REST API**: Provides a REST API for business systems to enhance functionality, such as group creation and message pushing through backend interfaces.
- **Webhooks**: Expands business forms through callbacks, sending requests to business servers before or after certain events.

## :rocket: Quick Start
Experience online for iOS/Android/H5/PC/Web:
👉 **[OpenIM Online Demo](https://www.openim.io/en/commercial)**
To facilitate user experience, we offer various deployment solutions. You can choose your preferred deployment method from the list below:
- **[Source Code Deployment Guide](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
- **[Docker Deployment Guide](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
## System Support
Supports Linux, Windows, Mac systems, and ARM and AMD CPU architectures.
## :link: Links
- **[Developer Manual](https://docs.openim.io/)**
- **[Changelog](https://github.com/openimsdk/open-im-server/blob/main/CHANGELOG.md)**
## :writing_hand: How to Contribute
We welcome contributions of any kind! Please make sure to read our [Contributor Documentation](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md) before submitting a Pull Request.
- **[Report a Bug](https://github.com/openimsdk/open-im-server/issues/new?assignees=&labels=bug&template=bug_report.md&title=)**
- **[Suggest a Feature](https://github.com/openimsdk/open-im-server/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)**
- **[Submit a Pull Request](https://github.com/openimsdk/open-im-server/pulls)**
Thank you for contributing to building a powerful instant messaging solution!
## :closed_book: License
This software is licensed under the Apache License 2.0
## 🔮 Thanks to our contributors!
<a href="https://github.com/openimsdk/open-im-server/graphs/contributors">
<img src="https://contrib.rocks/image?repo=openimsdk/open-im-server" />
</a>
================================================
FILE: README_zh_CN.md
================================================
<p align="center">
<a href="https://openim.io">
<img src="./assets/logo-gif/openim-logo.gif" width="60%" height="30%"/>
</a>
</p>
<div align="center">
[](https://github.com/openimsdk/open-im-server/stargazers)
[](https://github.com/openimsdk/open-im-server/network/members)
[](https://app.codecov.io/gh/openimsdk/open-im-server)
[](https://goreportcard.com/report/github.com/openimsdk/open-im-server)
[](https://pkg.go.dev/github.com/openimsdk/open-im-server/v3)
[](https://github.com/openimsdk/open-im-server/blob/main/LICENSE)
[](https://join.slack.com/t/openimsdk/shared_invite/zt-2ijy1ys1f-O0aEDCr7ExRZ7mwsHAVg9A)
[](https://www.bestpractices.dev/projects/8045)
[](https://github.com/openimsdk/open-im-server/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22)
[](https://golang.org/)
<p align="center">
<a href="./README.md">English</a> ·
<a href="./README_zh_CN.md">中文</a> ·
<a href="./docs/readme/README_uk.md">Українська</a> ·
<a href="./docs/readme/README_cs.md">Česky</a> ·
<a href="./docs/readme/README_hu.md">Magyar</a> ·
<a href="./docs/readme/README_es.md">Español</a> ·
<a href="./docs/readme/README_fa.md">فارسی</a> ·
<a href="./docs/readme/README_fr.md">Français</a> ·
<a href="./docs/readme/README_de.md">Deutsch</a> ·
<a href="./docs/readme/README_pl.md">Polski</a> ·
<a href="./docs/readme/README_id.md">Indonesian</a> ·
<a href="./docs/readme/README_fi.md">Suomi</a> ·
<a href="./docs/readme/README_ml.md">മലയാളം</a> ·
<a href="./docs/readme/README_ja.md">日本語</a> ·
<a href="./docs/readme/README_nl.md">Nederlands</a> ·
<a href="./docs/readme/README_it.md">Italiano</a> ·
<a href="./docs/readme/README_ru.md">Русский</a> ·
<a href="./docs/readme/README_pt_BR.md">Português (Brasil)</a> ·
<a href="./docs/readme/README_eo.md">Esperanto</a> ·
<a href="./docs/readme/README_ko.md">한국어</a> ·
<a href="./docs/readme/README_ar.md">العربي</a> ·
<a href="./docs/readme/README_vi.md">Tiếng Việt</a> ·
<a href="./docs/readme/README_da.md">Dansk</a> ·
<a href="./docs/readme/README_el.md">Ελληνικά</a> ·
<a href="./docs/readme/README_tr.md">Türkçe</a>
</p>
</div>
</p>
## :busts_in_silhouette: 加入我们的社区
- 💬 [关注我们的 Twitter](https://twitter.com/founder_im63606)
- 🚀 [加入我们的 Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-2hljfom5u-9ZuzP3NfEKW~BJKbpLm0Hw)
- :eyes: [加入我们的微信群](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg)
## Ⓜ️ 关于 OpenIM
与 Telegram、Signal、Rocket.Chat 等独立聊天应用不同,OpenIM 提供了专为开发者设计的开源即时通讯解决方案,而不是直接安装使用的独立聊天应用。OpenIM 由 OpenIM SDK 和 OpenIM Server 两大部分组成,为开发者提供了一整套集成即时通讯功能的工具和服务,包括消息发送接收、用户管理和群组管理等。总体来说,OpenIM 旨在为开发者提供必要的工具和框架,帮助他们在自己的应用中实现高效的即时通讯解决方案。

## 🚀 OpenIMSDK 介绍
**OpenIMSDK** 是为 **OpenIMServer** 设计的 IM SDK,专为集成到客户端应用而生。它支持多种功能和模块:
- 🌟 主要功能:
- 📦 本地存储
- 🔔 监听器回调
- 🛡️ API 封装
- 🌐 连接管理
- 📚 主要模块:
1. 🚀 初始化及登录
2. 👤 用户管理
3. 👫 好友管理
4. 🤖 群组功能
5. 💬 会话处理
它使用 Golang 构建,并支持跨平台部署,确保在所有平台上提供一致的接入体验。
👉 **[探索 GO SDK](https://github.com/openimsdk/openim-sdk-core)**
## 🌐 OpenIMServer 介绍
- **OpenIMServer** 的特点包括:
- 🌐 微服务架构:支持集群模式,包括网关(gateway)和多个 rpc 服务。
- 🚀 多样的部署方式:支持源代码、Kubernetes 或 Docker 部署。
- 海量用户支持:支持十万级超大群组,千万级用户和百亿级消息。
### 增强的业务功能:
- **REST API**:为业务系统提供 REST API,增加群组创建、消息推送等后台接口功能。
- **Webhooks**:通过事件前后的回调,向业务服务器发送请求,扩展更多的业务形态。

## :rocket: 快速入门
在线体验 iOS/Android/H5/PC/Web:
👉 **[OpenIM 在线演示](https://www.openim.io/en/commercial)**
为了便于用户体验,我们提供了多种部署解决方案,您可以根据以下列表选择适合您的部署方式:
- **[源代码部署指南](https://docs.openim.io/guides/gettingStarted/imSourceCodeDeployment)**
- **[Docker 部署指南](https://docs.openim.io/guides/gettingStarted/dockerCompose)**
## 系统支持
支持 Linux、Windows、Mac 系统以及 ARM 和 AMD CPU 架构。
## :link: 相关链接
- **[开发手册](https://docs.openim.io/)**
- **[更新日志](https://github.com/openimsdk/open-im-server/blob/main/CHANGELOG.md)**
## :writing_hand: 如何贡献
我们欢迎任何形式的贡献!在提交 Pull Request 之前,请确保阅读我们的[贡献者文档](https://github.com/openimsdk/open-im-server/blob/main/CONTRIBUTING.md)
- **[报告 Bug](https://github.com/openimsdk/open-im-server/issues/new?assignees=&labels=bug&template=bug_report.md&title=)**
- **[提出新特性](https://github.com/openimsdk/open-im-server/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)**
- **[提交 Pull Request](https://github.com/openimsdk/open-im-server/pulls)**
感谢您的贡献,一起来打造强大的即时通讯解决方案!
## :closed_book: 开源许可证 License
This software is licensed under the Apache License 2.0
## 🔮 Thanks to our contributors!
<a href="https://github.com/openimsdk/open-im-server/graphs/contributors">
<img src="https://contrib.rocks/image?repo=openimsdk/open-im-server" />
</a>
================================================
FILE: assets/README.md
================================================
# `/assets`
The `/assets` directory in the OpenIM repository contains various assets such as images, logos, and animated GIFs. These assets serve different purposes and contribute to the functionality and aesthetics of the OpenIM project.
## Directory Structure:
```bash
assets/
├── README.md # Documentation for the assets directory
├── images # Directory holding images related to OpenIM
│ ├── architecture.png # Image depicting the architecture of OpenIM
│ └── mvc.png # Image illustrating the Model-View-Controller (MVC) pattern
├── intive-slack.png # Image displaying the Intive Slack logo
├── logo # Directory containing various logo variations for OpenIM
│ ├── openim-logo-black.png # OpenIM logo with a black background
│ ├── openim-logo-blue.png # OpenIM logo with a blue background
│ ├── openim-logo-green.png # OpenIM logo with a green background
│ ├── openim-logo-purple.png # OpenIM logo with a purple background
│ ├── openim-logo-white.png # OpenIM logo with a white background
│ ├── openim-logo-yellow.png # OpenIM logo with a yellow background
│ └── openim-logo.png # OpenIM logo with a transparent background
└── logo-gif # Directory containing animated GIF versions of the OpenIM logo
└── openim-log.gif # Animated OpenIM logo with a transparent background
```
## Copyright Notice:
The OpenIM logo, including its variations and animated versions, displayed in this repository [OpenIM](https://github.com/openimsdk/open-im-server) under the `/assets/logo` and `/assets/logo-gif` directories, are protected by copyright laws.
The logo design is credited to @Xx(席欣).
Please respect the intellectual property rights and refrain from unauthorized use and distribution of these assets.
================================================
FILE: assets/colors.md
================================================
# Official Colors
The openim logo has an official blue color. When reproducing the logo, please use the official color, when possible.
## Pantone
When possible, the Pantone color is preferred for print material. The official Pantone color is *285C*.
## RGB
When used digitally, the official RGB color code is *#326CE5*.
================================================
FILE: assets/demo/README.md
================================================
## :star2: Why OpenIM
**🔍 Function screenshot display**
<div align="center">
| multiple message | Efficient meetings |
| :---------------------------------------: | :---------------------------------------------: |
|  |  |
| **One-to-one and group chats** | **Special features - Custom messages** |
|  |  |
</div>
================================================
FILE: assets/logo/LICENSE
================================================
# The OpenIM logo files are licensed under a choice of either Apache-2.0 or CC-BY-4.0 (Creative Commons Attribution 4.0 International).
================================================
FILE: assets/logo-gif/LICENSE
================================================
# The OpenIM logo files are licensed under a choice of either Apache-2.0 or CC-BY-4.0 (Creative Commons Attribution 4.0 International).
================================================
FILE: bootstrap.bat
================================================
@echo off
SETLOCAL
mage -version >nul 2>&1
IF %ERRORLEVEL% EQU 0 (
echo Mage is already installed.
GOTO DOWNLOAD
)
go version >nul 2>&1
IF NOT %ERRORLEVEL% EQU 0 (
echo Go is not installed. Please install Go and try again.
exit /b 1
)
echo Installing Mage...
go install github.com/magefile/mage@latest
mage -version >nul 2>&1
IF NOT %ERRORLEVEL% EQU 0 (
echo Mage installation failed.
echo Please ensure that %GOPATH%/bin is in your PATH.
exit /b 1
)
echo Mage installed successfully.
:DOWNLOAD
go mod download
ENDLOCAL
================================================
FILE: bootstrap.sh
================================================
#!/bin/bash
if [[ ":$PATH:" == *":$HOME/.local/bin:"* ]]; then
TARGET_DIR="$HOME/.local/bin"
else
TARGET_DIR="/usr/local/bin"
echo "Using /usr/local/bin as the installation directory. Might require sudo permissions."
fi
if ! command -v mage &> /dev/null; then
echo "Installing Mage to $TARGET_DIR ..."
GOBIN=$TARGET_DIR go install github.com/magefile/mage@latest
fi
if ! command -v mage &> /dev/null; then
echo "Mage installation failed."
echo "Please ensure that $TARGET_DIR is in your \$PATH."
exit 1
fi
echo "Mage installed successfully."
go mod download
================================================
FILE: build/README.md
================================================
# Building OpenIM
Building OpenIM is easy if you take advantage of the containerized build environment. This document will help guide you through understanding this build process.
## Requirements
1. Docker, using one of the following configurations:
* **macOS** Install Docker for Mac. See installation instructions [here](https://docs.docker.com/docker-for-mac/).
**Note**: You will want to set the Docker VM to have at least 4GB of initial memory or building will likely fail.
* **Linux with local Docker** Install Docker according to the [instructions](https://docs.docker.com/installation/#installation) for your OS.
* **Windows with Docker Desktop WSL2 backend** Install Docker according to the [instructions](https://docs.docker.com/docker-for-windows/wsl-tech-preview/). Be sure to store your sources in the local Linux file system, not the Windows remote mount at `/mnt/c`.
**Note**: You will need to check if Docker CLI plugin buildx is properly installed (`docker-buildx` file should be present in `~/.docker/cli-plugins`). You can install buildx according to the [instructions](https://github.com/docker/buildx/blob/master/README.md#installing).
2. **Optional** [Google Cloud SDK](https://developers.google.com/cloud/sdk/)
You must install and configure Google Cloud SDK if you want to upload your release to Google Cloud Storage and may safely omit this otherwise.
## Actions
About [Images packages](https://github.com/orgs/OpenIMSDK/packages?repo_name=Open-IM-Server)
All files in the `build/images` directory are not templated and are instead rendered by Github Actions, which is an automated process.
Trigger condition:
1. create a new tag with the format `vX.Y.Z` (e.g. `v1.0.0`)
2. push the tag to the remote repository
3. wait for the build to finish
4. download the artifacts from the release page
## Make images
**help info:**
```bash
$ make image.help
```
**build images:**
```bash
$ make image
```
## Overview
While it is possible to build OpenIM using a local golang installation, we have a build process that runs in a Docker container. This simplifies initial set up and provides for a very consistent build and test environment.
## Basic Flow
The scripts directly under [`build/`](.) are used to build and test. They will ensure that the `openim-build` Docker image is built (based on [`build/build-image/Dockerfile`](../Dockerfile) and after base image's `OPENIM_BUILD_IMAGE_CROSS_TAG` from Dockerfile is replaced with one of those actual tags of the base image, like `v1.13.9-2`) and then execute the appropriate command in that container. These scripts will both ensure that the right data is cached from run to run for incremental builds and will copy the results back out of the container. You can specify a different registry/name and version for `openim-cross` by setting `OPENIM_CROSS_IMAGE` and `OPENIM_CROSS_VERSION`, see [`common.sh`](common.sh) for more details.
The `openim-build` container image is built by first creating a "context" directory in `_output/images/build-image`. It is done there instead of at the root of the OpenIM repo to minimize the amount of data we need to package up when building the image.
There are 3 different containers instances that are run from this image. The first is a "data" container to store all data that needs to persist across to support incremental builds. Next there is an "rsync" container that is used to transfer data in and out to the data container. Lastly there is a "build" container that is used for actually doing build actions. The data container persists across runs while the rsync and build containers are deleted after each use.
`rsync` is used transparently behind the scenes to efficiently move data in and out of the container. This will use an ephemeral port picked by Docker. You can modify this by setting the `OPENIM_RSYNC_PORT` env variable.
All Docker names are suffixed with a hash derived from the file path (to allow concurrent usage on things like CI machines) and a version number. When the version number changes all state is cleared and clean build is started. This allows the build infrastructure to be changed and signal to CI systems that old artifacts need to be deleted.
## Build artifacts
The build system output all its products to a top level directory in the source repository named `_output`.
These include the binary compiled packages (e.g. imctl, openim-api etc.) and archived Docker images.
If you intend to run a component with a docker image you will need to import it from this directory with
================================================
FILE: build/goreleaser.yaml
================================================
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
- make clean
# You may remove this if you don't use go modules.
- make tidy
- make copyright.add
# you may remove this if you don't need go generate
- go generate ./...
git:
# What should be used to sort tags when gathering the current and previous
# tags if there are more than one tag in the same commit.
#
# Default: '-version:refname'
tag_sort: -version:creatordate
# What should be used to specify prerelease suffix while sorting tags when gathering
# the current and previous tags if there are more than one tag in the same commit.
#
# Since: v1.17
prerelease_suffix: "-"
# Tags to be ignored by GoReleaser.
# This means that GoReleaser will not pick up tags that match any of the
# provided values as either previous or current tags.
#
# Templates: allowed.
# Since: v1.21.
ignore_tags:
- nightly
# - "{{.Env.IGNORE_TAG}}"
snapshot:
name_template: "{{ incpatch .Version }}-next"
# gomod:
# proxy: true
report_sizes: true
# metadata:
# mod_timestamp: "{{ .CommitTimestamp }}"
builds:
- binary: openim-api
id: openim-api
main: ./cmd/openim-api/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-cmdutils
id: openim-cmdutils
main: ./cmd/openim-cmdutils/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-crontask
id: openim-crontask
main: ./cmd/openim-crontask/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-msggateway
id: openim-msggateway
main: ./cmd/openim-msggateway/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-msgtransfer
id: openim-msgtransfer
main: ./cmd/openim-msgtransfer/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-push
id: openim-push
main: ./cmd/openim-push/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-rpc-auth
id: openim-rpc-auth
main: ./cmd/openim-rpc/openim-rpc-auth/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-rpc-conversation
id: openim-rpc-conversation
main: ./cmd/openim-rpc/openim-rpc-conversation/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-rpc-friend
id: openim-rpc-friend
main: ./cmd/openim-rpc/openim-rpc-friend/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-rpc-group
id: openim-rpc-group
main: ./cmd/openim-rpc/openim-rpc-group/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-rpc-msg
id: openim-rpc-msg
main: ./cmd/openim-rpc/openim-rpc-msg/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-rpc-third
id: openim-rpc-third
main: ./cmd/openim-rpc/openim-rpc-third/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
- binary: openim-rpc-user
id: openim-rpc-user
main: ./cmd/openim-rpc/openim-rpc-user/main.go
goos:
- darwin
- windows
- linux
goarch:
- amd64
- arm64
# TODO:Need a script, such as the init - release to help binary to find the right directory
# ,which can be compiled binary
archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of uname.
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# Set this to true if you want all files in the archive to be in a single directory.
# If set to true and you extract the archive 'goreleaser_Linux_arm64.tar.gz',
# you'll get a folder 'goreleaser_Linux_arm64'.
# If set to false, all files are extracted separately.
# You can also set it to a custom folder name (templating is supported).
wrap_in_directory: true
# use zip for windows archives
files:
- CHANGELOG/*
- deployment/*
- config/*
- build/*
- scripts/*
- Makefile
- install.sh
- docs/*
- src: "*.md"
dst: docs
# Strip parent folders when adding files to the archive.
strip_parent: true
# File info.
# Not all fields are supported by all formats available formats.
#
# Default: copied from the source file
info:
# Templates: allowed (since v1.14)
owner: root
# Templates: allowed (since v1.14)
group: root
# Must be in time.RFC3339Nano format.
#
# Templates: allowed (since v1.14)
mtime: "{{ .CommitDate }}"
# File mode.
mode: 0644
format_overrides:
- goos: windows
format: zip
changelog:
sort: asc
use: github
filters:
exclude:
- "^test:"
- "^chore"
- "merge conflict"
- Merge pull request
- Merge remote-tracking branch
- Merge branch
- go mod tidy
groups:
- title: Dependency updates
regexp: '^.*?(feat|fix)\(deps\)!?:.+$'
order: 300
- title: "New Features"
regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$'
order: 100
- title: "Security updates"
regexp: '^.*?sec(\([[:word:]]+\))??!?:.+$'
order: 150
- title: "Bug fixes"
regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$'
order: 200
- title: "Documentation updates"
regexp: ^.*?doc(\([[:word:]]+\))??!?:.+$
order: 400
- title: "Build process updates"
regexp: ^.*?build(\([[:word:]]+\))??!?:.+$
order: 400
- title: Other work
order: 9999
# dockers:
# - image_templates:
# - "openimsdk/open-im-server:{{ .Tag }}-amd64"
# - "ghcr.io/goreleaser/goreleaser:{{ .Tag }}-amd64"
# dockerfile: build/images/openim-api/Dockerfile.release
# ids:
# - openim-api
# use: buildx
# build_flag_templates:
# - "--pull"
# - "--label=io.artifacthub.package.readme-url=https://raw.githubusercontent.com/openimsdk/open-im-server/main/README.md"
# - "--label=io.artifacthub.package.logo-url=hhttps://github.com/openimsdk/open-im-server/blob/main/assets/logo/openim-logo-green.png"
# - '--label=io.artifacthub.package.maintainers=[{"name":"Xinwei Xiong","email":"3293172751nss@gmail.com"}]'
# - "--label=io.artifacthub.package.license=Apace-2.0"
# - "--label=org.opencontainers.image.description=OpenIM Open source top instant messaging system"
# - "--label=org.opencontainers.image.created={{.Date}}"
# - "--label=org.opencontainers.image.name={{.ProjectName}}"
# - "--label=org.opencontainers.image.revision={{.FullCommit}}"
# - "--label=org.opencontainers.image.version={{.Version}}"
# - "--label=org.opencontainers.image.source={{.GitURL}}"
# - "--platform=linux/amd64"
# extra_files:
# - scripts/entrypoint.sh
# - image_templates:
# - "goreleaser/goreleaser:{{ .Tag }}-arm64"
# - "ghcr.io/goreleaser/goreleaser:{{ .Tag }}-arm64"
# dockerfile: build/images/openim-api/Dockerfile.release
# use: buildx
# build_flag_templates:
# - "--pull"
# - "--label=io.artifacthub.package.readme-url=https://raw.githubusercontent.com/openimsdk/open-im-server/main/README.md"
# - "--label=io.artifacthub.package.logo-url=hhttps://github.com/openimsdk/open-im-server/blob/main/assets/logo/openim-logo-green.png"
# - '--label=io.artifacthub.package.maintainers=[{"name":"Xinwei Xiong","email":"3293172751nss@gmail.com"}]'
# - "--label=io.artifacthub.package.license=Apace-2.0"
# - "--label=org.opencontainers.image.description=OpenIM Open source top instant messaging system"
# - "--label=org.opencontainers.image.created={{.Date}}"
# - "--label=org.opencontainers.image.name={{.ProjectName}}"
# - "--label=org.opencontainers.image.revision={{.FullCommit}}"
# - "--label=org.opencontainers.image.version={{.Version}}"
# - "--label=org.opencontainers.image.source={{.GitURL}}"
# - "--platform=linux/arm64"
# goarch: arm64
# extra_files:
# - scripts/entrypoint.sh
# docker_manifests:
# - name_template: "goreleaser/goreleaser:{{ .Tag }}"
# image_templates:
# - "goreleaser/goreleaser:{{ .Tag }}-amd64"
# - "goreleaser/goreleaser:{{ .Tag }}-arm64"
# - name_template: "ghcr.io/goreleaser/goreleaser:{{ .Tag }}"
# image_templates:
# - "ghcr.io/goreleaser/goreleaser:{{ .Tag }}-amd64"
# - "ghcr.io/goreleaser/goreleaser:{{ .Tag }}-arm64"
# - name_template: "goreleaser/goreleaser:latest"
# image_templates:
# - "goreleaser/goreleaser:{{ .Tag }}-amd64"
# - "goreleaser/goreleaser:{{ .Tag }}-arm64"
# - name_template: "ghcr.io/goreleaser/goreleaser:latest"
# image_templates:
# - "ghcr.io/goreleaser/goreleaser:{{ .Tag }}-amd64"
# - "ghcr.io/goreleaser/goreleaser:{{ .Tag }}-arm64"
nfpms:
- id: packages
builds:
- openim-api
- openim-cmdutils
- openim-crontask
- openim-msggateway
- openim-msgtransfer
- openim-push
- openim-rpc-auth
- openim-rpc-conversation
- openim-rpc-friend
- openim-rpc-group
- openim-rpc-msg
- openim-rpc-third
- openim-rpc-user
# Your app's vendor.
vendor: OpenIMSDK
homepage: https://github.com/openimsdk/open-im-server
maintainer: kubbot <https://github.com/kubbot>
description: |-
Auto sync github labels
kubbot && openimbot
license: MIT
formats:
- apk
- deb
- rpm
- termux.deb # Since: v1.11
- archlinux # Since: v1.13
dependencies:
- git
recommends:
- golang
# The lines beneath this are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
# Default: './dist'
dist: ./_output/dist
# .goreleaser.yaml
milestones:
# You can have multiple milestone configs
-
# Repository for the milestone
# Default is extracted from the origin remote URL
repo:
owner: OpenIMSDK
name: Open-IM-Server
# Whether to close the milestone
close: true
# Fail release on errors, such as missing milestone.
fail_on_error: false
# Name of the milestone
#
# Default: '{{ .Tag }}'
name_template: "Current Release"
# publishers:
# - name: "fury.io"
# ids:
# - packages
# dir: "{{ dir .ArtifactPath }}"
# cmd: |
# bash -c '
# if [[ "{{ .Tag }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
# curl -F package=@{{ .ArtifactName }} https://{{ .Env.FURY_TOKEN }}@push.fury.io/{{ .Env.USERNAME }}/
# else
# echo "Skipping deployment: Non-production release detected"
# fi'
checksum:
name_template: "{{ .ProjectName }}_checksums.txt"
algorithm: sha256
release:
prerelease: auto
================================================
FILE: build/images/Dockerfile
================================================
# # 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.
# FROM BASE_IMAGE
# WORKDIR ${SERVER_WORKDIR}
# # Set HTTP proxy
# ARG BINARY_NAME
# COPY BINARY_NAME ./bin/BINARY_NAME
# ENTRYPOINT ["./bin/BINARY_NAME"]
================================================
FILE: build/images/openim-api/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-api ./cmd/openim-api
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-api"]
================================================
FILE: build/images/openim-crontask/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-crontask ./cmd/openim-crontask
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-crontask"]
================================================
FILE: build/images/openim-msggateway/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-msggateway ./cmd/openim-msggateway
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-msggateway"]
================================================
FILE: build/images/openim-msgtransfer/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-msgtransfer ./cmd/openim-msgtransfer
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-msgtransfer"]
================================================
FILE: build/images/openim-push/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-push ./cmd/openim-push
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-push"]
================================================
FILE: build/images/openim-rpc-auth/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-rpc-auth ./cmd/openim-rpc/openim-rpc-auth
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-rpc-auth"]
================================================
FILE: build/images/openim-rpc-conversation/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-rpc-conversation ./cmd/openim-rpc/openim-rpc-conversation
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-rpc-conversation"]
================================================
FILE: build/images/openim-rpc-friend/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-rpc-friend ./cmd/openim-rpc/openim-rpc-friend
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-rpc-friend"]
================================================
FILE: build/images/openim-rpc-group/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-rpc-group ./cmd/openim-rpc/openim-rpc-group
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-rpc-group"]
================================================
FILE: build/images/openim-rpc-msg/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-rpc-msg ./cmd/openim-rpc/openim-rpc-msg
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-rpc-msg"]
================================================
FILE: build/images/openim-rpc-third/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-rpc-third ./cmd/openim-rpc/openim-rpc-third
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-rpc-third"]
================================================
FILE: build/images/openim-rpc-user/Dockerfile
================================================
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod tidy
RUN go build -o _output/openim-rpc-user ./cmd/openim-rpc/openim-rpc-user
# Using Alpine Linux for the final image
FROM alpine:latest
# Install necessary packages, such as bash
RUN apk add --no-cache bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
# COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "_output/openim-rpc-user"]
================================================
FILE: build/images/openim-tools/component/Dockerfile
================================================
# # 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.
# # OpenIM base image: https://github.com/openim-sigs/openim-base-image
# # Set go mod installation source and proxy
# FROM golang:1.20 AS builder
#
# WORKDIR /openim/openim-server
#
# ENV GOPROXY=$GOPROXY
# COPY go.mod go.sum ./
# RUN go mod download
# COPY . .
# RUN make clean
# RUN make build BINS=component
# # FROM ghcr.io/openim-sigs/openim-bash-image:latest
# FROM ghcr.io/openim-sigs/openim-bash-image:latest
# WORKDIR /openim/openim-server
# COPY --from=builder /openim/openim-server/_output/bin/tools /openim/openim-server/_output/bin/tools/
# COPY --from=builder /openim/openim-server/config /openim/openim-server/config
# ENV OPENIM_SERVER_CONFIG_NAME=/openim/openim-server/config
# RUN mv ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/component /usr/bin/component
# ENTRYPOINT ["bash", "-c", "component -c $OPENIM_SERVER_CONFIG_NAME"]
# Use Go 1.22 Alpine as the base image for building the application
FROM golang:1.22-alpine AS builder
# Define the base directory for the application as an environment variable
ENV SERVER_DIR=/openim-server
# Set the working directory inside the container based on the environment variable
WORKDIR $SERVER_DIR
# Set the Go proxy to improve dependency resolution speed
#ENV GOPROXY=https://goproxy.io,direct
# Copy all files from the current directory into the container
COPY . .
RUN go mod download
# Install Mage to use for building the application
RUN go install github.com/magefile/mage@v1.15.0
# ENV BINS=openim-rpc-user
# Optionally build your application if needed
# RUN mage build ${BINS} check-free-memory seq || true
RUN mage build check-free-memory seq || true
# Using Alpine Linux with Go environment for the final image
FROM golang:1.22-alpine
# Install necessary packages, such as bash
RUN apk add bash
# Set the environment and work directory
ENV SERVER_DIR=/openim-server
WORKDIR $SERVER_DIR
# Copy the compiled binaries and mage from the builder image to the final image
COPY --from=builder $SERVER_DIR/_output $SERVER_DIR/_output
COPY --from=builder $SERVER_DIR/config $SERVER_DIR/config
COPY --from=builder /go/bin/mage /usr/local/bin/mage
COPY --from=builder $SERVER_DIR/magefile_windows.go $SERVER_DIR/
COPY --from=builder $SERVER_DIR/magefile_unix.go $SERVER_DIR/
COPY --from=builder $SERVER_DIR/magefile.go $SERVER_DIR/
# COPY --from=builder $SERVER_DIR/start-config.yml $SERVER_DIR/
COPY --from=builder $SERVER_DIR/go.mod $SERVER_DIR/
COPY --from=builder $SERVER_DIR/go.sum $SERVER_DIR/
RUN echo -e "serviceBinaries:\n \n" \
> $SERVER_DIR/start-config.yml && \
echo -e "toolBinaries:\n - check-free-memory\n - seq\n" >> $SERVER_DIR/start-config.yml && \
echo "maxFileDescriptors: 10000" >> $SERVER_DIR/start-config.yml
RUN go get github.com/openimsdk/gomake@v0.0.15-alpha.1
# Set the command to run when the container starts
ENTRYPOINT ["sh", "-c", "mage start && tail -f /dev/null"]
================================================
FILE: cmd/main.go
================================================
package main
import (
"bytes"
"context"
"flag"
"fmt"
"net"
"os"
"os/signal"
"path"
"path/filepath"
"reflect"
"runtime"
"strings"
"sync"
"syscall"
"time"
"github.com/mitchellh/mapstructure"
"github.com/openimsdk/open-im-server/v3/internal/api"
"github.com/openimsdk/open-im-server/v3/internal/msggateway"
"github.com/openimsdk/open-im-server/v3/internal/msgtransfer"
"github.com/openimsdk/open-im-server/v3/internal/push"
"github.com/openimsdk/open-im-server/v3/internal/rpc/auth"
"github.com/openimsdk/open-im-server/v3/internal/rpc/conversation"
"github.com/openimsdk/open-im-server/v3/internal/rpc/group"
"github.com/openimsdk/open-im-server/v3/internal/rpc/msg"
"github.com/openimsdk/open-im-server/v3/internal/rpc/relation"
"github.com/openimsdk/open-im-server/v3/internal/rpc/third"
"github.com/openimsdk/open-im-server/v3/internal/rpc/user"
"github.com/openimsdk/open-im-server/v3/internal/tools/cron"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/discovery"
"github.com/openimsdk/tools/discovery/standalone"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/system/program"
"github.com/openimsdk/tools/utils/datautil"
"github.com/spf13/viper"
"google.golang.org/grpc"
)
func init() {
config.SetStandalone()
prommetrics.RegistryAll()
}
func main() {
var configPath string
flag.StringVar(&configPath, "c", "", "config path")
flag.Parse()
if configPath == "" {
_, _ = fmt.Fprintln(os.Stderr, "config path is empty")
os.Exit(1)
return
}
cmd := newCmds(configPath)
putCmd(cmd, false, auth.Start)
putCmd(cmd, false, conversation.Start)
putCmd(cmd, false, relation.Start)
putCmd(cmd, false, group.Start)
putCmd(cmd, false, msg.Start)
putCmd(cmd, false, third.Start)
putCmd(cmd, false, user.Start)
putCmd(cmd, false, push.Start)
putCmd(cmd, true, msggateway.Start)
putCmd(cmd, true, msgtransfer.Start)
putCmd(cmd, true, api.Start)
putCmd(cmd, true, cron.Start)
ctx := context.Background()
if err := cmd.run(ctx); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "server exit %s", err)
os.Exit(1)
return
}
}
func newCmds(confPath string) *cmds {
return &cmds{confPath: confPath}
}
type cmdName struct {
Name string
Func func(ctx context.Context) error
B
gitextract_q8p9a5l9/
├── .dockerignore
├── .gitattributes
├── .github/
│ ├── .codecov.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.yml
│ │ ├── config.yml
│ │ ├── deployment.yml
│ │ ├── documentation.md
│ │ ├── feature-request.yml
│ │ ├── other.yml
│ │ └── rfc.md
│ ├── sync-release.yml
│ └── workflows/
│ ├── auto-assign-issue.yml
│ ├── auto-invite-comment.yml
│ ├── changelog.yml
│ ├── cla-assistant.yml
│ ├── cleanup-after-milestone-prs-merged.yml
│ ├── codeql-analysis.yml
│ ├── comment-check.yml
│ ├── docker-build-and-release-services-images.yml
│ ├── go-build-test.yml
│ ├── help-comment-issue.yml
│ ├── issue-translator.yml
│ ├── merge-from-milestone.yml
│ ├── publish-docker-image.yml
│ ├── remove-unused-labels.yml
│ ├── reopen-issue.yml
│ ├── update-version-file-on-release.yml
│ └── user-first-interaction.yml
├── .gitignore
├── .golangci.yml
├── CHANGELOG/
│ ├── CHANGELOG-3.8.md
│ └── README.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING-zh_CN.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── README_zh_CN.md
├── assets/
│ ├── README.md
│ ├── colors.md
│ ├── demo/
│ │ └── README.md
│ ├── logo/
│ │ └── LICENSE
│ └── logo-gif/
│ └── LICENSE
├── bootstrap.bat
├── bootstrap.sh
├── build/
│ ├── README.md
│ ├── goreleaser.yaml
│ └── images/
│ ├── Dockerfile
│ ├── openim-api/
│ │ └── Dockerfile
│ ├── openim-crontask/
│ │ └── Dockerfile
│ ├── openim-msggateway/
│ │ └── Dockerfile
│ ├── openim-msgtransfer/
│ │ └── Dockerfile
│ ├── openim-push/
│ │ └── Dockerfile
│ ├── openim-rpc-auth/
│ │ └── Dockerfile
│ ├── openim-rpc-conversation/
│ │ └── Dockerfile
│ ├── openim-rpc-friend/
│ │ └── Dockerfile
│ ├── openim-rpc-group/
│ │ └── Dockerfile
│ ├── openim-rpc-msg/
│ │ └── Dockerfile
│ ├── openim-rpc-third/
│ │ └── Dockerfile
│ ├── openim-rpc-user/
│ │ └── Dockerfile
│ └── openim-tools/
│ └── component/
│ └── Dockerfile
├── cmd/
│ ├── main.go
│ ├── openim-api/
│ │ └── main.go
│ ├── openim-cmdutils/
│ │ └── main.go
│ ├── openim-crontask/
│ │ └── main.go
│ ├── openim-msggateway/
│ │ └── main.go
│ ├── openim-msgtransfer/
│ │ └── main.go
│ ├── openim-push/
│ │ └── main.go
│ └── openim-rpc/
│ ├── openim-rpc-auth/
│ │ └── main.go
│ ├── openim-rpc-conversation/
│ │ └── main.go
│ ├── openim-rpc-friend/
│ │ └── main.go
│ ├── openim-rpc-group/
│ │ └── main.go
│ ├── openim-rpc-msg/
│ │ └── main.go
│ ├── openim-rpc-third/
│ │ └── main.go
│ └── openim-rpc-user/
│ └── main.go
├── config/
│ ├── README.md
│ ├── README_zh_CN.md
│ ├── alertmanager.yml
│ ├── discovery.yml
│ ├── email.tmpl
│ ├── grafana-template/
│ │ └── Demo.json
│ ├── instance-down-rules.yml
│ ├── kafka.yml
│ ├── local-cache.yml
│ ├── log.yml
│ ├── minio.yml
│ ├── mongodb.yml
│ ├── notification.yml
│ ├── openim-api.yml
│ ├── openim-crontask.yml
│ ├── openim-msggateway.yml
│ ├── openim-msgtransfer.yml
│ ├── openim-push.yml
│ ├── openim-rpc-auth.yml
│ ├── openim-rpc-conversation.yml
│ ├── openim-rpc-friend.yml
│ ├── openim-rpc-group.yml
│ ├── openim-rpc-msg.yml
│ ├── openim-rpc-third.yml
│ ├── openim-rpc-user.yml
│ ├── prometheus.yml
│ ├── redis.yml
│ ├── share.yml
│ └── webhooks.yml
├── deployments/
│ ├── Readme.md
│ └── deploy/
│ ├── clusterRole.yml
│ ├── ingress.yml
│ ├── kafka-secret.yml
│ ├── kafka-service.yml
│ ├── kafka-statefulset.yml
│ ├── minio-secret.yml
│ ├── minio-service.yml
│ ├── minio-statefulset.yml
│ ├── mongo-secret.yml
│ ├── mongo-service.yml
│ ├── mongo-statefulset.yml
│ ├── openim-api-deployment.yml
│ ├── openim-api-service.yml
│ ├── openim-config.yml
│ ├── openim-crontask-deployment.yml
│ ├── openim-msggateway-deployment.yml
│ ├── openim-msggateway-service.yml
│ ├── openim-msgtransfer-deployment.yml
│ ├── openim-msgtransfer-service.yml
│ ├── openim-push-deployment.yml
│ ├── openim-push-service.yml
│ ├── openim-rpc-auth-deployment.yml
│ ├── openim-rpc-auth-service.yml
│ ├── openim-rpc-conversation-deployment.yml
│ ├── openim-rpc-conversation-service.yml
│ ├── openim-rpc-friend-deployment.yml
│ ├── openim-rpc-friend-service.yml
│ ├── openim-rpc-group-deployment.yml
│ ├── openim-rpc-group-service.yml
│ ├── openim-rpc-msg-deployment.yml
│ ├── openim-rpc-msg-service.yml
│ ├── openim-rpc-third-deployment.yml
│ ├── openim-rpc-third-service.yml
│ ├── openim-rpc-user-deployment.yml
│ ├── openim-rpc-user-service.yml
│ ├── redis-secret.yml
│ ├── redis-service.yml
│ └── redis-statefulset.yml
├── docker-compose.yml
├── docs/
│ ├── .generated_docs
│ ├── CODEOWNERS
│ ├── README.md
│ ├── contrib/
│ │ ├── README.md
│ │ ├── api.md
│ │ ├── bash-log.md
│ │ ├── cicd-actions.md
│ │ ├── code-conventions.md
│ │ ├── commit.md
│ │ ├── development.md
│ │ ├── directory.md
│ │ ├── environment.md
│ │ ├── error-code.md
│ │ ├── git-workflow.md
│ │ ├── gitcherry-pick.md
│ │ ├── github-workflow.md
│ │ ├── go-code.md
│ │ ├── go-code1.md
│ │ ├── go-doc.md
│ │ ├── images.md
│ │ ├── init-config.md
│ │ ├── install-docker.md
│ │ ├── install-openim-linux-system.md
│ │ ├── kafka.md
│ │ ├── linux-development.md
│ │ ├── local-actions.md
│ │ ├── logging.md
│ │ ├── mac-developer-deployment-guide.md
│ │ ├── offline-deployment.md
│ │ ├── prometheus-grafana.md
│ │ ├── protoc-tools.md
│ │ ├── release.md
│ │ ├── test.md
│ │ ├── util-go.md
│ │ ├── util-makefile.md
│ │ ├── util-scripts.md
│ │ └── version.md
│ ├── contributing/
│ │ ├── CONTRIBUTING-JP.md
│ │ └── CONTRIBUTING-PL.md
│ └── readme/
│ ├── README_cs.md
│ ├── README_da.md
│ ├── README_el.md
│ ├── README_es.md
│ ├── README_fa.md
│ ├── README_fr.md
│ ├── README_hu.md
│ ├── README_ja.md
│ ├── README_ko.md
│ ├── README_tr.md
│ ├── README_uk.md
│ └── README_vi.md
├── go.mod
├── go.sum
├── install.sh
├── internal/
│ ├── api/
│ │ ├── auth.go
│ │ ├── config_manager.go
│ │ ├── conversation.go
│ │ ├── custom_validator.go
│ │ ├── friend.go
│ │ ├── group.go
│ │ ├── init.go
│ │ ├── jssdk/
│ │ │ ├── jssdk.go
│ │ │ ├── sort.go
│ │ │ └── tools.go
│ │ ├── msg.go
│ │ ├── prometheus_discovery.go
│ │ ├── ratelimit.go
│ │ ├── router.go
│ │ ├── third.go
│ │ └── user.go
│ ├── msggateway/
│ │ ├── callback.go
│ │ ├── client.go
│ │ ├── client_conn.go
│ │ ├── compressor.go
│ │ ├── compressor_test.go
│ │ ├── constant.go
│ │ ├── context.go
│ │ ├── encoder.go
│ │ ├── http_error.go
│ │ ├── hub_server.go
│ │ ├── init.go
│ │ ├── message_handler.go
│ │ ├── online.go
│ │ ├── options.go
│ │ ├── subscription.go
│ │ ├── user_map.go
│ │ └── ws_server.go
│ ├── msgtransfer/
│ │ ├── callback.go
│ │ ├── init.go
│ │ ├── online_history_msg_handler.go
│ │ └── online_msg_to_mongo_handler.go
│ ├── push/
│ │ ├── callback.go
│ │ ├── offlinepush/
│ │ │ ├── dummy/
│ │ │ │ └── push.go
│ │ │ ├── fcm/
│ │ │ │ └── push.go
│ │ │ ├── getui/
│ │ │ │ ├── body.go
│ │ │ │ └── push.go
│ │ │ ├── jpush/
│ │ │ │ ├── body/
│ │ │ │ │ ├── audience.go
│ │ │ │ │ ├── message.go
│ │ │ │ │ ├── notification.go
│ │ │ │ │ ├── options.go
│ │ │ │ │ ├── platform.go
│ │ │ │ │ └── pushobj.go
│ │ │ │ └── push.go
│ │ │ ├── offlinepusher.go
│ │ │ └── options/
│ │ │ └── options.go
│ │ ├── offlinepush_handler.go
│ │ ├── onlinepusher.go
│ │ ├── push.go
│ │ └── push_handler.go
│ ├── rpc/
│ │ ├── auth/
│ │ │ └── auth.go
│ │ ├── conversation/
│ │ │ ├── callback.go
│ │ │ ├── conversation.go
│ │ │ ├── db_map.go
│ │ │ ├── notification.go
│ │ │ └── sync.go
│ │ ├── group/
│ │ │ ├── cache.go
│ │ │ ├── callback.go
│ │ │ ├── convert.go
│ │ │ ├── db_map.go
│ │ │ ├── fill.go
│ │ │ ├── group.go
│ │ │ ├── notification.go
│ │ │ ├── statistics.go
│ │ │ └── sync.go
│ │ ├── incrversion/
│ │ │ ├── batch_option.go
│ │ │ └── option.go
│ │ ├── msg/
│ │ │ ├── as_read.go
│ │ │ ├── callback.go
│ │ │ ├── clear.go
│ │ │ ├── delete.go
│ │ │ ├── filter.go
│ │ │ ├── msg_status.go
│ │ │ ├── notification.go
│ │ │ ├── revoke.go
│ │ │ ├── send.go
│ │ │ ├── seq.go
│ │ │ ├── server.go
│ │ │ ├── statistics.go
│ │ │ ├── sync_msg.go
│ │ │ ├── utils.go
│ │ │ └── verify.go
│ │ ├── relation/
│ │ │ ├── black.go
│ │ │ ├── callback.go
│ │ │ ├── friend.go
│ │ │ ├── notification.go
│ │ │ └── sync.go
│ │ ├── third/
│ │ │ ├── log.go
│ │ │ ├── s3.go
│ │ │ ├── third.go
│ │ │ └── tool.go
│ │ └── user/
│ │ ├── callback.go
│ │ ├── config.go
│ │ ├── notification.go
│ │ ├── online.go
│ │ ├── statistics.go
│ │ └── user.go
│ └── tools/
│ └── cron/
│ ├── cron_task.go
│ ├── cron_test.go
│ ├── dist_look.go
│ ├── msg.go
│ ├── s3.go
│ └── user_msg.go
├── magefile.go
├── magefile_unix.go
├── magefile_windows.go
├── pkg/
│ ├── apistruct/
│ │ ├── config_manager.go
│ │ ├── doc.go
│ │ ├── manage.go
│ │ ├── msg.go
│ │ └── public.go
│ ├── authverify/
│ │ ├── doc.go
│ │ └── token.go
│ ├── callbackstruct/
│ │ ├── common.go
│ │ ├── constant.go
│ │ ├── conversation.go
│ │ ├── doc.go
│ │ ├── friend.go
│ │ ├── group.go
│ │ ├── message.go
│ │ ├── msg_gateway.go
│ │ ├── push.go
│ │ ├── revoke.go
│ │ └── user.go
│ ├── common/
│ │ ├── cmd/
│ │ │ ├── api.go
│ │ │ ├── auth.go
│ │ │ ├── conversation.go
│ │ │ ├── cron_task.go
│ │ │ ├── doc.go
│ │ │ ├── friend.go
│ │ │ ├── group.go
│ │ │ ├── msg.go
│ │ │ ├── msg_gateway.go
│ │ │ ├── msg_gateway_test.go
│ │ │ ├── msg_transfer.go
│ │ │ ├── msg_utils.go
│ │ │ ├── push.go
│ │ │ ├── root.go
│ │ │ ├── third.go
│ │ │ └── user.go
│ │ ├── config/
│ │ │ ├── config.go
│ │ │ ├── constant.go
│ │ │ ├── doc.go
│ │ │ ├── env.go
│ │ │ ├── global.go
│ │ │ ├── load_config.go
│ │ │ ├── load_config_test.go
│ │ │ └── parse.go
│ │ ├── convert/
│ │ │ ├── auth.go
│ │ │ ├── black.go
│ │ │ ├── conversation.go
│ │ │ ├── doc.go
│ │ │ ├── friend.go
│ │ │ ├── group.go
│ │ │ ├── msg.go
│ │ │ ├── user.go
│ │ │ └── user_test.go
│ │ ├── discovery/
│ │ │ ├── direct/
│ │ │ │ ├── direct_resolver.go
│ │ │ │ ├── directconn.go
│ │ │ │ └── doc.go
│ │ │ ├── discoveryregister.go
│ │ │ ├── discoveryregister_test.go
│ │ │ ├── doc.go
│ │ │ ├── etcd/
│ │ │ │ ├── config_manager.go
│ │ │ │ └── const.go
│ │ │ └── kubernetes/
│ │ │ ├── doc.go
│ │ │ └── kubernetes.go
│ │ ├── ginprometheus/
│ │ │ ├── doc.go
│ │ │ └── ginprometheus.go
│ │ ├── prommetrics/
│ │ │ ├── api.go
│ │ │ ├── grpc_auth.go
│ │ │ ├── grpc_msg.go
│ │ │ ├── grpc_msggateway.go
│ │ │ ├── grpc_push.go
│ │ │ ├── grpc_user.go
│ │ │ ├── prommetrics.go
│ │ │ ├── prommetrics_test.go
│ │ │ ├── rpc.go
│ │ │ └── transfer.go
│ │ ├── servererrs/
│ │ │ ├── code.go
│ │ │ ├── doc.go
│ │ │ ├── predefine.go
│ │ │ └── relation.go
│ │ ├── startrpc/
│ │ │ ├── circuitbreaker.go
│ │ │ ├── mw.go
│ │ │ ├── ratelimit.go
│ │ │ ├── start.go
│ │ │ └── tools.go
│ │ ├── storage/
│ │ │ ├── cache/
│ │ │ │ ├── batch_handler.go
│ │ │ │ ├── black.go
│ │ │ │ ├── cachekey/
│ │ │ │ │ ├── black.go
│ │ │ │ │ ├── client_config.go
│ │ │ │ │ ├── conversation.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── friend.go
│ │ │ │ │ ├── group.go
│ │ │ │ │ ├── msg.go
│ │ │ │ │ ├── online.go
│ │ │ │ │ ├── s3.go
│ │ │ │ │ ├── seq.go
│ │ │ │ │ ├── third.go
│ │ │ │ │ ├── token.go
│ │ │ │ │ └── user.go
│ │ │ │ ├── client_config.go
│ │ │ │ ├── conversation.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── friend.go
│ │ │ │ ├── group.go
│ │ │ │ ├── mcache/
│ │ │ │ │ ├── minio.go
│ │ │ │ │ ├── msg_cache.go
│ │ │ │ │ ├── online.go
│ │ │ │ │ ├── seq_conversation.go
│ │ │ │ │ ├── third.go
│ │ │ │ │ ├── token.go
│ │ │ │ │ └── tools.go
│ │ │ │ ├── msg.go
│ │ │ │ ├── online.go
│ │ │ │ ├── redis/
│ │ │ │ │ ├── batch.go
│ │ │ │ │ ├── batch_handler.go
│ │ │ │ │ ├── batch_test.go
│ │ │ │ │ ├── black.go
│ │ │ │ │ ├── client_config.go
│ │ │ │ │ ├── conversation.go
│ │ │ │ │ ├── friend.go
│ │ │ │ │ ├── group.go
│ │ │ │ │ ├── lua_script.go
│ │ │ │ │ ├── lua_script_test.go
│ │ │ │ │ ├── minio.go
│ │ │ │ │ ├── msg.go
│ │ │ │ │ ├── online.go
│ │ │ │ │ ├── online_test.go
│ │ │ │ │ ├── redis_shard_manager.go
│ │ │ │ │ ├── s3.go
│ │ │ │ │ ├── seq_conversation.go
│ │ │ │ │ ├── seq_conversation_test.go
│ │ │ │ │ ├── seq_user.go
│ │ │ │ │ ├── seq_user_test.go
│ │ │ │ │ ├── third.go
│ │ │ │ │ ├── token.go
│ │ │ │ │ └── user.go
│ │ │ │ ├── s3.go
│ │ │ │ ├── seq_conversation.go
│ │ │ │ ├── seq_user.go
│ │ │ │ ├── third.go
│ │ │ │ ├── token.go
│ │ │ │ └── user.go
│ │ │ ├── common/
│ │ │ │ └── types.go
│ │ │ ├── controller/
│ │ │ │ ├── auth.go
│ │ │ │ ├── black.go
│ │ │ │ ├── client_config.go
│ │ │ │ ├── conversation.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── friend.go
│ │ │ │ ├── group.go
│ │ │ │ ├── msg.go
│ │ │ │ ├── msg_transfer.go
│ │ │ │ ├── push.go
│ │ │ │ ├── s3.go
│ │ │ │ ├── third.go
│ │ │ │ └── user.go
│ │ │ ├── database/
│ │ │ │ ├── black.go
│ │ │ │ ├── cache.go
│ │ │ │ ├── client_config.go
│ │ │ │ ├── conversation.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── friend.go
│ │ │ │ ├── friend_request.go
│ │ │ │ ├── group.go
│ │ │ │ ├── group_member.go
│ │ │ │ ├── group_request.go
│ │ │ │ ├── log.go
│ │ │ │ ├── mgo/
│ │ │ │ │ ├── black.go
│ │ │ │ │ ├── cache.go
│ │ │ │ │ ├── cache_test.go
│ │ │ │ │ ├── client_config.go
│ │ │ │ │ ├── conversation.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── friend.go
│ │ │ │ │ ├── friend_request.go
│ │ │ │ │ ├── group.go
│ │ │ │ │ ├── group_member.go
│ │ │ │ │ ├── group_request.go
│ │ │ │ │ ├── helpers.go
│ │ │ │ │ ├── log.go
│ │ │ │ │ ├── msg.go
│ │ │ │ │ ├── msg_test.go
│ │ │ │ │ ├── object.go
│ │ │ │ │ ├── seq_conversation.go
│ │ │ │ │ ├── seq_conversation_test.go
│ │ │ │ │ ├── seq_user.go
│ │ │ │ │ ├── user.go
│ │ │ │ │ ├── version_log.go
│ │ │ │ │ └── version_test.go
│ │ │ │ ├── msg.go
│ │ │ │ ├── name.go
│ │ │ │ ├── object.go
│ │ │ │ ├── seq.go
│ │ │ │ ├── seq_user.go
│ │ │ │ ├── user.go
│ │ │ │ └── version_log.go
│ │ │ ├── kafka/
│ │ │ │ ├── config.go
│ │ │ │ ├── consumer_group.go
│ │ │ │ ├── producer.go
│ │ │ │ ├── sarama.go
│ │ │ │ ├── tls.go
│ │ │ │ ├── util.go
│ │ │ │ └── verify.go
│ │ │ ├── model/
│ │ │ │ ├── application.go
│ │ │ │ ├── black.go
│ │ │ │ ├── cache.go
│ │ │ │ ├── client_config.go
│ │ │ │ ├── conversation.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── friend.go
│ │ │ │ ├── friend_request.go
│ │ │ │ ├── group.go
│ │ │ │ ├── group_member.go
│ │ │ │ ├── group_request.go
│ │ │ │ ├── log.go
│ │ │ │ ├── msg.go
│ │ │ │ ├── object.go
│ │ │ │ ├── seq.go
│ │ │ │ ├── seq_user.go
│ │ │ │ ├── subscribe.go
│ │ │ │ ├── user.go
│ │ │ │ └── version_log.go
│ │ │ └── versionctx/
│ │ │ ├── rpc.go
│ │ │ └── version.go
│ │ └── webhook/
│ │ ├── condition.go
│ │ ├── doc.go
│ │ ├── http_client.go
│ │ └── http_client_test.go
│ ├── dbbuild/
│ │ ├── builder.go
│ │ ├── microservices.go
│ │ └── standalone.go
│ ├── localcache/
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ ├── doc.go
│ │ ├── init.go
│ │ ├── link/
│ │ │ ├── doc.go
│ │ │ ├── link.go
│ │ │ └── link_test.go
│ │ ├── lru/
│ │ │ ├── doc.go
│ │ │ ├── lru.go
│ │ │ ├── lru_expiration.go
│ │ │ ├── lru_lazy.go
│ │ │ ├── lru_lazy_test.go
│ │ │ └── lru_slot.go
│ │ ├── option.go
│ │ └── tool.go
│ ├── mqbuild/
│ │ └── builder.go
│ ├── msgprocessor/
│ │ ├── conversation.go
│ │ ├── doc.go
│ │ └── options.go
│ ├── notification/
│ │ ├── common_user/
│ │ │ └── common.go
│ │ ├── grouphash/
│ │ │ └── grouphash.go
│ │ └── msg.go
│ ├── rpccache/
│ │ ├── auth.go
│ │ ├── common.go
│ │ ├── conversation.go
│ │ ├── doc.go
│ │ ├── friend.go
│ │ ├── group.go
│ │ ├── online.go
│ │ ├── subscriber.go
│ │ └── user.go
│ ├── rpcli/
│ │ ├── auth.go
│ │ ├── conversation.go
│ │ ├── group.go
│ │ ├── msg.go
│ │ ├── msggateway.go
│ │ ├── push.go
│ │ ├── relation.go
│ │ ├── rtc.go
│ │ ├── third.go
│ │ ├── tool.go
│ │ └── user.go
│ ├── statistics/
│ │ ├── doc.go
│ │ └── statistics.go
│ ├── tools/
│ │ └── batcher/
│ │ ├── batcher.go
│ │ └── batcher_test.go
│ └── util/
│ ├── conversationutil/
│ │ ├── conversationutil.go
│ │ └── doc.go
│ ├── hashutil/
│ │ └── id.go
│ └── useronline/
│ └── split.go
├── scripts/
│ └── template/
│ ├── LICENSE
│ ├── LICENSE_TEMPLATES
│ ├── boilerplate.txt
│ ├── footer.md.tmpl
│ ├── head.md.tmpl
│ └── project_README.md
├── start-config.yml
├── test/
│ ├── e2e/
│ │ ├── README.md
│ │ ├── api/
│ │ │ ├── token/
│ │ │ │ └── token.go
│ │ │ └── user/
│ │ │ ├── curd.go
│ │ │ └── user.go
│ │ ├── conformance/
│ │ │ └── .keep
│ │ ├── e2e.go
│ │ ├── e2e_test.go
│ │ ├── framework/
│ │ │ ├── config/
│ │ │ │ ├── config.go
│ │ │ │ └── config_test.go
│ │ │ ├── ginkgowrapper/
│ │ │ │ ├── .keep
│ │ │ │ ├── ginkgowrapper.go
│ │ │ │ └── ginkgowrapper_test.go
│ │ │ └── helpers/
│ │ │ ├── .keep
│ │ │ └── chat/
│ │ │ └── chat.go
│ │ ├── page/
│ │ │ ├── chat_page.go
│ │ │ └── login_page.go
│ │ ├── performance/
│ │ │ └── .keep
│ │ ├── rpc/
│ │ │ ├── auth/
│ │ │ │ └── .keep
│ │ │ ├── conversation/
│ │ │ │ └── .keep
│ │ │ ├── friend/
│ │ │ │ └── .keep
│ │ │ ├── group/
│ │ │ │ └── .keep
│ │ │ └── message/
│ │ │ └── .keep
│ │ ├── scalability/
│ │ │ └── .keep
│ │ ├── upgrade/
│ │ │ └── .keep
│ │ └── web/
│ │ └── Readme.md
│ ├── jwt/
│ │ └── main.go
│ ├── readme
│ ├── stress-test/
│ │ ├── README.md
│ │ └── main.go
│ ├── stress-test-v2/
│ │ ├── README.md
│ │ └── main.go
│ ├── testdata/
│ │ ├── README.md
│ │ ├── db/
│ │ │ ├── messages.json
│ │ │ └── users.json
│ │ ├── requests/
│ │ │ ├── login.json
│ │ │ ├── register.json
│ │ │ └── send-message.json
│ │ └── responses/
│ │ ├── login.json
│ │ ├── register.json
│ │ └── sendMessage.json
│ └── webhook/
│ └── msgmodify/
│ └── main.go
├── tools/
│ ├── README.md
│ ├── changelog/
│ │ └── changelog.go
│ ├── check-component/
│ │ └── main.go
│ ├── check-free-memory/
│ │ └── main.go
│ ├── imctl/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ └── main.go
│ ├── infra/
│ │ └── main.go
│ ├── ncpu/
│ │ ├── README.md
│ │ ├── main.go
│ │ └── main_test.go
│ ├── s3/
│ │ ├── README.md
│ │ ├── internal/
│ │ │ └── conversion.go
│ │ └── main.go
│ ├── seq/
│ │ ├── internal/
│ │ │ └── seq.go
│ │ └── main.go
│ ├── stress-test-v2/
│ │ └── main.go
│ ├── url2im/
│ │ ├── main.go
│ │ └── pkg/
│ │ ├── api.go
│ │ ├── buffer.go
│ │ ├── config.go
│ │ ├── http.go
│ │ ├── manage.go
│ │ ├── md5.go
│ │ └── progress.go
│ ├── versionchecker/
│ │ └── main.go
│ └── yamlfmt/
│ ├── main.go
│ └── main_test.go
└── version/
├── version
└── version.go
Showing preview only (334K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3403 symbols across 411 files)
FILE: cmd/main.go
function init (line 45) | func init() {
function main (line 50) | func main() {
function newCmds (line 80) | func newCmds(confPath string) *cmds {
type cmdName (line 84) | type cmdName struct
type cmds (line 89) | type cmds struct
method getTypePath (line 96) | func (x *cmds) getTypePath(typ reflect.Type) string {
method initDiscovery (line 100) | func (x *cmds) initDiscovery() {
method initAllConfig (line 117) | func (x *cmds) initAllConfig() error {
method parseConf (line 159) | func (x *cmds) parseConf(conf any) error {
method add (line 197) | func (x *cmds) add(name string, block bool, fn func(ctx context.Contex...
method initLog (line 201) | func (x *cmds) initLog() error {
method run (line 222) | func (x *cmds) run(ctx context.Context) error {
function putCmd (line 332) | func putCmd[C any](cmd *cmds, block bool, fn func(ctx context.Context, c...
type cmdManger (line 346) | type cmdManger struct
method Start (line 353) | func (x *cmdManger) Start(name string) {
method Shutdown (line 369) | func (x *cmdManger) Shutdown(name string) {
method Wait (line 387) | func (x *cmdManger) Wait() <-chan struct{} {
method Running (line 398) | func (x *cmdManger) Running() []string {
FILE: cmd/openim-api/main.go
function main (line 23) | func main() {
FILE: cmd/openim-cmdutils/main.go
function main (line 22) | func main() {
FILE: cmd/openim-crontask/main.go
function main (line 22) | func main() {
FILE: cmd/openim-msggateway/main.go
function main (line 22) | func main() {
FILE: cmd/openim-msgtransfer/main.go
function main (line 22) | func main() {
FILE: cmd/openim-push/main.go
function main (line 22) | func main() {
FILE: cmd/openim-rpc/openim-rpc-auth/main.go
function main (line 22) | func main() {
FILE: cmd/openim-rpc/openim-rpc-conversation/main.go
function main (line 22) | func main() {
FILE: cmd/openim-rpc/openim-rpc-friend/main.go
function main (line 22) | func main() {
FILE: cmd/openim-rpc/openim-rpc-group/main.go
function main (line 22) | func main() {
FILE: cmd/openim-rpc/openim-rpc-msg/main.go
function main (line 22) | func main() {
FILE: cmd/openim-rpc/openim-rpc-third/main.go
function main (line 22) | func main() {
FILE: cmd/openim-rpc/openim-rpc-user/main.go
function main (line 22) | func main() {
FILE: internal/api/auth.go
type AuthApi (line 23) | type AuthApi struct
method GetAdminToken (line 31) | func (o *AuthApi) GetAdminToken(c *gin.Context) {
method GetUserToken (line 35) | func (o *AuthApi) GetUserToken(c *gin.Context) {
method ParseToken (line 39) | func (o *AuthApi) ParseToken(c *gin.Context) {
method ForceLogout (line 43) | func (o *AuthApi) ForceLogout(c *gin.Context) {
function NewAuthApi (line 27) | func NewAuthApi(client auth.AuthClient) AuthApi {
FILE: internal/api/config_manager.go
constant waitHttp (line 25) | waitHttp = time.Millisecond * 200
type ConfigManager (line 28) | type ConfigManager struct
method CheckAdmin (line 46) | func (cm *ConfigManager) CheckAdmin(c *gin.Context) {
method GetConfig (line 53) | func (cm *ConfigManager) GetConfig(c *gin.Context) {
method GetConfigList (line 72) | func (cm *ConfigManager) GetConfigList(c *gin.Context) {
method SetConfig (line 81) | func (cm *ConfigManager) SetConfig(c *gin.Context) {
method SetConfigs (line 148) | func (cm *ConfigManager) SetConfigs(c *gin.Context) {
method ResetConfig (line 273) | func (cm *ConfigManager) ResetConfig(c *gin.Context) {
method resetConfig (line 282) | func (cm *ConfigManager) resetConfig(c *gin.Context, checkChange bool,...
method Restart (line 344) | func (cm *ConfigManager) Restart(c *gin.Context) {
method restart (line 349) | func (cm *ConfigManager) restart(c *gin.Context) {
method SetEnableConfigManager (line 358) | func (cm *ConfigManager) SetEnableConfigManager(c *gin.Context) {
method GetEnableConfigManager (line 398) | func (cm *ConfigManager) GetEnableConfigManager(c *gin.Context) {
function NewConfigManager (line 36) | func NewConfigManager(IMAdminUserID []string, cfg *config.AllConfig, cli...
function compareAndOp (line 234) | func compareAndOp[T any](c *gin.Context, old any, req *apistruct.SetConf...
function compareAndSave (line 252) | func compareAndSave[T any](c *gin.Context, old any, req *apistruct.SetCo...
FILE: internal/api/conversation.go
type ConversationApi (line 24) | type ConversationApi struct
method GetAllConversations (line 32) | func (o *ConversationApi) GetAllConversations(c *gin.Context) {
method GetSortedConversationList (line 36) | func (o *ConversationApi) GetSortedConversationList(c *gin.Context) {
method GetConversation (line 40) | func (o *ConversationApi) GetConversation(c *gin.Context) {
method GetConversations (line 44) | func (o *ConversationApi) GetConversations(c *gin.Context) {
method SetConversations (line 48) | func (o *ConversationApi) SetConversations(c *gin.Context) {
method GetFullOwnerConversationIDs (line 56) | func (o *ConversationApi) GetFullOwnerConversationIDs(c *gin.Context) {
method GetIncrementalConversation (line 60) | func (o *ConversationApi) GetIncrementalConversation(c *gin.Context) {
method GetOwnerConversation (line 64) | func (o *ConversationApi) GetOwnerConversation(c *gin.Context) {
method GetNotNotifyConversationIDs (line 68) | func (o *ConversationApi) GetNotNotifyConversationIDs(c *gin.Context) {
method GetPinnedConversationIDs (line 72) | func (o *ConversationApi) GetPinnedConversationIDs(c *gin.Context) {
method UpdateConversationsByUser (line 76) | func (o *ConversationApi) UpdateConversationsByUser(c *gin.Context) {
method DeleteConversations (line 80) | func (o *ConversationApi) DeleteConversations(c *gin.Context) {
function NewConversationApi (line 28) | func NewConversationApi(client conversation.ConversationClient) Conversa...
FILE: internal/api/custom_validator.go
function RequiredIf (line 23) | func RequiredIf(fl validator.FieldLevel) bool {
FILE: internal/api/friend.go
type FriendApi (line 24) | type FriendApi struct
method ApplyToAddFriend (line 32) | func (o *FriendApi) ApplyToAddFriend(c *gin.Context) {
method RespondFriendApply (line 36) | func (o *FriendApi) RespondFriendApply(c *gin.Context) {
method DeleteFriend (line 40) | func (o *FriendApi) DeleteFriend(c *gin.Context) {
method GetFriendApplyList (line 44) | func (o *FriendApi) GetFriendApplyList(c *gin.Context) {
method GetDesignatedFriendsApply (line 48) | func (o *FriendApi) GetDesignatedFriendsApply(c *gin.Context) {
method GetSelfApplyList (line 52) | func (o *FriendApi) GetSelfApplyList(c *gin.Context) {
method GetFriendList (line 56) | func (o *FriendApi) GetFriendList(c *gin.Context) {
method GetDesignatedFriends (line 60) | func (o *FriendApi) GetDesignatedFriends(c *gin.Context) {
method SetFriendRemark (line 64) | func (o *FriendApi) SetFriendRemark(c *gin.Context) {
method AddBlack (line 68) | func (o *FriendApi) AddBlack(c *gin.Context) {
method GetPaginationBlacks (line 72) | func (o *FriendApi) GetPaginationBlacks(c *gin.Context) {
method GetSpecifiedBlacks (line 76) | func (o *FriendApi) GetSpecifiedBlacks(c *gin.Context) {
method RemoveBlack (line 80) | func (o *FriendApi) RemoveBlack(c *gin.Context) {
method ImportFriends (line 84) | func (o *FriendApi) ImportFriends(c *gin.Context) {
method IsFriend (line 88) | func (o *FriendApi) IsFriend(c *gin.Context) {
method GetFriendIDs (line 92) | func (o *FriendApi) GetFriendIDs(c *gin.Context) {
method GetSpecifiedFriendsInfo (line 96) | func (o *FriendApi) GetSpecifiedFriendsInfo(c *gin.Context) {
method UpdateFriends (line 100) | func (o *FriendApi) UpdateFriends(c *gin.Context) {
method GetIncrementalFriends (line 104) | func (o *FriendApi) GetIncrementalFriends(c *gin.Context) {
method GetIncrementalBlacks (line 110) | func (o *FriendApi) GetIncrementalBlacks(c *gin.Context) {
method GetFullFriendUserIDs (line 114) | func (o *FriendApi) GetFullFriendUserIDs(c *gin.Context) {
method GetSelfUnhandledApplyCount (line 118) | func (o *FriendApi) GetSelfUnhandledApplyCount(c *gin.Context) {
function NewFriendApi (line 28) | func NewFriendApi(client relation.FriendClient) FriendApi {
FILE: internal/api/group.go
type GroupApi (line 23) | type GroupApi struct
method CreateGroup (line 31) | func (o *GroupApi) CreateGroup(c *gin.Context) {
method SetGroupInfo (line 35) | func (o *GroupApi) SetGroupInfo(c *gin.Context) {
method SetGroupInfoEx (line 39) | func (o *GroupApi) SetGroupInfoEx(c *gin.Context) {
method JoinGroup (line 43) | func (o *GroupApi) JoinGroup(c *gin.Context) {
method QuitGroup (line 47) | func (o *GroupApi) QuitGroup(c *gin.Context) {
method ApplicationGroupResponse (line 51) | func (o *GroupApi) ApplicationGroupResponse(c *gin.Context) {
method TransferGroupOwner (line 55) | func (o *GroupApi) TransferGroupOwner(c *gin.Context) {
method GetRecvGroupApplicationList (line 59) | func (o *GroupApi) GetRecvGroupApplicationList(c *gin.Context) {
method GetUserReqGroupApplicationList (line 63) | func (o *GroupApi) GetUserReqGroupApplicationList(c *gin.Context) {
method GetGroupUsersReqApplicationList (line 67) | func (o *GroupApi) GetGroupUsersReqApplicationList(c *gin.Context) {
method GetSpecifiedUserGroupRequestInfo (line 71) | func (o *GroupApi) GetSpecifiedUserGroupRequestInfo(c *gin.Context) {
method GetGroupsInfo (line 75) | func (o *GroupApi) GetGroupsInfo(c *gin.Context) {
method KickGroupMember (line 80) | func (o *GroupApi) KickGroupMember(c *gin.Context) {
method GetGroupMembersInfo (line 84) | func (o *GroupApi) GetGroupMembersInfo(c *gin.Context) {
method GetGroupMemberList (line 89) | func (o *GroupApi) GetGroupMemberList(c *gin.Context) {
method InviteUserToGroup (line 93) | func (o *GroupApi) InviteUserToGroup(c *gin.Context) {
method GetJoinedGroupList (line 97) | func (o *GroupApi) GetJoinedGroupList(c *gin.Context) {
method DismissGroup (line 101) | func (o *GroupApi) DismissGroup(c *gin.Context) {
method MuteGroupMember (line 105) | func (o *GroupApi) MuteGroupMember(c *gin.Context) {
method CancelMuteGroupMember (line 109) | func (o *GroupApi) CancelMuteGroupMember(c *gin.Context) {
method MuteGroup (line 113) | func (o *GroupApi) MuteGroup(c *gin.Context) {
method CancelMuteGroup (line 117) | func (o *GroupApi) CancelMuteGroup(c *gin.Context) {
method SetGroupMemberInfo (line 121) | func (o *GroupApi) SetGroupMemberInfo(c *gin.Context) {
method GetGroupAbstractInfo (line 125) | func (o *GroupApi) GetGroupAbstractInfo(c *gin.Context) {
method GroupCreateCount (line 137) | func (o *GroupApi) GroupCreateCount(c *gin.Context) {
method GetGroups (line 141) | func (o *GroupApi) GetGroups(c *gin.Context) {
method GetGroupMemberUserIDs (line 145) | func (o *GroupApi) GetGroupMemberUserIDs(c *gin.Context) {
method GetIncrementalJoinGroup (line 149) | func (o *GroupApi) GetIncrementalJoinGroup(c *gin.Context) {
method GetIncrementalGroupMember (line 153) | func (o *GroupApi) GetIncrementalGroupMember(c *gin.Context) {
method GetIncrementalGroupMemberBatch (line 157) | func (o *GroupApi) GetIncrementalGroupMemberBatch(c *gin.Context) {
method GetFullGroupMemberUserIDs (line 161) | func (o *GroupApi) GetFullGroupMemberUserIDs(c *gin.Context) {
method GetFullJoinGroupIDs (line 165) | func (o *GroupApi) GetFullJoinGroupIDs(c *gin.Context) {
method GetGroupApplicationUnhandledCount (line 169) | func (o *GroupApi) GetGroupApplicationUnhandledCount(c *gin.Context) {
function NewGroupApi (line 27) | func NewGroupApi(client group.GroupClient) GroupApi {
FILE: internal/api/init.go
type Config (line 35) | type Config struct
function Start (line 42) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/api/jssdk/jssdk.go
constant maxGetActiveConversation (line 23) | maxGetActiveConversation = 500
constant defaultGetActiveConversation (line 24) | defaultGetActiveConversation = 100
function NewJSSdkApi (line 27) | func NewJSSdkApi(userClient *rpcli.UserClient, relationClient *rpcli.Rel...
type JSSdk (line 38) | type JSSdk struct
method GetActiveConversations (line 46) | func (x *JSSdk) GetActiveConversations(c *gin.Context) {
method GetConversations (line 50) | func (x *JSSdk) GetConversations(c *gin.Context) {
method fillConversations (line 54) | func (x *JSSdk) fillConversations(ctx context.Context, conversations [...
method getActiveConversations (line 104) | func (x *JSSdk) getActiveConversations(ctx context.Context, req *jssdk...
method getConversations (line 191) | func (x *JSSdk) getConversations(ctx context.Context, req *jssdk.GetCo...
method checkMessagesAndGetLastMessage (line 258) | func (x *JSSdk) checkMessagesAndGetLastMessage(ctx context.Context, us...
FILE: internal/api/jssdk/sort.go
type sortActiveConversations (line 5) | type sortActiveConversations struct
method Top (line 10) | func (s sortActiveConversations) Top(limit int) []*msg.ActiveConversat...
method Len (line 17) | func (s sortActiveConversations) Len() int {
method Less (line 21) | func (s sortActiveConversations) Less(i, j int) bool {
method Swap (line 31) | func (s sortActiveConversations) Swap(i, j int) {
FILE: internal/api/jssdk/tools.go
function field (line 16) | func field[A, B, C any](ctx context.Context, fn func(ctx context.Context...
function call (line 25) | func call[A, B any](c *gin.Context, fn func(ctx context.Context, req *A)...
FILE: internal/api/msg.go
function getMsgDataDescriptor (line 51) | func getMsgDataDescriptor() []protoreflect.FieldDescriptor {
type MessageApi (line 79) | type MessageApi struct
method SetOptions (line 90) | func (*MessageApi) SetOptions(options map[string]bool, value bool) {
method newUserSendMsgReq (line 97) | func (m *MessageApi) newUserSendMsgReq(_ *gin.Context, params *apistru...
method GetSeq (line 154) | func (m *MessageApi) GetSeq(c *gin.Context) {
method PullMsgBySeqs (line 158) | func (m *MessageApi) PullMsgBySeqs(c *gin.Context) {
method RevokeMsg (line 162) | func (m *MessageApi) RevokeMsg(c *gin.Context) {
method MarkMsgsAsRead (line 166) | func (m *MessageApi) MarkMsgsAsRead(c *gin.Context) {
method MarkConversationAsRead (line 170) | func (m *MessageApi) MarkConversationAsRead(c *gin.Context) {
method GetConversationsHasReadAndMaxSeq (line 174) | func (m *MessageApi) GetConversationsHasReadAndMaxSeq(c *gin.Context) {
method SetConversationHasReadSeq (line 178) | func (m *MessageApi) SetConversationHasReadSeq(c *gin.Context) {
method ClearConversationsMsg (line 182) | func (m *MessageApi) ClearConversationsMsg(c *gin.Context) {
method UserClearAllMsg (line 186) | func (m *MessageApi) UserClearAllMsg(c *gin.Context) {
method DeleteMsgs (line 190) | func (m *MessageApi) DeleteMsgs(c *gin.Context) {
method DeleteMsgPhysicalBySeq (line 194) | func (m *MessageApi) DeleteMsgPhysicalBySeq(c *gin.Context) {
method DeleteMsgPhysical (line 198) | func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) {
method getSendMsgReq (line 202) | func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendM...
method getModifyFields (line 243) | func (m *MessageApi) getModifyFields(req, respModify *sdkws.MsgData) m...
method ginRespSendMsg (line 270) | func (m *MessageApi) ginRespSendMsg(c *gin.Context, req *msg.SendMsgRe...
method SendMessage (line 280) | func (m *MessageApi) SendMessage(c *gin.Context) {
method SendBusinessNotification (line 335) | func (m *MessageApi) SendBusinessNotification(c *gin.Context) {
method BatchSendMsg (line 401) | func (m *MessageApi) BatchSendMsg(c *gin.Context) {
method SendSimpleMessage (line 458) | func (m *MessageApi) SendSimpleMessage(c *gin.Context) {
method CheckMsgIsSendSuccess (line 553) | func (m *MessageApi) CheckMsgIsSendSuccess(c *gin.Context) {
method GetUsersOnlineStatus (line 557) | func (m *MessageApi) GetUsersOnlineStatus(c *gin.Context) {
method GetActiveUser (line 561) | func (m *MessageApi) GetActiveUser(c *gin.Context) {
method GetActiveGroup (line 565) | func (m *MessageApi) GetActiveGroup(c *gin.Context) {
method SearchMsg (line 569) | func (m *MessageApi) SearchMsg(c *gin.Context) {
method GetServerTime (line 573) | func (m *MessageApi) GetServerTime(c *gin.Context) {
function NewMessageApi (line 86) | func NewMessageApi(client msg.MsgClient, userClient *rpcli.UserClient, i...
FILE: internal/api/prometheus_discovery.go
type PrometheusDiscoveryApi (line 15) | type PrometheusDiscoveryApi struct
method discovery (line 28) | func (p *PrometheusDiscoveryApi) discovery(c *gin.Context, key string) {
method Api (line 57) | func (p *PrometheusDiscoveryApi) Api(c *gin.Context) {
method User (line 61) | func (p *PrometheusDiscoveryApi) User(c *gin.Context) {
method Group (line 65) | func (p *PrometheusDiscoveryApi) Group(c *gin.Context) {
method Msg (line 69) | func (p *PrometheusDiscoveryApi) Msg(c *gin.Context) {
method Friend (line 73) | func (p *PrometheusDiscoveryApi) Friend(c *gin.Context) {
method Conversation (line 77) | func (p *PrometheusDiscoveryApi) Conversation(c *gin.Context) {
method Third (line 81) | func (p *PrometheusDiscoveryApi) Third(c *gin.Context) {
method Auth (line 85) | func (p *PrometheusDiscoveryApi) Auth(c *gin.Context) {
method Push (line 89) | func (p *PrometheusDiscoveryApi) Push(c *gin.Context) {
method MessageGateway (line 93) | func (p *PrometheusDiscoveryApi) MessageGateway(c *gin.Context) {
method MessageTransfer (line 97) | func (p *PrometheusDiscoveryApi) MessageTransfer(c *gin.Context) {
function NewPrometheusDiscoveryApi (line 20) | func NewPrometheusDiscoveryApi(config *Config, client discovery.SvcDisco...
FILE: internal/api/ratelimit.go
type RateLimiter (line 19) | type RateLimiter struct
function RateLimitMiddleware (line 26) | func RateLimitMiddleware(config *RateLimiter) gin.HandlerFunc {
function calculateBBRRetryAfter (line 68) | func calculateBBRRetryAfter(status bbr.Stat) string {
FILE: internal/api/router.go
constant NoCompression (line 36) | NoCompression = -1
constant DefaultCompression (line 37) | DefaultCompression = 0
constant BestCompression (line 38) | BestCompression = 1
constant BestSpeed (line 39) | BestSpeed = 2
function prommetricsGin (line 42) | func prommetricsGin() gin.HandlerFunc {
function newGinRouter (line 57) | func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegi...
function GinParseToken (line 347) | func GinParseToken(authClient *rpcli.AuthClient) gin.HandlerFunc {
function setGinIsAdmin (line 378) | func setGinIsAdmin(imAdminUserID []string) gin.HandlerFunc {
FILE: internal/api/third.go
type ThirdApi (line 33) | type ThirdApi struct
method FcmUpdateToken (line 42) | func (o *ThirdApi) FcmUpdateToken(c *gin.Context) {
method SetAppBadge (line 46) | func (o *ThirdApi) SetAppBadge(c *gin.Context) {
method PartLimit (line 81) | func (o *ThirdApi) PartLimit(c *gin.Context) {
method PartSize (line 85) | func (o *ThirdApi) PartSize(c *gin.Context) {
method InitiateMultipartUpload (line 89) | func (o *ThirdApi) InitiateMultipartUpload(c *gin.Context) {
method AuthSign (line 96) | func (o *ThirdApi) AuthSign(c *gin.Context) {
method CompleteMultipartUpload (line 100) | func (o *ThirdApi) CompleteMultipartUpload(c *gin.Context) {
method AccessURL (line 107) | func (o *ThirdApi) AccessURL(c *gin.Context) {
method InitiateFormData (line 111) | func (o *ThirdApi) InitiateFormData(c *gin.Context) {
method CompleteFormData (line 115) | func (o *ThirdApi) CompleteFormData(c *gin.Context) {
method ObjectRedirect (line 122) | func (o *ThirdApi) ObjectRedirect(c *gin.Context) {
method UploadLogs (line 160) | func (o *ThirdApi) UploadLogs(c *gin.Context) {
method DeleteLogs (line 164) | func (o *ThirdApi) DeleteLogs(c *gin.Context) {
method SearchLogs (line 168) | func (o *ThirdApi) SearchLogs(c *gin.Context) {
method GetPrometheus (line 172) | func (o *ThirdApi) GetPrometheus(c *gin.Context) {
function NewThirdApi (line 38) | func NewThirdApi(client third.ThirdClient, grafanaUrl string) ThirdApi {
function setURLPrefixOption (line 52) | func setURLPrefixOption[A, B, C any](_ func(client C, ctx context.Contex...
function setURLPrefix (line 58) | func setURLPrefix(c *gin.Context, urlPrefix *string) error {
FILE: internal/api/user.go
type UserApi (line 30) | type UserApi struct
method UserRegister (line 40) | func (u *UserApi) UserRegister(c *gin.Context) {
method UpdateUserInfo (line 45) | func (u *UserApi) UpdateUserInfo(c *gin.Context) {
method UpdateUserInfoEx (line 49) | func (u *UserApi) UpdateUserInfoEx(c *gin.Context) {
method SetGlobalRecvMessageOpt (line 52) | func (u *UserApi) SetGlobalRecvMessageOpt(c *gin.Context) {
method GetUsersPublicInfo (line 56) | func (u *UserApi) GetUsersPublicInfo(c *gin.Context) {
method GetAllUsersID (line 60) | func (u *UserApi) GetAllUsersID(c *gin.Context) {
method AccountCheck (line 64) | func (u *UserApi) AccountCheck(c *gin.Context) {
method GetUsers (line 68) | func (u *UserApi) GetUsers(c *gin.Context) {
method GetUsersOnlineStatus (line 73) | func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
method UserRegisterCount (line 129) | func (u *UserApi) UserRegisterCount(c *gin.Context) {
method GetUsersOnlineTokenDetail (line 134) | func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
method SubscriberStatus (line 195) | func (u *UserApi) SubscriberStatus(c *gin.Context) {
method GetUserStatus (line 200) | func (u *UserApi) GetUserStatus(c *gin.Context) {
method GetSubscribeUsersStatus (line 205) | func (u *UserApi) GetSubscribeUsersStatus(c *gin.Context) {
method ProcessUserCommandAdd (line 210) | func (u *UserApi) ProcessUserCommandAdd(c *gin.Context) {
method ProcessUserCommandDelete (line 215) | func (u *UserApi) ProcessUserCommandDelete(c *gin.Context) {
method ProcessUserCommandUpdate (line 220) | func (u *UserApi) ProcessUserCommandUpdate(c *gin.Context) {
method ProcessUserCommandGet (line 225) | func (u *UserApi) ProcessUserCommandGet(c *gin.Context) {
method ProcessUserCommandGetAll (line 230) | func (u *UserApi) ProcessUserCommandGetAll(c *gin.Context) {
method AddNotificationAccount (line 234) | func (u *UserApi) AddNotificationAccount(c *gin.Context) {
method UpdateNotificationAccountInfo (line 238) | func (u *UserApi) UpdateNotificationAccountInfo(c *gin.Context) {
method SearchNotificationAccount (line 242) | func (u *UserApi) SearchNotificationAccount(c *gin.Context) {
method GetUserClientConfig (line 246) | func (u *UserApi) GetUserClientConfig(c *gin.Context) {
method SetUserClientConfig (line 250) | func (u *UserApi) SetUserClientConfig(c *gin.Context) {
method DelUserClientConfig (line 254) | func (u *UserApi) DelUserClientConfig(c *gin.Context) {
method PageUserClientConfig (line 258) | func (u *UserApi) PageUserClientConfig(c *gin.Context) {
function NewUserApi (line 36) | func NewUserApi(client user.UserClient, discov discovery.Conn, config co...
FILE: internal/msggateway/callback.go
method webhookAfterUserOnline (line 27) | func (ws *WsServer) webhookAfterUserOnline(ctx context.Context, after *c...
method webhookAfterUserOffline (line 45) | func (ws *WsServer) webhookAfterUserOffline(ctx context.Context, after *...
method webhookAfterUserKickOff (line 62) | func (ws *WsServer) webhookAfterUserKickOff(ctx context.Context, after *...
FILE: internal/msggateway/client.go
constant MessageText (line 44) | MessageText = iota + 1
constant MessageBinary (line 46) | MessageBinary
constant CloseMessage (line 50) | CloseMessage = 8
constant PingMessage (line 54) | PingMessage = 9
constant PongMessage (line 58) | PongMessage = 10
type PingPongHandler (line 61) | type PingPongHandler
type Client (line 63) | type Client struct
method ResetClient (line 85) | func (c *Client) ResetClient(ctx *UserConnContext, conn ClientConn, lo...
method readMessage (line 114) | func (c *Client) readMessage() {
method handleMessage (line 147) | func (c *Client) handleMessage(message []byte) error {
method setAppBackgroundStatus (line 216) | func (c *Client) setAppBackgroundStatus(ctx context.Context, req *Req)...
method close (line 227) | func (c *Client) close() {
method replyMessage (line 239) | func (c *Client) replyMessage(ctx context.Context, binaryReq *Req, err...
method PushMessage (line 263) | func (c *Client) PushMessage(ctx context.Context, msgData *sdkws.MsgDa...
method KickOnlineMessage (line 285) | func (c *Client) KickOnlineMessage() error {
method PushUserOnlineStatus (line 295) | func (c *Client) PushUserOnlineStatus(data []byte) error {
method writeBinaryMsg (line 303) | func (c *Client) writeBinaryMsg(resp Resp) error {
FILE: internal/msggateway/client_conn.go
type ClientConn (line 18) | type ClientConn interface
type websocketMessage (line 24) | type websocketMessage struct
function NewWebSocketClientConn (line 29) | func NewWebSocketClientConn(conn *websocket.Conn, readLimit int64, readT...
type websocketClientConn (line 49) | type websocketClientConn struct
method ReadMessage (line 57) | func (c *websocketClientConn) ReadMessage() ([]byte, error) {
method WriteMessage (line 65) | func (c *websocketClientConn) WriteMessage(message []byte) error {
method Close (line 69) | func (c *websocketClientConn) Close() error {
method closeBy (line 73) | func (c *websocketClientConn) closeBy(err error) error {
method writeMessage (line 83) | func (c *websocketClientConn) writeMessage(messageType int, data []byt...
method loopSend (line 95) | func (c *websocketClientConn) loopSend() {
method setReadDeadline (line 135) | func (c *websocketClientConn) setReadDeadline() error {
method readMessage (line 140) | func (c *websocketClientConn) readMessage() ([]byte, error) {
method onReadTextMessage (line 175) | func (c *websocketClientConn) onReadTextMessage(buf []byte) error {
method pingHandler (line 198) | func (c *websocketClientConn) pingHandler(appData string) error {
method pongHandler (line 211) | func (c *websocketClientConn) pongHandler(string) error {
method doPing (line 215) | func (c *websocketClientConn) doPing(d time.Duration) {
FILE: internal/msggateway/compressor.go
type Compressor (line 31) | type Compressor interface
type GzipCompressor (line 38) | type GzipCompressor struct
method Compress (line 46) | func (g *GzipCompressor) Compress(rawData []byte) ([]byte, error) {
method CompressWithPool (line 61) | func (g *GzipCompressor) CompressWithPool(rawData []byte) ([]byte, err...
method DeCompress (line 77) | func (g *GzipCompressor) DeCompress(compressedData []byte) ([]byte, er...
method DecompressWithPool (line 95) | func (g *GzipCompressor) DecompressWithPool(compressedData []byte) ([]...
function NewGzipCompressor (line 42) | func NewGzipCompressor() *GzipCompressor {
FILE: internal/msggateway/compressor_test.go
function mockRandom (line 25) | func mockRandom() []byte {
function TestCompressDecompress (line 31) | func TestCompressDecompress(t *testing.T) {
function TestCompressDecompressWithConcurrency (line 57) | func TestCompressDecompressWithConcurrency(t *testing.T) {
function BenchmarkCompress (line 89) | func BenchmarkCompress(b *testing.B) {
function BenchmarkCompressWithSyncPool (line 99) | func BenchmarkCompressWithSyncPool(b *testing.B) {
function BenchmarkDecompress (line 109) | func BenchmarkDecompress(b *testing.B) {
function BenchmarkDecompressWithSyncPool (line 123) | func BenchmarkDecompressWithSyncPool(b *testing.B) {
function TestName (line 136) | func TestName(t *testing.T) {
FILE: internal/msggateway/constant.go
constant WsUserID (line 20) | WsUserID = "sendID"
constant CommonUserID (line 21) | CommonUserID = "userID"
constant PlatformID (line 22) | PlatformID = "platformID"
constant ConnID (line 23) | ConnID = "connID"
constant Token (line 24) | Token = "token"
constant OperationID (line 25) | OperationID = "operationID"
constant Compression (line 26) | Compression = "compression"
constant GzipCompressionProtocol (line 27) | GzipCompressionProtocol = "gzip"
constant BackgroundStatus (line 28) | BackgroundStatus = "isBackground"
constant SendResponse (line 29) | SendResponse = "isMsgResp"
constant SDKType (line 30) | SDKType = "sdkType"
constant SDKVersion (line 31) | SDKVersion = "sdkVersion"
constant GoSDK (line 35) | GoSDK = "go"
constant JsSDK (line 36) | JsSDK = "js"
constant WebSocket (line 40) | WebSocket = iota + 1
constant WSGetNewestSeq (line 45) | WSGetNewestSeq = 1001
constant WSPullMsgBySeqList (line 46) | WSPullMsgBySeqList = 1002
constant WSSendMsg (line 47) | WSSendMsg = 1003
constant WSSendSignalMsg (line 48) | WSSendSignalMsg = 1004
constant WSPullMsg (line 49) | WSPullMsg = 1005
constant WSGetConvMaxReadSeq (line 50) | WSGetConvMaxReadSeq = 1006
constant WsPullConvLastMessage (line 51) | WsPullConvLastMessage = 1007
constant WSPushMsg (line 52) | WSPushMsg = 2001
constant WSKickOnlineMsg (line 53) | WSKickOnlineMsg = 2002
constant WsLogoutMsg (line 54) | WsLogoutMsg = 2003
constant WsSetBackgroundStatus (line 55) | WsSetBackgroundStatus = 2004
constant WsSubUserOnlineStatus (line 56) | WsSubUserOnlineStatus = 2005
constant WSDataError (line 57) | WSDataError = 3001
constant writeWait (line 62) | writeWait = 10 * time.Second
constant pongWait (line 65) | pongWait = 30 * time.Second
constant pingPeriod (line 68) | pingPeriod = (pongWait * 9) / 10
constant maxMessageSize (line 71) | maxMessageSize = 51200
FILE: internal/msggateway/context.go
type UserConnContextInfo (line 32) | type UserConnContextInfo struct
type UserConnContext (line 44) | type UserConnContext struct
method Deadline (line 54) | func (c *UserConnContext) Deadline() (deadline time.Time, ok bool) {
method Done (line 58) | func (c *UserConnContext) Done() <-chan struct{} {
method Err (line 62) | func (c *UserConnContext) Err() error {
method Value (line 66) | func (c *UserConnContext) Value(key any) any {
method ParseEssentialArgs (line 107) | func (c *UserConnContext) ParseEssentialArgs() error {
method parseByQuery (line 116) | func (c *UserConnContext) parseByQuery(query url.Values, header http.H...
method parseByJson (line 148) | func (c *UserConnContext) parseByJson(data string) error {
method checkInfo (line 160) | func (c *UserConnContext) checkInfo(info *UserConnContextInfo) error {
method GetRemoteAddr (line 184) | func (c *UserConnContext) GetRemoteAddr() string {
method SetHeader (line 188) | func (c *UserConnContext) SetHeader(key, value string) {
method ErrReturn (line 192) | func (c *UserConnContext) ErrReturn(error string, code int) {
method GetConnID (line 196) | func (c *UserConnContext) GetConnID() string {
method GetUserID (line 200) | func (c *UserConnContext) GetUserID() string {
method GetPlatformID (line 207) | func (c *UserConnContext) GetPlatformID() int {
method GetOperationID (line 214) | func (c *UserConnContext) GetOperationID() string {
method SetOperationID (line 221) | func (c *UserConnContext) SetOperationID(operationID string) {
method GetToken (line 228) | func (c *UserConnContext) GetToken() string {
method GetCompression (line 235) | func (c *UserConnContext) GetCompression() bool {
method GetSDKType (line 239) | func (c *UserConnContext) GetSDKType() string {
method GetSDKVersion (line 253) | func (c *UserConnContext) GetSDKVersion() string {
method ShouldSendResp (line 260) | func (c *UserConnContext) ShouldSendResp() bool {
method SetToken (line 264) | func (c *UserConnContext) SetToken(token string) {
method GetBackground (line 271) | func (c *UserConnContext) GetBackground() bool {
function newContext (line 85) | func newContext(respWriter http.ResponseWriter, req *http.Request) *User...
function newTempContext (line 100) | func newTempContext() *UserConnContext {
FILE: internal/msggateway/encoder.go
type Encoder (line 25) | type Encoder interface
type GobEncoder (line 30) | type GobEncoder struct
method Encode (line 36) | func (g GobEncoder) Encode(data any) ([]byte, error) {
method Decode (line 45) | func (g GobEncoder) Decode(encodeData []byte, decodeData any) error {
function NewGobEncoder (line 32) | func NewGobEncoder() Encoder {
type JsonEncoder (line 54) | type JsonEncoder struct
method Encode (line 60) | func (g JsonEncoder) Encode(data any) ([]byte, error) {
method Decode (line 68) | func (g JsonEncoder) Decode(encodeData []byte, decodeData any) error {
function NewJsonEncoder (line 56) | func NewJsonEncoder() Encoder {
FILE: internal/msggateway/http_error.go
function httpError (line 22) | func httpError(ctx *UserConnContext, err error) {
FILE: internal/msggateway/hub_server.go
type Server (line 74) | type Server struct
method InitServer (line 37) | func (s *Server) InitServer(ctx context.Context, config *Config, disCo...
method SetLongConnServer (line 85) | func (s *Server) SetLongConnServer(LongConnServer LongConnServer) {
method GetUsersOnlineStatus (line 102) | func (s *Server) GetUsersOnlineStatus(ctx context.Context, req *msggat...
method pushToUser (line 135) | func (s *Server) pushToUser(ctx context.Context, userID string, msgDat...
method SuperGroupOnlineBatchPushOneMsg (line 171) | func (s *Server) SuperGroupOnlineBatchPushOneMsg(ctx context.Context, ...
method KickUserOffline (line 222) | func (s *Server) KickUserOffline(ctx context.Context, req *msggateway....
method MultiTerminalLoginCheck (line 242) | func (s *Server) MultiTerminalLoginCheck(ctx context.Context, req *msg...
function NewServer (line 89) | func NewServer(longConnServer LongConnServer, conf *Config, ready func(s...
FILE: internal/msggateway/init.go
type Config (line 32) | type Config struct
function Start (line 42) | func Start(ctx context.Context, conf *Config, client discovery.SvcDiscov...
FILE: internal/msggateway/message_handler.go
constant TextPing (line 34) | TextPing = "ping"
constant TextPong (line 35) | TextPong = "pong"
type TextMessage (line 38) | type TextMessage struct
type Req (line 43) | type Req struct
method String (line 52) | func (r *Req) String() string {
function getReq (line 68) | func getReq() *Req {
function freeReq (line 79) | func freeReq(req *Req) {
type Resp (line 83) | type Resp struct
method String (line 92) | func (r *Resp) String() string {
type MessageHandler (line 102) | type MessageHandler interface
type GrpcHandler (line 116) | type GrpcHandler struct
method GetSeq (line 130) | func (g *GrpcHandler) GetSeq(ctx context.Context, data *Req) ([]byte, ...
method SendMessage (line 151) | func (g *GrpcHandler) SendMessage(ctx context.Context, data *Req) ([]b...
method SendSignalMessage (line 175) | func (g *GrpcHandler) SendSignalMessage(ctx context.Context, data *Req...
method PullMessageBySeqList (line 187) | func (g *GrpcHandler) PullMessageBySeqList(ctx context.Context, data *...
method GetConversationsHasReadAndMaxSeq (line 206) | func (g *GrpcHandler) GetConversationsHasReadAndMaxSeq(ctx context.Con...
method GetSeqMessage (line 225) | func (g *GrpcHandler) GetSeqMessage(ctx context.Context, data *Req) ([...
method UserLogout (line 244) | func (g *GrpcHandler) UserLogout(ctx context.Context, data *Req) ([]by...
method SetUserDeviceBackground (line 260) | func (g *GrpcHandler) SetUserDeviceBackground(ctx context.Context, dat...
method GetLastMessage (line 271) | func (g *GrpcHandler) GetLastMessage(ctx context.Context, data *Req) (...
function NewGrpcHandler (line 122) | func NewGrpcHandler(validate *validator.Validate, msgClient *rpcli.MsgCl...
FILE: internal/msggateway/online.go
method ChangeOnlineStatus (line 21) | func (ws *WsServer) ChangeOnlineStatus(concurrent int) {
FILE: internal/msggateway/options.go
type Option (line 20) | type Option
type configs (line 21) | type configs struct
function WithPort (line 35) | func WithPort(port int) Option {
function WithMaxConnNum (line 41) | func WithMaxConnNum(num int64) Option {
function WithHandshakeTimeout (line 47) | func WithHandshakeTimeout(t time.Duration) Option {
function WithMessageMaxMsgLength (line 53) | func WithMessageMaxMsgLength(length int) Option {
function WithWriteBufferSize (line 59) | func WithWriteBufferSize(size int) Option {
FILE: internal/msggateway/subscription.go
method subscriberUserOnlineStatusChanges (line 12) | func (ws *WsServer) subscriberUserOnlineStatusChanges(ctx context.Contex...
method SubUserOnlineStatus (line 21) | func (ws *WsServer) SubUserOnlineStatus(ctx context.Context, client *Cli...
function newSubscription (line 44) | func newSubscription() *Subscription {
type subClient (line 50) | type subClient struct
type Subscription (line 54) | type Subscription struct
method DelClient (line 59) | func (s *Subscription) DelClient(client *Client) {
method GetClient (line 84) | func (s *Subscription) GetClient(userID string) []*Client {
method Sub (line 98) | func (s *Subscription) Sub(client *Client, addUserIDs, delUserIDs []st...
method pushUserIDOnlineStatus (line 149) | func (ws *WsServer) pushUserIDOnlineStatus(ctx context.Context, userID s...
FILE: internal/msggateway/user_map.go
type UserMap (line 9) | type UserMap interface
type UserState (line 19) | type UserState struct
type UserPlatform (line 25) | type UserPlatform struct
method PlatformIDs (line 30) | func (u *UserPlatform) PlatformIDs() []int32 {
method PlatformIDSet (line 41) | func (u *UserPlatform) PlatformIDSet() map[int32]struct{} {
function newUserMap (line 52) | func newUserMap() UserMap {
type userMap (line 59) | type userMap struct
method RecvSubChange (line 65) | func (u *userMap) RecvSubChange(userID string, platformIDs []int32) bo...
method push (line 83) | func (u *userMap) push(userID string, userPlatform *UserPlatform, offl...
method GetAll (line 93) | func (u *userMap) GetAll(userID string) ([]*Client, bool) {
method Get (line 103) | func (u *userMap) Get(userID string, platformID int) ([]*Client, bool,...
method Set (line 119) | func (u *userMap) Set(userID string, client *Client) {
method DeleteClients (line 134) | func (u *userMap) DeleteClients(userID string, clients []*Client) (isD...
method GetAllUserStatus (line 165) | func (u *userMap) GetAllUserStatus(deadline time.Time, nowtime time.Ti...
method UserState (line 183) | func (u *userMap) UserState() <-chan UserState {
FILE: internal/msggateway/ws_server.go
type LongConnServer (line 33) | type LongConnServer interface
type WsServer (line 48) | type WsServer struct
method SetDiscoveryRegistry (line 82) | func (ws *WsServer) SetDiscoveryRegistry(ctx context.Context, disCov d...
method UnRegister (line 121) | func (ws *WsServer) UnRegister(c *Client) {
method Validate (line 125) | func (ws *WsServer) Validate(_ any) error {
method GetUserAllCons (line 129) | func (ws *WsServer) GetUserAllCons(userID string) ([]*Client, bool) {
method GetUserPlatformCons (line 133) | func (ws *WsServer) GetUserPlatformCons(userID string, platform int) (...
method Run (line 171) | func (ws *WsServer) Run(ctx context.Context) error {
method sendUserOnlineInfoToOtherNode (line 221) | func (ws *WsServer) sendUserOnlineInfoToOtherNode(ctx context.Context,...
method SetKickHandlerInfo (line 259) | func (ws *WsServer) SetKickHandlerInfo(i *kickHandler) {
method registerClient (line 263) | func (ws *WsServer) registerClient(client *Client) {
method KickUserConn (line 328) | func (ws *WsServer) KickUserConn(client *Client) error {
method multiTerminalLoginChecker (line 333) | func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClient...
method unregisterClient (line 439) | func (ws *WsServer) unregisterClient(client *Client) {
method validateRespWithRequest (line 456) | func (ws *WsServer) validateRespWithRequest(ctx *UserConnContext, resp...
method handlerError (line 468) | func (ws *WsServer) handlerError(ctx *UserConnContext, w http.Response...
method wsHandler (line 491) | func (ws *WsServer) wsHandler(w http.ResponseWriter, r *http.Request) {
type kickHandler (line 76) | type kickHandler struct
function NewWsServer (line 137) | func NewWsServer(msgGatewayConfig *Config, opts ...Option) *WsServer {
constant concurrentRequest (line 219) | concurrentRequest = 3
function getRemoteAdders (line 316) | func getRemoteAdders(client []*Client) string {
FILE: internal/msgtransfer/callback.go
function toCommonCallback (line 20) | func toCommonCallback(ctx context.Context, msg *sdkws.MsgData, command s...
function GetContent (line 43) | func GetContent(msg *sdkws.MsgData) string {
method webhookAfterMsgSaveDB (line 54) | func (mc *OnlineHistoryMongoConsumerHandler) webhookAfterMsgSaveDB(ctx c...
function buildKeyMsgDataQuery (line 74) | func buildKeyMsgDataQuery(msg *sdkws.MsgData) map[string]string {
function filterAfterMsg (line 86) | func filterAfterMsg(msg *sdkws.MsgData, after *config.AfterConfig) bool {
function filterMsg (line 90) | func filterMsg(msg *sdkws.MsgData, attentionIds []string, deniedTypes []...
function defaultDeniedTypes (line 111) | func defaultDeniedTypes(contentType int32) bool {
FILE: internal/msgtransfer/init.go
type MsgTransfer (line 37) | type MsgTransfer struct
method Start (line 149) | func (m *MsgTransfer) Start(ctx context.Context) error {
type Config (line 50) | type Config struct
function Start (line 61) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/msgtransfer/online_history_msg_handler.go
constant size (line 47) | size = 500
constant mainDataBuffer (line 48) | mainDataBuffer = 500
constant subChanBuffer (line 49) | subChanBuffer = 50
constant worker (line 50) | worker = 50
constant interval (line 51) | interval = 100 * time.Millisecond
constant hasReadChanBuffer (line 52) | hasReadChanBuffer = 1000
type ContextMsg (line 55) | type ContextMsg struct
type userHasReadSeq (line 62) | type userHasReadSeq struct
type OnlineHistoryRedisConsumerHandler (line 67) | type OnlineHistoryRedisConsumerHandler struct
method do (line 126) | func (och *OnlineHistoryRedisConsumerHandler) do(ctx context.Context, ...
method doSetReadSeq (line 144) | func (och *OnlineHistoryRedisConsumerHandler) doSetReadSeq(ctx context...
method parseConsumerMessages (line 192) | func (och *OnlineHistoryRedisConsumerHandler) parseConsumerMessages(ct...
method categorizeMessageLists (line 211) | func (och *OnlineHistoryRedisConsumerHandler) categorizeMessageLists(t...
method handleMsg (line 254) | func (och *OnlineHistoryRedisConsumerHandler) handleMsg(ctx context.Co...
method handleNotification (line 331) | func (och *OnlineHistoryRedisConsumerHandler) handleNotification(ctx c...
method HandleUserHasReadSeqMessages (line 354) | func (och *OnlineHistoryRedisConsumerHandler) HandleUserHasReadSeqMess...
method Close (line 371) | func (och *OnlineHistoryRedisConsumerHandler) Close() {
method toPushTopic (line 376) | func (och *OnlineHistoryRedisConsumerHandler) toPushTopic(ctx context....
method HandlerRedisMessage (line 399) | func (och *OnlineHistoryRedisConsumerHandler) HandlerRedisMessage(msg ...
type ConsumerMessage (line 78) | type ConsumerMessage struct
function NewOnlineHistoryRedisConsumerHandler (line 85) | func NewOnlineHistoryRedisConsumerHandler(ctx context.Context, client di...
function withAggregationCtx (line 385) | func withAggregationCtx(ctx context.Context, values []*ContextMsg) conte...
FILE: internal/msgtransfer/online_msg_to_mongo_handler.go
type OnlineHistoryMongoConsumerHandler (line 28) | type OnlineHistoryMongoConsumerHandler struct
method HandleChatWs2Mongo (line 42) | func (mc *OnlineHistoryMongoConsumerHandler) HandleChatWs2Mongo(val mq...
function NewOnlineHistoryMongoConsumerHandler (line 34) | func NewOnlineHistoryMongoConsumerHandler(database controller.MsgTransfe...
FILE: internal/push/callback.go
method webhookBeforeOfflinePush (line 30) | func (c *ConsumerHandler) webhookBeforeOfflinePush(ctx context.Context, ...
method webhookBeforeOnlinePush (line 71) | func (c *ConsumerHandler) webhookBeforeOnlinePush(ctx context.Context, b...
method webhookBeforeGroupOnlinePush (line 102) | func (c *ConsumerHandler) webhookBeforeGroupOnlinePush(
function GetContent (line 140) | func GetContent(msg *sdkws.MsgData) string {
FILE: internal/push/offlinepush/dummy/push.go
function NewClient (line 24) | func NewClient() *Dummy {
type Dummy (line 28) | type Dummy struct
method Push (line 32) | func (d *Dummy) Push(ctx context.Context, userIDs []string, title, con...
FILE: internal/push/offlinepush/fcm/push.go
constant SinglePushCountLimit (line 37) | SinglePushCountLimit = 400
type Fcm (line 41) | type Fcm struct
method Push (line 79) | func (f *Fcm) Push(ctx context.Context, userIDs []string, title, conte...
function NewClient (line 48) | func NewClient(pushConf *config.Push, cache cache.ThirdCache, fcmConfigP...
FILE: internal/push/offlinepush/getui/body.go
type Resp (line 33) | type Resp struct
method parseError (line 39) | func (r *Resp) parseError() (err error) {
type RespI (line 51) | type RespI interface
type AuthReq (line 55) | type AuthReq struct
type AuthResp (line 61) | type AuthResp struct
type TaskResp (line 66) | type TaskResp struct
type Settings (line 70) | type Settings struct
type strategy (line 75) | type strategy struct
type Audience (line 91) | type Audience struct
type PushMessage (line 95) | type PushMessage struct
type PushChannel (line 100) | type PushChannel struct
type PushReq (line 105) | type PushReq struct
method setPushChannel (line 184) | func (pushReq *PushReq) setPushChannel(title string, body string) {
type Ios (line 115) | type Ios struct
type Alert (line 124) | type Alert struct
type Android (line 129) | type Android struct
type Notification (line 136) | type Notification struct
type Options (line 146) | type Options struct
type Payload (line 162) | type Payload struct
function newPushReq (line 166) | func newPushReq(pushConf *config.Push, title, content string) PushReq {
function newBatchPushReq (line 179) | func newBatchPushReq(userIDs []string, taskID string) PushReq {
FILE: internal/push/offlinepush/getui/push.go
constant pushURL (line 43) | pushURL = "/push/single/alias"
constant authURL (line 44) | authURL = "/auth"
constant taskURL (line 45) | taskURL = "/push/list/message"
constant batchPushURL (line 46) | batchPushURL = "/push/list/alias"
constant tokenExpireCode (line 49) | tokenExpireCode = 10001
constant tokenExpireTime (line 50) | tokenExpireTime = 60 * 60 * 23
constant taskIDTTL (line 51) | taskIDTTL = 1000 * 60 * 60 * 24
type Client (line 54) | type Client struct
method Push (line 71) | func (g *Client) Push(ctx context.Context, userIDs []string, title, co...
method Auth (line 125) | func (g *Client) Auth(ctx context.Context, timeStamp int64) (token str...
method GetTaskID (line 145) | func (g *Client) GetTaskID(ctx context.Context, token string, pushReq ...
method batchPush (line 157) | func (g *Client) batchPush(ctx context.Context, token string, userIDs ...
method singlePush (line 166) | func (g *Client) singlePush(ctx context.Context, token, userID string,...
method request (line 173) | func (g *Client) request(ctx context.Context, url string, input any, t...
method postReturn (line 180) | func (g *Client) postReturn(
method getTokenAndSave2Redis (line 196) | func (g *Client) getTokenAndSave2Redis(ctx context.Context) (token str...
method GetTaskIDAndSave2Redis (line 208) | func (g *Client) GetTaskIDAndSave2Redis(ctx context.Context, token str...
function NewClient (line 62) | func NewClient(pushConf *config.Push, cache cache.ThirdCache) *Client {
FILE: internal/push/offlinepush/jpush/body/audience.go
constant TAG (line 18) | TAG = "tag"
constant TAGAND (line 19) | TAGAND = "tag_and"
constant TAGNOT (line 20) | TAGNOT = "tag_not"
constant ALIAS (line 21) | ALIAS = "alias"
constant REGISTRATIONID (line 22) | REGISTRATIONID = "registration_id"
type Audience (line 25) | type Audience struct
method set (line 30) | func (a *Audience) set(key string, v []string) {
method SetTag (line 42) | func (a *Audience) SetTag(tags []string) {
method SetTagAnd (line 46) | func (a *Audience) SetTagAnd(tags []string) {
method SetTagNot (line 50) | func (a *Audience) SetTagNot(tags []string) {
method SetAlias (line 54) | func (a *Audience) SetAlias(alias []string) {
method SetRegistrationId (line 58) | func (a *Audience) SetRegistrationId(ids []string) {
method SetAll (line 62) | func (a *Audience) SetAll() {
FILE: internal/push/offlinepush/jpush/body/message.go
type Message (line 17) | type Message struct
method SetMsgContent (line 24) | func (m *Message) SetMsgContent(c string) {
method SetTitle (line 28) | func (m *Message) SetTitle(t string) {
method SetContentType (line 32) | func (m *Message) SetContentType(c string) {
method SetExtras (line 36) | func (m *Message) SetExtras(key string, value any) {
FILE: internal/push/offlinepush/jpush/body/notification.go
type Notification (line 22) | type Notification struct
method SetAlert (line 49) | func (n *Notification) SetAlert(alert string, title string, opts *opti...
method SetExtras (line 61) | func (n *Notification) SetExtras(extras map[string]string) {
method SetAndroidIntent (line 66) | func (n *Notification) SetAndroidIntent(pushConf *config.Push) {
method IOSEnableMutableContent (line 70) | func (n *Notification) IOSEnableMutableContent() {
type Android (line 28) | type Android struct
type Ios (line 36) | type Ios struct
type IosAlert (line 44) | type IosAlert struct
FILE: internal/push/offlinepush/jpush/body/options.go
type Options (line 17) | type Options struct
method SetApnsProduction (line 21) | func (o *Options) SetApnsProduction(c bool) {
FILE: internal/push/offlinepush/jpush/body/platform.go
constant ANDROID (line 24) | ANDROID = "android"
constant IOS (line 25) | IOS = "ios"
constant QUICKAPP (line 26) | QUICKAPP = "quickapp"
constant WINDOWSPHONE (line 27) | WINDOWSPHONE = "winphone"
constant ALL (line 28) | ALL = "all"
type Platform (line 31) | type Platform struct
method Set (line 36) | func (p *Platform) Set(os string) error {
method SetPlatform (line 70) | func (p *Platform) SetPlatform(platform string) error {
method SetIOS (line 81) | func (p *Platform) SetIOS() error {
method SetAndroid (line 85) | func (p *Platform) SetAndroid() error {
method SetQuickApp (line 89) | func (p *Platform) SetQuickApp() error {
method SetWindowsPhone (line 93) | func (p *Platform) SetWindowsPhone() error {
method SetAll (line 97) | func (p *Platform) SetAll() {
FILE: internal/push/offlinepush/jpush/body/pushobj.go
type PushObj (line 17) | type PushObj struct
method SetPlatform (line 25) | func (p *PushObj) SetPlatform(pf *Platform) {
method SetAudience (line 29) | func (p *PushObj) SetAudience(ad *Audience) {
method SetNotification (line 33) | func (p *PushObj) SetNotification(no *Notification) {
method SetMessage (line 37) | func (p *PushObj) SetMessage(m *Message) {
method SetOptions (line 41) | func (p *PushObj) SetOptions(o *Options) {
FILE: internal/push/offlinepush/jpush/push.go
type JPush (line 28) | type JPush struct
method Auth (line 39) | func (j *JPush) Auth(apiKey, secretKey string, timeStamp int64) (token...
method SetAlias (line 43) | func (j *JPush) SetAlias(cid, alias string) (resp string, err error) {
method getAuthorization (line 47) | func (j *JPush) getAuthorization(appKey string, masterSecret string) s...
method Push (line 54) | func (j *JPush) Push(ctx context.Context, userIDs []string, title, con...
method request (line 89) | func (j *JPush) request(ctx context.Context, po body.PushObj, resp *ma...
function NewClient (line 33) | func NewClient(pushConf *config.Push) *JPush {
FILE: internal/push/offlinepush/offlinepusher.go
constant geTUI (line 30) | geTUI = "getui"
constant firebase (line 31) | firebase = "fcm"
constant jPush (line 32) | jPush = "jpush"
type OfflinePusher (line 36) | type OfflinePusher interface
function NewOfflinePusher (line 40) | func NewOfflinePusher(pushConf *config.Push, cache cache.ThirdCache, fcm...
FILE: internal/push/offlinepush/options/options.go
type Opts (line 4) | type Opts struct
type Signal (line 12) | type Signal struct
FILE: internal/push/offlinepush_handler.go
type OfflinePushConsumerHandler (line 18) | type OfflinePushConsumerHandler struct
method HandleMsg2OfflinePush (line 28) | func (o *OfflinePushConsumerHandler) HandleMsg2OfflinePush(ctx context...
method getOfflinePushInfos (line 49) | func (o *OfflinePushConsumerHandler) getOfflinePushInfos(msg *sdkws.Ms...
method offlinePushMsg (line 94) | func (o *OfflinePushConsumerHandler) offlinePushMsg(ctx context.Contex...
function NewOfflinePushConsumerHandler (line 22) | func NewOfflinePushConsumerHandler(offlinePusher offlinepush.OfflinePush...
FILE: internal/push/onlinepusher.go
type OnlinePusher (line 21) | type OnlinePusher interface
type emptyOnlinePusher (line 28) | type emptyOnlinePusher struct
method GetConnsAndOnlinePush (line 34) | func (emptyOnlinePusher) GetConnsAndOnlinePush(ctx context.Context, ms...
method GetOnlinePushFailedUserIDs (line 38) | func (u emptyOnlinePusher) GetOnlinePushFailedUserIDs(ctx context.Cont...
function newEmptyOnlinePusher (line 30) | func newEmptyOnlinePusher() *emptyOnlinePusher {
function NewOnlinePusher (line 43) | func NewOnlinePusher(disCov discovery.Conn, config *Config) (OnlinePushe...
type DefaultAllNode (line 58) | type DefaultAllNode struct
method GetConnsAndOnlinePush (line 67) | func (d *DefaultAllNode) GetConnsAndOnlinePush(ctx context.Context, ms...
method GetOnlinePushFailedUserIDs (line 122) | func (d *DefaultAllNode) GetOnlinePushFailedUserIDs(_ context.Context,...
function NewDefaultAllNode (line 63) | func NewDefaultAllNode(disCov discovery.Conn, config *Config) *DefaultAl...
type K8sStaticConsistentHash (line 141) | type K8sStaticConsistentHash struct
method GetConnsAndOnlinePush (line 150) | func (k *K8sStaticConsistentHash) GetConnsAndOnlinePush(ctx context.Co...
method GetOnlinePushFailedUserIDs (line 205) | func (k *K8sStaticConsistentHash) GetOnlinePushFailedUserIDs(_ context...
function NewK8sStaticConsistentHash (line 146) | func NewK8sStaticConsistentHash(disCov discovery.SvcDiscoveryRegistry, c...
FILE: internal/push/push.go
type pushServer (line 26) | type pushServer struct
method DelUserPushToken (line 46) | func (p pushServer) DelUserPushToken(ctx context.Context,
type Config (line 33) | type Config struct
function Start (line 54) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/push/push_handler.go
type ConsumerHandler (line 31) | type ConsumerHandler struct
method HandleMs2PsChat (line 88) | func (c *ConsumerHandler) HandleMs2PsChat(ctx context.Context, msg []b...
method WaitCache (line 122) | func (c *ConsumerHandler) WaitCache() {
method Push2User (line 127) | func (c *ConsumerHandler) Push2User(ctx context.Context, userIDs []str...
method shouldPushOffline (line 181) | func (c *ConsumerHandler) shouldPushOffline(_ context.Context, msg *sd...
method GetConnsAndOnlinePush (line 195) | func (c *ConsumerHandler) GetConnsAndOnlinePush(ctx context.Context, m...
method Push2Group (line 221) | func (c *ConsumerHandler) Push2Group(ctx context.Context, groupID stri...
method asyncOfflinePush (line 265) | func (c *ConsumerHandler) asyncOfflinePush(ctx context.Context, needOf...
method groupMessagesHandler (line 286) | func (c *ConsumerHandler) groupMessagesHandler(ctx context.Context, gr...
method offlinePushMsg (line 334) | func (c *ConsumerHandler) offlinePushMsg(ctx context.Context, msg *sdk...
method filterGroupMessageOfflinePush (line 348) | func (c *ConsumerHandler) filterGroupMessageOfflinePush(ctx context.Co...
method getOfflinePushInfos (line 357) | func (c *ConsumerHandler) getOfflinePushInfos(msg *sdkws.MsgData) (tit...
method DeleteMemberAndSetConversationSeq (line 402) | func (c *ConsumerHandler) DeleteMemberAndSetConversationSeq(ctx contex...
function NewConsumerHandler (line 47) | func NewConsumerHandler(ctx context.Context, config *Config, database co...
function unmarshalNotificationElem (line 411) | func unmarshalNotificationElem(bytes []byte, t any) error {
FILE: internal/rpc/auth/auth.go
type authServer (line 49) | type authServer struct
method GetAdminToken (line 116) | func (s *authServer) GetAdminToken(ctx context.Context, req *pbauth.Ge...
method GetUserToken (line 143) | func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.Get...
method GetExistingToken (line 174) | func (s *authServer) GetExistingToken(ctx context.Context, req *pbauth...
method parseToken (line 185) | func (s *authServer) parseToken(ctx context.Context, tokensString stri...
method ParseToken (line 225) | func (s *authServer) ParseToken(ctx context.Context, req *pbauth.Parse...
method ForceLogout (line 237) | func (s *authServer) ForceLogout(ctx context.Context, req *pbauth.Forc...
method forceKickOff (line 247) | func (s *authServer) forceKickOff(ctx context.Context, userID string, ...
method InvalidateToken (line 279) | func (s *authServer) InvalidateToken(ctx context.Context, req *pbauth....
method KickTokens (line 304) | func (s *authServer) KickTokens(ctx context.Context, req *pbauth.KickT...
type Config (line 59) | type Config struct
function Start (line 68) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/rpc/conversation/callback.go
method webhookBeforeCreateSingleChatConversations (line 13) | func (c *conversationServer) webhookBeforeCreateSingleChatConversations(...
method webhookAfterCreateSingleChatConversations (line 47) | func (c *conversationServer) webhookAfterCreateSingleChatConversations(c...
method webhookBeforeCreateGroupChatConversations (line 67) | func (c *conversationServer) webhookBeforeCreateGroupChatConversations(c...
method webhookAfterCreateGroupChatConversations (line 100) | func (c *conversationServer) webhookAfterCreateGroupChatConversations(ct...
FILE: internal/rpc/conversation/conversation.go
type conversationServer (line 48) | type conversationServer struct
method GetConversation (line 120) | func (c *conversationServer) GetConversation(ctx context.Context, req ...
method GetSortedConversationList (line 137) | func (c *conversationServer) GetSortedConversationList(ctx context.Con...
method GetAllConversations (line 224) | func (c *conversationServer) GetAllConversations(ctx context.Context, ...
method GetConversations (line 237) | func (c *conversationServer) GetConversations(ctx context.Context, req...
method getConversations (line 250) | func (c *conversationServer) getConversations(ctx context.Context, own...
method SetConversation (line 261) | func (c *conversationServer) SetConversation(ctx context.Context, req ...
method SetConversations (line 280) | func (c *conversationServer) SetConversations(ctx context.Context, req...
method UpdateConversationsByUser (line 366) | func (c *conversationServer) UpdateConversationsByUser(ctx context.Con...
method CreateSingleChatConversations (line 383) | func (c *conversationServer) CreateSingleChatConversations(ctx context...
method CreateGroupChatConversations (line 442) | func (c *conversationServer) CreateGroupChatConversations(ctx context....
method SetConversationMaxSeq (line 466) | func (c *conversationServer) SetConversationMaxSeq(ctx context.Context...
method SetConversationMinSeq (line 480) | func (c *conversationServer) SetConversationMinSeq(ctx context.Context...
method GetConversationIDs (line 494) | func (c *conversationServer) GetConversationIDs(ctx context.Context, r...
method GetUserConversationIDsHash (line 505) | func (c *conversationServer) GetUserConversationIDsHash(ctx context.Co...
method GetConversationOfflinePushUserIDs (line 516) | func (c *conversationServer) GetConversationOfflinePushUserIDs(ctx con...
method conversationSort (line 540) | func (c *conversationServer) conversationSort(conversations map[int64]...
method getConversationInfo (line 562) | func (c *conversationServer) getConversationInfo(ctx context.Context, ...
method GetConversationNotReceiveMessageUserIDs (line 639) | func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(c...
method UpdateConversation (line 647) | func (c *conversationServer) UpdateConversation(ctx context.Context, r...
method GetOwnerConversation (line 698) | func (c *conversationServer) GetOwnerConversation(ctx context.Context,...
method GetNotNotifyConversationIDs (line 712) | func (c *conversationServer) GetNotNotifyConversationIDs(ctx context.C...
method GetPinnedConversationIDs (line 723) | func (c *conversationServer) GetPinnedConversationIDs(ctx context.Cont...
method ClearUserConversationMsg (line 734) | func (c *conversationServer) ClearUserConversationMsg(ctx context.Cont...
method setConversationMinSeqAndLatestMsgDestructTime (line 764) | func (c *conversationServer) setConversationMinSeqAndLatestMsgDestruct...
method DeleteConversations (line 782) | func (c *conversationServer) DeleteConversations(ctx context.Context, ...
type Config (line 61) | type Config struct
function Start (line 72) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/rpc/conversation/db_map.go
function UpdateConversationsMap (line 10) | func UpdateConversationsMap(ctx context.Context, req *conversation.SetCo...
function UserUpdateCheckMap (line 56) | func UserUpdateCheckMap(ctx context.Context, userID string, req *convers...
FILE: internal/rpc/conversation/notification.go
type ConversationNotificationSender (line 29) | type ConversationNotificationSender struct
method ConversationSetPrivateNotification (line 40) | func (c *ConversationNotificationSender) ConversationSetPrivateNotific...
method ConversationChangeNotification (line 53) | func (c *ConversationNotificationSender) ConversationChangeNotificatio...
method ConversationUnreadChangeNotification (line 62) | func (c *ConversationNotificationSender) ConversationUnreadChangeNotif...
method ConversationDeleteNotification (line 77) | func (c *ConversationNotificationSender) ConversationDeleteNotificatio...
function NewConversationNotificationSender (line 33) | func NewConversationNotificationSender(conf *config.Notification, msgCli...
FILE: internal/rpc/conversation/sync.go
method GetFullOwnerConversationIDs (line 13) | func (c *conversationServer) GetFullOwnerConversationIDs(ctx context.Con...
method GetIncrementalConversation (line 37) | func (c *conversationServer) GetIncrementalConversation(ctx context.Cont...
FILE: internal/rpc/group/cache.go
method GetGroupInfoCache (line 25) | func (g *groupServer) GetGroupInfoCache(ctx context.Context, req *pbgrou...
method GetGroupMemberCache (line 35) | func (g *groupServer) GetGroupMemberCache(ctx context.Context, req *pbgr...
FILE: internal/rpc/group/callback.go
method webhookBeforeCreateGroup (line 35) | func (g *groupServer) webhookBeforeCreateGroup(ctx context.Context, befo...
method webhookAfterCreateGroup (line 80) | func (g *groupServer) webhookAfterCreateGroup(ctx context.Context, after...
method webhookBeforeMembersJoinGroup (line 104) | func (g *groupServer) webhookBeforeMembersJoinGroup(ctx context.Context,...
method webhookBeforeSetGroupMemberInfo (line 147) | func (g *groupServer) webhookBeforeSetGroupMemberInfo(ctx context.Contex...
method webhookAfterSetGroupMemberInfo (line 186) | func (g *groupServer) webhookAfterSetGroupMemberInfo(ctx context.Context...
method webhookAfterQuitGroup (line 207) | func (g *groupServer) webhookAfterQuitGroup(ctx context.Context, after *...
method webhookAfterKickGroupMember (line 216) | func (g *groupServer) webhookAfterKickGroupMember(ctx context.Context, a...
method webhookAfterDismissGroup (line 226) | func (g *groupServer) webhookAfterDismissGroup(ctx context.Context, afte...
method webhookBeforeApplyJoinGroup (line 231) | func (g *groupServer) webhookBeforeApplyJoinGroup(ctx context.Context, b...
method webhookAfterTransferGroupOwner (line 242) | func (g *groupServer) webhookAfterTransferGroupOwner(ctx context.Context...
method webhookBeforeInviteUserToGroup (line 252) | func (g *groupServer) webhookBeforeInviteUserToGroup(ctx context.Context...
method webhookAfterJoinGroup (line 278) | func (g *groupServer) webhookAfterJoinGroup(ctx context.Context, after *...
method webhookBeforeSetGroupInfo (line 290) | func (g *groupServer) webhookBeforeSetGroupInfo(ctx context.Context, bef...
method webhookAfterSetGroupInfo (line 339) | func (g *groupServer) webhookAfterSetGroupInfo(ctx context.Context, afte...
method webhookBeforeSetGroupInfoEx (line 363) | func (g *groupServer) webhookBeforeSetGroupInfoEx(ctx context.Context, b...
method webhookAfterSetGroupInfoEx (line 408) | func (g *groupServer) webhookAfterSetGroupInfoEx(ctx context.Context, af...
FILE: internal/rpc/group/convert.go
method groupDB2PB (line 22) | func (g *groupServer) groupDB2PB(group *model.Group, ownerUserID string,...
method groupMemberDB2PB (line 44) | func (g *groupServer) groupMemberDB2PB(member *model.GroupMember, appMan...
method groupMemberDB2PB2 (line 61) | func (g *groupServer) groupMemberDB2PB2(member *model.GroupMember) *sdkw...
FILE: internal/rpc/group/db_map.go
function UpdateGroupInfoMap (line 28) | func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSe...
function UpdateGroupInfoExMap (line 59) | func UpdateGroupInfoExMap(ctx context.Context, group *pbgroup.SetGroupIn...
function UpdateGroupStatusMap (line 107) | func UpdateGroupStatusMap(status int) map[string]any {
function UpdateGroupMemberMutedTimeMap (line 113) | func UpdateGroupMemberMutedTimeMap(t time.Time) map[string]any {
function UpdateGroupMemberMap (line 119) | func UpdateGroupMemberMap(req *pbgroup.SetGroupMemberInfo) map[string]any {
FILE: internal/rpc/group/fill.go
method PopulateGroupMember (line 23) | func (g *groupServer) PopulateGroupMember(ctx context.Context, members ....
FILE: internal/rpc/group/group.go
type groupServer (line 57) | type groupServer struct
method NotificationUserInfoUpdate (line 129) | func (g *groupServer) NotificationUserInfoUpdate(ctx context.Context, ...
method CheckGroupAdmin (line 155) | func (g *groupServer) CheckGroupAdmin(ctx context.Context, groupID str...
method IsNotFound (line 172) | func (g *groupServer) IsNotFound(err error) bool {
method GenGroupID (line 176) | func (g *groupServer) GenGroupID(ctx context.Context, groupID *string)...
method CreateGroup (line 205) | func (g *groupServer) CreateGroup(ctx context.Context, req *pbgroup.Cr...
method GetJoinedGroupList (line 315) | func (g *groupServer) GetJoinedGroupList(ctx context.Context, req *pbg...
method InviteUserToGroup (line 361) | func (g *groupServer) InviteUserToGroup(ctx context.Context, req *pbgr...
method GetGroupAllMember (line 481) | func (g *groupServer) GetGroupAllMember(ctx context.Context, req *pbgr...
method checkAdminOrInGroup (line 509) | func (g *groupServer) checkAdminOrInGroup(ctx context.Context, groupID...
method GetGroupMemberList (line 524) | func (g *groupServer) GetGroupMemberList(ctx context.Context, req *pbg...
method KickGroupMember (line 550) | func (g *groupServer) KickGroupMember(ctx context.Context, req *pbgrou...
method GetGroupMembersInfo (line 660) | func (g *groupServer) GetGroupMembersInfo(ctx context.Context, req *pb...
method getGroupMembersInfo (line 679) | func (g *groupServer) getGroupMembersInfo(ctx context.Context, groupID...
method GetGroupApplicationList (line 696) | func (g *groupServer) GetGroupApplicationList(ctx context.Context, req...
method GetGroupsInfo (line 779) | func (g *groupServer) GetGroupsInfo(ctx context.Context, req *pbgroup....
method GetGroupApplicationUnhandledCount (line 792) | func (g *groupServer) GetGroupApplicationUnhandledCount(ctx context.Co...
method getGroupsInfo (line 809) | func (g *groupServer) getGroupsInfo(ctx context.Context, groupIDs []st...
method GroupApplicationResponse (line 840) | func (g *groupServer) GroupApplicationResponse(ctx context.Context, re...
method JoinGroup (line 922) | func (g *groupServer) JoinGroup(ctx context.Context, req *pbgroup.Join...
method QuitGroup (line 1000) | func (g *groupServer) QuitGroup(ctx context.Context, req *pbgroup.Quit...
method deleteMemberAndSetConversationSeq (line 1031) | func (g *groupServer) deleteMemberAndSetConversationSeq(ctx context.Co...
method setMemberJoinSeq (line 1040) | func (g *groupServer) setMemberJoinSeq(ctx context.Context, groupID st...
method SetGroupInfo (line 1045) | func (g *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.S...
method SetGroupInfoEx (line 1138) | func (g *groupServer) SetGroupInfoEx(ctx context.Context, req *pbgroup...
method TransferGroupOwner (line 1252) | func (g *groupServer) TransferGroupOwner(ctx context.Context, req *pbg...
method GetGroups (line 1315) | func (g *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetG...
method GetGroupMembersCMS (line 1364) | func (g *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbg...
method GetUserReqApplicationList (line 1383) | func (g *groupServer) GetUserReqApplicationList(ctx context.Context, r...
method DismissGroup (line 1437) | func (g *groupServer) DismissGroup(ctx context.Context, req *pbgroup.D...
method MuteGroupMember (line 1491) | func (g *groupServer) MuteGroupMember(ctx context.Context, req *pbgrou...
method CancelMuteGroupMember (line 1525) | func (g *groupServer) CancelMuteGroupMember(ctx context.Context, req *...
method MuteGroup (line 1565) | func (g *groupServer) MuteGroup(ctx context.Context, req *pbgroup.Mute...
method CancelMuteGroup (line 1576) | func (g *groupServer) CancelMuteGroup(ctx context.Context, req *pbgrou...
method SetGroupMemberInfo (line 1587) | func (g *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbg...
method GetGroupAbstractInfo (line 1743) | func (g *groupServer) GetGroupAbstractInfo(ctx context.Context, req *p...
method GetUserInGroupMembers (line 1779) | func (g *groupServer) GetUserInGroupMembers(ctx context.Context, req *...
method GetGroupMemberUserIDs (line 1800) | func (g *groupServer) GetGroupMemberUserIDs(ctx context.Context, req *...
method GetGroupMemberRoleLevel (line 1813) | func (g *groupServer) GetGroupMemberRoleLevel(ctx context.Context, req...
method GetGroupUsersReqApplicationList (line 1834) | func (g *groupServer) GetGroupUsersReqApplicationList(ctx context.Cont...
method GetSpecifiedUserGroupRequestInfo (line 1905) | func (g *groupServer) GetSpecifiedUserGroupRequestInfo(ctx context.Con...
type Config (line 69) | type Config struct
function Start (line 80) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/rpc/group/notification.go
constant applicantReceiver (line 51) | applicantReceiver = iota
constant adminReceiver (line 52) | adminReceiver
function NewNotificationSender (line 55) | func NewNotificationSender(db controller.GroupDatabase, config *Config, ...
type NotificationSender (line 77) | type NotificationSender struct
method PopulateGroupMember (line 86) | func (g *NotificationSender) PopulateGroupMember(ctx context.Context, ...
method getUser (line 121) | func (g *NotificationSender) getUser(ctx context.Context, userID strin...
method getGroupInfo (line 137) | func (g *NotificationSender) getGroupInfo(ctx context.Context, groupID...
method getGroupMembers (line 158) | func (g *NotificationSender) getGroupMembers(ctx context.Context, grou...
method getGroupMemberMap (line 174) | func (g *NotificationSender) getGroupMemberMap(ctx context.Context, gr...
method getGroupMember (line 186) | func (g *NotificationSender) getGroupMember(ctx context.Context, group...
method getGroupOwnerAndAdminUserID (line 197) | func (g *NotificationSender) getGroupOwnerAndAdminUserID(ctx context.C...
method groupMemberDB2PB (line 209) | func (g *NotificationSender) groupMemberDB2PB(member *model.GroupMembe...
method fillOpUser (line 238) | func (g *NotificationSender) fillOpUser(ctx context.Context, targetUse...
method fillUserByUserID (line 242) | func (g *NotificationSender) fillUserByUserID(ctx context.Context, use...
method setVersion (line 286) | func (g *NotificationSender) setVersion(ctx context.Context, version *...
method setSortVersion (line 298) | func (g *NotificationSender) setSortVersion(ctx context.Context, versi...
method GroupCreatedNotification (line 313) | func (g *NotificationSender) GroupCreatedNotification(ctx context.Cont...
method GroupInfoSetNotification (line 327) | func (g *NotificationSender) GroupInfoSetNotification(ctx context.Cont...
method GroupInfoSetNameNotification (line 341) | func (g *NotificationSender) GroupInfoSetNameNotification(ctx context....
method GroupInfoSetAnnouncementNotification (line 355) | func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx ...
method uuid (line 369) | func (g *NotificationSender) uuid() string {
method getGroupRequest (line 373) | func (g *NotificationSender) getGroupRequest(ctx context.Context, grou...
method JoinGroupApplicationNotification (line 397) | func (g *NotificationSender) JoinGroupApplicationNotification(ctx cont...
method MemberQuitNotification (line 436) | func (g *NotificationSender) MemberQuitNotification(ctx context.Contex...
method GroupApplicationAcceptedNotification (line 453) | func (g *NotificationSender) GroupApplicationAcceptedNotification(ctx ...
method GroupApplicationRejectedNotification (line 497) | func (g *NotificationSender) GroupApplicationRejectedNotification(ctx ...
method GroupOwnerTransferredNotification (line 541) | func (g *NotificationSender) GroupOwnerTransferredNotification(ctx con...
method MemberKickedNotification (line 572) | func (g *NotificationSender) MemberKickedNotification(ctx context.Cont...
method GroupApplicationAgreeMemberEnterNotification (line 586) | func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotificat...
method groupApplicationAgreeMemberEnterNotification (line 590) | func (g *NotificationSender) groupApplicationAgreeMemberEnterNotificat...
method MemberEnterNotification (line 642) | func (g *NotificationSender) MemberEnterNotification(ctx context.Conte...
method GroupDismissedNotification (line 683) | func (g *NotificationSender) GroupDismissedNotification(ctx context.Co...
method GroupMemberMutedNotification (line 696) | func (g *NotificationSender) GroupMemberMutedNotification(ctx context....
method GroupMemberCancelMutedNotification (line 724) | func (g *NotificationSender) GroupMemberCancelMutedNotification(ctx co...
method GroupMutedNotification (line 749) | func (g *NotificationSender) GroupMutedNotification(ctx context.Contex...
method GroupCancelMutedNotification (line 777) | func (g *NotificationSender) GroupCancelMutedNotification(ctx context....
method GroupMemberInfoSetNotification (line 805) | func (g *NotificationSender) GroupMemberInfoSetNotification(ctx contex...
method GroupMemberSetToAdminNotification (line 830) | func (g *NotificationSender) GroupMemberSetToAdminNotification(ctx con...
method GroupMemberSetToOrdinaryUserNotification (line 854) | func (g *NotificationSender) GroupMemberSetToOrdinaryUserNotification(...
FILE: internal/rpc/group/statistics.go
method GroupCreateCount (line 26) | func (g *groupServer) GroupCreateCount(ctx context.Context, req *group.G...
FILE: internal/rpc/group/sync.go
constant versionSyncLimit (line 18) | versionSyncLimit = 500
method GetFullGroupMemberUserIDs (line 20) | func (g *groupServer) GetFullGroupMemberUserIDs(ctx context.Context, req...
method GetFullJoinGroupIDs (line 44) | func (g *groupServer) GetFullJoinGroupIDs(ctx context.Context, req *pbgr...
method GetIncrementalGroupMember (line 68) | func (g *groupServer) GetIncrementalGroupMember(ctx context.Context, req...
method GetIncrementalJoinGroup (line 146) | func (g *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *...
method BatchGetIncrementalGroupMember (line 172) | func (g *groupServer) BatchGetIncrementalGroupMember(ctx context.Context...
FILE: internal/rpc/incrversion/batch_option.go
type BatchOption (line 12) | type BatchOption struct
method newError (line 24) | func (o *BatchOption[A, B]) newError(msg string) error {
method check (line 28) | func (o *BatchOption[A, B]) check() error {
method validVersions (line 47) | func (o *BatchOption[A, B]) validVersions() []bool {
method equalIDs (line 56) | func (o *BatchOption[A, B]) equalIDs(objIDs []primitive.ObjectID) []bool {
method getVersions (line 64) | func (o *BatchOption[A, B]) getVersions(tags *[]int) (versions map[strin...
method Build (line 139) | func (o *BatchOption[A, B]) Build() (*B, error) {
FILE: internal/rpc/incrversion/option.go
constant syncLimit (line 19) | syncLimit = 200
constant tagQuery (line 22) | tagQuery = iota + 1
constant tagFull (line 23) | tagFull
constant tagEqual (line 24) | tagEqual
type Option (line 27) | type Option struct
method newError (line 40) | func (o *Option[A, B]) newError(msg string) error {
method check (line 44) | func (o *Option[A, B]) check() error {
method validVersion (line 69) | func (o *Option[A, B]) validVersion() bool {
method equalID (line 74) | func (o *Option[A, B]) equalID(objID primitive.ObjectID) bool {
method getVersion (line 78) | func (o *Option[A, B]) getVersion(tag *int) (*model.VersionLog, error) {
method Build (line 108) | func (o *Option[A, B]) Build() (*B, error) {
FILE: internal/rpc/msg/as_read.go
method GetConversationsHasReadAndMaxSeq (line 32) | func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context...
method SetConversationHasReadSeq (line 88) | func (m *msgServer) SetConversationHasReadSeq(ctx context.Context, req *...
method MarkMsgsAsRead (line 106) | func (m *msgServer) MarkMsgsAsRead(ctx context.Context, req *msg.MarkMsg...
method MarkConversationAsRead (line 148) | func (m *msgServer) MarkConversationAsRead(ctx context.Context, req *msg...
method sendMarkAsReadNotification (line 221) | func (m *msgServer) sendMarkAsReadNotification(ctx context.Context, conv...
FILE: internal/rpc/msg/callback.go
function toCommonCallback (line 37) | func toCommonCallback(ctx context.Context, msg *pbchat.SendMsgReq, comma...
function GetContent (line 60) | func GetContent(msg *sdkws.MsgData) string {
method webhookBeforeSendSingleMsg (line 71) | func (m *msgServer) webhookBeforeSendSingleMsg(ctx context.Context, befo...
method webhookAfterSendSingleMsg (line 93) | func (m *msgServer) webhookAfterSendSingleMsg(ctx context.Context, after...
method webhookBeforeSendGroupMsg (line 107) | func (m *msgServer) webhookBeforeSendGroupMsg(ctx context.Context, befor...
method webhookAfterSendGroupMsg (line 127) | func (m *msgServer) webhookAfterSendGroupMsg(ctx context.Context, after ...
method webhookBeforeMsgModify (line 142) | func (m *msgServer) webhookBeforeMsgModify(ctx context.Context, before *...
method webhookAfterGroupMsgRead (line 186) | func (m *msgServer) webhookAfterGroupMsgRead(ctx context.Context, after ...
method webhookAfterSingleMsgRead (line 191) | func (m *msgServer) webhookAfterSingleMsgRead(ctx context.Context, after...
method webhookAfterRevokeMsg (line 199) | func (m *msgServer) webhookAfterRevokeMsg(ctx context.Context, after *co...
function buildKeyMsgDataQuery (line 209) | func buildKeyMsgDataQuery(msg *sdkws.MsgData) map[string]string {
FILE: internal/rpc/msg/clear.go
method DestructMsgs (line 13) | func (m *msgServer) DestructMsgs(ctx context.Context, req *msg.DestructM...
method GetLastMessageSeqByTime (line 55) | func (m *msgServer) GetLastMessageSeqByTime(ctx context.Context, req *ms...
FILE: internal/rpc/msg/delete.go
method getMinSeqs (line 28) | func (m *msgServer) getMinSeqs(maxSeqs map[string]int64) map[string]int64 {
method validateDeleteSyncOpt (line 36) | func (m *msgServer) validateDeleteSyncOpt(opt *msg.DeleteSyncOpt) (isSyn...
method ClearConversationsMsg (line 43) | func (m *msgServer) ClearConversationsMsg(ctx context.Context, req *msg....
method UserClearAllMsg (line 53) | func (m *msgServer) UserClearAllMsg(ctx context.Context, req *msg.UserCl...
method DeleteMsgs (line 67) | func (m *msgServer) DeleteMsgs(ctx context.Context, req *msg.DeleteMsgsR...
method DeleteMsgPhysicalBySeq (line 95) | func (m *msgServer) DeleteMsgPhysicalBySeq(ctx context.Context, req *msg...
method DeleteMsgPhysical (line 106) | func (m *msgServer) DeleteMsgPhysical(ctx context.Context, req *msg.Dele...
method clearConversation (line 117) | func (m *msgServer) clearConversation(ctx context.Context, conversationI...
FILE: internal/rpc/msg/filter.go
constant separator (line 14) | separator = "-"
function filterAfterMsg (line 17) | func filterAfterMsg(msg *pbchat.SendMsgReq, after *config.AfterConfig) b...
function filterBeforeMsg (line 21) | func filterBeforeMsg(msg *pbchat.SendMsgReq, before *config.BeforeConfig...
function filterMsg (line 25) | func filterMsg(msg *pbchat.SendMsgReq, attentionIds []string, deniedType...
function defaultDeniedTypes (line 47) | func defaultDeniedTypes(contentType int32) bool {
function isInInterval (line 61) | func isInInterval(data int32, interval []string) bool {
FILE: internal/rpc/msg/msg_status.go
method SetSendMsgStatus (line 25) | func (m *msgServer) SetSendMsgStatus(ctx context.Context, req *pbmsg.Set...
method GetSendMsgStatus (line 33) | func (m *msgServer) GetSendMsgStatus(ctx context.Context, req *pbmsg.Get...
FILE: internal/rpc/msg/notification.go
type MsgNotificationSender (line 25) | type MsgNotificationSender struct
method UserDeleteMsgsNotification (line 33) | func (m *MsgNotificationSender) UserDeleteMsgsNotification(ctx context...
method MarkAsReadNotification (line 42) | func (m *MsgNotificationSender) MarkAsReadNotification(ctx context.Con...
function NewMsgNotificationSender (line 29) | func NewMsgNotificationSender(config *Config, opts ...notification.Notif...
FILE: internal/rpc/msg/revoke.go
method RevokeMsg (line 35) | func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq...
FILE: internal/rpc/msg/send.go
method SendMsg (line 37) | func (m *msgServer) SendMsg(ctx context.Context, req *pbmsg.SendMsgReq) ...
method sendMsg (line 55) | func (m *msgServer) sendMsg(ctx context.Context, req *pbmsg.SendMsgReq, ...
method sendMsgGroupChat (line 69) | func (m *msgServer) sendMsgGroupChat(ctx context.Context, req *pbmsg.Sen...
method setConversationAtInfo (line 99) | func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdk...
method sendMsgNotification (line 161) | func (m *msgServer) sendMsgNotification(ctx context.Context, req *pbmsg....
method sendMsgSingleChat (line 173) | func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbmsg.Se...
method SendSimpleMsg (line 207) | func (m *msgServer) SendSimpleMsg(ctx context.Context, req *pbmsg.SendSi...
FILE: internal/rpc/msg/seq.go
method GetConversationMaxSeq (line 26) | func (m *msgServer) GetConversationMaxSeq(ctx context.Context, req *pbms...
method GetMaxSeqs (line 34) | func (m *msgServer) GetMaxSeqs(ctx context.Context, req *pbmsg.GetMaxSeq...
method GetHasReadSeqs (line 42) | func (m *msgServer) GetHasReadSeqs(ctx context.Context, req *pbmsg.GetHa...
method GetMsgByConversationIDs (line 50) | func (m *msgServer) GetMsgByConversationIDs(ctx context.Context, req *pb...
method SetUserConversationsMinSeq (line 58) | func (m *msgServer) SetUserConversationsMinSeq(ctx context.Context, req ...
method GetActiveConversation (line 67) | func (m *msgServer) GetActiveConversation(ctx context.Context, req *pbms...
method SetUserConversationMaxSeq (line 89) | func (m *msgServer) SetUserConversationMaxSeq(ctx context.Context, req *...
method SetUserConversationMinSeq (line 98) | func (m *msgServer) SetUserConversationMinSeq(ctx context.Context, req *...
FILE: internal/rpc/msg/server.go
type MessageInterceptorFunc (line 41) | type MessageInterceptorFunc
type MessageInterceptorChain (line 44) | type MessageInterceptorChain
type Config (line 46) | type Config struct
type msgServer (line 59) | type msgServer struct
method addInterceptorHandler (line 77) | func (m *msgServer) addInterceptorHandler(interceptorFunc ...MessageIn...
method conversationAndGetRecvID (line 160) | func (m *msgServer) conversationAndGetRecvID(conversation *conversatio...
function Start (line 82) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/rpc/msg/statistics.go
method GetActiveUser (line 29) | func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiv...
method GetActiveGroup (line 67) | func (m *msgServer) GetActiveGroup(ctx context.Context, req *msg.GetActi...
FILE: internal/rpc/msg/sync_msg.go
method PullMessageBySeqs (line 31) | func (m *msgServer) PullMessageBySeqs(ctx context.Context, req *sdkws.Pu...
method GetSeqMessage (line 92) | func (m *msgServer) GetSeqMessage(ctx context.Context, req *msg.GetSeqMe...
method GetMaxSeq (line 123) | func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqR...
method SearchMessage (line 152) | func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMe...
method GetServerTime (line 248) | func (m *msgServer) GetServerTime(ctx context.Context, _ *msg.GetServerT...
method GetLastMessage (line 252) | func (m *msgServer) GetLastMessage(ctx context.Context, req *msg.GetLast...
FILE: internal/rpc/msg/utils.go
function IsNotFound (line 24) | func IsNotFound(err error) bool {
type activeConversations (line 33) | type activeConversations
method Len (line 35) | func (s activeConversations) Len() int {
method Less (line 39) | func (s activeConversations) Less(i, j int) bool {
method Swap (line 43) | func (s activeConversations) Swap(i, j int) {
FILE: internal/rpc/msg/verify.go
type Validator (line 37) | type Validator interface
type MessageRevoked (line 41) | type MessageRevoked struct
method messageVerification (line 54) | func (m *msgServer) messageVerification(ctx context.Context, data *msg.S...
method encapsulateMsgData (line 143) | func (m *msgServer) encapsulateMsgData(msg *sdkws.MsgData) {
function GetMsgID (line 171) | func GetMsgID(sendID string) string {
method modifyMessageByUserMessageReceiveOpt (line 176) | func (m *msgServer) modifyMessageByUserMessageReceiveOpt(ctx context.Con...
FILE: internal/rpc/relation/black.go
method GetPaginationBlacks (line 31) | func (s *friendServer) GetPaginationBlacks(ctx context.Context, req *rel...
method IsBlack (line 48) | func (s *friendServer) IsBlack(ctx context.Context, req *relation.IsBlac...
method RemoveBlack (line 62) | func (s *friendServer) RemoveBlack(ctx context.Context, req *relation.Re...
method AddBlack (line 77) | func (s *friendServer) AddBlack(ctx context.Context, req *relation.AddBl...
method GetSpecifiedBlacks (line 103) | func (s *friendServer) GetSpecifiedBlacks(ctx context.Context, req *rela...
FILE: internal/rpc/relation/callback.go
method webhookAfterDeleteFriend (line 27) | func (s *friendServer) webhookAfterDeleteFriend(ctx context.Context, aft...
method webhookBeforeAddFriend (line 36) | func (s *friendServer) webhookBeforeAddFriend(ctx context.Context, befor...
method webhookAfterAddFriend (line 54) | func (s *friendServer) webhookAfterAddFriend(ctx context.Context, after ...
method webhookAfterSetFriendRemark (line 65) | func (s *friendServer) webhookAfterSetFriendRemark(ctx context.Context, ...
method webhookAfterImportFriends (line 76) | func (s *friendServer) webhookAfterImportFriends(ctx context.Context, af...
method webhookAfterRemoveBlack (line 86) | func (s *friendServer) webhookAfterRemoveBlack(ctx context.Context, afte...
method webhookBeforeSetFriendRemark (line 96) | func (s *friendServer) webhookBeforeSetFriendRemark(ctx context.Context,...
method webhookBeforeAddBlack (line 115) | func (s *friendServer) webhookBeforeAddBlack(ctx context.Context, before...
method webhookBeforeAddFriendAgree (line 127) | func (s *friendServer) webhookBeforeAddFriendAgree(ctx context.Context, ...
method webhookAfterAddFriendAgree (line 141) | func (s *friendServer) webhookAfterAddFriendAgree(ctx context.Context, a...
method webhookBeforeImportFriends (line 153) | func (s *friendServer) webhookBeforeImportFriends(ctx context.Context, b...
FILE: internal/rpc/relation/friend.go
type friendServer (line 45) | type friendServer struct
method ApplyToAddFriend (line 137) | func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *rela...
method ImportFriends (line 168) | func (s *friendServer) ImportFriends(ctx context.Context, req *relatio...
method RespondFriendApply (line 203) | func (s *friendServer) RespondFriendApply(ctx context.Context, req *re...
method DeleteFriend (line 239) | func (s *friendServer) DeleteFriend(ctx context.Context, req *relation...
method SetFriendRemark (line 260) | func (s *friendServer) SetFriendRemark(ctx context.Context, req *relat...
method GetFriendInfo (line 284) | func (s *friendServer) GetFriendInfo(ctx context.Context, req *relatio...
method GetDesignatedFriends (line 295) | func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *...
method getFriend (line 312) | func (s *friendServer) getFriend(ctx context.Context, ownerUserID stri...
method GetDesignatedFriendsApply (line 324) | func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context, ...
method GetPaginationFriendsApplyTo (line 341) | func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context...
method GetPaginationFriendsApplyFrom (line 365) | func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Conte...
method IsFriend (line 390) | func (s *friendServer) IsFriend(ctx context.Context, req *relation.IsF...
method GetPaginationFriends (line 402) | func (s *friendServer) GetPaginationFriends(ctx context.Context, req *...
method GetFriendIDs (line 423) | func (s *friendServer) GetFriendIDs(ctx context.Context, req *relation...
method GetSpecifiedFriendsInfo (line 437) | func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, re...
method UpdateFriends (line 517) | func (s *friendServer) UpdateFriends(ctx context.Context, req *relatio...
method GetSelfUnhandledApplyCount (line 555) | func (s *friendServer) GetSelfUnhandledApplyCount(ctx context.Context,...
method getCommonUserMap (line 570) | func (s *friendServer) getCommonUserMap(ctx context.Context, userIDs [...
type Config (line 57) | type Config struct
function Start (line 69) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/rpc/relation/notification.go
type FriendNotificationSender (line 42) | type FriendNotificationSender struct
method getUsersInfoMap (line 102) | func (f *FriendNotificationSender) getUsersInfoMap(ctx context.Context...
method getFromToUserNickname (line 115) | func (f *FriendNotificationSender) getFromToUserNickname(ctx context.C...
method UserInfoUpdatedNotification (line 123) | func (f *FriendNotificationSender) UserInfoUpdatedNotification(ctx con...
method getCommonUserMap (line 128) | func (f *FriendNotificationSender) getCommonUserMap(ctx context.Contex...
method getFriendRequests (line 138) | func (f *FriendNotificationSender) getFriendRequests(ctx context.Conte...
method FriendApplicationAddNotification (line 158) | func (f *FriendNotificationSender) FriendApplicationAddNotification(ct...
method FriendApplicationAgreedNotification (line 174) | func (f *FriendNotificationSender) FriendApplicationAgreedNotification...
method FriendApplicationRefusedNotification (line 197) | func (f *FriendNotificationSender) FriendApplicationRefusedNotificatio...
method FriendDeletedNotification (line 236) | func (f *FriendNotificationSender) FriendDeletedNotification(ctx conte...
method setVersion (line 244) | func (f *FriendNotificationSender) setVersion(ctx context.Context, ver...
method setSortVersion (line 255) | func (f *FriendNotificationSender) setSortVersion(ctx context.Context,...
method FriendRemarkSetNotification (line 270) | func (f *FriendNotificationSender) FriendRemarkSetNotification(ctx con...
method FriendsInfoUpdateNotification (line 278) | func (f *FriendNotificationSender) FriendsInfoUpdateNotification(ctx c...
method BlackAddedNotification (line 285) | func (f *FriendNotificationSender) BlackAddedNotification(ctx context....
method BlackDeletedNotification (line 292) | func (f *FriendNotificationSender) BlackDeletedNotification(ctx contex...
method FriendInfoUpdatedNotification (line 300) | func (f *FriendNotificationSender) FriendInfoUpdatedNotification(ctx c...
type friendNotificationSenderOptions (line 50) | type friendNotificationSenderOptions
function WithFriendDB (line 52) | func WithFriendDB(db controller.FriendDatabase) friendNotificationSender...
function WithDBFunc (line 58) | func WithDBFunc(fn func(ctx context.Context, userIDs []string) (users []...
function WithRpcFunc (line 74) | func WithRpcFunc(fn func(ctx context.Context, userIDs []string) ([]*sdkw...
function NewFriendNotificationSender (line 90) | func NewFriendNotificationSender(conf *config.Notification, msgClient *r...
FILE: internal/rpc/relation/sync.go
method NotificationUserInfoUpdate (line 17) | func (s *friendServer) NotificationUserInfoUpdate(ctx context.Context, r...
method GetFullFriendUserIDs (line 42) | func (s *friendServer) GetFullFriendUserIDs(ctx context.Context, req *re...
method GetIncrementalFriends (line 66) | func (s *friendServer) GetIncrementalFriends(ctx context.Context, req *r...
FILE: internal/rpc/third/log.go
function genLogID (line 32) | func genLogID() string {
method UploadLogs (line 47) | func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadL...
method DeleteLogs (line 85) | func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteL...
function dbToPbLogInfos (line 109) | func dbToPbLogInfos(logs []*relationtb.Log) []*third.LogInfo {
method SearchLogs (line 126) | func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchL...
FILE: internal/rpc/third/s3.go
method PartLimit (line 40) | func (t *thirdServer) PartLimit(ctx context.Context, req *third.PartLimi...
method PartSize (line 52) | func (t *thirdServer) PartSize(ctx context.Context, req *third.PartSizeR...
method InitiateMultipartUpload (line 60) | func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *...
method AuthSign (line 114) | func (t *thirdServer) AuthSign(ctx context.Context, req *third.AuthSignR...
method CompleteMultipartUpload (line 137) | func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *...
method AccessURL (line 163) | func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessUR...
method InitiateFormData (line 188) | func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.I...
method CompleteFormData (line 249) | func (t *thirdServer) CompleteFormData(ctx context.Context, req *third.C...
method apiAddress (line 287) | func (t *thirdServer) apiAddress(prefix, name string) string {
method DeleteOutdatedData (line 291) | func (t *thirdServer) DeleteOutdatedData(ctx context.Context, req *third...
type FormDataMate (line 323) | type FormDataMate struct
FILE: internal/rpc/third/third.go
type thirdServer (line 46) | type thirdServer struct
method FcmUpdateToken (line 143) | func (t *thirdServer) FcmUpdateToken(ctx context.Context, req *third.F...
method SetAppBadge (line 151) | func (t *thirdServer) SetAppBadge(ctx context.Context, req *third.SetA...
type Config (line 56) | type Config struct
function Start (line 67) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/rpc/third/tool.go
function toPbMapArray (line 29) | func toPbMapArray(m map[string][]string) []*third.KeyValues {
method checkUploadName (line 43) | func (t *thirdServer) checkUploadName(ctx context.Context, name string) ...
function checkValidObjectNamePrefix (line 65) | func checkValidObjectNamePrefix(objectName string) error {
function checkValidObjectName (line 75) | func checkValidObjectName(objectName string) error {
function putUpdate (line 82) | func putUpdate[T any](update map[string]any, name string, val interface{...
FILE: internal/rpc/user/callback.go
method webhookBeforeUpdateUserInfo (line 28) | func (s *userServer) webhookBeforeUpdateUserInfo(ctx context.Context, be...
method webhookAfterUpdateUserInfo (line 48) | func (s *userServer) webhookAfterUpdateUserInfo(ctx context.Context, aft...
method webhookBeforeUpdateUserInfoEx (line 58) | func (s *userServer) webhookBeforeUpdateUserInfoEx(ctx context.Context, ...
method webhookAfterUpdateUserInfoEx (line 78) | func (s *userServer) webhookAfterUpdateUserInfoEx(ctx context.Context, a...
method webhookBeforeUserRegister (line 88) | func (s *userServer) webhookBeforeUserRegister(ctx context.Context, befo...
method webhookAfterUserRegister (line 108) | func (s *userServer) webhookAfterUserRegister(ctx context.Context, after...
FILE: internal/rpc/user/config.go
method GetUserClientConfig (line 12) | func (s *userServer) GetUserClientConfig(ctx context.Context, req *pbuse...
method SetUserClientConfig (line 28) | func (s *userServer) SetUserClientConfig(ctx context.Context, req *pbuse...
method DelUserClientConfig (line 43) | func (s *userServer) DelUserClientConfig(ctx context.Context, req *pbuse...
method PageUserClientConfig (line 53) | func (s *userServer) PageUserClientConfig(ctx context.Context, req *pbus...
FILE: internal/rpc/user/notification.go
type UserNotificationSender (line 32) | type UserNotificationSender struct
method UserStatusChangeNotification (line 103) | func (u *UserNotificationSender) UserStatusChangeNotification(
method UserCommandUpdateNotification (line 109) | func (u *UserNotificationSender) UserCommandUpdateNotification(
method UserCommandAddNotification (line 115) | func (u *UserNotificationSender) UserCommandAddNotification(
method UserCommandDeleteNotification (line 121) | func (u *UserNotificationSender) UserCommandDeleteNotification(
type userNotificationSenderOptions (line 39) | type userNotificationSenderOptions
function WithUserDB (line 41) | func WithUserDB(db controller.UserDatabase) userNotificationSenderOptions {
function WithUserFunc (line 47) | func WithUserFunc(
function NewUserNotificationSender (line 65) | func NewUserNotificationSender(config *Config, msgClient *rpcli.MsgClien...
FILE: internal/rpc/user/online.go
method getUserOnlineStatus (line 12) | func (s *userServer) getUserOnlineStatus(ctx context.Context, userID str...
method getUsersOnlineStatus (line 29) | func (s *userServer) getUsersOnlineStatus(ctx context.Context, userIDs [...
method SubscribeOrCancelUsersStatus (line 42) | func (s *userServer) SubscribeOrCancelUsersStatus(ctx context.Context, r...
method GetUserStatus (line 47) | func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetU...
method SetUserStatus (line 56) | func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetU...
method GetSubscribeUsersStatus (line 74) | func (s *userServer) GetSubscribeUsersStatus(ctx context.Context, req *p...
method SetUserOnlineStatus (line 78) | func (s *userServer) SetUserOnlineStatus(ctx context.Context, req *pbuse...
method GetAllOnlineUsers (line 87) | func (s *userServer) GetAllOnlineUsers(ctx context.Context, req *pbuser....
FILE: internal/rpc/user/statistics.go
method UserRegisterCount (line 25) | func (s *userServer) UserRegisterCount(ctx context.Context, req *pbuser....
FILE: internal/rpc/user/user.go
constant defaultSecret (line 53) | defaultSecret = "openIM123"
type userServer (line 56) | type userServer struct
method GetDesignateUsers (line 145) | func (s *userServer) GetDesignateUsers(ctx context.Context, req *pbuse...
method UpdateUserInfo (line 158) | func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.U...
method UpdateUserInfoEx (line 185) | func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser...
method SetGlobalRecvMessageOpt (line 228) | func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req ...
method AccountCheck (line 242) | func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.Acc...
method GetPaginationUsers (line 270) | func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbus...
method UserRegister (line 288) | func (s *userServer) UserRegister(ctx context.Context, req *pbuser.Use...
method GetGlobalRecvMessageOpt (line 346) | func (s *userServer) GetGlobalRecvMessageOpt(ctx context.Context, req ...
method GetAllUserID (line 355) | func (s *userServer) GetAllUserID(ctx context.Context, req *pbuser.Get...
method ProcessUserCommandAdd (line 364) | func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *p...
method ProcessUserCommandDelete (line 392) | func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req...
method ProcessUserCommandUpdate (line 411) | func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req...
method ProcessUserCommandGet (line 439) | func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *p...
method ProcessUserCommandGetAll (line 469) | func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req...
method AddNotificationAccount (line 498) | func (s *userServer) AddNotificationAccount(ctx context.Context, req *...
method UpdateNotificationAccountInfo (line 544) | func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context...
method SearchNotificationAccount (line 570) | func (s *userServer) SearchNotificationAccount(ctx context.Context, re...
method GetNotificationAccount (line 619) | func (s *userServer) GetNotificationAccount(ctx context.Context, req *...
method genUserID (line 639) | func (s *userServer) genUserID() string {
method userModelToResp (line 654) | func (s *userServer) userModelToResp(users []*tablerelation.User, pagi...
method NotificationUserInfoUpdate (line 680) | func (s *userServer) NotificationUserInfoUpdate(ctx context.Context, u...
method SortQuery (line 714) | func (s *userServer) SortQuery(ctx context.Context, req *pbuser.SortQu...
type Config (line 72) | type Config struct
function Start (line 84) | func Start(ctx context.Context, config *Config, client discovery.SvcDisc...
FILE: internal/tools/cron/cron_task.go
type Config (line 21) | type Config struct
function Start (line 27) | func Start(ctx context.Context, conf *Config, client discovery.SvcDiscov...
type Locker (line 98) | type Locker interface
type emptyLocker (line 102) | type emptyLocker struct
method ExecuteWithLock (line 104) | func (emptyLocker) ExecuteWithLock(ctx context.Context, taskName strin...
type cronServer (line 108) | type cronServer struct
method registerClearS3 (line 118) | func (c *cronServer) registerClearS3() error {
method registerDeleteMsg (line 129) | func (c *cronServer) registerDeleteMsg() error {
method registerClearUserMsg (line 140) | func (c *cronServer) registerClearUserMsg() error {
FILE: internal/tools/cron/cron_test.go
function TestName (line 19) | func TestName(t *testing.T) {
FILE: internal/tools/cron/dist_look.go
constant lockLeaseTTL (line 15) | lockLeaseTTL = 300
type EtcdLocker (line 18) | type EtcdLocker struct
method ExecuteWithLock (line 37) | func (e *EtcdLocker) ExecuteWithLock(ctx context.Context, taskName str...
function NewEtcdLocker (line 24) | func NewEtcdLocker(client *clientv3.Client) (*EtcdLocker, error) {
FILE: internal/tools/cron/msg.go
method deleteMsg (line 13) | func (c *cronServer) deleteMsg() {
FILE: internal/tools/cron/s3.go
method clearS3 (line 13) | func (c *cronServer) clearS3() {
FILE: internal/tools/cron/user_msg.go
method clearUserMsg (line 13) | func (c *cronServer) clearUserMsg() {
FILE: magefile.go
function Build (line 34) | func Build() {
function BuildWithCustomConfig (line 43) | func BuildWithCustomConfig() {
function Start (line 62) | func Start() {
function StartWithCustomConfig (line 81) | func StartWithCustomConfig() {
function Stop (line 106) | func Stop() {
function Check (line 110) | func Check() {
function Export (line 114) | func Export() {
FILE: magefile_unix.go
function setMaxOpenFiles (line 12) | func setMaxOpenFiles() error {
FILE: magefile_windows.go
function setMaxOpenFiles (line 6) | func setMaxOpenFiles() error {
FILE: pkg/apistruct/config_manager.go
type GetConfigReq (line 3) | type GetConfigReq struct
type GetConfigListResp (line 7) | type GetConfigListResp struct
type SetConfigReq (line 13) | type SetConfigReq struct
type SetConfigsReq (line 18) | type SetConfigsReq struct
type SetEnableConfigManagerReq (line 22) | type SetEnableConfigManagerReq struct
type GetEnableConfigManagerResp (line 26) | type GetEnableConfigManagerResp struct
FILE: pkg/apistruct/manage.go
type SendMsg (line 23) | type SendMsg struct
type SendMsgReq (line 65) | type SendMsgReq struct
type GetConversationListReq (line 71) | type GetConversationListReq struct
type GetConversationListResp (line 79) | type GetConversationListResp struct
type ConversationElem (line 84) | type ConversationElem struct
type BatchSendMsgReq (line 96) | type BatchSendMsgReq struct
type BatchSendMsgResp (line 107) | type BatchSendMsgResp struct
type SendSingleMsgReq (line 116) | type SendSingleMsgReq struct
type KeyMsgData (line 124) | type KeyMsgData struct
type SingleReturnResult (line 131) | type SingleReturnResult struct
type SendMsgResp (line 148) | type SendMsgResp struct
FILE: pkg/apistruct/msg.go
type PictureBaseInfo (line 19) | type PictureBaseInfo struct
type PictureElem (line 28) | type PictureElem struct
type SoundElem (line 35) | type SoundElem struct
type VideoElem (line 43) | type VideoElem struct
type FileElem (line 58) | type FileElem struct
type AtElem (line 65) | type AtElem struct
type LocationElem (line 72) | type LocationElem struct
type CustomElem (line 78) | type CustomElem struct
type TextElem (line 84) | type TextElem struct
type MarkdownTextElem (line 88) | type MarkdownTextElem struct
type StreamMsgElem (line 92) | type StreamMsgElem struct
type RevokeElem (line 97) | type RevokeElem struct
type QuoteElem (line 101) | type QuoteElem struct
type OANotificationElem (line 106) | type OANotificationElem struct
type MessageRevoked (line 120) | type MessageRevoked struct
type MsgStruct (line 129) | type MsgStruct struct
type AtInfo (line 164) | type AtInfo struct
FILE: pkg/apistruct/public.go
type GroupAddMemberInfo (line 17) | type GroupAddMemberInfo struct
FILE: pkg/authverify/token.go
function Secret (line 28) | func Secret(secret string) jwt.Keyfunc {
function CheckAdmin (line 34) | func CheckAdmin(ctx context.Context) error {
function CheckUserIsAdmin (line 45) | func CheckUserIsAdmin(ctx context.Context, userID string) bool {
function CheckSystemAccount (line 49) | func CheckSystemAccount(ctx context.Context, level int32) bool {
constant CtxAdminUserIDsKey (line 54) | CtxAdminUserIDsKey = "CtxAdminUserIDsKey"
function WithIMAdminUserIDs (line 57) | func WithIMAdminUserIDs(ctx context.Context, imAdminUserID []string) con...
function GetIMAdminUserIDs (line 61) | func GetIMAdminUserIDs(ctx context.Context) []string {
function IsAdmin (line 66) | func IsAdmin(ctx context.Context) bool {
function CheckAccess (line 70) | func CheckAccess(ctx context.Context, ownerUserID string) error {
function CheckAccessIn (line 80) | func CheckAccessIn(ctx context.Context, ownerUserIDs ...string) error {
constant ctxTempAdminKey (line 95) | ctxTempAdminKey = "ctxImTempAdminKey"
function WithTempAdmin (line 97) | func WithTempAdmin(ctx context.Context) context.Context {
function IsTempAdmin (line 113) | func IsTempAdmin(ctx context.Context) bool {
function IsSystemAdmin (line 118) | func IsSystemAdmin(ctx context.Context) bool {
FILE: pkg/callbackstruct/common.go
constant Next (line 23) | Next = 1
type CommonCallbackReq (line 26) | type CommonCallbackReq struct
method GetCallbackCommand (line 47) | func (c *CommonCallbackReq) GetCallbackCommand() string {
type CallbackReq (line 51) | type CallbackReq interface
type CallbackResp (line 55) | type CallbackResp interface
type CommonCallbackResp (line 59) | type CommonCallbackResp struct
method Parse (line 67) | func (c CommonCallbackResp) Parse() error {
type UserStatusBaseCallback (line 74) | type UserStatusBaseCallback struct
method GetCallbackCommand (line 81) | func (c UserStatusBaseCallback) GetCallbackCommand() string {
type UserStatusCallbackReq (line 85) | type UserStatusCallbackReq struct
type UserStatusBatchCallbackReq (line 90) | type UserStatusBatchCallbackReq struct
FILE: pkg/callbackstruct/constant.go
constant CallbackBeforeInviteJoinGroupCommand (line 18) | CallbackBeforeInviteJoinGroupCommand = "callbackBeforeInvi...
constant CallbackAfterJoinGroupCommand (line 19) | CallbackAfterJoinGroupCommand = "callbackAfterJoinG...
constant CallbackAfterSetGroupInfoCommand (line 20) | CallbackAfterSetGroupInfoCommand = "callbackAfterSetGr...
constant CallbackAfterSetGroupInfoExCommand (line 21) | CallbackAfterSetGroupInfoExCommand = "callbackAfterSetGr...
constant CallbackBeforeSetGroupInfoCommand (line 22) | CallbackBeforeSetGroupInfoCommand = "callbackBeforeSetG...
constant CallbackBeforeSetGroupInfoExCommand (line 23) | CallbackBeforeSetGroupInfoExCommand = "callbackBeforeSetG...
constant CallbackAfterRevokeMsgCommand (line 24) | CallbackAfterRevokeMsgCommand = "callbackBeforeAfte...
constant CallbackBeforeAddBlackCommand (line 25) | CallbackBeforeAddBlackCommand = "callbackBeforeAddB...
constant CallbackAfterAddFriendCommand (line 26) | CallbackAfterAddFriendCommand = "callbackAfterAddFr...
constant CallbackBeforeAddFriendAgreeCommand (line 27) | CallbackBeforeAddFriendAgreeCommand = "callbackBeforeAddF...
constant CallbackAfterAddFriendAgreeCommand (line 28) | CallbackAfterAddFriendAgreeCommand = "callbackAfterAddFr...
constant CallbackAfterDeleteFriendCommand (line 29) | CallbackAfterDeleteFriendCommand = "callbackAfterDelet...
constant CallbackBeforeImportFriendsCommand (line 30) | CallbackBeforeImportFriendsCommand = "callbackBeforeImpo...
constant CallbackAfterImportFriendsCommand (line 31) | CallbackAfterImportFriendsCommand = "callbackAfterImpor...
constant CallbackAfterRemoveBlackCommand (line 32) | CallbackAfterRemoveBlackCommand = "callbackAfterRemov...
constant CallbackAfterQuitGroupCommand (line 33) | CallbackAfterQuitGroupCommand = "callbackAfterQuitG...
constant CallbackAfterKickGroupCommand (line 34) | CallbackAfterKickGroupCommand = "callbackAfterKickG...
constant CallbackAfterDisMissGroupCommand (line 35) | CallbackAfterDisMissGroupCommand = "callbackAfterDisMi...
constant CallbackBeforeJoinGroupCommand (line 36) | CallbackBeforeJoinGroupCommand = "callbackBeforeJoin...
constant CallbackAfterGroupMsgReadCommand (line 37) | CallbackAfterGroupMsgReadCommand = "callbackAfterGroup...
constant CallbackBeforeMsgModifyCommand (line 38) | CallbackBeforeMsgModifyCommand = "callbackBeforeMsgM...
constant CallbackAfterUpdateUserInfoCommand (line 39) | CallbackAfterUpdateUserInfoCommand = "callbackAfterUpdat...
constant CallbackAfterUpdateUserInfoExCommand (line 40) | CallbackAfterUpdateUserInfoExCommand = "callbackAfterUpdat...
constant CallbackBeforeUpdateUserInfoExCommand (line 41) | CallbackBeforeUpdateUserInfoExCommand = "callbackBeforeUpda...
constant CallbackBeforeUserRegisterCommand (line 42) | CallbackBeforeUserRegisterCommand = "callbackBeforeUser...
constant CallbackAfterUserRegisterCommand (line 43) | CallbackAfterUserRegisterCommand = "callbackAfterUserR...
constant CallbackAfterTransferGroupOwnerCommand (line 44) | CallbackAfterTransferGroupOwnerCommand = "callbackAfterTrans...
constant CallbackBeforeSetFriendRemarkCommand (line 45) | CallbackBeforeSetFriendRemarkCommand = "callbackBeforeSetF...
constant CallbackAfterSetFriendRemarkCommand (line 46) | CallbackAfterSetFriendRemarkCommand = "callbackAfterSetFr...
constant CallbackAfterSingleMsgReadCommand (line 47) | CallbackAfterSingleMsgReadCommand = "callbackAfterSingl...
constant CallbackBeforeSendSingleMsgCommand (line 48) | CallbackBeforeSendSingleMsgCommand = "callbackBeforeSend...
constant CallbackAfterSendSingleMsgCommand (line 49) | CallbackAfterSendSingleMsgCommand = "callbackAfterSendS...
constant CallbackBeforeSendGroupMsgCommand (line 50) | CallbackBeforeSendGroupMsgCommand = "callbackBeforeSend...
constant CallbackAfterSendGroupMsgCommand (line 51) | CallbackAfterSendGroupMsgCommand = "callbackAfterSendG...
constant CallbackAfterUserOnlineCommand (line 52) | CallbackAfterUserOnlineCommand = "callbackAfterUserO...
constant CallbackAfterUserOfflineCommand (line 53) | CallbackAfterUserOfflineCommand = "callbackAfterUserO...
constant CallbackAfterUserKickOffCommand (line 54) | CallbackAfterUserKickOffCommand = "callbackAfterUserK...
constant CallbackBeforeOfflinePushCommand (line 55) | CallbackBeforeOfflinePushCommand = "callbackBeforeOffl...
constant CallbackBeforeOnlinePushCommand (line 56) | CallbackBeforeOnlinePushCommand = "callbackBeforeOnli...
constant CallbackBeforeGroupOnlinePushCommand (line 57) | CallbackBeforeGroupOnlinePushCommand = "callbackBeforeGrou...
constant CallbackBeforeAddFriendCommand (line 58) | CallbackBeforeAddFriendCommand = "callbackBeforeAddF...
constant CallbackBeforeUpdateUserInfoCommand (line 59) | CallbackBeforeUpdateUserInfoCommand = "callbackBeforeUpda...
constant CallbackBeforeCreateGroupCommand (line 60) | CallbackBeforeCreateGroupCommand = "callbackBeforeCrea...
constant CallbackAfterCreateGroupCommand (line 61) | CallbackAfterCreateGroupCommand = "callbackAfterCreat...
constant CallbackBeforeMembersJoinGroupCommand (line 62) | CallbackBeforeMembersJoinGroupCommand = "callbackBeforeMemb...
constant CallbackBeforeSetGroupMemberInfoCommand (line 63) | CallbackBeforeSetGroupMemberInfoCommand = "callbackBeforeSetG...
constant CallbackAfterSetGroupMemberInfoCommand (line 64) | CallbackAfterSetGroupMemberInfoCommand = "callbackAfterSetGr...
constant CallbackBeforeCreateSingleChatConversationsCommand (line 65) | CallbackBeforeCreateSingleChatConversationsCommand = "callbackBeforeCrea...
constant CallbackAfterCreateSingleChatConversationsCommand (line 66) | CallbackAfterCreateSingleChatConversationsCommand = "callbackAfterCreat...
constant CallbackBeforeCreateGroupChatConversationsCommand (line 67) | CallbackBeforeCreateGroupChatConversationsCommand = "callbackBeforeCrea...
constant CallbackAfterCreateGroupChatConversationsCommand (line 68) | CallbackAfterCreateGroupChatConversationsCommand = "callbackAfterCreat...
constant CallbackAfterMsgSaveDBCommand (line 69) | CallbackAfterMsgSaveDBCommand = "callbackAfterMsgSa...
FILE: pkg/callbackstruct/conversation.go
type CallbackBeforeCreateSingleChatConversationsReq (line 3) | type CallbackBeforeCreateSingleChatConversationsReq struct
type CallbackBeforeCreateSingleChatConversationsResp (line 18) | type CallbackBeforeCreateSingleChatConversationsResp struct
type CallbackAfterCreateSingleChatConversationsReq (line 29) | type CallbackAfterCreateSingleChatConversationsReq struct
type CallbackAfterCreateSingleChatConversationsResp (line 44) | type CallbackAfterCreateSingleChatConversationsResp struct
type CallbackBeforeCreateGroupChatConversationsReq (line 48) | type CallbackBeforeCreateGroupChatConversationsReq struct
type CallbackBeforeCreateGroupChatConversationsResp (line 63) | type CallbackBeforeCreateGroupChatConversationsResp struct
type CallbackAfterCreateGroupChatConversationsReq (line 74) | type CallbackAfterCreateGroupChatConversationsReq struct
type CallbackAfterCreateGroupChatConversationsResp (line 89) | type CallbackAfterCreateGroupChatConversationsResp struct
FILE: pkg/callbackstruct/friend.go
type CallbackBeforeAddFriendReq (line 17) | type CallbackBeforeAddFriendReq struct
type CallbackBeforeAddFriendResp (line 25) | type CallbackBeforeAddFriendResp struct
type CallBackAddFriendReplyBeforeReq (line 29) | type CallBackAddFriendReplyBeforeReq struct
type CallBackAddFriendReplyBeforeResp (line 35) | type CallBackAddFriendReplyBeforeResp struct
type CallbackBeforeSetFriendRemarkReq (line 39) | type CallbackBeforeSetFriendRemarkReq struct
type CallbackBeforeSetFriendRemarkResp (line 46) | type CallbackBeforeSetFriendRemarkResp struct
type CallbackAfterSetFriendRemarkReq (line 51) | type CallbackAfterSetFriendRemarkReq struct
type CallbackAfterSetFriendRemarkResp (line 58) | type CallbackAfterSetFriendRemarkResp struct
type CallbackAfterAddFriendReq (line 61) | type CallbackAfterAddFriendReq struct
type CallbackAfterAddFriendResp (line 68) | type CallbackAfterAddFriendResp struct
type CallbackBeforeAddBlackReq (line 71) | type CallbackBeforeAddBlackReq struct
type CallbackBeforeAddBlackResp (line 77) | type CallbackBeforeAddBlackResp struct
type CallbackBeforeAddFriendAgreeReq (line 81) | type CallbackBeforeAddFriendAgreeReq struct
type CallbackBeforeAddFriendAgreeResp (line 89) | type CallbackBeforeAddFriendAgreeResp struct
type CallbackAfterAddFriendAgreeReq (line 93) | type CallbackAfterAddFriendAgreeReq struct
type CallbackAfterAddFriendAgreeResp (line 101) | type CallbackAfterAddFriendAgreeResp struct
type CallbackAfterDeleteFriendReq (line 105) | type CallbackAfterDeleteFriendReq struct
type CallbackAfterDeleteFriendResp (line 110) | type CallbackAfterDeleteFriendResp struct
type CallbackBeforeImportFriendsReq (line 114) | type CallbackBeforeImportFriendsReq struct
type CallbackBeforeImportFriendsResp (line 119) | type CallbackBeforeImportFriendsResp struct
type CallbackAfterImportFriendsReq (line 123) | type CallbackAfterImportFriendsReq struct
type CallbackAfterImportFriendsResp (line 128) | type CallbackAfterImportFriendsResp struct
type CallbackAfterRemoveBlackReq (line 132) | type CallbackAfterRemoveBlackReq struct
type CallbackAfterRemoveBlackResp (line 137) | type CallbackAfterRemoveBlackResp struct
FILE: pkg/callbackstruct/group.go
type CallbackCommand (line 23) | type CallbackCommand
method GetCallbackCommand (line 25) | func (c CallbackCommand) GetCallbackCommand() string {
type CallbackBeforeCreateGroupReq (line 29) | type CallbackBeforeCreateGroupReq struct
type CallbackBeforeCreateGroupResp (line 36) | type CallbackBeforeCreateGroupResp struct
type CallbackAfterCreateGroupReq (line 53) | type CallbackAfterCreateGroupReq struct
type CallbackAfterCreateGroupResp (line 59) | type CallbackAfterCreateGroupResp struct
type CallbackGroupMember (line 63) | type CallbackGroupMember struct
type CallbackBeforeMembersJoinGroupReq (line 68) | type CallbackBeforeMembersJoinGroupReq struct
type MemberJoinGroupCallBack (line 75) | type MemberJoinGroupCallBack struct
type CallbackBeforeMembersJoinGroupResp (line 84) | type CallbackBeforeMembersJoinGroupResp struct
type CallbackBeforeSetGroupMemberInfoReq (line 89) | type CallbackBeforeSetGroupMemberInfoReq struct
type CallbackBeforeSetGroupMemberInfoResp (line 99) | type CallbackBeforeSetGroupMemberInfoResp struct
type CallbackAfterSetGroupMemberInfoReq (line 107) | type CallbackAfterSetGroupMemberInfoReq struct
type CallbackAfterSetGroupMemberInfoResp (line 117) | type CallbackAfterSetGroupMemberInfoResp struct
type CallbackQuitGroupReq (line 121) | type CallbackQuitGroupReq struct
type CallbackQuitGroupResp (line 127) | type CallbackQuitGroupResp struct
type CallbackKillGroupMemberReq (line 131) | type CallbackKillGroupMemberReq struct
type CallbackKillGroupMemberResp (line 138) | type CallbackKillGroupMemberResp struct
type CallbackDisMissGroupReq (line 142) | type CallbackDisMissGroupReq struct
type CallbackDisMissGroupResp (line 150) | type CallbackDisMissGroupResp struct
type CallbackJoinGroupReq (line 154) | type CallbackJoinGroupReq struct
type CallbackJoinGroupResp (line 163) | type CallbackJoinGroupResp struct
type CallbackTransferGroupOwnerReq (line 167) | type CallbackTransferGroupOwnerReq struct
type CallbackTransferGroupOwnerResp (line 174) | type CallbackTransferGroupOwnerResp struct
type CallbackBeforeInviteUserToGroupReq (line 178) | type CallbackBeforeInviteUserToGroupReq struct
type CallbackBeforeInviteUserToGroupResp (line 185) | type CallbackBeforeInviteUserToGroupResp struct
type CallbackAfterJoinGroupReq (line 190) | type CallbackAfterJoinGroupReq struct
type CallbackAfterJoinGroupResp (line 198) | type CallbackAfterJoinGroupResp struct
type CallbackBeforeSetGroupInfoReq (line 202) | type CallbackBeforeSetGroupInfoReq struct
type CallbackBeforeSetGroupInfoResp (line 216) | type CallbackBeforeSetGroupInfoResp struct
type CallbackAfterSetGroupInfoReq (line 229) | type CallbackAfterSetGroupInfoReq struct
type CallbackAfterSetGroupInfoResp (line 243) | type CallbackAfterSetGroupInfoResp struct
type CallbackBeforeSetGroupInfoExReq (line 247) | type CallbackBeforeSetGroupInfoExReq struct
type CallbackBeforeSetGroupInfoExResp (line 261) | type CallbackBeforeSetGroupInfoExResp struct
type CallbackAfterSetGroupInfoExReq (line 274) | type CallbackAfterSetGroupInfoExReq struct
type CallbackAfterSetGroupInfoExResp (line 288) | type CallbackAfterSetGroupInfoExResp struct
FILE: pkg/callbackstruct/message.go
type CallbackBeforeSendSingleMsgReq (line 21) | type CallbackBeforeSendSingleMsgReq struct
type CallbackBeforeSendSingleMsgResp (line 26) | type CallbackBeforeSendSingleMsgResp struct
type CallbackAfterSendSingleMsgReq (line 30) | type CallbackAfterSendSingleMsgReq struct
type CallbackAfterSendSingleMsgResp (line 35) | type CallbackAfterSendSingleMsgResp struct
type CallbackBeforeSendGroupMsgReq (line 39) | type CallbackBeforeSendGroupMsgReq struct
type CallbackBeforeSendGroupMsgResp (line 44) | type CallbackBeforeSendGroupMsgResp struct
type CallbackAfterSendGroupMsgReq (line 48) | type CallbackAfterSendGroupMsgReq struct
type CallbackAfterSendGroupMsgResp (line 53) | type CallbackAfterSendGroupMsgResp struct
type CallbackMsgModifyCommandReq (line 57) | type CallbackMsgModifyCommandReq struct
type CallbackMsgModifyCommandResp (line 61) | type CallbackMsgModifyCommandResp struct
type CallbackGroupMsgReadReq (line 83) | type CallbackGroupMsgReadReq struct
type CallbackGroupMsgReadResp (line 91) | type CallbackGroupMsgReadResp struct
type CallbackSingleMsgReadReq (line 95) | type CallbackSingleMsgReadReq struct
type CallbackSingleMsgReadResp (line 103) | type CallbackSingleMsgReadResp struct
type CallbackAfterMsgSaveDBReq (line 107) | type CallbackAfterMsgSaveDBReq struct
type CallbackAfterMsgSaveDBResp (line 113) | type CallbackAfterMsgSaveDBResp struct
FILE: pkg/callbackstruct/msg_gateway.go
type CallbackUserOnlineReq (line 17) | type CallbackUserOnlineReq struct
type CallbackUserOnlineResp (line 25) | type CallbackUserOnlineResp struct
type CallbackUserOfflineReq (line 29) | type CallbackUserOfflineReq struct
type CallbackUserOfflineResp (line 35) | type CallbackUserOfflineResp struct
type CallbackUserKickOffReq (line 39) | type CallbackUserKickOffReq struct
type CallbackUserKickOffResp (line 44) | type CallbackUserKickOffResp struct
FILE: pkg/callbackstruct/push.go
type CallbackBeforePushReq (line 19) | type CallbackBeforePushReq struct
type CallbackBeforePushResp (line 31) | type CallbackBeforePushResp struct
type CallbackBeforeSuperGroupOnlinePushReq (line 37) | type CallbackBeforeSuperGroupOnlinePushReq struct
type CallbackBeforeSuperGroupOnlinePushResp (line 49) | type CallbackBeforeSuperGroupOnlinePushResp struct
FILE: pkg/callbackstruct/revoke.go
type CallbackAfterRevokeMsgReq (line 17) | type CallbackAfterRevokeMsgReq struct
type CallbackAfterRevokeMsgResp (line 24) | type CallbackAfterRevokeMsgResp struct
FILE: pkg/callbackstruct/user.go
type CallbackBeforeUpdateUserInfoReq (line 22) | type CallbackBeforeUpdateUserInfoReq struct
type CallbackBeforeUpdateUserInfoResp (line 30) | type CallbackBeforeUpdateUserInfoResp struct
type CallbackAfterUpdateUserInfoReq (line 37) | type CallbackAfterUpdateUserInfoReq struct
type CallbackAfterUpdateUserInfoResp (line 44) | type CallbackAfterUpdateUserInfoResp struct
type CallbackBeforeUpdateUserInfoExReq (line 48) | type CallbackBeforeUpdateUserInfoExReq struct
type CallbackBeforeUpdateUserInfoExResp (line 55) | type CallbackBeforeUpdateUserInfoExResp struct
type CallbackAfterUpdateUserInfoExReq (line 62) | type CallbackAfterUpdateUserInfoExReq struct
type CallbackAfterUpdateUserInfoExResp (line 69) | type CallbackAfterUpdateUserInfoExResp struct
type CallbackBeforeUserRegisterReq (line 73) | type CallbackBeforeUserRegisterReq struct
type CallbackBeforeUserRegisterResp (line 78) | type CallbackBeforeUserRegisterResp struct
type CallbackAfterUserRegisterReq (line 83) | type CallbackAfterUserRegisterReq struct
type CallbackAfterUserRegisterResp (line 88) | type CallbackAfterUserRegisterResp struct
FILE: pkg/common/cmd/api.go
type ApiCmd (line 29) | type ApiCmd struct
method Exec (line 72) | func (a *ApiCmd) Exec() error {
method runE (line 76) | func (a *ApiCmd) runE() error {
function NewApiCmd (line 36) | func NewApiCmd() *ApiCmd {
FILE: pkg/common/cmd/auth.go
type AuthRpcCmd (line 28) | type AuthRpcCmd struct
method Exec (line 55) | func (a *AuthRpcCmd) Exec() error {
method runE (line 59) | func (a *AuthRpcCmd) runE() error {
function NewAuthRpcCmd (line 35) | func NewAuthRpcCmd() *AuthRpcCmd {
FILE: pkg/common/cmd/conversation.go
type ConversationRpcCmd (line 28) | type ConversationRpcCmd struct
method Exec (line 56) | func (a *ConversationRpcCmd) Exec() error {
method runE (line 60) | func (a *ConversationRpcCmd) runE() error {
function NewConversationRpcCmd (line 35) | func NewConversationRpcCmd() *ConversationRpcCmd {
FILE: pkg/common/cmd/cron_task.go
type CronTaskCmd (line 28) | type CronTaskCmd struct
method Exec (line 51) | func (a *CronTaskCmd) Exec() error {
method runE (line 55) | func (a *CronTaskCmd) runE() error {
function NewCronTaskCmd (line 35) | func NewCronTaskCmd() *CronTaskCmd {
FILE: pkg/common/cmd/friend.go
type FriendRpcCmd (line 28) | type FriendRpcCmd struct
method Exec (line 56) | func (a *FriendRpcCmd) Exec() error {
method runE (line 60) | func (a *FriendRpcCmd) runE() error {
function NewFriendRpcCmd (line 35) | func NewFriendRpcCmd() *FriendRpcCmd {
FILE: pkg/common/cmd/group.go
type GroupRpcCmd (line 29) | type GroupRpcCmd struct
method Exec (line 57) | func (a *GroupRpcCmd) Exec() error {
method runE (line 61) | func (a *GroupRpcCmd) runE() error {
function NewGroupRpcCmd (line 36) | func NewGroupRpcCmd() *GroupRpcCmd {
FILE: pkg/common/cmd/msg.go
type MsgRpcCmd (line 28) | type MsgRpcCmd struct
method Exec (line 57) | func (a *MsgRpcCmd) Exec() error {
method runE (line 61) | func (a *MsgRpcCmd) runE() error {
function NewMsgRpcCmd (line 35) | func NewMsgRpcCmd() *MsgRpcCmd {
FILE: pkg/common/cmd/msg_gateway.go
type MsgGatewayCmd (line 29) | type MsgGatewayCmd struct
method Exec (line 54) | func (m *MsgGatewayCmd) Exec() error {
method runE (line 58) | func (m *MsgGatewayCmd) runE() error {
function NewMsgGatewayCmd (line 36) | func NewMsgGatewayCmd() *MsgGatewayCmd {
FILE: pkg/common/cmd/msg_gateway_test.go
type MockRootCmd (line 29) | type MockRootCmd struct
method Execute (line 33) | func (m *MockRootCmd) Execute() error {
function TestName (line 38) | func TestName(t *testing.T) {
function TestName1 (line 65) | func TestName1(t *testing.T) {
FILE: pkg/common/cmd/msg_transfer.go
type MsgTransferCmd (line 29) | type MsgTransferCmd struct
method Exec (line 56) | func (m *MsgTransferCmd) Exec() error {
method runE (line 60) | func (m *MsgTransferCmd) runE() error {
function NewMsgTransferCmd (line 36) | func NewMsgTransferCmd() *MsgTransferCmd {
FILE: pkg/common/cmd/msg_utils.go
type MsgUtilsCmd (line 22) | type MsgUtilsCmd struct
method AddUserIDFlag (line 26) | func (m *MsgUtilsCmd) AddUserIDFlag() {
method AddIndexFlag (line 29) | func (m *MsgUtilsCmd) AddIndexFlag() {
method AddConfigDirFlag (line 33) | func (m *MsgUtilsCmd) AddConfigDirFlag() {
method getUserIDFlag (line 38) | func (m *MsgUtilsCmd) getUserIDFlag(cmdLines *cobra.Command) string {
method AddFixAllFlag (line 43) | func (m *MsgUtilsCmd) AddFixAllFlag() {
method AddClearAllFlag (line 52) | func (m *MsgUtilsCmd) AddClearAllFlag() {
method AddSuperGroupIDFlag (line 61) | func (m *MsgUtilsCmd) AddSuperGroupIDFlag() {
method getSuperGroupIDFlag (line 65) | func (m *MsgUtilsCmd) getSuperGroupIDFlag(cmdLines *cobra.Command) str...
method AddBeginSeqFlag (line 70) | func (m *MsgUtilsCmd) AddBeginSeqFlag() {
method AddLimitFlag (line 79) | func (m *MsgUtilsCmd) AddLimitFlag() {
method Execute (line 88) | func (m *MsgUtilsCmd) Execute() error {
function NewMsgUtilsCmd (line 92) | func NewMsgUtilsCmd(use, short string, args cobra.PositionalArgs) *MsgUt...
type GetCmd (line 102) | type GetCmd struct
function NewGetCmd (line 106) | func NewGetCmd() *GetCmd {
type FixCmd (line 112) | type FixCmd struct
function NewFixCmd (line 116) | func NewFixCmd() *FixCmd {
type ClearCmd (line 122) | type ClearCmd struct
function NewClearCmd (line 126) | func NewClearCmd() *ClearCmd {
type SeqCmd (line 132) | type SeqCmd struct
method GetSeqCmd (line 143) | func (s *SeqCmd) GetSeqCmd() *cobra.Command {
method FixSeqCmd (line 150) | func (s *SeqCmd) FixSeqCmd() *cobra.Command {
function NewSeqCmd (line 136) | func NewSeqCmd() *SeqCmd {
type MsgCmd (line 154) | type MsgCmd struct
method GetMsgCmd (line 165) | func (m *MsgCmd) GetMsgCmd() *cobra.Command {
method ClearMsgCmd (line 169) | func (m *MsgCmd) ClearMsgCmd() *cobra.Command {
function NewMsgCmd (line 158) | func NewMsgCmd() *MsgCmd {
FILE: pkg/common/cmd/push.go
type PushRpcCmd (line 28) | type PushRpcCmd struct
method Exec (line 58) | func (a *PushRpcCmd) Exec() error {
method runE (line 62) | func (a *PushRpcCmd) runE() error {
function NewPushRpcCmd (line 35) | func NewPushRpcCmd() *PushRpcCmd {
FILE: pkg/common/cmd/root.go
type RootCmd (line 19) | type RootCmd struct
method ConfigPath (line 30) | func (r *RootCmd) ConfigPath() string {
method Index (line 34) | func (r *RootCmd) Index() int {
method Port (line 38) | func (r *RootCmd) Port() int {
method initEtcd (line 82) | func (r *RootCmd) initEtcd() error {
method persistentPreRun (line 99) | func (r *RootCmd) persistentPreRun(cmd *cobra.Command, opts ...func(*C...
method initializeConfiguration (line 119) | func (r *RootCmd) initializeConfiguration(cmd *cobra.Command, opts *Cm...
method updateConfigFromEtcd (line 137) | func (r *RootCmd) updateConfigFromEtcd(opts *CmdOpts) error {
method applyOptions (line 195) | func (r *RootCmd) applyOptions(opts ...func(*CmdOpts)) *CmdOpts {
method initializeLogger (line 204) | func (r *RootCmd) initializeLogger(cmdOpts *CmdOpts) error {
method getFlag (line 231) | func (r *RootCmd) getFlag(cmd *cobra.Command) (string, int, error) {
method Execute (line 245) | func (r *RootCmd) Execute() error {
type CmdOpts (line 42) | type CmdOpts struct
function WithCronTaskLogName (line 47) | func WithCronTaskLogName() func(*CmdOpts) {
function WithLogName (line 53) | func WithLogName(logName string) func(*CmdOpts) {
function WithConfigMap (line 58) | func WithConfigMap(configMap map[string]any) func(*CmdOpts) {
function NewRootCmd (line 64) | func NewRootCmd(processName string, opts ...func(*CmdOpts)) *RootCmd {
function defaultCmdOpts (line 225) | func defaultCmdOpts() *CmdOpts {
FILE: pkg/common/cmd/third.go
type ThirdRpcCmd (line 28) | type ThirdRpcCmd struct
method Exec (line 56) | func (a *ThirdRpcCmd) Exec() error {
method runE (line 60) | func (a *ThirdRpcCmd) runE() error {
function NewThirdRpcCmd (line 35) | func NewThirdRpcCmd() *ThirdRpcCmd {
FILE: pkg/common/cmd/user.go
type UserRpcCmd (line 28) | type UserRpcCmd struct
method Exec (line 57) | func (a *UserRpcCmd) Exec() error {
method runE (line 61) | func (a *UserRpcCmd) runE() error {
function NewUserRpcCmd (line 35) | func NewUserRpcCmd() *UserRpcCmd {
FILE: pkg/common/config/config.go
constant StructTagName (line 31) | StructTagName = "yaml"
type Path (line 33) | type Path
type Index (line 35) | type Index
type CacheConfig (line 37) | type CacheConfig struct
method Failed (line 677) | func (l *CacheConfig) Failed() time.Duration {
method Success (line 681) | func (l *CacheConfig) Success() time.Duration {
method Enable (line 685) | func (l *CacheConfig) Enable() bool {
type LocalCache (line 45) | type LocalCache struct
method GetConfigFileName (line 895) | func (lc *LocalCache) GetConfigFileName() string {
type Log (line 53) | type Log struct
method GetConfigFileName (line 899) | func (l *Log) GetConfigFileName() string {
type Minio (line 64) | type Minio struct
method Build (line 615) | func (m *Minio) Build() *minio.Config {
method GetConfigFileName (line 903) | func (m *Minio) GetConfigFileName() string {
type Mongo (line 74) | type Mongo struct
method Build (line 549) | func (m *Mongo) Build() *mongoutil.Config {
method GetConfigFileName (line 907) | func (m *Mongo) GetConfigFileName() string {
type ReplicaSetConfig (line 89) | type ReplicaSetConfig struct
type ReadPrefConfig (line 96) | type ReadPrefConfig struct
type WriteConcernConfig (line 102) | type WriteConcernConfig struct
type Kafka (line 108) | type Kafka struct
method Build (line 597) | func (k *Kafka) Build() *kafka.Config {
method GetConfigFileName (line 891) | func (k *Kafka) GetConfigFileName() string {
type TLSConfig (line 125) | type TLSConfig struct
type API (line 134) | type API struct
method GetConfigFileName (line 915) | func (a *API) GetConfigFileName() string {
type RateLimiter (line 150) | type RateLimiter struct
type CircuitBreaker (line 157) | type CircuitBreaker struct
type CronTask (line 165) | type CronTask struct
method GetConfigFileName (line 919) | func (ct *CronTask) GetConfigFileName() string {
type OfflinePushConfig (line 172) | type OfflinePushConfig struct
type NotificationConfig (line 179) | type NotificationConfig struct
type Notification (line 186) | type Notification struct
method GetConfigFileName (line 911) | func (n *Notification) GetConfigFileName() string {
type Prometheus (line 222) | type Prometheus struct
type MsgGateway (line 227) | type MsgGateway struct
method GetConfigFileName (line 923) | func (mg *MsgGateway) GetConfigFileName() string {
type MsgTransfer (line 241) | type MsgTransfer struct
method GetConfigFileName (line 927) | func (mt *MsgTransfer) GetConfigFileName() string {
type Push (line 251) | type Push struct
method GetConfigFileName (line 931) | func (p *Push) GetConfigFileName() string {
type Auth (line 284) | type Auth struct
method GetConfigFileName (line 935) | func (a *Auth) GetConfigFileName() string {
type Conversation (line 294) | type Conversation struct
method GetConfigFileName (line 939) | func (c *Conversation) GetConfigFileName() string {
type Friend (line 301) | type Friend struct
method GetConfigFileName (line 943) | func (f *Friend) GetConfigFileName() string {
type Group (line 308) | type Group struct
method GetConfigFileName (line 947) | func (g *Group) GetConfigFileName() string {
type Msg (line 316) | type Msg struct
method GetConfigFileName (line 951) | func (m *Msg) GetConfigFileName() string {
type Third (line 324) | type Third struct
method GetConfigFileName (line 955) | func (t *Third) GetConfigFileName() string {
type Cos (line 337) | type Cos struct
method Build (line 633) | func (c *Cos) Build() *cos.Config {
type Oss (line 344) | type Oss struct
method Build (line 643) | func (o *Oss) Build() *oss.Config {
type Kodo (line 354) | type Kodo struct
method Build (line 655) | func (o *Kodo) Build() *kodo.Config {
type Aws (line 364) | type Aws struct
method Build (line 667) | func (o *Aws) Build() *aws.Config {
type User (line 373) | type User struct
method GetConfigFileName (line 959) | func (u *User) GetConfigFileName() string {
type RPC (line 380) | type RPC struct
type Redis (line 387) | type Redis struct
method Build (line 579) | func (r *Redis) Build() *redisutil.Config {
method GetConfigFileName (line 963) | func (r *Redis) GetConfigFileName() string {
type Sentinel (line 399) | type Sentinel struct
type BeforeConfig (line 406) | type BeforeConfig struct
type AfterConfig (line 413) | type AfterConfig struct
type Share (line 420) | type Share struct
method GetConfigFileName (line 967) | func (s *Share) GetConfigFileName() string {
type MaxRequestBody (line 430) | type MaxRequestBody struct
type MultiLogin (line 435) | type MultiLogin struct
type RpcService (line 440) | type RpcService struct
method GetServiceNames (line 452) | func (r *RpcService) GetServiceNames() []string {
type Webhooks (line 467) | type Webhooks struct
method GetConfigFileName (line 971) | func (w *Webhooks) GetConfigFileName() string {
type ZooKeeper (line 524) | type ZooKeeper struct
type Discovery (line 531) | type Discovery struct
method GetConfigFileName (line 887) | func (d *Discovery) GetConfigFileName() string {
type Kubernetes (line 538) | type Kubernetes struct
type Etcd (line 542) | type Etcd struct
function InitNotification (line 689) | func InitNotification(notification *Notification) {
type AllConfig (line 758) | type AllConfig struct
method Name2Config (line 783) | func (a *AllConfig) Name2Config(name string) any {
method GetConfigNames (line 834) | func (a *AllConfig) GetConfigNames() []string {
constant FileName (line 862) | FileName = "config.yaml"
constant DiscoveryConfigFilename (line 863) | DiscoveryConfigFilename = "discovery.yml"
constant KafkaConfigFileName (line 864) | KafkaConfigFileName = "kafka.yml"
constant LocalCacheConfigFileName (line 865) | LocalCacheConfigFileName = "local-cache.yml"
constant LogConfigFileName (line 866) | LogConfigFileName = "log.yml"
constant MinioConfigFileName (line 867) | MinioConfigFileName = "minio.yml"
constant MongodbConfigFileName (line 868) | MongodbConfigFileName = "mongodb.yml"
constant NotificationFileName (line 869) | NotificationFileName = "notification.yml"
constant OpenIMAPICfgFileName (line 870) | OpenIMAPICfgFileName = "openim-api.yml"
constant OpenIMCronTaskCfgFileName (line 871) | OpenIMCronTaskCfgFileName = "openim-crontask.yml"
constant OpenIMMsgGatewayCfgFileName (line 872) | OpenIMMsgGatewayCfgFileName = "openim-msggateway.yml"
constant OpenIMMsgTransferCfgFileName (line 873) | OpenIMMsgTransferCfgFileName = "openim-msgtransfer.yml"
constant OpenIMPushCfgFileName (line 874) | OpenIMPushCfgFileName = "openim-push.yml"
constant OpenIMRPCAuthCfgFileName (line 875) | OpenIMRPCAuthCfgFileName = "openim-rpc-auth.yml"
constant OpenIMRPCConversationCfgFileName (line 876) | OpenIMRPCConversationCfgFileName = "openim-rpc-conversation.yml"
constant OpenIMRPCFriendCfgFileName (line 877) | OpenIMRPCFriendCfgFileName = "openim-rpc-friend.yml"
constant OpenIMRPCGroupCfgFileName (line 878) | OpenIMRPCGroupCfgFileName = "openim-rpc-group.yml"
constant OpenIMRPCMsgCfgFileName (line 879) | OpenIMRPCMsgCfgFileName = "openim-rpc-msg.yml"
constant OpenIMRPCThirdCfgFileName (line 880) | OpenIMRPCThirdCfgFileName = "openim-rpc-third.yml"
constant OpenIMRPCUserCfgFileName (line 881) | OpenIMRPCUserCfgFileName = "openim-rpc-user.yml"
constant RedisConfigFileName (line 882) | RedisConfigFileName = "redis.yml"
constant ShareFileName (line 883) | ShareFileName = "share.yml"
constant WebhooksConfigFileName (line 884) | WebhooksConfigFileName = "webhooks.yml"
FILE: pkg/common/config/constant.go
constant ConfKey (line 19) | ConfKey = "conf"
constant MountConfigFilePath (line 22) | MountConfigFilePath = "CONFIG_PATH"
constant DeploymentType (line 23) | DeploymentType = "DEPLOYMENT_TYPE"
constant KUBERNETES (line 24) | KUBERNETES = runtimeenv.Kubernetes
constant ETCD (line 25) | ETCD = "etcd"
constant DefaultDirPerm (line 32) | DefaultDirPerm = 0755
constant PrivateFilePerm (line 35) | PrivateFilePerm = 0600
constant ExecFilePerm (line 39) | ExecFilePerm = 0754
constant SharedDirPerm (line 43) | SharedDirPerm = 0770
constant ReadOnlyDirPerm (line 46) | ReadOnlyDirPerm = 0555
FILE: pkg/common/config/env.go
function init (line 7) | func init() {
constant FlagConf (line 28) | FlagConf = "config_folder_path"
constant FlagTransferIndex (line 29) | FlagTransferIndex = "index"
FILE: pkg/common/config/global.go
function SetStandalone (line 5) | func SetStandalone() {
function Standalone (line 9) | func Standalone() bool {
FILE: pkg/common/config/load_config.go
function Load (line 14) | func Load(configDirectory string, configFileName string, envPrefix strin...
function loadConfig (line 27) | func loadConfig(path string, envPrefix string, config any) error {
FILE: pkg/common/config/load_config_test.go
function TestLoadLogConfig (line 10) | func TestLoadLogConfig(t *testing.T) {
function TestLoadMongoConfig (line 19) | func TestLoadMongoConfig(t *testing.T) {
function TestLoadMinioConfig (line 39) | func TestLoadMinioConfig(t *testing.T) {
function TestLoadWebhooksConfig (line 46) | func TestLoadWebhooksConfig(t *testing.T) {
function TestLoadOpenIMRpcUserConfig (line 54) | func TestLoadOpenIMRpcUserConfig(t *testing.T) {
function TestLoadNotificationConfig (line 64) | func TestLoadNotificationConfig(t *testing.T) {
function TestLoadOpenIMThirdConfig (line 71) | func TestLoadOpenIMThirdConfig(t *testing.T) {
function TestTransferConfig (line 87) | func TestTransferConfig(t *testing.T) {
FILE: pkg/common/config/parse.go
constant DefaultFolderPath (line 30) | DefaultFolderPath = "../config/"
function GetDefaultConfigPath (line 34) | func GetDefaultConfigPath() (string, error) {
function GetProjectRoot (line 48) | func GetProjectRoot() (string, error) {
function GetOptionsByNotification (line 60) | func GetOptionsByNotification(cfg NotificationConfig, sendMessage *bool)...
function initConfig (line 85) | func initConfig(config any, configName, configFolderPath string) error {
FILE: pkg/common/convert/auth.go
function TokenMapDB2Pb (line 3) | func TokenMapDB2Pb(tokenMapDB map[string]int) map[string]int32 {
function TokenMapPb2DB (line 15) | func TokenMapPb2DB(tokenMapPB map[string]int32) map[string]int {
FILE: pkg/common/convert/black.go
function BlackDB2Pb (line 25) | func BlackDB2Pb(ctx context.Context, blackDBs []*model.Black, f func(ctx...
FILE: pkg/common/convert/conversation.go
function ConversationDB2Pb (line 23) | func ConversationDB2Pb(conversationDB *model.Conversation) *conversation...
function ConversationsDB2Pb (line 32) | func ConversationsDB2Pb(conversationsDB []*model.Conversation) (conversa...
function ConversationPb2DB (line 44) | func ConversationPb2DB(conversationPB *conversation.Conversation) *model...
function ConversationsPb2DB (line 52) | func ConversationsPb2DB(conversationsPB []*conversation.Conversation) (c...
FILE: pkg/common/convert/friend.go
function FriendPb2DB (line 30) | func FriendPb2DB(friend *sdkws.FriendInfo) *model.Friend {
function FriendDB2Pb (line 41) | func FriendDB2Pb(ctx context.Context, friendDB *model.Friend, getUsers f...
function FriendsDB2Pb (line 57) | func FriendsDB2Pb(ctx context.Context, friendsDB []*model.Friend, getUse...
function FriendOnlyDB2PbOnly (line 88) | func FriendOnlyDB2PbOnly(friendsDB []*model.Friend) []*relation.FriendIn...
function FriendRequestDB2Pb (line 103) | func FriendRequestDB2Pb(ctx context.Context, friendRequests []*model.Fri...
function FriendPb2DBMap (line 141) | func FriendPb2DBMap(friend *sdkws.FriendInfo) map[string]any {
FILE: pkg/common/convert/group.go
function Db2PbGroupInfo (line 25) | func Db2PbGroupInfo(m *model.Group, ownerUserID string, memberCount uint...
function Pb2DbGroupRequest (line 47) | func Pb2DbGroupRequest(req *pbgroup.GroupApplicationResponseReq, handleU...
function Db2PbCMSGroup (line 58) | func Db2PbCMSGroup(m *model.Group, ownerUserID string, ownerUserName str...
function Db2PbGroupMember (line 66) | func Db2PbGroupMember(m *model.GroupMember) *sdkws.GroupMemberFullInfo {
function Db2PbGroupRequest (line 83) | func Db2PbGroupRequest(m *model.GroupRequest, user *sdkws.UserInfo, grou...
function Db2PbGroupAbstractInfo (line 108) | func Db2PbGroupAbstractInfo(
function Pb2DBGroupInfo (line 120) | func Pb2DBGroupInfo(m *sdkws.GroupInfo) *model.Group {
FILE: pkg/common/convert/msg.go
function MsgPb2DB (line 23) | func MsgPb2DB(msg *sdkws.MsgData) *model.MsgDataModel {
function MsgDB2Pb (line 60) | func MsgDB2Pb(msgModel *model.MsgDataModel) *sdkws.MsgData {
FILE: pkg/common/convert/user.go
function UserDB2Pb (line 25) | func UserDB2Pb(user *relationtb.User) *sdkws.UserInfo {
function UsersDB2Pb (line 37) | func UsersDB2Pb(users []*relationtb.User) []*sdkws.UserInfo {
function UserPb2DB (line 41) | func UserPb2DB(user *sdkws.UserInfo) *relationtb.User {
function UserPb2DBMap (line 53) | func UserPb2DBMap(user *sdkws.UserInfo) map[string]any {
function UserPb2DBMapEx (line 74) | func UserPb2DBMapEx(user *sdkws.UserInfoWithEx) map[string]any {
FILE: pkg/common/convert/user_test.go
function TestUsersDB2Pb (line 25) | func TestUsersDB2Pb(t *testing.T) {
function TestUserPb2DB (line 45) | func TestUserPb2DB(t *testing.T) {
function TestUserPb2DBMap (line 65) | func TestUserPb2DBMap(t *testing.T) {
FILE: pkg/common/discovery/direct/direct_resolver.go
constant slashSeparator (line 27) | slashSeparator = "/"
constant EndpointSepChar (line 29) | EndpointSepChar = ','
constant subsetSize (line 31) | subsetSize = 32
constant scheme (line 32) | scheme = "direct"
type ResolverDirect (line 35) | type ResolverDirect struct
method Build (line 42) | func (rd *ResolverDirect) Build(target resolver.Target, cc resolver.Cl...
method Scheme (line 67) | func (rd *ResolverDirect) Scheme() string {
function NewResolverDirect (line 38) | func NewResolverDirect() *ResolverDirect {
function init (line 64) | func init() {
function GetEndpoints (line 72) | func GetEndpoints(target resolver.Target) string {
function subset (line 75) | func subset(set []string, sub int) []string {
type nopResolver (line 86) | type nopResolver struct
method ResolveNow (line 90) | func (n nopResolver) ResolveNow(options resolver.ResolveNowOptions) {
method Close (line 94) | func (n nopResolver) Close() {
FILE: pkg/common/discovery/discoveryregister.go
function NewDiscoveryRegister (line 33) | func NewDiscoveryRegister(discovery *config.Discovery, watchNames []stri...
FILE: pkg/common/discovery/discoveryregister_test.go
function setupTestEnvironment (line 21) | func setupTestEnvironment() {
FILE: pkg/common/discovery/etcd/config_manager.go
function RegisterShutDown (line 21) | func RegisterShutDown(shutDown ...func() error) {
type ConfigManager (line 25) | type ConfigManager struct
method Watch (line 41) | func (c *ConfigManager) Watch(ctx context.Context) {
function BuildKey (line 31) | func BuildKey(s string) string {
function NewConfigManager (line 35) | func NewConfigManager(client *clientv3.Client, configNames []string) *Co...
function restartServer (line 72) | func restartServer(ctx context.Context) error {
FILE: pkg/common/discovery/etcd/const.go
constant ConfigKeyPrefix (line 4) | ConfigKeyPrefix = "/open-im/config/"
constant RestartKey (line 5) | RestartKey = "restart"
constant EnableConfigCenterKey (line 6) | EnableConfigCenterKey = "enable-config-center"
constant Enable (line 7) | Enable = "enable"
constant Disable (line 8) | Disable = "disable"
FILE: pkg/common/discovery/kubernetes/kubernetes.go
type KubernetesConnManager (line 21) | type KubernetesConnManager struct
method initializeConns (line 57) | func (k *KubernetesConnManager) initializeConns(serviceName string) er...
method GetConns (line 91) | func (k *KubernetesConnManager) GetConns(ctx context.Context, serviceN...
method GetConn (line 117) | func (k *KubernetesConnManager) GetConn(ctx context.Context, serviceNa...
method GetSelfConnTarget (line 146) | func (k *KubernetesConnManager) GetSelfConnTarget() string {
method AddOption (line 180) | func (k *KubernetesConnManager) AddOption(opts ...grpc.DialOption) {
method CloseConn (line 187) | func (k *KubernetesConnManager) CloseConn(conn *grpc.ClientConn) {
method Close (line 192) | func (k *KubernetesConnManager) Close() {
method Register (line 203) | func (k *KubernetesConnManager) Register(serviceName, host string, por...
method UnRegister (line 207) | func (k *KubernetesConnManager) UnRegister() error {
method GetUserIdHashGatewayHost (line 211) | func (k *KubernetesConnManager) GetUserIdHashGatewayHost(ctx context.C...
method getServicePort (line 215) | func (k *KubernetesConnManager) getServicePort(serviceName string) (in...
method watchEndpoints (line 240) | func (k *KubernetesConnManager) watchEndpoints() {
method handleEndpointChange (line 261) | func (k *KubernetesConnManager) handleEndpointChange(obj interface{}) {
function NewKubernetesConnManager (line 34) | func NewKubernetesConnManager(namespace string, options ...grpc.DialOpti...
FILE: pkg/common/prommetrics/api.go
function RegistryApi (line 28) | func RegistryApi() {
function ApiInit (line 32) | func ApiInit(listener net.Listener) error {
function APICall (line 42) | func APICall(path string, method string, apiCode int) {
function HttpCall (line 46) | func HttpCall(path string, method string, status int) {
FILE: pkg/common/prommetrics/grpc_auth.go
function RegistryAuth (line 28) | func RegistryAuth() {
FILE: pkg/common/prommetrics/grpc_msg.go
function RegistryMsg (line 40) | func RegistryMsg() {
FILE: pkg/common/prommetrics/grpc_msggateway.go
function RegistryMsgGateway (line 28) | func RegistryMsgGateway() {
FILE: pkg/common/prommetrics/grpc_push.go
function RegistryPush (line 32) | func RegistryPush() {
FILE: pkg/common/prommetrics/grpc_user.go
function RegistryUser (line 12) | func RegistryUser() {
FILE: pkg/common/prommetrics/prommetrics.go
constant commonPath (line 28) | commonPath = "/metrics"
type prometheusRegistry (line 32) | type prometheusRegistry struct
method MustRegister (line 36) | func (x *prometheusRegistry) MustRegister(cs ...prometheus.Collector) {
function init (line 47) | func init() {
function Init (line 61) | func Init(registry *prometheus.Registry, listener net.Listener, path str...
function RegistryAll (line 68) | func RegistryAll() {
function Start (line 79) | func Start(listener net.Listener) error {
constant APIKeyName (line 86) | APIKeyName = "api"
constant MessageTransferKeyName (line 87) | MessageTransferKeyName = "message-transfer"
constant TTL (line 89) | TTL = 300
type Target (line 92) | type Target struct
type RespTarget (line 97) | type RespTarget struct
function BuildDiscoveryKeyPrefix (line 102) | func BuildDiscoveryKeyPrefix(name string) string {
function BuildDiscoveryKey (line 106) | func BuildDiscoveryKey(name string, index int) string {
function BuildDefaultTarget (line 110) | func BuildDefaultTarget(host string, ip int) Target {
FILE: pkg/common/prommetrics/prommetrics_test.go
function TestName (line 73) | func TestName(t *testing.T) {
FILE: pkg/common/prommetrics/rpc.go
constant rpcPath (line 13) | rpcPath = commonPath
function RegistryRpc (line 26) | func RegistryRpc() {
function RpcInit (line 30) | func RpcInit(cs []prometheus.Collector, listener net.Listener) error {
function RPCCall (line 39) | func RPCCall(name string, path string, code int) {
function GetGrpcServerMetrics (line 43) | func GetGrpcServerMetrics() *gp.ServerMetrics {
function GetGrpcCusMetrics (line 51) | func GetGrpcCusMetrics(registerName string, discovery *config.Discovery)...
FILE: pkg/common/prommetrics/transfer.go
function RegistryTransfer (line 47) | func RegistryTransfer() {
function TransferInit (line 57) | func TransferInit(listener net.Listener) error {
FILE: pkg/common/servererrs/code.go
constant UnknownCode (line 18) | UnknownCode = 1000
constant FormattingError (line 22) | FormattingError = 10001
constant HasRegistered (line 23) | HasRegistered = 10002
constant NotRegistered (line 24) | NotRegistered = 10003
constant PasswordErr (line 25) | PasswordErr = 10004
constant GetIMTokenErr (line 26) | GetIMTokenErr = 10005
constant RepeatSendCode (line 27) | RepeatSendCode = 10006
constant MailSendCodeErr (line 28) | MailSendCodeErr = 10007
constant SmsSendCodeErr (line 29) | SmsSendCodeErr = 10008
constant CodeInvalidOrExpired (line 30) | CodeInvalidOrExpired = 10009
constant RegisterFailed (line 31) | RegisterFailed = 10010
constant ResetPasswordFailed (line 32) | ResetPasswordFailed = 10011
constant RegisterLimit (line 33) | RegisterLimit = 10012
constant LoginLimit (line 34) | LoginLimit = 10013
constant InvitationError (line 35) | InvitationError = 10014
constant NoError (line 40) | NoError = 0
constant DatabaseError (line 42) | DatabaseError = 90002
constant NetworkError (line 43) | NetworkError = 90004
constant DataError (line 44) | DataError = 90007
constant CallbackError (line 46) | CallbackError = 80000
constant ServerInternalError (line 49) | ServerInternalError = 500
constant ArgsError (line 50) | ArgsError = 1001
constant NoPermissionError (line 51) | NoPermissionError = 1002
constant DuplicateKeyError (line 52) | DuplicateKeyError = 1003
constant RecordNotFoundError (line 53) | RecordNotFoundError = 1004
constant SecretNotChangedError (line 54) | SecretNotChangedError = 1050
constant UserIDNotFoundError (line 57) | UserIDNotFoundError = 1101
constant RegisteredAlreadyError (line 58) | RegisteredAlreadyError = 1102
constant GroupIDNotFoundError (line 61) | GroupIDNotFoundError = 1201
constant GroupIDExisted (line 62) | GroupIDExisted = 1202
constant NotInGroupYetError (line 63) | NotInGroupYetError = 1203
constant DismissedAlreadyError (line 64) | DismissedAlreadyError = 1204
constant GroupTypeNotSupport (line 65) | GroupTypeNotSupport = 1205
constant GroupRequestHandled (line 66) | GroupRequestHandled = 1206
constant CanNotAddYourselfError (line 69) | CanNotAddYourselfError = 1301
constant BlockedByPeer (line 70) | BlockedByPeer = 1302
constant NotPeersFriend (line 71) | NotPeersFriend = 1303
constant RelationshipAlreadyError (line 72) | RelationshipAlreadyError = 1304
constant FriendRequestHandled (line 73) | FriendRequestHandled = 1305
constant MessageHasReadDisable (line 76) | MessageHasReadDisable = 1401
constant MutedInGroup (line 77) | MutedInGroup = 1402
constant MutedGroup (line 78) | MutedGroup = 1403
constant MsgAlreadyRevoke (line 79) | MsgAlreadyRevoke = 1404
constant TokenExpiredError (line 82) | TokenExpiredError = 1501
constant TokenInvalidError (line 83) | TokenInvalidError = 1502
constant TokenMalformedError (line 84) | TokenMalformedError = 1503
constant TokenNotValidYetError (line 85) | TokenNotValidYetError = 1504
constant TokenUnknownError (line 86) | TokenUnknownError = 1505
constant TokenKickedError (line 87) | TokenKickedError = 1506
constant TokenNotExistError (line 88) | TokenNotExistError = 1507
constant ConnOverMaxNumLimit (line 91) | ConnOverMaxNumLimit = 1601
constant ConnArgsErr (line 92) | ConnArgsErr = 1602
constant PushMsgErr (line 93) | PushMsgErr = 1603
constant IOSBackgroundPushErr (line 94) | IOSBackgroundPushErr = 1604
constant FileUploadedExpiredError (line 97) | FileUploadedExpiredError = 1701
FILE: pkg/common/servererrs/relation.go
function init (line 21) | func init() {
type relation (line 27) | type relation struct
method Add (line 31) | func (r *relation) Add(codes ...int) {
method Is (line 48) | func (r *relation) Is(parent, child int) bool {
FILE: pkg/common/startrpc/circuitbreaker.go
type CircuitBreaker (line 15) | type CircuitBreaker struct
function NewCircuitBreaker (line 23) | func NewCircuitBreaker(config *CircuitBreaker) circuitbreaker.CircuitBre...
function UnaryCircuitBreakerInterceptor (line 36) | func UnaryCircuitBreakerInterceptor(breaker circuitbreaker.CircuitBreake...
function StreamCircuitBreakerInterceptor (line 73) | func StreamCircuitBreakerInterceptor(breaker circuitbreaker.CircuitBreak...
FILE: pkg/common/startrpc/mw.go
function grpcServerIMAdminUserID (line 10) | func grpcServerIMAdminUserID(imAdminUserID []string) grpc.ServerOption {
FILE: pkg/common/startrpc/ratelimit.go
type RateLimiter (line 15) | type RateLimiter struct
function NewRateLimiter (line 22) | func NewRateLimiter(config *RateLimiter) ratelimit.Limiter {
function UnaryRateLimitInterceptor (line 34) | func UnaryRateLimitInterceptor(limiter ratelimit.Limiter) grpc.ServerOpt...
function StreamRateLimitInterceptor (line 53) | func StreamRateLimitInterceptor(limiter ratelimit.Limiter) grpc.ServerOp...
FILE: pkg/common/startrpc/start.go
function init (line 46) | func init() {
function Start (line 50) | func Start[T any](ctx context.Context, disc *conf.Discovery, circuitBrea...
function listenTCP (line 278) | func listenTCP(addr string) (net.Listener, int, error) {
function prommetricsUnaryInterceptor (line 286) | func prommetricsUnaryInterceptor(rpcRegisterName string) grpc.ServerOpti...
function prommetricsStreamInterceptor (line 304) | func prommetricsStreamInterceptor(rpcRegisterName string) grpc.ServerOpt...
type grpcServiceRegistrar (line 308) | type grpcServiceRegistrar struct
method RegisterService (line 312) | func (x *grpcServiceRegistrar) RegisterService(desc *grpc.ServiceDesc,...
FILE: pkg/common/startrpc/tools.go
function getConfig (line 9) | func getConfig[T any](value reflect.Value) *T {
function getConfigRpcMaxRequestBody (line 33) | func getConfigRpcMaxRequestBody(value reflect.Value) *conf.MaxRequestBody {
function getConfigShare (line 37) | func getConfigShare(value reflect.Value) *conf.Share {
FILE: pkg/common/storage/cache/batch_handler.go
type BatchDeleter (line 8) | type BatchDeleter interface
FILE: pkg/common/storage/cache/black.go
type BlackCache (line 21) | type BlackCache interface
FILE: pkg/common/storage/cache/cachekey/black.go
constant BlackIDsKey (line 18) | BlackIDsKey = "BLACK_IDS:"
constant IsBlackKey (line 19) | IsBlackKey = "IS_BLACK:"
function GetBlackIDsKey (line 22) | func GetBlackIDsKey(ownerUserID string) string {
function GetIsBlackIDsKey (line 27) | func GetIsBlackIDsKey(possibleBlackUserID, userID string) string {
FILE: pkg/common/storage/cache/cachekey/client_config.go
constant ClientConfig (line 3) | ClientConfig = "CLIENT_CONFIG"
function GetClientConfigKey (line 5) | func GetClientConfigKey(userID string) string {
FILE: pkg/common/storage/cache/cachekey/conversation.go
constant ConversationKey (line 18) | ConversationKey = "CONVERSATION:"
constant ConversationIDsKey (line 19) | ConversationIDsKey = "CONVERSATION_IDS:"
constant NotNotifyConversationIDsKey (line 20) | NotNotifyConversationIDsKey = "NOT_NOTIFY_CONVERSATION_IDS:"
constant PinnedConversationIDsKey (line 21) | PinnedConversationIDsKey = "PINNED_CONVERSATION_IDS:"
constant ConversationIDsHashKey (line 22) | ConversationIDsHashKey = "CONVERSATION_IDS_HASH:"
constant ConversationHasReadSeqKey (line 23) | ConversationHasReadSeqKey = "CONVERSATION_HAS_READ_SEQ:"
constant RecvMsgOptKey (line 24) | RecvMsgOptKey = "RECV_MSG_OPT:"
constant SuperGroupRecvMsgNotNotifyUserIDsKey (line 25) | SuperGroupRecvMsgNotNotifyUserIDsKey = "SUPER_GROUP_RECV_MSG_NOT_NOT...
constant SuperGroupRecvMsgNotNotifyUserIDsHashKey (line 26) | SuperGroupRecvMsgNotNotifyUserIDsHashKey = "SUPER_GROUP_RECV_MSG_NOT_NOT...
constant ConversationNotReceiveMessageUserIDsKey (line 27) | ConversationNotReceiveMessageUserIDsKey = "CONVERSATION_NOT_RECEIVE_MES...
constant ConversationUserMaxKey (line 28) | ConversationUserMaxKey = "CONVERSATION_USER_MAX:"
function GetConversationKey (line 31) | func GetConversationKey(ownerUserID, conversationID string) string {
function GetConversationIDsKey (line 35) | func GetConversationIDsKey(ownerUserID string) string {
function GetNotNotifyConversationIDsKey (line 39) | func GetNotNotifyConversationIDsKey(ownerUserID string) string {
function GetPinnedConversationIDs (line 43) | func GetPinnedConversationIDs(ownerUserID string) string {
function GetSuperGroupRecvNotNotifyUserIDsKey (line 47) | func GetSuperGroupRecvNotNotifyUserIDsKey(groupID string) string {
function GetRecvMsgOptKey (line 51) | func GetRecvMsgOptKey(ownerUserID, conversationID string) string {
function GetSuperGroupRecvNotNotifyUserIDsHashKey (line 55) | func GetSuperGroupRecvNotNotifyUserIDsHashKey(groupID string) string {
function GetConversationHasReadSeqKey (line 59) | func GetConversationHasReadSeqKey(ownerUserID, conversationID string) st...
function GetConversationNotReceiveMessageUserIDsKey (line 63) | func GetConversationNotReceiveMessageUserIDsKey(conversationID string) s...
function GetUserConversationIDsHashKey (line 67) | func GetUserConversationIDsHashKey(ownerUserID string) string {
function GetConversationUserMaxVersionKey (line 71) | func GetConversationUserMaxVersionKey(userID string) string {
FILE: pkg/common/storage/cache/cachekey/friend.go
constant FriendIDsKey (line 18) | FriendIDsKey = "FRIEND_IDS:"
constant TwoWayFriendsIDsKey (line 19) | TwoWayFriendsIDsKey = "COMMON_FRIENDS_IDS:"
constant FriendKey (line 20) | FriendKey = "FRIEND_INFO:"
constant IsFriendKey (line 21) | IsFriendKey = "IS_FRIEND:"
constant FriendMaxVersionKey (line 23) | FriendMaxVersionKey = "FRIEND_MAX_VERSION:"
function GetFriendIDsKey (line 26) | func GetFriendIDsKey(ownerUserID string) string {
function GetTwoWayFriendsIDsKey (line 30) | func GetTwoWayFriendsIDsKey(ownerUserID string) string {
function GetFriendKey (line 34) | func GetFriendKey(ownerUserID, friendUserID string) string {
function GetFriendMaxVersionKey (line 38) | func GetFriendMaxVersionKey(ownerUserID string) string {
function GetIsFriendKey (line 42) | func GetIsFriendKey(possibleFriendUserID, userID string) string {
FILE: pkg/common/storage/cache/cachekey/group.go
constant groupExpireTime (line 23) | groupExpireTime = time.Second * 60 * 60 * 12
constant GroupInfoKey (line 24) | GroupInfoKey = "GROUP_INFO:"
constant GroupMemberIDsKey (line 25) | GroupMemberIDsKey = "GROUP_MEMBER_IDS:"
constant GroupMembersHashKey (line 26) | GroupMembersHashKey = "GROUP_MEMBERS_HASH2:"
constant GroupMemberInfoKey (line 27) | GroupMemberInfoKey = "GROUP_MEMBER_INFO:"
constant JoinedGroupsKey (line 28) | JoinedGroupsKey = "JOIN_GROUPS_KEY:"
constant GroupMemberNumKey (line 29) | GroupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
constant GroupRoleLevelMemberIDsKey (line 30) | GroupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:"
constant GroupAdminLevelMemberIDsKey (line 31) | GroupAdminLevelMemberIDsKey = "GROUP_ADMIN_LEVEL_MEMBER_IDS:"
constant GroupMemberMaxVersionKey (line 32) | GroupMemberMaxVersionKey = "GROUP_MEMBER_MAX_VERSION:"
constant GroupJoinMaxVersionKey (line 33) | GroupJoinMaxVersionKey = "GROUP_JOIN_MAX_VERSION:"
function GetGroupInfoKey (line 36) | func GetGroupInfoKey(groupID string) string {
function GetJoinedGroupsKey (line 40) | func GetJoinedGroupsKey(userID string) string {
function GetGroupMembersHashKey (line 44) | func GetGroupMembersHashKey(groupID string) string {
function GetGroupMemberIDsKey (line 48) | func GetGroupMemberIDsKey(groupID string) string {
function GetGroupMemberInfoKey (line 52) | func GetGroupMemberInfoKey(groupID, userID string) string {
function GetGroupMemberNumKey (line 56) | func GetGroupMemberNumKey(groupID string) string {
function GetGroupRoleLevelMemberIDsKey (line 60) | func GetGroupRoleLevelMemberIDsKey(groupID string, roleLevel int32) stri...
function GetGroupMemberMaxVersionKey (line 64) | func GetGroupMemberMaxVersionKey(groupID string) string {
function GetJoinGroupMaxVersionKey (line 68) | func GetJoinGroupMaxVersionKey(userID string) string {
FILE: pkg/common/storage/cache/cachekey/msg.go
constant sendMsgFailedFlag (line 22) | sendMsgFailedFlag = "SEND_MSG_FAILED_FLAG:"
constant messageCache (line 23) | messageCache = "MSG_CACHE:"
function GetMsgCacheKey (line 26) | func GetMsgCacheKey(conversationID string, seq int64) string {
function GetSendMsgKey (line 30) | func GetSendMsgKey(id string) string {
FILE: pkg/common/storage/cache/cachekey/online.go
constant OnlineKey (line 9) | OnlineKey = "ONLINE:"
constant OnlineChannel (line 10) | OnlineChannel = "online_change"
constant OnlineExpire (line 11) | OnlineExpire = time.Hour / 2
function GetOnlineKey (line 14) | func GetOnlineKey(userID string) string {
function GetOnlineKeyUserID (line 18) | func GetOnlineKeyUserID(key string) string {
FILE: pkg/common/storage/cache/cachekey/s3.go
constant object (line 20) | object = "OBJECT:"
constant s3 (line 21) | s3 = "S3:"
constant minioImageInfo (line 22) | minioImageInfo = "MINIO:IMAGE:"
constant minioThumbnail (line 23) | minioThumbnail = "MINIO:THUMBNAIL:"
function GetObjectKey (line 26) | func GetObjectKey(engine string, name string) string {
function GetS3Key (line 30) | func GetS3Key(engine string, name string) string {
function GetObjectImageInfoKey (line 34) | func GetObjectImageInfoKey(key string) string {
function GetMinioImageThumbnailKey (line 38) | func GetMinioImageThumbnailKey(key string, format string, width int, hei...
FILE: pkg/common/storage/cache/cachekey/seq.go
constant MallocSeq (line 4) | MallocSeq = "MALLOC_SEQ:"
constant MallocMinSeqLock (line 5) | MallocMinSeqLock = "MALLOC_MIN_SEQ:"
constant SeqUserMaxSeq (line 7) | SeqUserMaxSeq = "SEQ_USER_MAX:"
constant SeqUserMinSeq (line 8) | SeqUserMinSeq = "SEQ_USER_MIN:"
constant SeqUserReadSeq (line 9) | SeqUserReadSeq = "SEQ_USER_READ:"
function GetMallocSeqKey (line 12) | func GetMallocSeqKey(conversationID string) string {
function GetMallocMinSeqKey (line 16) | func GetMallocMinSeqKey(conversationID string) string {
function GetSeqUserMaxSeqKey (line 20) | func GetSeqUserMaxSeqKey(conversationID string, userID string) string {
function GetSeqUserMinSeqKey (line 24) | func GetSeqUserMinSeqKey(conversationID string, userID string) string {
function GetSeqUserReadSeqKey (line 28) | func GetSeqUserReadSeqKey(conversationID string, userID string) string {
FILE: pkg/common/storage/cache/cachekey/third.go
constant getuiToken (line 22) | getuiToken = "GETUI_TOKEN"
constant getuiTaskID (line 23) | getuiTaskID = "GETUI_TASK_ID"
constant fmcToken (line 24) | fmcToken = "FCM_TOKEN:"
constant userBadgeUnreadCountSum (line 25) | userBadgeUnreadCountSum = "USER_BADGE_UNREAD_COUNT_SUM:"
function GetFcmAccountTokenKey (line 28) | func GetFcmAccountTokenKey(account string, platformID int) string {
function GetUserBadgeUnreadCountSumKey (line 32) | func GetUserBadgeUnreadCountSumKey(userID string) string {
function GetGetuiTokenKey (line 36) | func GetGetuiTokenKey() string {
function GetGetuiTaskIDKey (line 39) | func GetGetuiTaskIDKey() string {
FILE: pkg/common/storage/cache/cachekey/token.go
constant UidPidToken (line 10) | UidPidToken = "UID_PID_TOKEN_STATUS:"
function GetTokenKey (line 13) | func GetTokenKey(userID string, platformID int) string {
function GetTemporaryTokenKey (line 17) | func GetTemporaryTokenKey(userID string, platformID int, token string) s...
function GetAllPlatformTokenKey (line 21) | func GetAllPlatformTokenKey(userID string) []string {
function GetPlatformIDByTokenKey (line 29) | func GetPlatformIDByTokenKey(key string) int {
FILE: pkg/common/storage/cache/cachekey/user.go
constant UserInfoKey (line 18) | UserInfoKey = "USER_INFO:"
constant UserGlobalRecvMsgOptKey (line 19) | UserGlobalRecvMsgOptKey = "USER_GLOBAL_RECV_MSG_OPT_KEY:"
function GetUserInfoKey (line 22) | func GetUserInfoKey(userID string) string {
function GetUserGlobalRecvMsgOptKey (line 26) | func GetUserGlobalRecvMsgOptKey(userID string) string {
FILE: pkg/common/storage/cache/client_config.go
type ClientConfigCache (line 5) | type ClientConfigCache interface
FILE: pkg/common/storage/cache/conversation.go
type ConversationCache (line 24) | type ConversationCache interface
FILE: pkg/common/storage/cache/friend.go
type FriendCache (line 23) | type FriendCache interface
FILE: pkg/common/storage/cache/group.go
type GroupHash (line 24) | type GroupHash interface
type GroupCache (line 28) | type GroupCache interface
FILE: pkg/common/storage/cache/mcache/minio.go
function NewMinioCache (line 12) | func NewMinioCache(cache database.Cache) minio.Cache {
type minioCache (line 19) | type minioCache struct
method getObjectImageInfoKey (line 24) | func (g *minioCache) getObjectImageInfoKey(key string) string {
method getMinioImageThumbnailKey (line 28) | func (g *minioCache) getMinioImageThumbnailKey(key string, format stri...
method DelObjectImageInfoKey (line 32) | func (g *minioCache) DelObjectImageInfoKey(ctx context.Context, keys ....
method DelImageThumbnailKey (line 40) | func (g *minioCache) DelImageThumbnailKey(ctx context.Context, key str...
method GetImageObjectKeyInfo (line 44) | func (g *minioCache) GetImageObjectKeyInfo(ctx context.Context, key st...
method GetThumbnailKey (line 48) | func (g *minioCache) GetThumbnailKey(ctx context.Context, key string, ...
FILE: pkg/common/storage/cache/mcache/msg_cache.go
function NewMsgCache (line 25) | func NewMsgCache(cache database.Cache, msgDocDatabase database.Msg) cach...
type msgCache (line 36) | type msgCache struct
method getSendMsgKey (line 42) | func (x *msgCache) getSendMsgKey(id string) string {
method SetSendMsgStatus (line 46) | func (x *msgCache) SetSendMsgStatus(ctx context.Context, id string, st...
method GetSendMsgStatus (line 50) | func (x *msgCache) GetSendMsgStatus(ctx context.Context, id string) (i...
method getMsgCacheKey (line 67) | func (x *msgCache) getMsgCacheKey(conversationID string, seq int64) st...
method GetMessageBySeqs (line 72) | func (x *msgCache) GetMessageBySeqs(ctx context.Context, conversationI...
method DelMessageBySeqs (line 113) | func (x msgCache) DelMessageBySeqs(ctx context.Context, conversationID...
method SetMessageBySeqs (line 123) | func (x *msgCache) SetMessageBySeqs(ctx context.Context, conversationI...
FILE: pkg/common/storage/cache/mcache/online.go
function NewOnlineCache (line 15) | func NewOnlineCache() cache.OnlineCache {
type onlineCache (line 24) | type onlineCache struct
method GetOnline (line 29) | func (x *onlineCache) GetOnline(ctx context.Context, userID string) ([...
method SetUserOnline (line 43) | func (x *onlineCache) SetUserOnline(ctx context.Context, userID string...
method GetAllOnlineUsers (line 67) | func (x *onlineCache) GetAllOnlineUsers(ctx context.Context, cursor ui...
FILE: pkg/common/storage/cache/mcache/seq_conversation.go
function NewSeqConversationCache (line 10) | func NewSeqConversationCache(sc database.SeqConversation) cache.SeqConve...
type seqConversationCache (line 16) | type seqConversationCache struct
method Malloc (line 20) | func (x *seqConversationCache) Malloc(ctx context.Context, conversatio...
method SetMinSeq (line 24) | func (x *seqConversationCache) SetMinSeq(ctx context.Context, conversa...
method GetMinSeq (line 28) | func (x *seqConversationCache) GetMinSeq(ctx context.Context, conversa...
method GetMaxSeqs (line 32) | func (x *seqConversationCache) GetMaxSeqs(ctx context.Context, convers...
method GetMaxSeqsWithTime (line 44) | func (x *seqConversationCache) GetMaxSeqsWithTime(ctx context.Context,...
method GetMaxSeq (line 56) | func (x *seqConversationCache) GetMaxSeq(ctx context.Context, conversa...
method GetMaxSeqWithTime (line 60) | func (x *seqConversationCache) GetMaxSeqWithTime(ctx context.Context, ...
method SetMinSeqs (line 68) | func (x *seqConversationCache) SetMinSeqs(ctx context.Context, seqs ma...
method GetCacheMaxSeqWithTime (line 77) | func (x *seqConversationCache) GetCacheMaxSeqWithTime(ctx context.Cont...
FILE: pkg/common/storage/cache/mcache/third.go
function NewThirdCache (line 15) | func NewThirdCache(cache database.Cache) cache.ThirdCache {
type thirdCache (line 21) | type thirdCache struct
method getGetuiTokenKey (line 25) | func (c *thirdCache) getGetuiTokenKey() string {
method getGetuiTaskIDKey (line 29) | func (c *thirdCache) getGetuiTaskIDKey() string {
method getUserBadgeUnreadCountSumKey (line 33) | func (c *thirdCache) getUserBadgeUnreadCountSumKey(userID string) stri...
method getFcmAccountTokenKey (line 37) | func (c *thirdCache) getFcmAccountTokenKey(account string, platformID ...
method get (line 41) | func (c *thirdCache) get(ctx context.Context, key string) (string, err...
method SetFcmToken (line 52) | func (c *thirdCache) SetFcmToken(ctx context.Context, account string, ...
method GetFcmToken (line 56) | func (c *thirdCache) GetFcmToken(ctx context.Context, account string, ...
method DelFcmToken (line 60) | func (c *thirdCache) DelFcmToken(ctx context.Context, account string, ...
method IncrUserBadgeUnreadCountSum (line 64) | func (c *thirdCache) IncrUserBadgeUnreadCountSum(ctx context.Context, ...
method SetUserBadgeUnreadCountSum (line 68) | func (c *thirdCache) SetUserBadgeUnreadCountSum(ctx context.Context, u...
method GetUserBadgeUnreadCountSum (line 72) | func (c *thirdCache) GetUserBadgeUnreadCountSum(ctx context.Context, u...
method SetGetuiToken (line 84) | func (c *thirdCache) SetGetuiToken(ctx context.Context, token string, ...
method GetGetuiToken (line 88) | func (c *thirdCache) GetGetuiToken(ctx context.Context) (string, error) {
method SetGetuiTaskID (line 92) | func (c *thirdCache) SetGetuiTaskID(ctx context.Context, taskID string...
method GetGetuiTaskID (line 96) | func (c *thirdCache) GetGetuiTaskID(ctx context.Context) (string, erro...
FILE: pkg/common/storage/cache/mcache/token.go
function NewTokenCacheModel (line 17) | func NewTokenCacheModel(cache database.Cache, accessExpire int64) cache....
type tokenCache (line 23) | type tokenCache struct
method getTokenKey (line 28) | func (x *tokenCache) getTokenKey(userID string, platformID int, token ...
method SetTokenFlag (line 32) | func (x *tokenCache) SetTokenFlag(ctx context.Context, userID string, ...
method SetTokenFlagEx (line 37) | func (x *tokenCache) SetTokenFlagEx(ctx context.Context, userID string...
method GetTokensWithoutError (line 41) | func (x *tokenCache) GetTokensWithoutError(ctx context.Context, userID...
method HasTemporaryToken (line 59) | func (x *tokenCache) HasTemporaryToken(ctx context.Context, userID str...
method GetAllTokensWithoutError (line 67) | func (x *tokenCache) GetAllTokensWithoutError(ctx context.Context, use...
method SetTokenMapByUidPid (line 105) | func (x *tokenCache) SetTokenMapByUidPid(ctx context.Context, userID s...
method BatchSetTokenMapByUidPid (line 115) | func (x *tokenCache) BatchSetTokenMapByUidPid(ctx context.Context, tok...
method DeleteTokenByUidPid (line 127) | func (x *tokenCache) DeleteTokenByUidPid(ctx context.Context, userID s...
method getExpireTime (line 135) | func (x *tokenCache) getExpireTime(t int64) time.Duration {
method DeleteTokenByTokenMap (line 139) | func (x *tokenCache) DeleteTokenByTokenMap(ctx context.Context, userID...
method DeleteAndSetTemporary (line 149) | func (x *tokenCache) DeleteAndSetTemporary(ctx context.Context, userID...
FILE: pkg/common/storage/cache/mcache/tools.go
function getCache (line 12) | func getCache[V any](ctx context.Context, cache database.Cache, key stri...
FILE: pkg/common/storage/cache/msg.go
type MsgCache (line 22) | type MsgCache interface
FILE: pkg/common/storage/cache/online.go
type OnlineCache (line 5) | type OnlineCache interface
FILE: pkg/common/storage/cache/redis/batch.go
function GetRocksCacheOptions (line 16) | func GetRocksCacheOptions() *rockscache.Options {
function newRocksCacheClient (line 26) | func newRocksCacheClient(rdb redis.UniversalClient) *rocksCacheClient {
type rocksCacheClient (line 37) | type rocksCacheClient struct
method GetClient (line 42) | func (x *rocksCacheClient) GetClient() *rockscache.Client {
method Disable (line 46) | func (x *rocksCacheClient) Disable() bool {
method GetRedis (line 50) | func (x *rocksCacheClient) GetRedis() redis.UniversalClient {
method GetBatchDeleter (line 54) | func (x *rocksCacheClient) GetBatchDeleter(topics ...string) cache.Bat...
function batchGetCache2 (line 58) | func batchGetCache2[K comparable, V any](ctx context.Context, rcClient *...
type BatchCacheCallback (line 133) | type BatchCacheCallback interface
FILE: pkg/common/storage/cache/redis/batch_handler.go
constant rocksCacheTimeout (line 19) | rocksCacheTimeout = 11 * time.Second
type BatchDeleterRedis (line 23) | type BatchDeleterRedis struct
method ExecDelWithKeys (line 40) | func (c *BatchDeleterRedis) ExecDelWithKeys(ctx context.Context, keys ...
method ChainExecDel (line 46) | func (c *BatchDeleterRedis) ChainExecDel(ctx context.Context) error {
method execDel (line 52) | func (c *BatchDeleterRedis) execDel(ctx context.Context, keys []string...
method Clone (line 83) | func (c *BatchDeleterRedis) Clone() cache.BatchDeleter {
method AddKeys (line 93) | func (c *BatchDeleterRedis) AddKeys(keys ...string) {
function NewBatchDeleterRedis (line 31) | func NewBatchDeleterRedis(rcClient *rocksCacheClient, redisPubTopics []s...
type disableBatchDeleter (line 97) | type disableBatchDeleter struct
method ChainExecDel (line 99) | func (x disableBatchDeleter) ChainExecDel(ctx context.Context) error {
method ExecDelWithKeys (line 103) | func (x disableBatchDeleter) ExecDelWithKeys(ctx context.Context, keys...
method Clone (line 107) | func (x disableBatchDeleter) Clone() cache.BatchDeleter {
method AddKeys (line 111) | func (x disableBatchDeleter) AddKeys(keys ...string) {}
function getCache (line 113) | func getCache[T any](ctx context.Context, rcClient *rocksCacheClient, ke...
FILE: pkg/common/storage/cache/redis/batch_test.go
function TestName (line 12) | func TestName(t *testing.T) {
FILE: pkg/common/storage/cache/redis/black.go
constant blackExpireTime (line 15) | blackExpireTime = time.Second * 60 * 60 * 12
type BlackCacheRedis (line 18) | type BlackCacheRedis struct
method CloneBlackCache (line 35) | func (b *BlackCacheRedis) CloneBlackCache() cache.BlackCache {
method getBlackIDsKey (line 44) | func (b *BlackCacheRedis) getBlackIDsKey(ownerUserID string) string {
method GetBlackIDs (line 48) | func (b *BlackCacheRedis) GetBlackIDs(ctx context.Context, userID stri...
method DelBlackIDs (line 60) | func (b *BlackCacheRedis) DelBlackIDs(_ context.Context, userID string...
function NewBlackCacheRedis (line 25) | func NewBlackCacheRedis(rdb redis.UniversalClient, localCache *config.Lo...
FILE: pkg/common/storage/cache/redis/client_config.go
function NewClientConfigCache (line 13) | func NewClientConfigCache(rdb redis.UniversalClient, mgo database.Client...
type ClientConfigCache (line 22) | type ClientConfigCache struct
method getExpireTime (line 28) | func (x *ClientConfigCache) getExpireTime(userID string) time.Duration {
method getClientConfigKey (line 36) | func (x *ClientConfigCache) getClientConfigKey(userID string) string {
method GetConfig (line 40) | func (x *ClientConfigCache) GetConfig(ctx context.Context, userID stri...
method DeleteUserCache (line 46) | func (x *ClientConfigCache) DeleteUserCache(ctx context.Context, userI...
method GetUserConfig (line 54) | func (x *ClientConfigCache) GetUserConfig(ctx context.Context, userID ...
FILE: pkg/common/storage/cache/redis/conversation.go
constant conversationExpireTime (line 20) | conversationExpireTime = time.Second * 60 * 60 * 12
function NewConversationRedis (line 23) | func NewConversationRedis(rdb redis.UniversalClient, localCache *config....
type ConversationRedisCache (line 33) | type ConversationRedisCache struct
method CloneConversationCache (line 40) | func (c *ConversationRedisCache) CloneConversationCache() cache.Conver...
method getConversationKey (line 49) | func (c *ConversationRedisCache) getConversationKey(ownerUserID, conve...
method getConversationIDsKey (line 53) | func (c *ConversationRedisCache) getConversationIDsKey(ownerUserID str...
method getNotNotifyConversationIDsKey (line 57) | func (c *ConversationRedisCache) getNotNotifyConversationIDsKey(ownerU...
method getPinnedConversationIDsKey (line 61) | func (c *ConversationRedisCache) getPinnedConversationIDsKey(ownerUser...
method getSuperGroupRecvNotNotifyUserIDsKey (line 65) | func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsKey(...
method getRecvMsgOptKey (line 69) | func (c *ConversationRedisCache) getRecvMsgOptKey(ownerUserID, convers...
method getSuperGroupRecvNotNotifyUserIDsHashKey (line 73) | func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsHash...
method getConversationHasReadSeqKey (line 77) | func (c *ConversationRedisCache) getConversationHasReadSeqKey(ownerUse...
method getConversationNotReceiveMessageUserIDsKey (line 81) | func (c *ConversationRedisCache) getConversationNotReceiveMessageUserI...
method getUserConversationIDsHashKey (line 85) | func (c *ConversationRedisCache) getUserConversationIDsHashKey(ownerUs...
method getConversationUserMaxVersionKey (line 89) | func (c *ConversationRedisCache) getConversationUserMaxVersionKey(owne...
method GetUserConversationIDs (line 93) | func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Co...
method GetUserNotNotifyConversationIDs (line 99) | func (c *ConversationRedisCache) GetUserNotNotifyConversationIDs(ctx c...
method GetPinnedConversationIDs (line 105) | func (c *ConversationRedisCache) GetPinnedConversationIDs(ctx context....
method DelConversationIDs (line 111) | func (c *ConversationRedisCache) DelConversationIDs(userIDs ...string)...
method GetUserConversationIDsHash (line 122) | func (c *ConversationRedisCache) GetUserConversationIDsHash(ctx contex...
method DelUserConversationIDsHash (line 141) | func (c *ConversationRedisCache) DelUserConversationIDsHash(ownerUserI...
method GetConversation (line 152) | func (c *ConversationRedisCache) GetConversation(ctx context.Context, ...
method DelConversations (line 158) | func (c *ConversationRedisCache) DelConversations(ownerUserID string, ...
method GetConversations (line 169) | func (c *ConversationRedisCache) GetConversations(ctx context.Context,...
method GetUserAllConversations (line 179) | func (c *ConversationRedisCache) GetUserAllConversations(ctx context.C...
method GetUserRecvMsgOpt (line 187) | func (c *ConversationRedisCache) GetUserRecvMsgOpt(ctx context.Context...
method DelUsersConversation (line 193) | func (c *ConversationRedisCache) DelUsersConversation(conversationID s...
method DelUserRecvMsgOpt (line 204) | func (c *ConversationRedisCache) DelUserRecvMsgOpt(ownerUserID, conver...
method DelSuperGroupRecvMsgNotNotifyUserIDs (line 211) | func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDs(...
method DelSuperGroupRecvMsgNotNotifyUserIDsHash (line 218) | func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDsH...
method DelUserAllHasReadSeqs (line 225) | func (c *ConversationRedisCache) DelUserAllHasReadSeqs(ownerUserID str...
method GetConversationNotReceiveMessageUserIDs (line 234) | func (c *ConversationRedisCache) GetConversationNotReceiveMessageUserI...
method DelConversationNotReceiveMessageUserIDs (line 240) | func (c *ConversationRedisCache) DelConversationNotReceiveMessageUserI...
method DelConversationNotNotifyMessageUserIDs (line 248) | func (c *ConversationRedisCache) DelConversationNotNotifyMessageUserID...
method DelUserPinnedConversations (line 256) | func (c *ConversationRedisCache) DelUserPinnedConversations(userIDs .....
method DelConversationVersionUserIDs (line 264) | func (c *ConversationRedisCache) DelConversationVersionUserIDs(userIDs...
method FindMaxConversationUserVersion (line 272) | func (c *ConversationRedisCache) FindMaxConversationUserVersion(ctx co...
FILE: pkg/common/storage/cache/redis/friend.go
constant friendExpireTime (line 17) | friendExpireTime = time.Second * 60 * 60 * 12
type FriendCacheRedis (line 21) | type FriendCacheRedis struct
method CloneFriendCache (line 40) | func (f *FriendCacheRedis) CloneFriendCache() cache.FriendCache {
method getFriendIDsKey (line 50) | func (f *FriendCacheRedis) getFriendIDsKey(ownerUserID string) string {
method getFriendMaxVersionKey (line 54) | func (f *FriendCacheRedis) getFriendMaxVersionKey(ownerUserID string) ...
method getTwoWayFriendsIDsKey (line 59) | func (f *FriendCacheRedis) getTwoWayFriendsIDsKey(ownerUserID string) ...
method getFriendKey (line 64) | func (f *FriendCacheRedis) getFriendKey(ownerUserID, friendUserID stri...
method GetFriendIDs (line 69) | func (f *FriendCacheRedis) GetFriendIDs(ctx context.Context, ownerUser...
method DelFriendIDs (line 76) | func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) cache....
method GetTwoWayFriendIDs (line 88) | func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, own...
method DelTwoWayFriendIDs (line 107) | func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, own...
method GetFriend (line 115) | func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID,...
method DelFriend (line 123) | func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string)...
method DelFriends (line 131) | func (f *FriendCacheRedis) DelFriends(ownerUserID string, friendUserID...
method DelOwner (line 142) | func (f *FriendCacheRedis) DelOwner(friendUserID string, ownerUserIDs ...
method DelMaxFriendVersion (line 153) | func (f *FriendCacheRedis) DelMaxFriendVersion(ownerUserIDs ...string)...
method FindMaxFriendVersion (line 163) | func (f *FriendCacheRedis) FindMaxFriendVersion(ctx context.Context, o...
function NewFriendCacheRedis (line 30) | func NewFriendCacheRedis(rdb redis.UniversalClient, localCache *config.L...
FILE: pkg/common/storage/cache/redis/group.go
constant groupExpireTime (line 21) | groupExpireTime = time.Second * 60 * 60 * 12
type GroupCacheRedis (line 24) | type GroupCacheRedis struct
method CloneGroupCache (line 47) | func (g *GroupCacheRedis) CloneGroupCache() cache.GroupCache {
method getGroupInfoKey (line 58) | func (g *GroupCacheRedis) getGroupInfoKey(groupID string) string {
method getJoinedGroupsKey (line 62) | func (g *GroupCacheRedis) getJoinedGroupsKey(userID string) string {
method getGroupMembersHashKey (line 66) | func (g *GroupCacheRedis) getGroupMembersHashKey(groupID string) string {
method getGroupMemberIDsKey (line 70) | func (g *GroupCacheRedis) getGroupMemberIDsKey(groupID string) string {
method getGroupMemberInfoKey (line 74) | func (g *GroupCacheRedis) getGroupMemberInfoKey(groupID, userID string...
method getGroupMemberNumKey (line 78) | func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string {
method getGroupRoleLevelMemberIDsKey (line 82) | func (g *GroupCacheRedis) getGroupRoleLevelMemberIDsKey(groupID string...
method getGroupMemberMaxVersionKey (line 86) | func (g *GroupCacheRedis) getGroupMemberMaxVersionKey(groupID string) ...
method getJoinGroupMaxVersionKey (line 90) | func (g *GroupCacheRedis) getJoinGroupMaxVersionKey(userID string) str...
method getGroupID (line 94) | func (g *GroupCacheRedis) getGroupID(group *model.Group) string {
method GetGroupsInfo (line 98) | func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs ...
method GetGroupInfo (line 102) | func (g *GroupCacheRedis) GetGroupInfo(ctx context.Context, groupID st...
method DelGroupsInfo (line 108) | func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) cache.Grou...
method DelGroupsOwner (line 119) | func (g *GroupCacheRedis) DelGroupsOwner(groupIDs ...string) cache.Gro...
method DelGroupRoleLevel (line 130) | func (g *GroupCacheRedis) DelGroupRoleLevel(groupID string, roleLevels...
method DelGroupAllRoleLevel (line 140) | func (g *GroupCacheRedis) DelGroupAllRoleLevel(groupID string) cache.G...
method GetGroupMembersHash (line 144) | func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, gro...
method GetGroupMemberHashMap (line 153) | func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, g...
method DelGroupMembersHash (line 174) | func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) cache.Gr...
method GetGroupMemberIDs (line 181) | func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, group...
method DelGroupMemberIDs (line 187) | func (g *GroupCacheRedis) DelGroupMemberIDs(groupID string) cache.Grou...
method findUserJoinedGroupID (line 194) | func (g *GroupCacheRedis) findUserJoinedGroupID(ctx context.Context, u...
method GetJoinedGroupIDs (line 202) | func (g *GroupCacheRedis) GetJoinedGroupIDs(ctx context.Context, userI...
method DelJoinedGroupID (line 208) | func (g *GroupCacheRedis) DelJoinedGroupID(userIDs ...string) cache.Gr...
method GetGroupMemberInfo (line 219) | func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, grou...
method GetGroupMembersInfo (line 225) | func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, gro...
method GetAllGroupMembersInfo (line 235) | func (g *GroupCacheRedis) GetAllGroupMembersInfo(ctx context.Context, ...
method DelGroupMembersInfo (line 244) | func (g *GroupCacheRedis) DelGroupMembersInfo(groupID string, userIDs ...
method GetGroupMemberNum (line 255) | func (g *GroupCacheRedis) GetGroupMemberNum(ctx context.Context, group...
method DelGroupsMemberNum (line 261) | func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) cache....
method GetGroupOwner (line 272) | func (g *GroupCacheRedis) GetGroupOwner(ctx context.Context, groupID s...
method GetGroupsOwner (line 283) | func (g *GroupCacheRedis) GetGroupsOwner(ctx context.Context, groupIDs...
method GetGroupRoleLevelMemberIDs (line 297) | func (g *GroupCacheRedis) GetGroupRoleLevelMemberIDs(ctx context.Conte...
method GetGroupRoleLevelMemberInfo (line 303) | func (g *GroupCacheRedis) GetGroupRoleLevelMemberInfo(ctx context.Cont...
method GetGroupRolesLevelMemberInfo (line 311) | func (g *GroupCacheRedis) GetGroupRolesLevelMemberInfo(ctx context.Con...
method FindGroupMemberUser (line 323) | func (g *GroupCacheRedis) FindGroupMemberUser(ctx context.Context, gro...
method DelMaxGroupMemberVersion (line 340) | func (g *GroupCacheRedis) DelMaxGroupMemberVersion(groupIDs ...string)...
method DelMaxJoinGroupVersion (line 350) | func (g *GroupCacheRedis) DelMaxJoinGroupVersion(userIDs ...string) ca...
method FindMaxGroupMemberVersion (line 360) | func (g *GroupCacheRedis) FindMaxGroupMemberVersion(ctx context.Contex...
method BatchFindMaxGroupMemberVersion (line 366) | func (g *GroupCacheRedis) BatchFindMaxGroupMemberVersion(ctx context.C...
method FindMaxJoinGroupVersion (line 381) | func (g *GroupCacheRedis) FindMaxJoinGroupVersion(ctx context.Context,...
function NewGroupCacheRedis (line 34) | func NewGroupCacheRedis(rdb redis.UniversalClient, localCache *config.Lo...
FILE: pkg/common/storage/cache/redis/lua_script.go
function callLua (line 50) | func callLua(ctx context.Context, rdb redis.Scripter, script *redis.Scri...
function LuaSetBatchWithCommonExpire (line 67) | func LuaSetBatchWithCommonExpire(ctx context.Context, rdb redis.Scripter...
function LuaSetBatchWithIndividualExpire (line 88) | func LuaSetBatchWithIndividualExpire(ctx context.Context, rdb redis.Scri...
function LuaDeleteBatch (line 111) | func LuaDeleteBatch(ctx context.Context, rdb redis.Scripter, keys []stri...
function LuaGetBatch (line 116) | func LuaGetBatch(ctx context.Context, rdb redis.Scripter, keys []string)...
FILE: pkg/common/storage/cache/redis/lua_script_test.go
function TestLuaSetBatchWithCommonExpire (line 11) | func TestLuaSetBatchWithCommonExpire(t *testing.T) {
function TestLuaSetBatchWithIndividualExpire (line 26) | func TestLuaSetBatchWithIndividualExpire(t *testing.T) {
function TestLuaDeleteBatch (line 49) | func TestLuaDeleteBatch(t *testing.T) {
function TestLuaGetBatch (line 62) | func TestLuaGetBatch(t *testing.T) {
FILE: pkg/common/storage/cache/redis/minio.go
function NewMinioCache (line 13) | func NewMinioCache(rdb redis.UniversalClient) minio.Cache {
type minioCacheRedis (line 22) | type minioCacheRedis struct
method getObjectImageInfoKey (line 28) | func (g *minioCacheRedis) getObjectImageInfoKey(key string) string {
method getMinioImageThumbnailKey (line 32) | func (g *minioCacheRedis) getMinioImageThumbnailKey(key string, format...
method DelObjectImageInfoKey (line 36) | func (g *minioCacheRedis) DelObjectImageInfoKey(ctx context.Context, k...
method DelImageThumbnailKey (line 44) | func (g *minioCacheRedis) DelImageThumbnailKey(ctx context.Context, ke...
method GetImageObjectKeyInfo (line 49) | func (g *minioCacheRedis) GetImageObjectKeyInfo(ctx context.Context, k...
method GetThumbnailKey (line 57) | func (g *minioCacheRedis) GetThumbnailKey(ctx context.Context, key str...
FILE: pkg/common/storage/cache/redis/msg.go
constant msgCacheTimeout (line 18) | msgCacheTimeout = time.Hour * 24
function NewMsgCache (line 20) | func NewMsgCache(client redis.UniversalClient, db database.Msg) cache.Ms...
type msgCache (line 27) | type msgCache struct
method getSendMsgKey (line 32) | func (c *msgCache) getSendMsgKey(id string) string {
method SetSendMsgStatus (line 36) | func (c *msgCache) SetSendMsgStatus(ctx context.Context, id string, st...
method GetSendMsgStatus (line 40) | func (c *msgCache) GetSendMsgStatus(ctx context.Context, id string) (i...
method GetMessageBySeqs (line 45) | func (c *msgCache) GetMess
Condensed preview — 667 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,048K chars).
[
{
"path": ".dockerignore",
"chars": 390,
"preview": "# Ignore files and directories starting with a dot\n\n# Ignore specific files\n.dockerignore\n.git\n\n# Ignore build artifacts"
},
{
"path": ".gitattributes",
"chars": 17,
"preview": "*.sh text eol=lf\n"
},
{
"path": ".github/.codecov.yml",
"chars": 1065,
"preview": "coverage:\n status:\n project:\n default: false # disable the default status that measures entire project\n pk"
},
{
"path": ".github/ISSUE_TEMPLATE/bug-report.yml",
"chars": 2364,
"preview": "name: Bug Report\ntitle: \"[BUG] \"\nlabels: [\"bug\"]\ndescription: \"Create a detailed report to help us identify and resolve "
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 468,
"preview": "blank_issues_enabled: false\ncontact_links:\n # - name: \"Bug Report\"\n # description: \"Report a bug in the project\"\n #"
},
{
"path": ".github/ISSUE_TEMPLATE/deployment.yml",
"chars": 2418,
"preview": "name: Deployment issue\ntitle: \"[Deployment] \"\nlabels: [\"deployment\"]\ndescription: \"Create a detailed report to help us i"
},
{
"path": ".github/ISSUE_TEMPLATE/documentation.md",
"chars": 895,
"preview": "---\nname: Documentation Update\nabout: Propose updates to documentation, including README files and other docs.\ntitle: \"["
},
{
"path": ".github/ISSUE_TEMPLATE/feature-request.yml",
"chars": 1664,
"preview": "name: Feature Request\ntitle: \"[FEATURE REQUEST] \"\nlabels: [\"feature request\",\"enhancement\"]\ndescription: \"Propose a new "
},
{
"path": ".github/ISSUE_TEMPLATE/other.yml",
"chars": 967,
"preview": "name: 🐧 Other\ndescription: Use this for any other issues. Please do NOT create blank issues\ntitle: \"[Other]: <give this "
},
{
"path": ".github/ISSUE_TEMPLATE/rfc.md",
"chars": 958,
"preview": "---\nname: RFC - Feature Proposal\nabout: Submit a proposal for a significant feature to invite community discussion.\ntitl"
},
{
"path": ".github/sync-release.yml",
"chars": 387,
"preview": "openimsdk/openim-docker:\n - source: ./config\n dest: ./openim-server/release/config\n replace: true\n - source: ./d"
},
{
"path": ".github/workflows/auto-assign-issue.yml",
"chars": 1382,
"preview": "name: Assign issue to comment author\non:\n issue_comment:\n types: [created]\njobs:\n assign-issue:\n if: |\n con"
},
{
"path": ".github/workflows/auto-invite-comment.yml",
"chars": 3685,
"preview": "name: Invite users to join OpenIM Community.\non:\n issue_comment:\n types:\n - created\njobs:\n issue_comment:\n "
},
{
"path": ".github/workflows/changelog.yml",
"chars": 3075,
"preview": "name: Release Changelog\n\non:\n release:\n types: [released]\n\npermissions:\n contents: write\n pull-requests: write\n\njo"
},
{
"path": ".github/workflows/cla-assistant.yml",
"chars": 2259,
"preview": "name: CLA Assistant\non:\n issue_comment:\n types: [created]\n pull_request_target:\n types: [opened,closed,synchroni"
},
{
"path": ".github/workflows/cleanup-after-milestone-prs-merged.yml",
"chars": 2315,
"preview": "name: Cleanup After Milestone PRs Merged\n\non:\n pull_request:\n types:\n - closed\n\njobs:\n handle_pr:\n runs-on:"
},
{
"path": ".github/workflows/codeql-analysis.yml",
"chars": 2340,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/comment-check.yml",
"chars": 1514,
"preview": "name: Non-English Comments Check\n\non:\n pull_request:\n branches:\n - main\n workflow_dispatch:\n\njobs:\n non-engli"
},
{
"path": ".github/workflows/docker-build-and-release-services-images.yml",
"chars": 3126,
"preview": "name: Build and release services Docker Images\n\non:\n push:\n branches:\n - release-*\n release:\n types: [publi"
},
{
"path": ".github/workflows/go-build-test.yml",
"chars": 8374,
"preview": "name: Go Build Test\n\non:\n push:\n pull_request:\n paths-ignore:\n - \"**/*.md\"\n\n workflow_dispatch:\n\njobs:\n go-b"
},
{
"path": ".github/workflows/help-comment-issue.yml",
"chars": 1523,
"preview": "# Copyright © 2023 OpenIM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
},
{
"path": ".github/workflows/issue-translator.yml",
"chars": 760,
"preview": "name: 'issue-translator'\non: \n issue_comment: \n types: [created]\n issues: \n types: [opened]\n\njobs:\n build:\n "
},
{
"path": ".github/workflows/merge-from-milestone.yml",
"chars": 7602,
"preview": "name: Create Individual PRs from Milestone\n\npermissions:\n contents: write\n pull-requests: write\n issues: write\n\non:\n "
},
{
"path": ".github/workflows/publish-docker-image.yml",
"chars": 6913,
"preview": "name: Publish Docker image to registries\n\non:\n push:\n branches:\n - release-*\n release:\n types: [published]\n"
},
{
"path": ".github/workflows/remove-unused-labels.yml",
"chars": 2341,
"preview": "name: Remove Unused Labels\non:\n workflow_dispatch:\n\njobs:\n cleanup:\n runs-on: ubuntu-latest\n permissions:\n "
},
{
"path": ".github/workflows/reopen-issue.yml",
"chars": 2687,
"preview": "name: Reopen and Update Stale Issues\n\non:\n workflow_dispatch:\n\njobs:\n reopen_stale_issues:\n runs-on: ubuntu-latest\n"
},
{
"path": ".github/workflows/update-version-file-on-release.yml",
"chars": 4135,
"preview": "name: Update Version File on Release\n\non:\n release:\n types: [created]\n\njobs:\n update-version:\n runs-on: ubuntu-l"
},
{
"path": ".github/workflows/user-first-interaction.yml",
"chars": 1340,
"preview": "name: User First Interaction\n\non:\n issues:\n types: [opened]\n pull_request:\n branches: [main]\n types: [opened]"
},
{
"path": ".gitignore",
"chars": 6954,
"preview": "# Copyright © 2023 OpenIMSDK.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this"
},
{
"path": ".golangci.yml",
"chars": 33217,
"preview": "# options for analysis running\nrun:\n # default concurrency is a available CPU number\n concurrency: 4\n\n # timeout for "
},
{
"path": "CHANGELOG/CHANGELOG-3.8.md",
"chars": 4145,
"preview": "## [v3.8.3-patch.6](https://github.com/openimsdk/open-im-server/releases/tag/v3.8.3-patch.6) \t(2025-07-23)\n\n### Bug Fixe"
},
{
"path": "CHANGELOG/README.md",
"chars": 56,
"preview": "# CHANGELOGs\n\n- [CHANGELOG-3.8.md](./CHANGELOG-3.8.md)\n\n"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5222,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "CONTRIBUTING-zh_CN.md",
"chars": 3273,
"preview": "\n\n# 如何给 OpenIM 贡献代码(提交 Pull Request)\n\n<p align=\"center\">\n <a href=\"./CONTRIBUTING.md\">English</a> · \n <a href=\"./CONTR"
},
{
"path": "CONTRIBUTING.md",
"chars": 4594,
"preview": "# How to Contribute to OpenIM (Submitting Pull Requests)\n\n<p align=\"center\">\n <a href=\"./CONTRIBUTING.md\">English</a> ·"
},
{
"path": "Dockerfile",
"chars": 1688,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n\n# Define the bas"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 7586,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"./assets/logo-gif/openim-logo.gif\" width=\"60%\" hei"
},
{
"path": "README_zh_CN.md",
"chars": 5843,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"./assets/logo-gif/openim-logo.gif\" width=\"60%\" hei"
},
{
"path": "assets/README.md",
"chars": 1899,
"preview": "# `/assets`\n\nThe `/assets` directory in the OpenIM repository contains various assets such as images, logos, and animate"
},
{
"path": "assets/colors.md",
"chars": 327,
"preview": "# Official Colors\n\nThe openim logo has an official blue color. When reproducing the logo, please use the official color"
},
{
"path": "assets/demo/README.md",
"chars": 572,
"preview": "## :star2: Why OpenIM\n\n**🔍 Function screenshot display**\n\n<div align=\"center\">\n\n\n| multiple message "
},
{
"path": "assets/logo/LICENSE",
"chars": 135,
"preview": "# The OpenIM logo files are licensed under a choice of either Apache-2.0 or CC-BY-4.0 (Creative Commons Attribution 4.0 "
},
{
"path": "assets/logo-gif/LICENSE",
"chars": 135,
"preview": "# The OpenIM logo files are licensed under a choice of either Apache-2.0 or CC-BY-4.0 (Creative Commons Attribution 4.0 "
},
{
"path": "bootstrap.bat",
"chars": 555,
"preview": "@echo off\nSETLOCAL\n\nmage -version >nul 2>&1\nIF %ERRORLEVEL% EQU 0 (\n echo Mage is already installed.\n GOTO DOWNLOA"
},
{
"path": "bootstrap.sh",
"chars": 595,
"preview": "#!/bin/bash\n\nif [[ \":$PATH:\" == *\":$HOME/.local/bin:\"* ]]; then\n TARGET_DIR=\"$HOME/.local/bin\"\nelse\n TARGET_DIR=\"/"
},
{
"path": "build/README.md",
"chars": 4574,
"preview": "# Building OpenIM\n\nBuilding OpenIM is easy if you take advantage of the containerized build environment. This document w"
},
{
"path": "build/goreleaser.yaml",
"chars": 11704,
"preview": "# This is an example .goreleaser.yml file with some sensible defaults.\n# Make sure to check the documentation at https:/"
},
{
"path": "build/images/Dockerfile",
"chars": 779,
"preview": "# # Copyright © 2023 OpenIM. All rights reserved.\n# #\n# # Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "build/images/openim-api/Dockerfile",
"chars": 1077,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n\n# Define the bas"
},
{
"path": "build/images/openim-crontask/Dockerfile",
"chars": 1097,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-msggateway/Dockerfile",
"chars": 1103,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-msgtransfer/Dockerfile",
"chars": 1106,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-push/Dockerfile",
"chars": 1085,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-rpc-auth/Dockerfile",
"chars": 1108,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-rpc-conversation/Dockerfile",
"chars": 1132,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-rpc-friend/Dockerfile",
"chars": 1114,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-rpc-group/Dockerfile",
"chars": 1111,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-rpc-msg/Dockerfile",
"chars": 1105,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-rpc-third/Dockerfile",
"chars": 1111,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-rpc-user/Dockerfile",
"chars": 1106,
"preview": "# Use Go 1.22 Alpine as the base image for building the application\nFROM golang:1.22-alpine AS builder\n# Define the base"
},
{
"path": "build/images/openim-tools/component/Dockerfile",
"chars": 3538,
"preview": "# # Copyright © 2023 OpenIM. All rights reserved.\n# #\n# # Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "cmd/main.go",
"chars": 9643,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"reflect\"\n"
},
{
"path": "cmd/openim-api/main.go",
"chars": 852,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-cmdutils/main.go",
"chars": 2190,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-crontask/main.go",
"chars": 837,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-msggateway/main.go",
"chars": 839,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-msgtransfer/main.go",
"chars": 840,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-push/main.go",
"chars": 836,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-rpc/openim-rpc-auth/main.go",
"chars": 836,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-rpc/openim-rpc-conversation/main.go",
"chars": 844,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-rpc/openim-rpc-friend/main.go",
"chars": 838,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-rpc/openim-rpc-group/main.go",
"chars": 837,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-rpc/openim-rpc-msg/main.go",
"chars": 835,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-rpc/openim-rpc-third/main.go",
"chars": 837,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "cmd/openim-rpc/openim-rpc-user/main.go",
"chars": 836,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
},
{
"path": "config/README.md",
"chars": 5120,
"preview": "# \t\t\t\t\t\tOpenIM Configuration File Descriptions and Common Configuration Modifications\n\n## External Component Configurati"
},
{
"path": "config/README_zh_CN.md",
"chars": 3643,
"preview": "# \t\t\t\t\t\tOpenIM配置文件说明以及常用配置修改说明\n\n## 外部组件相关配置\n\n| Configuration File | Description |\n| -------------"
},
{
"path": "config/alertmanager.yml",
"chars": 762,
"preview": "global:\n resolve_timeout: 5m\n smtp_from: alert@openim.io\n smtp_smarthost: smtp.163.com:465\n smtp_auth_username: aler"
},
{
"path": "config/discovery.yml",
"chars": 519,
"preview": "enable: etcd\netcd:\n rootDirectory: openim\n address: [localhost:12379]\n ## Attention: If you set auth in etcd\n ## you"
},
{
"path": "config/email.tmpl",
"chars": 1643,
"preview": "{{ define \"email.to.html\" }}\n{{ if eq .Status \"firing\" }}\n {{ range .Alerts }}\n <!-- Begin of OpenIM Alert -->\n "
},
{
"path": "config/grafana-template/Demo.json",
"chars": 158152,
"preview": "{\n \"__inputs\": [\n {\n \"name\": \"DS_PROMETHEUS\",\n \"label\": \"prometheus\",\n \"description\": \"\",\n \"type"
},
{
"path": "config/instance-down-rules.yml",
"chars": 1765,
"preview": "groups:\n - name: instance_down\n rules:\n - alert: InstanceDown\n expr: up == 0\n for: 1m\n lab"
},
{
"path": "config/kafka.yml",
"chars": 1114,
"preview": "## Kafka authentication\nusername:\npassword:\n\n# Producer acknowledgment settings\nproducerAck:\n# Compression type to use ("
},
{
"path": "config/local-cache.yml",
"chars": 546,
"preview": "auth:\n topic: DELETE_CACHE_AUTH\n slotNum: 100\n slotSize: 2000\n successExpire: 300\n failedExpire: 5\n\nuser:\n topic: "
},
{
"path": "config/log.yml",
"chars": 651,
"preview": "# Log storage path, default is acceptable, change to a full path if modification is needed\nstorageLocation: ../../../../"
},
{
"path": "config/minio.yml",
"chars": 552,
"preview": "# Name of the bucket in MinIO\nbucket: openim\n# Access key ID for MinIO authentication\naccessKeyID: root\n# Secret access "
},
{
"path": "config/mongodb.yml",
"chars": 1828,
"preview": "# URI for database connection, leave empty if using address and credential settings directly\nuri:\n# List of MongoDB serv"
},
{
"path": "config/notification.yml",
"chars": 7231,
"preview": "groupCreated:\n isSendMsg: true\n# Deprecated. Fixed as 1.\n reliabilityLevel: 1\n# Deprecated. Fixed as false.\n unreadCo"
},
{
"path": "config/openim-api.yml",
"chars": 1032,
"preview": "api:\n # Listening IP; 0.0.0.0 means both internal and external IPs are listened to, default is recommended\n listenIP: "
},
{
"path": "config/openim-crontask.yml",
"chars": 169,
"preview": "cronExecuteTime: 0 2 * * *\nretainChatRecords: 365\nfileExpireTime: 180\ndeleteObjectType: [\"msg-picture\",\"msg-file\", \"msg-"
},
{
"path": "config/openim-msggateway.yml",
"chars": 1851,
"preview": "rpc:\n # The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP\n "
},
{
"path": "config/openim-msgtransfer.yml",
"chars": 910,
"preview": "prometheus:\n # Enable or disable Prometheus monitoring\n enable: true\n # autoSetPorts indicates whether to automatical"
},
{
"path": "config/openim-push.yml",
"chars": 2222,
"preview": "rpc:\n # The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP\n "
},
{
"path": "config/openim-rpc-auth.yml",
"chars": 1573,
"preview": "rpc:\n # The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP\n "
},
{
"path": "config/openim-rpc-conversation.yml",
"chars": 1511,
"preview": "rpc:\n # The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP\n "
},
{
"path": "config/openim-rpc-friend.yml",
"chars": 1511,
"preview": "rpc:\n # The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP\n "
},
{
"path": "config/openim-rpc-group.yml",
"chars": 1545,
"preview": "rpc:\n # The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP\n "
},
{
"path": "config/openim-rpc-msg.yml",
"chars": 1584,
"preview": "rpc:\n # The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP\n "
},
{
"path": "config/openim-rpc-third.yml",
"chars": 2382,
"preview": "rpc:\n # The IP address where this RPC service registers itself; if left blank, it defaults to the internal network IP\n "
},
{
"path": "config/openim-rpc-user.yml",
"chars": 1445,
"preview": "rpc:\n # API or other RPCs can access this RPC through this IP; if left blank, the internal network IP is obtained by de"
},
{
"path": "config/prometheus.yml",
"chars": 4713,
"preview": "# my global config\nglobal:\n scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 "
},
{
"path": "config/redis.yml",
"chars": 402,
"preview": "address: [localhost:16379]\nusername:\npassword: openIM123\n# redis Mode, including \"standalone\",\"cluster\",\"sentinel\"\nredis"
},
{
"path": "config/share.yml",
"chars": 685,
"preview": "secret: openIM123\n\n# imAdminUser: Configuration for instant messaging system administrators\nimAdminUser:\n # userIDs: Li"
},
{
"path": "config/webhooks.yml",
"chars": 3937,
"preview": "url: http://127.0.0.1:10006/callbackExample\nbeforeSendSingleMsg:\n enable: false\n timeout: 5\n failedContinue: true\n #"
},
{
"path": "deployments/Readme.md",
"chars": 5259,
"preview": "# Kubernetes Deployment\n\n## Resource Requests\n\n- CPU: 2 cores\n- Memory: 4 GiB\n- Disk usage: 20 GiB (on Node)\n\n## Precond"
},
{
"path": "deployments/deploy/clusterRole.yml",
"chars": 527,
"preview": "# ClusterRole.yaml\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: service-reader\nrules:\n "
},
{
"path": "deployments/deploy/ingress.yml",
"chars": 630,
"preview": "apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: openim-ingress\n annotations:\n nginx.ingress.kuberne"
},
{
"path": "deployments/deploy/kafka-secret.yml",
"chars": 106,
"preview": "apiVersion: v1\nkind: Secret\nmetadata:\n name: openim-kafka-secret\ntype: Opaque\ndata:\n kafka-password: \"\"\n"
},
{
"path": "deployments/deploy/kafka-service.yml",
"chars": 333,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: kafka-service\n labels:\n app: kafka\nspec:\n ports:\n - name: plainte"
},
{
"path": "deployments/deploy/kafka-statefulset.yml",
"chars": 1970,
"preview": "apiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: kafka-statefulset\n labels:\n app: kafka\nspec:\n replicas: 2\n "
},
{
"path": "deployments/deploy/minio-secret.yml",
"chars": 202,
"preview": "apiVersion: v1\nkind: Secret\nmetadata:\n name: openim-minio-secret\ntype: Opaque\ndata:\n minio-root-user: cm9vdA== # Base6"
},
{
"path": "deployments/deploy/minio-service.yml",
"chars": 448,
"preview": "---\napiVersion: v1\nkind: Service\nmetadata:\n name: minio-service\nspec:\n selector:\n app: minio\n ports:\n - name: m"
},
{
"path": "deployments/deploy/minio-statefulset.yml",
"chars": 1751,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: minio\n labels:\n app: minio\nspec:\n replicas: 2\n selector:\n "
},
{
"path": "deployments/deploy/mongo-secret.yml",
"chars": 256,
"preview": "apiVersion: v1\nkind: Secret\nmetadata:\n name: openim-mongo-secret\ntype: Opaque\ndata:\n mongo_openim_username: b3BlbklN #"
},
{
"path": "deployments/deploy/mongo-service.yml",
"chars": 207,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: mongo-service\nspec:\n selector:\n app: mongo\n ports:\n - name: mongo"
},
{
"path": "deployments/deploy/mongo-statefulset.yml",
"chars": 3646,
"preview": "apiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: mongo-statefulset\nspec:\n serviceName: \"mongo\"\n replicas: 2\n s"
},
{
"path": "deployments/deploy/openim-api-deployment.yml",
"chars": 1246,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: openim-api\nspec:\n replicas: 2\n selector:\n matchLabels:\n "
},
{
"path": "deployments/deploy/openim-api-service.yml",
"chars": 306,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: openim-api-service\nspec:\n selector:\n app: openim-api\n ports:\n - n"
},
{
"path": "deployments/deploy/openim-config.yml",
"chars": 35188,
"preview": "apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: openim-config\ndata:\n discovery.yml: |\n enable: \"kubernetes\" # \"kube"
},
{
"path": "deployments/deploy/openim-crontask-deployment.yml",
"chars": 610,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: openim-crontask\nspec:\n replicas: 2\n selector:\n matchLabels:\n"
},
{
"path": "deployments/deploy/openim-msggateway-deployment.yml",
"chars": 930,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: messagegateway-rpc-server\nspec:\n replicas: 2\n selector:\n mat"
},
{
"path": "deployments/deploy/openim-msggateway-service.yml",
"chars": 424,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: messagegateway-rpc-service\nspec:\n selector:\n app: messagegateway-rpc-"
},
{
"path": "deployments/deploy/openim-msgtransfer-deployment.yml",
"chars": 1449,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: openim-msgtransfer-server\nspec:\n replicas: 2\n selector:\n mat"
},
{
"path": "deployments/deploy/openim-msgtransfer-service.yml",
"chars": 245,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: openim-msgtransfer-service\nspec:\n selector:\n app: openim-msgtransfer-"
},
{
"path": "deployments/deploy/openim-push-deployment.yml",
"chars": 1070,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: push-rpc-server\nspec:\n replicas: 2\n selector:\n matchLabels:\n"
},
{
"path": "deployments/deploy/openim-push-service.yml",
"chars": 310,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: push-rpc-service\nspec:\n selector:\n app: push-rpc-server\n ports:\n "
},
{
"path": "deployments/deploy/openim-rpc-auth-deployment.yml",
"chars": 929,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: auth-rpc-server\nspec:\n replicas: 2\n selector:\n matchLabels:\n"
},
{
"path": "deployments/deploy/openim-rpc-auth-service.yml",
"chars": 310,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: auth-rpc-service\nspec:\n selector:\n app: auth-rpc-server\n ports:\n "
},
{
"path": "deployments/deploy/openim-rpc-conversation-deployment.yml",
"chars": 1310,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: conversation-rpc-server\nspec:\n replicas: 2\n selector:\n match"
},
{
"path": "deployments/deploy/openim-rpc-conversation-service.yml",
"chars": 326,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: conversation-rpc-service\nspec:\n selector:\n app: conversation-rpc-serv"
},
{
"path": "deployments/deploy/openim-rpc-friend-deployment.yml",
"chars": 1280,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: friend-rpc-server\nspec:\n replicas: 2\n selector:\n matchLabels"
},
{
"path": "deployments/deploy/openim-rpc-friend-service.yml",
"chars": 314,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: friend-rpc-service\nspec:\n selector:\n app: friend-rpc-server\n ports:\n"
},
{
"path": "deployments/deploy/openim-rpc-group-deployment.yml",
"chars": 1275,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: group-rpc-server\nspec:\n replicas: 2\n selector:\n matchLabels:"
},
{
"path": "deployments/deploy/openim-rpc-group-service.yml",
"chars": 312,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: group-rpc-service\nspec:\n selector:\n app: group-rpc-server\n ports:\n "
},
{
"path": "deployments/deploy/openim-rpc-msg-deployment.yml",
"chars": 1443,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: msg-rpc-server\nspec:\n replicas: 2\n selector:\n matchLabels:\n "
},
{
"path": "deployments/deploy/openim-rpc-msg-service.yml",
"chars": 308,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: msg-rpc-service\nspec:\n selector:\n app: msg-rpc-server\n ports:\n - "
},
{
"path": "deployments/deploy/openim-rpc-third-deployment.yml",
"chars": 1647,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: third-rpc-server\nspec:\n replicas: 2\n selector:\n matchLabels:"
},
{
"path": "deployments/deploy/openim-rpc-third-service.yml",
"chars": 312,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: third-rpc-service\nspec:\n selector:\n app: third-rpc-server\n ports:\n "
},
{
"path": "deployments/deploy/openim-rpc-user-deployment.yml",
"chars": 1448,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: user-rpc-server\nspec:\n replicas: 2\n selector:\n matchLabels:\n"
},
{
"path": "deployments/deploy/openim-rpc-user-service.yml",
"chars": 310,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: user-rpc-service\nspec:\n selector:\n app: user-rpc-server\n ports:\n "
},
{
"path": "deployments/deploy/redis-secret.yml",
"chars": 140,
"preview": "apiVersion: v1\nkind: Secret\nmetadata:\n name: openim-redis-secret\ntype: Opaque\ndata:\n redis-password: b3BlbklNMTIz # \"o"
},
{
"path": "deployments/deploy/redis-service.yml",
"chars": 230,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: redis-service\n labels:\n app: redis\nspec:\n type: ClusterIP\n selector"
},
{
"path": "deployments/deploy/redis-statefulset.yml",
"chars": 1209,
"preview": "apiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: redis-statefulset\nspec:\n serviceName: \"redis\"\n replicas: 2\n s"
},
{
"path": "docker-compose.yml",
"chars": 14144,
"preview": "networks:\n openim:\n driver: bridge\n\nservices:\n mongodb:\n image: \"${MONGO_IMAGE}\"\n ports:\n - \"37017:27017"
},
{
"path": "docs/.generated_docs",
"chars": 3136,
"preview": "docs/.generated_docs\n\ndocs/guide/en-US/cmd/openim/openim.md\ndocs/guide/en-US/cmd/openim/openim_color.md\ndocs/guide/en-US"
},
{
"path": "docs/CODEOWNERS",
"chars": 168,
"preview": "# CODEOWNERS file\n# This file is used to specify the individuals who are required to review changes in this repository.\n"
},
{
"path": "docs/README.md",
"chars": 5711,
"preview": "# OpenIM Server Docs\n\nWelcome to the OpenIM Documentation hub! This center provides a comprehensive range of guides and "
},
{
"path": "docs/contrib/README.md",
"chars": 4016,
"preview": "# Contrib Documentation Index\n\n## 📚 General Information\n- [📄 README](https://github.com/openimsdk/open-im-server/tree/ma"
},
{
"path": "docs/contrib/api.md",
"chars": 283,
"preview": "## Interface Standards\n\nOur project, OpenIM, adheres to the [OpenAPI 3.0](https://spec.openapis.org/oas/latest.html) int"
},
{
"path": "docs/contrib/bash-log.md",
"chars": 4118,
"preview": "## OpenIM Logging System: Design and Usage\n\n**PATH:** `scripts/lib/logging.sh`\n\n\n\n### Introduction\n\nOpenIM, an intricate"
},
{
"path": "docs/contrib/cicd-actions.md",
"chars": 8094,
"preview": "# Continuous Integration and Automation\n\nEvery change on the OpenIM repository, either made through a pull request or di"
},
{
"path": "docs/contrib/code-conventions.md",
"chars": 4874,
"preview": "# Code conventions\n\n- [Code conventions](#code-conventions)\n - [POSIX shell](#posix-shell)\n - [Go](#go)\n - [OpenIM Na"
},
{
"path": "docs/contrib/commit.md",
"chars": 1004,
"preview": "## Commit Standards\n\nOur project, OpenIM, follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0"
},
{
"path": "docs/contrib/development.md",
"chars": 3428,
"preview": "# Development Guide\n\nSince OpenIM is written in Go, it is fair to assume that the Go tools are all one needs to contribu"
},
{
"path": "docs/contrib/directory.md",
"chars": 138,
"preview": "## Catalog Service Interface Specification\n\n+ [https://github.com/kubecub/go-project-layout](https://github.com/kubecub/"
},
{
"path": "docs/contrib/environment.md",
"chars": 33458,
"preview": "# OpenIM ENVIRONMENT CONFIGURATION\n\n<!-- vscode-markdown-toc -->\n* 1. [OpenIM Deployment Guide](#OpenIMDeploymentGuide)\n"
},
{
"path": "docs/contrib/error-code.md",
"chars": 1781,
"preview": "## Error Code Standards\n\nError codes are one of the important means for users to locate and solve problems. When an appl"
},
{
"path": "docs/contrib/git-workflow.md",
"chars": 4381,
"preview": "# Git workflows\n\nThis document is an overview of OpenIM git workflow. It includes conventions, tips, and how to maintain"
},
{
"path": "docs/contrib/gitcherry-pick.md",
"chars": 8867,
"preview": "# Git Cherry-Pick Guide\n\n- Git Cherry-Pick Guide\n - [Introduction](#introduction)\n - [What is git cherry-pick?](#what-"
},
{
"path": "docs/contrib/github-workflow.md",
"chars": 9627,
"preview": "---\ntitle: \"GitHub Workflow\"\nweight: 6\ndescription: |\n This document is an overview of the GitHub workflow used by the\n"
},
{
"path": "docs/contrib/go-code.md",
"chars": 47841,
"preview": "## OpenIM development specification\nWe have very high standards for code style and specification, and we want our produc"
},
{
"path": "docs/contrib/go-code1.md",
"chars": 48203,
"preview": "## OpenIM development specification\nWe have very high standards for code style and specification, and we want our produc"
},
{
"path": "docs/contrib/go-doc.md",
"chars": 3957,
"preview": "# Go Language Documentation for OpenIM\n\nIn the realm of software development, especially within Go language projects, do"
},
{
"path": "docs/contrib/images.md",
"chars": 7501,
"preview": "# OpenIM Image Management Strategy and Pulling Guide\n\nOpenIM is an efficient, stable, and scalable instant messaging fra"
},
{
"path": "docs/contrib/init-config.md",
"chars": 3965,
"preview": "# Init OpenIM Config\n\n- [Init OpenIM Config](#init-openim-config)\n - [Start](#start)\n - [Define Automated Configuratio"
},
{
"path": "docs/contrib/install-docker.md",
"chars": 950,
"preview": "<!-- vscode-markdown-toc -->\n\n<!-- vscode-markdown-toc-config\n\tnumbering=true\n\tautoSave=true\n\t/vscode-markdown-toc-confi"
},
{
"path": "docs/contrib/install-openim-linux-system.md",
"chars": 10371,
"preview": "# OpenIM System: Setup and Usage Guide\n\n<!-- vscode-markdown-toc -->\n* 1. [1. Introduction](#Introduction)\n* 2. [2. Prer"
},
{
"path": "docs/contrib/kafka.md",
"chars": 5448,
"preview": "# OpenIM Kafka Guide\n\nThis document aims to provide a set of concise guidelines to help you quickly install and use Kafk"
},
{
"path": "docs/contrib/linux-development.md",
"chars": 4497,
"preview": "# Ubuntu 22.04 OpenIM Project Development Guide\n\n## TOC\n- [Ubuntu 22.04 OpenIM Project Development Guide](#ubuntu-2204-o"
},
{
"path": "docs/contrib/local-actions.md",
"chars": 1137,
"preview": "# act\n\nRun your [GitHub Actions](https://developer.github.com/actions/) locally! Why would you want to do this? Two reas"
},
{
"path": "docs/contrib/logging.md",
"chars": 17421,
"preview": "# OpenIM Logging and Error Handling Documentation\n\n## Script Logging Documentation Link\n\nIf you wish to view the script'"
},
{
"path": "docs/contrib/mac-developer-deployment-guide.md",
"chars": 6912,
"preview": "# Mac Developer Deployment Guide for OpenIM\n\n## Introduction\n\nThis guide aims to assist Mac-based developers in contribu"
},
{
"path": "docs/contrib/offline-deployment.md",
"chars": 4629,
"preview": "# OpenIM Offline Deployment Design\n\n## 1. Base Images\n\nBelow are the base images and their versions you'll need:\n\n- [ ] "
},
{
"path": "docs/contrib/prometheus-grafana.md",
"chars": 18609,
"preview": "# Deployment and Design of OpenIM's Management Backend and Monitoring\n\n<!-- vscode-markdown-toc -->\n* 1. [Source Code & "
},
{
"path": "docs/contrib/protoc-tools.md",
"chars": 3050,
"preview": "# OpenIM Protoc Tool\n\n## Introduction\n\nOpenIM is passionate about ensuring that its suite of tools is custom-tailored to"
},
{
"path": "docs/contrib/release.md",
"chars": 11848,
"preview": "# OpenIM Release Automation Design Document\n\nThis document outlines the automation process for releasing OpenIM. You can"
},
{
"path": "docs/contrib/test.md",
"chars": 15583,
"preview": "# OpenIM RPC Service Test Control Script Documentation\n\nThis document serves as a comprehensive guide to understanding a"
},
{
"path": "docs/contrib/util-go.md",
"chars": 177,
"preview": "# utils go \n\n+ [toold readme](https://github.com/openimsdk/open-im-server/tree/main/tools)\n\nabout scripts fix:\n```\n\"${OP"
},
{
"path": "docs/contrib/util-makefile.md",
"chars": 4191,
"preview": "# Open-IM-Server Development Tools Guide\n\n- [Open-IM-Server Development Tools Guide](#open-im-server-development-tools-g"
},
{
"path": "docs/contrib/util-scripts.md",
"chars": 8524,
"preview": "# OpenIM Bash Utility Script\n\nThis script offers a variety of utilities and helpers to enhance and simplify operations r"
},
{
"path": "docs/contrib/version.md",
"chars": 13906,
"preview": "# OpenIM Branch Management and Versioning: A Blueprint for High-Grade Software Development\n\n[📚 **OpenIM TOC**](#openim-b"
},
{
"path": "docs/contributing/CONTRIBUTING-JP.md",
"chars": 1644,
"preview": "# How do I contribute code to OpenIM\n\n<p align=\"center\">\n <a href=\"./CONTRIBUTING.md\">English</a> · \n <a href=\"./CONTR"
},
{
"path": "docs/contributing/CONTRIBUTING-PL.md",
"chars": 1644,
"preview": "# How do I contribute code to OpenIM\n\n<p align=\"center\">\n <a href=\"./CONTRIBUTING.md\">English</a> · \n <a href=\"./CONTR"
},
{
"path": "docs/readme/README_cs.md",
"chars": 12629,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_da.md",
"chars": 12912,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_el.md",
"chars": 13608,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_es.md",
"chars": 13547,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_fa.md",
"chars": 12386,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_fr.md",
"chars": 12908,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_hu.md",
"chars": 13083,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_ja.md",
"chars": 10746,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_ko.md",
"chars": 10707,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_tr.md",
"chars": 12761,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_uk.md",
"chars": 12876,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "docs/readme/README_vi.md",
"chars": 12910,
"preview": "<p align=\"center\">\n <a href=\"https://openim.io\">\n <img src=\"../../assets/logo-gif/openim-logo.gif\" width=\"60%\""
},
{
"path": "go.mod",
"chars": 10953,
"preview": "module github.com/openimsdk/open-im-server/v3\n\ngo 1.25.0\n\nrequire (\n\tfirebase.google.com/go/v4 v4.14.1\n\tgithub.com/dtm-l"
},
{
"path": "go.sum",
"chars": 64172,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.112.1 h1:uJSei"
},
{
"path": "install.sh",
"chars": 21392,
"preview": "#!/usr/bin/env bash\n\n# Copyright © 2023 OpenIM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
},
{
"path": "internal/api/auth.go",
"chars": 1274,
"preview": "// Copyright © 2023 OpenIM. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n/"
}
]
// ... and 467 more files (download for full content)
About this extraction
This page contains the full source code of the openimsdk/open-im-server GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 667 files (2.7 MB), approximately 739.3k tokens, and a symbol index with 3403 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.