diff --git a/assets/images/chat/push_fcm_add_certificate.png b/assets/images/chat/push_fcm_add_certificate.png new file mode 100644 index 000000000..51662824b Binary files /dev/null and b/assets/images/chat/push_fcm_add_certificate.png differ diff --git a/assets/images/chat/push_fcm_download_googleservice.png b/assets/images/chat/push_fcm_download_googleservice.png new file mode 100644 index 000000000..63cbfae6b Binary files /dev/null and b/assets/images/chat/push_fcm_download_googleservice.png differ diff --git a/assets/images/chat/push_fcm_newcertificate_upload.png b/assets/images/chat/push_fcm_newcertificate_upload.png new file mode 100644 index 000000000..b91200aae Binary files /dev/null and b/assets/images/chat/push_fcm_newcertificate_upload.png differ diff --git a/assets/images/chat/push_fcm_oldcertificate_edit.png b/assets/images/chat/push_fcm_oldcertificate_edit.png new file mode 100644 index 000000000..20ab30958 Binary files /dev/null and b/assets/images/chat/push_fcm_oldcertificate_edit.png differ diff --git a/assets/images/chat/push_fcm_oldcertificate_switch.png b/assets/images/chat/push_fcm_oldcertificate_switch.png new file mode 100644 index 000000000..def67d734 Binary files /dev/null and b/assets/images/chat/push_fcm_oldcertificate_switch.png differ diff --git a/assets/images/chat/push_fcm_private_key.png b/assets/images/chat/push_fcm_private_key.png new file mode 100644 index 000000000..a847bb716 Binary files /dev/null and b/assets/images/chat/push_fcm_private_key.png differ diff --git a/assets/images/chat/push_fcm_senderid.png b/assets/images/chat/push_fcm_senderid.png new file mode 100644 index 000000000..3b015fe43 Binary files /dev/null and b/assets/images/chat/push_fcm_senderid.png differ diff --git a/assets/images/extensions-marketplace/blurred-background.jpg b/assets/images/extensions-marketplace/blurred-background.jpg new file mode 100644 index 000000000..4c0c53b39 Binary files /dev/null and b/assets/images/extensions-marketplace/blurred-background.jpg differ diff --git a/assets/images/extensions-marketplace/portrait-in-picture.jpg b/assets/images/extensions-marketplace/portrait-in-picture.jpg new file mode 100644 index 000000000..c839b5a87 Binary files /dev/null and b/assets/images/extensions-marketplace/portrait-in-picture.jpg differ diff --git a/assets/images/flexible-classroom/authentication-flow.puml b/assets/images/flexible-classroom/authentication-flow.puml new file mode 100644 index 000000000..13cc814d0 --- /dev/null +++ b/assets/images/flexible-classroom/authentication-flow.puml @@ -0,0 +1,20 @@ +@startuml geofencing +!include ../video-sdk/agora_skin.iuml + +box "Implemented by you" +participant "App client" as APP +participant "Server" as SERVER +end box + +box "Provided by Agora" +participant "Classroom SDK" as FCRSDK +participant "Flexible Classroom Server" as FCRSERVER +end box + +APP -> SERVER: Apply for token +SERVER -> APP: Generate and return token +APP -> FCRSDK: Log into Flexible Classroom with user ID and token +FCRSDK -> FCRSERVER: Verify token +FCRSERVER -> APP: Successful login callback + +@enduml diff --git a/assets/images/flexible-classroom/authentication-flow.svg b/assets/images/flexible-classroom/authentication-flow.svg new file mode 100644 index 000000000..b4fd60141 --- /dev/null +++ b/assets/images/flexible-classroom/authentication-flow.svg @@ -0,0 +1 @@ +Implemented by youProvided by AgoraApp clientApp clientServerServerClassroom SDKClassroom SDKFlexible Classroom ServerFlexible Classroom ServerApply for tokenGenerate and return tokenLog into Flexible Classroom with user ID and tokenVerify tokenSuccessful login callback \ No newline at end of file diff --git a/assets/images/media-gateway/enable-media-gateway.png b/assets/images/media-gateway/enable-media-gateway.png new file mode 100644 index 000000000..684c231a8 Binary files /dev/null and b/assets/images/media-gateway/enable-media-gateway.png differ diff --git a/assets/images/media-gateway/media-gateway-flow.svg b/assets/images/media-gateway/media-gateway-flow.svg new file mode 100644 index 000000000..21e8512b9 --- /dev/null +++ b/assets/images/media-gateway/media-gateway-flow.svg @@ -0,0 +1 @@ +Signal SourceTranscodingMediaGatewaySD-RTNAudienceEnhance imagequalityRTMPSRTRTC \ No newline at end of file diff --git a/assets/images/media-gateway/obs-encoder-settings.png b/assets/images/media-gateway/obs-encoder-settings.png new file mode 100644 index 000000000..ab2451e8a Binary files /dev/null and b/assets/images/media-gateway/obs-encoder-settings.png differ diff --git a/assets/images/media-gateway/obs-fps-setting.png b/assets/images/media-gateway/obs-fps-setting.png new file mode 100644 index 000000000..d1c9e8eb2 Binary files /dev/null and b/assets/images/media-gateway/obs-fps-setting.png differ diff --git a/assets/images/media-gateway/obs-server-setting.png b/assets/images/media-gateway/obs-server-setting.png new file mode 100644 index 000000000..cfc787138 Binary files /dev/null and b/assets/images/media-gateway/obs-server-setting.png differ diff --git a/assets/images/media-gateway/overview-page-image.png b/assets/images/media-gateway/overview-page-image.png new file mode 100644 index 000000000..4664353bb Binary files /dev/null and b/assets/images/media-gateway/overview-page-image.png differ diff --git a/assets/images/video-sdk/connection-state-web.svg b/assets/images/video-sdk/connection-state-web.svg index 0c08c7617..a92d5cf52 100644 --- a/assets/images/video-sdk/connection-state-web.svg +++ b/assets/images/video-sdk/connection-state-web.svg @@ -1,6 +1,6 @@ - + - + @@ -35,6 +35,10 @@ + + + + @@ -89,6 +93,10 @@ + + + + @@ -144,29 +152,33 @@ + + + + - + - + - + - + - + - - + + @@ -179,97 +191,97 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - + + + + + - + - + - + diff --git a/cloud-recording/develop/integration-best-practices.md b/cloud-recording/develop/integration-best-practices.md index ef56871d9..d81546eed 100644 --- a/cloud-recording/develop/integration-best-practices.md +++ b/cloud-recording/develop/integration-best-practices.md @@ -23,20 +23,7 @@ Check that your Peak Concurrent Worker (PCW), Queries Per Second (QPS), and the #### PCW -The PCW limit depends on your video stream resolution and region. - -Resolutions: - -- SD: Standard definition video, resolution ≤ 640 × 360 -- HD: High definition video, resolution ≤ 1280 × 720 and > 640 × 360 -- FHD: Full HD video, resolution ≤ 1920 × 1080 and > 1280 × 720 - -| Service type | Mainland China | Europe | America | Asia (excluding mainland China) | -|:---------------------|:-----------------------|:---------|:--------------|:--------------------------------| -| Individual recording | 1000 | 200 | 400 | 300 | -| Composite recording | | | | | - -If you need to extend the PCW limit, please contact support@agora.io. +The PCW limit is set to 200 for all regions and resolutions. If you need to extend the PCW limit, please contact support@agora.io. #### QPS diff --git a/cloud-recording/develop/screen-capture.md b/cloud-recording/develop/screen-capture.md index 8698436fa..facef723b 100644 --- a/cloud-recording/develop/screen-capture.md +++ b/cloud-recording/develop/screen-capture.md @@ -21,6 +21,8 @@ To implement client-side screen capture, see [Screenshot Upload](../../video-cal ## Implementation +The initial Queries Per Second (QPS) limit is 10 per app ID when you register. If you need to extend the limit for QPS, contact support@agora.io. For more details on existing limitations, see [Integration best practices](integration-best-practices#check-the-limits). + ### Get a resource ID Before recording, call the [`acquire`](../reference/rest-api/acquire) method to apply for a resource ID. @@ -171,3 +173,5 @@ Pay attention to the following parameters as incorrect settings result in errors - If you set `subscribeAudioUid`, you must also set `subscribeVideoUids`. If a user stops sending video stream during a session, the Cloud Recording service stops taking screenshots until the stream resumes. + + diff --git a/cloud-recording/develop/webpage-best-practices.md b/cloud-recording/develop/webpage-best-practices.md index 8c950a854..4d7cd9b1e 100644 --- a/cloud-recording/develop/webpage-best-practices.md +++ b/cloud-recording/develop/webpage-best-practices.md @@ -27,19 +27,7 @@ Check that your Peak Concurrent Worker (PCW), Queries Per Second (QPS), and the #### PCW -The PCW limit depends on your video stream resolution and region. - -Resolutions: - -- SD: Standard definition video, resolution ≤ 640 × 360 -- HD: High definition video, resolution ≤ 1280 × 720 and > 640 × 360 -- FHD: Full HD video, resolution ≤ 1920 × 1080 and > 1280 × 720 - -| Service type | Mainland China | Europe | America | Asia (excluding mainland China) | -|:---------------------|:------------------------|:-------------------|:--------------------------------|:------------| -| Web page recording | | | | | - -If you need to extend the PCW limit, contact support@agora.io. +The PCW limit is set to 200 for all regions and resolutions. If you need to extend the PCW limit, please contact support@agora.io. #### QPS diff --git a/flexible-classroom/develop/authentication-workflow.mdx b/flexible-classroom/develop/authentication-workflow.mdx index fd817d112..847771777 100644 --- a/flexible-classroom/develop/authentication-workflow.mdx +++ b/flexible-classroom/develop/authentication-workflow.mdx @@ -3,296 +3,180 @@ title: 'Secure authentication with tokens' sidebar_position: 1 type: docs description: > - Create a Signaling token server and a Signaling client app. + Create a token server and use a token for authentication --- export const toc = [{}]; +Authentication is the act of validating the identity of each user before they access your system. Agora uses digital tokens to authenticate users and their privileges before they access an Agora service, for example, join a classroom. -Authentication is the act of validating the identity of each user before they access your system. Agora uses digital tokens to authenticate users and their privileges before they access an Agora service, such as joining an Agora call, or logging into the Signaling system. +In order to provide a better authentication experience and security guarantee, on August 18, 2022, Agora launched a new version of the token, AccessToken2. We recommend using AccessToken2, which is compatible with AccessToken. -This document shows you how to create a token server and a client app. The client app retrieves a token from the token server. This token authenticates the current user when the user accesses . +This page explains how to use AccessToken2 to deploy a token generator on the server and use token authentication on the client, as well as providing reference information. ## Understand the tech The following figure shows the steps in the authentication flow: -![ token authentication flow](https://web-cdn.agora.io/docs-files/1624939517653) +![FCR authentication flow](/images/flexible-classroom/authentication-flow.svg) -a token is a dynamic key generated on your app server that is valid for 24 hours. When your users log in to from your app client, validates the token and reads the user and project information stored in the token. a token contains the following information: +An token is a dynamic key generated on your app server that is valid for 24 hours or less. When your users log in to from your app client, the platform validates the token and reads the user and project information stored in the token. A token contains the following information: -- The App ID of your Agora project +- The app ID of your project -- The App Certificate of your Agora project +- The user ID -- The user ID of the user to be authenticated - -- The Unix timestamp when the token expires +- The Unix timestamp for when the token expires ## Prerequisites -In order to follow this procedure you must have the following: +This page provides an example procedure using Go. You can use another language or platform for the same purpose. -- A valid [ account](../get-started/manage-agora-account#_create_an_agora_account). +In order to follow this example procedure, you must have the following: -- An Agora project with the [App Certificate](../get-started/manage-agora-account#_get_the_app_certificate) enabled. +- A valid [ account](../get-started/manage-agora-account#create-an-agora-account). -- [Golang](https://golang.org/) 1.14+ with GO111MODULE set to on. +- An project with the [app certificate](../get-started/manage-agora-account#get-the-app-certificate) enabled. -- If you are using Go 1.16+, GO111MODULE is on by default. See [this blog](https://blog.golang.org/go116-module-changes) for details. +- [Golang](https://golang.org/) 1.14+ with GO111MODULE set to on. -- [npm](https://www.npmjs.com/get-npm) and a [supported browsers](../reference/supported-platforms#supported_platform_browsers). + If you are using Go 1.16+, GO111MODULE is on by default. See [this blog post](https://blog.golang.org/go116-module-changes) for details. -- For AccessToken2, v1.5.0 or greater. +- [npm](https://www.npmjs.com/get-npm) and a [supported browser](../reference/supported-platforms#supported_platform_browsers). ## Implement the authentication flow -This section shows you how to supply and consume a token that gives rights to specific functionality to authenticated users using the [source code](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey) provided by Agora. +This section shows you how to use a [token generator](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey) to generate tokens and authenticate users. -### Get the App ID and App Certificate +### Get the app ID and app certificate -This section shows you how to get the security information needed to generate a token, including the App ID and App Certificate of your project. +This section shows you how to get the security information needed to generate a token, including the app ID and app certificate of your project. -#### 1. Get the App ID +#### 1. Get the app ID -Agora automatically assigns each project an App ID as a unique identifier. + automatically assigns each project an app ID as a unique identifier. -To copy this App ID, find your project on the Project Management page in Agora Console, and click the copy icon in the App ID column. +To copy this app ID, find your project on the Project Management page in , and click the copy icon in the app ID column. -#### 2. Get the App Certificate +#### 2. Get the app certificate -To get an App Certificate, do the following: +To get an app certificate, do the following: 1. On the Project Management page, click **Config** for the project you want to use. -![1641971710869](https://web-cdn.agora.io/docs-files/1641971710869) - -2. Click the copy icon under **Primary Certificate**. -![1637660100222](https://web-cdn.agora.io/docs-files/1637660100222) - -### Deploy a token server - -Token generators create the tokens requested by your client app to enable secure access to Agora Platform. To serve these tokens you deploy a generator in your security infrastructure. - -In order to show the authentication workflow, this section shows how to build and run a token server written in Golang on your local machine. - -**This sample server is for demonstration purposes only. Do not use it in a production environment.** -1. Create a file, `server.go`, with the following content. Then replace `` and `` with your App ID and App Certificate. + ![1641971710869](https://web-cdn.agora.io/docs-files/1641971710869) - Implement either: +1. Click the copy icon under **Primary Certificate**. - - **AccessToken2** + ![1637660100222](https://web-cdn.agora.io/docs-files/1637660100222) - ```go - package main +### Deploy a token server for AccessToken2 - import ( - rtmtokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtmtokenbuilder2" - "fmt" - "log" - "net/http" - "time" - "encoding/json" - "errors" - "strconv" - ) - - type rtm_token_struct struct{ - Uid_rtm string `json:"uid"` - } +Token generators create the tokens requested by your client app to enable secure access to Platform. To serve these tokens you deploy a generator in your security infrastructure. - var rtm_token string - var rtm_uid string +In order to show the authentication workflow, this section shows how to build and run a token server written in Golang on your local machine. - func generateRtmToken(rtm_uid string){ +This sample server is for demonstration purposes only. Do not use it in a production environment. - appID := "Your_App_ID" - appCertificate := "Your_Certificate" - expireTimeInSeconds := uint32(3600) - currentTimestamp := uint32(time.Now().UTC().Unix()) - expireTimestamp := currentTimestamp + expireTimeInSeconds +1. Create a file, `server.go`, with the following content. Then replace `` and `` with your app ID and app certificate. - result, err := rtmtokenbuilder.BuildToken(appID, appCertificate, rtm_uid, expireTimestamp) - if err != nil { - fmt.Println(err) - } else { - fmt.Printf("Rtm Token: %s\n", result) + ```go + package main + + import ( + educationtokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/educationtokenbuilder" + "fmt" + "log" + "net/http" + "time" + "encoding/json" + "errors" + "strconv" + ) + + type education_token_struct struct { + roomUuid string `json:"roomUuid"` + userUuid string `json:"userUuid"` + role int `json:"role"` + } - rtm_token = result + var educationToken string - } - } + func generateEducationToken(roomUuid string, userUuid string, role int) { + // Replace "Your_App_ID" with your app ID + appID := "Your_App_ID" + // Replace "Your_Certificate" with your app certificate + appCertificate := "Your_Certificate" + expire := uint32(3600) - func rtmTokenHandler(w http.ResponseWriter, r *http.Request){ - w.Header().Set("Content-Type", "application/json;charset=UTF-8") - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS"); - w.Header().Set("Access-Control-Allow-Headers", "*"); - - if r.Method == "OPTIONS" { - w.WriteHeader(http.StatusOK) - return - } - - if r.Method != "POST" && r.Method != "OPTIONS" { - http.Error(w, "Unsupported method. Please check.", http.StatusNotFound) - return - } - - var t_rtm_str rtm_token_struct - var unmarshalErr *json.UnmarshalTypeError - str_decoder := json.NewDecoder(r.Body) - rtm_err := str_decoder.Decode(&t_rtm_str) - - if (rtm_err == nil) { - rtm_uid = t_rtm_str.Uid_rtm - } - - if (rtm_err != nil) { - if errors.As(rtm_err, &unmarshalErr){ - errorResponse(w, "Bad request. Please check your params.", http.StatusBadRequest) - } else { - errorResponse(w, "Bad request.", http.StatusBadRequest) - } - return - } + result, err := educationtokenbuilder.BuildRoomUserToken(appID, appCertificate, roomUuid, userUuid, role, expire) - generateRtmToken(rtm_uid) - errorResponse(w, rtm_token, http.StatusOK) - log.Println(w, r) + if err != nil { + fmt.Println(err) + } else { + fmt.Printf("EducationToken: %s\n", result) + educationToken = result } + } + func educationTokenHandler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json;charset=UTF-8") + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS"); + w.Header().Set("Access-Control-Allow-Headers", "*"); - func errorResponse(w http.ResponseWriter, message string, httpStatusCode int){ - w.Header().Set("Content-Type", "application/json") - w.Header().Set("Access-Control-Allow-Origin", "*") - w.WriteHeader(httpStatusCode) - resp := make(map[string]string) - resp["token"] = message - resp["code"] = strconv.Itoa(httpStatusCode) - jsonResp, _ := json.Marshal(resp) - w.Write(jsonResp) - + if r.Method == "OPTIONS" { + w.WriteHeader(http.StatusOK) + return } - func main(){ - // Handling routes - // token from uid - http.HandleFunc("/fetch_rtm_token", rtmTokenHandler) - - fmt.Printf("Starting server at port 8082\n") - - if err := http.ListenAndServe(":8082", nil); err != nil { - log.Fatal(err) - } - } - ``` - - **AccessToken** - - ```go - package main - - import ( - rtmtokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/RtmTokenBuilder" - "fmt" - "log" - "net/http" - "time" - "encoding/json" - "errors" - "strconv" - ) - - type rtm_token_struct struct{ - Uid_rtm string `json:"uid"` + if r.Method != "POST" && r.Method != "OPTIONS" { + http.Error(w, "Unsupported method. Please check.", http.StatusNotFound) + return } - var rtm_token string - var rtm_uid string + var t_education_str education_token_struct + var unmarshalErr *json.UnmarshalTypeError + str_decoder := json.NewDecoder(r.Body) + education_err := str_decoder.Decode(&t_education_str) - func generateRtmToken(rtm_uid string){ - - appID := "Your_App_ID" - appCertificate := "Your_Certificate" - expireTimeInSeconds := uint32(3600) - currentTimestamp := uint32(time.Now().UTC().Unix()) - expireTimestamp := currentTimestamp + expireTimeInSeconds - - result, err := rtmtokenbuilder.BuildToken(appID, appCertificate, rtm_uid, rtmtokenbuilder.RoleRtmUser, expireTimestamp) - if err != nil { - fmt.Println(err) + if (education_err != nil) { + if errors.As(education_err, &unmarshalErr) { + errorResponse(w, "Bad request. Please check your params.", http.StatusBadRequest) } else { - fmt.Printf("Rtm Token: %s\n", result) - - rtm_token = result - + errorResponse(w, "Bad request.", http.StatusBadRequest) } + return } - func rtmTokenHandler(w http.ResponseWriter, r *http.Request){ - w.Header().Set("Content-Type", "application/json;charset=UTF-8") - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS"); - w.Header().Set("Access-Control-Allow-Headers", "*"); - - if r.Method == "OPTIONS" { - w.WriteHeader(http.StatusOK) - return - } - - if r.Method != "POST" && r.Method != "OPTIONS" { - http.Error(w, "Unsupported method. Please check.", http.StatusNotFound) - return - } - - var t_rtm_str rtm_token_struct - var unmarshalErr *json.UnmarshalTypeError - str_decoder := json.NewDecoder(r.Body) - rtm_err := str_decoder.Decode(&t_rtm_str) - - if (rtm_err == nil) { - rtm_uid = t_rtm_str.Uid_rtm - } - - if (rtm_err != nil) { - if errors.As(rtm_err, &unmarshalErr){ - errorResponse(w, "Bad request. Please check your params.", http.StatusBadRequest) - } else { - errorResponse(w, "Bad request.", http.StatusBadRequest) - } - return - } - - generateRtmToken(rtm_uid) - errorResponse(w, rtm_token, http.StatusOK) - log.Println(w, r) - } - - func errorResponse(w http.ResponseWriter, message string, httpStatusCode int){ - w.Header().Set("Content-Type", "application/json") - w.Header().Set("Access-Control-Allow-Origin", "*") - w.WriteHeader(httpStatusCode) - resp := make(map[string]string) - resp["token"] = message - resp["code"] = strconv.Itoa(httpStatusCode) - jsonResp, _ := json.Marshal(resp) - w.Write(jsonResp) + generateRtmToken(t_education_str.roomUuid,t_education_str.userUuid,t_education_str.role) + errorResponse(w, educationToken, http.StatusOK) + log.Println(w, r) + } - } + func errorResponse(w http.ResponseWriter, message string, httpStatusCode int) { + w.Header().Set("Content-Type", "application/json") + w.Header().Set("Access-Control-Allow-Origin", "*") + w.WriteHeader(httpStatusCode) + resp := make(map[string]string) + resp["token"] = message + resp["code"] = strconv.Itoa(httpStatusCode) + jsonResp, _ := json.Marshal(resp) + w.Write(jsonResp) + } - func main(){ - // Handling routes - // Signaling token from Signaling uid - http.HandleFunc("/fetch_rtm_token", rtmTokenHandler) + func main() { + // Handle routing + http.HandleFunc("/fetch_education_token", educationTokenHandler) - fmt.Printf("Starting server at port 8082\n") + fmt.Printf("Starting server at port 8082\n") - if err := http.ListenAndServe(":8082", nil); err != nil { - log.Fatal(err) - } + if err := http.ListenAndServe(":8082", nil); err != nil { + log.Fatal(err) } - ``` + } + ``` 2. A `go.mod` file defines this module’s import path and dependency requirements. To create the `go.mod` for your token server, run the following command: @@ -312,119 +196,49 @@ In order to show the authentication workflow, this section shows how to build an $ go run server.go ``` -### Use tokens for user authentication +### Use AccessToken2 for authentication This section uses the Web client as an example to show how to use a token for client-side user authentication. +The following reference code comes from the [ web source code](https://github.com/AgoraIO-Community/flexible-classroom-desktop/blob/release/2.8.30/packages/agora-demo-app/src/pages/home/index.tsx). -In order to show the authentication workflow, this section shows how to build and run a Web client on your local machine. - -**This sample client is for demonstration purposes only. Do not use it in a production environment.** - -1. Create the project structure of the Web client with a folder including the following files. - - - `index.html`: User interface - - - `client.js`: App logic with Agora - -2. Download [Agora for Web](../overview/downloads). Save the JS file in `libs` to your project directory. - -3. In `index.html`, add the following code to include the app logic in the UI, then replace `` with the path of the JS file you saved in step 2. - - ```html - - - Signaling token demo - - - -

Token demo

- - - - - ``` - -4. Create the app logic by editing `client.js` with the following content. Then replace `` with your App ID. The App ID must match the one in the server. You also need to replace `` with the host URL and port of the local Golang server you have just deployed, such as `10.53.3.234:8082`. - - ```js - // Parameters for the login method - let options = { - token: "", - uid: "" - } - - // Whether to stop the token renew loop - let stopped = false - - function sleep (time) { - return new Promise((resolve) => setTimeout(resolve, time)); - } - - function fetchToken(uid) { - - return new Promise(function (resolve) { - axios.post('http:///fetch_rtm_token', { - uid: uid, - }, { - headers: { - 'Content-Type': 'application/json; charset=UTF-8' - } - }) - .then(function (response) { - const token = response.data.token; - resolve(token); - }) - .catch(function (error) { - console.log(error); - }); - }) - } - - async function loginRTM() - { +1. Initiate a token request to the server integrated with the token generator: - // Your app ID - const appID = "" - - // Initialize the client - const client = AgoraRTM.createInstance(appID) - - // Display connection state changes - client.on('ConnectionStateChanged', function (state, reason) { - console.log("State changed To: " + state + " Reason: " + reason) - }) - - // Set Signaling user ID - options.uid = "1234" - // Get Token - options.token = await fetchToken(options.uid) - // Log in to Signaling - await client.login(options) - - while (!stopped) - { - // Renew a token every 30 seconds for demonstration purposes. - // Agora recommends that you renew a token regularly, such as every hour, in production. - await sleep(30000) - options.token = await fetchToken(options.uid) - client.renewToken(options.token) - - let currentDate = new Date(); - let time = currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds(); - - console.log("Renew Signaling token at " + time) - } - - } - - loginRTM() + ```typescript + const { token, appId } = await roomApi.getCredentialNoAuth({ + userUuid, + roomUuid, + role: userRole, + }); ``` -5. Open `index.html` with a supported browser to perform the following actions: +1. Use the token obtained in this request to create a `launchOption` object: + + ```typescript + const launchOption = { + appId, + sdkDomain, + pretest: true, + courseWareList: [], + language: language as LanguageEnum, + userUuid: `${userUuid}`, + rtmToken: token, + roomUuid: `${roomUuid}`, + roomType: roomType, + roomName: `${roomName}`, + userName: userName, + roleType: userRole, + region: region as EduRegion, + duration: +duration * 60, + latencyLevel: 2, + shareUrl, + }; + ``` -- Successfully logging in to . +1. Call `launch` and use the token to join the classroom: -- Renewing a token every 30 seconds. + ```typescript + AgoraEduSDK.launch(dom, launchOption); + ``` ## Reference @@ -432,7 +246,7 @@ This section introduces token generator libraries, version requirements, and rel ### Token generator libraries -Agora provides an open-source [AgoraDynamicKey](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey) repository on GitHub, which enables you to generate tokens on your server with programming languages such as C++, Java, and Go. + provides an open-source [AgoraDynamicKey](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey) repository on GitHub, which enables you to generate tokens on your server with programming languages such as C++, Java, and Go. #### AccessToken2 @@ -450,24 +264,9 @@ Agora provides an open-source [AgoraDynamicKey](https://github.com/AgoraIO/Tools | Python 2 | HMAC-SHA256 | [build_app_token](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python/src/education_token_builder.py) | [education_token_builder_sample.py](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python/sample/education_token_builder_sample.py) | | Python 3 | HMAC-SHA256 | [build_app_token](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python3/src/education_token_builder.py) | [education_token_builder_sample.py](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python3/sample/education_token_builder_sample.py) | -- Personal user - - The scope is user-level operations under the specified App ID, which can be used across rooms, such as personal cloud disks. - - | Language | Algorithm | Core method | Sample code | - | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | C++ | HMAC-SHA256 | [BuildUserToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/cpp/src/EducationTokenBuilder2.h) | N/A | - | Go | HMAC-SHA256 | [BuildUserToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/go/src/educationtokenbuilder/educationtokenbuilder.go) | [sample.go](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/go/sample/educationtokenbuilder/sample.go) | - | Java | HMAC-SHA256 | [buildUserToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/java/src/main/java/io/agora/education/EducationTokenBuilder2.java) | [EducationTokenBuilder2Sample.java](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/java/src/main/java/io/agora/sample/EducationTokenBuilder2Sample.java) | - | Node.js| HMAC-SHA256 | [buildUserToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/nodejs/src/EducationTokenBuilder.js) | [EducationTokenSample.js](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/nodejs/sample/EducationTokenSample.js) | - | PHP | HMAC-SHA256 | [buildUserToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/php/src/EducationTokenBuilder.php) | [EducationTokenBuilderSample.php](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/php/sample/EducationTokenBuilderSample.php) | - | Python 2 | HMAC-SHA256 | [build_user_token](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python/src/education_token_builder.py) | [education_token_builder_sample.py](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python/sample/education_token_builder_sample.py) | - | Python 3 | HMAC-SHA256 | [build_user_token](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python3/src/education_token_builder.py) | [education_token_builder_sample.py](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python3/sample/education_token_builder_sample.py) | - - - Specify room and user (used by client) - The scope is the specified user in the specified room. This token packages two services, `ServiceEducation` and `ServiceRtm`, which are passed in when the client SDK is started. It can help users open the token for Flexible Classroom and RTM user login. + The scope is the specified user in the specified room. This token packages two services, `ServiceEducation` and `ServiceRtm`, which are passed in when the client SDK is started. It can help users open the token for and user login. | Language | Algorithm | Core method | Sample code | | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -493,123 +292,13 @@ Agora provides an open-source [AgoraDynamicKey](https://github.com/AgoraIO/Tools | Python 2 | HMAC-SHA256 | [buildToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python/src/RtmTokenBuilder.py) | [RtmTokenBuilderSample.py](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python/sample/RtmTokenBuilderSample.py) | | Python 3 | HMAC-SHA256 | [buildToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python3/src/RtmTokenBuilder.py) | [RtmTokenBuilderSample.py](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python3/sample/RtmTokenBuilderSample.py) | -### API reference - -This section introduces the method to generate a token. Take C++ as an example: - -- **AccessToken2** - - ```go - func BuildToken(appId string, appCertificate string, userId string, expire uint32) (string, error) { - token := accesstoken.NewAccessToken(appId, appCertificate, expire) - serviceRtm := accesstoken.NewServiceRtm(userId) - serviceRtm.AddPrivilege(accesstoken.PrivilegeLogin, expire) - token.AddService(serviceRtm) - return token.Build() - } - ``` - - | Parameter | Description | - | :----------------- | :----------------------------------------------------------- | - | `appId` | The App ID of your Agora project. | - | `appCertificate` | The App Certificate of your Agora project. | - | `userId` | The user ID of the system. You need specify the user ID yourself. See the userId parameter of the login method for supported character sets. | - | `expire` | The duration (in seconds) from the generation of AccessToken2 to the expiration of AccessToken2. For example, if you set it as 600, the AccessToken2 expires 10 minutes after generation. An AccessToken2 is valid for a maximum of 24 hours. If you set it to a duration longer than 24 hours, the AccessToken2 still expires after 24 hours. If you set it to 0, the AccessToken2 expires immediately. | - - -- **AccessToken** - ```cpp - static std::string buildToken(const std::string& appId, - const std::string& appCertificate, - const std::string& userAccount, - RtmUserRole userRole, - uint32_t privilegeExpiredTs = 0); - ``` - - | Parameter | Description | - |--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| - | appId | The App ID of your Agora project. | - | appCertificate | The App Certificate of your Agora project. | - | userAccount | The user ID of . You need specify the user ID yourself. See the userId parameter of the login method for supported character sets. | - | roleType | The user role. Agora supports only one user role. Set the value as the default value `Rtm_User`. | - | privilegeExpiredTs | The Unix timestamp (s) when the token expires, represented by the sum of the current timestamp and the valid time of the token. This parameter is currently invalid. You can ignore this parameter. a token is valid for 24 hours. | - -### Upgrade AccessToken2 - -This section introduces how to upgrade from AccessToken to AccessToken2 by example. - -#### Prerequisites - -- You have deployed a token server and a web client for AccessToken in a previous version. -- You have integrated an [SDK version](#sdk-version) that supports AccessToken2. - -#### Update the token server - -1. Replace the `rtmtokenbuilder` import statement: - -```go -// Replace "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/RtmTokenBuilder" -// with "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtmtokenbuilder2". -import ( - rtmtokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtmtokenbuilder2" - "fmt" - "log" - "net/http" - "time" - "encoding/json" - "errors" - "strconv" -) -``` - -2. Update the `BuildToken` function: - -```go -// Previously, it is `result, err := rtmtokenbuilder.BuildToken(appID, appCertificate, rtm_uid, rtmtokenbuilder.RoleRtmUser, expireTimestamp)`. -// Now, remove `rtmtokenbuilder.RoleRtmUser`. -result, err := rtmtokenbuilder.BuildToken(appID, appCertificate, rtm_uid, expireTimestamp) -``` - -#### Test the AccessToken2 server - -The client does not require any updates; however, the [expiration logic](#expiration) changes accordingly. - -To use AccessToken2 in server-side, refer to [RESTful API Authentication](../reference/restful-authentication#sample-code-for-accesstoken2) and authenticate with new request headers. - - ### Considerations -#### User ID - -The user ID that you use to generate the token must be the same as the one you use to log in to . - -#### App Certificate and token - -To use the token for authentication, you need to enable the App Certificate for your project on Console. Once a project has enabled the App Certificate, you must use tokens to authenticate its users. - -### Token expiration - -- **AccessToken2** - - AccessToken2 allows you to specify the validity period of an token in seconds based on your business requirements. The validity period can be a maximum of 24 hours. - - When a token is due to expire in 30 seconds, the triggers the `onTokenPrivilegeWillExpire` callback. Upon receiving this callback, you can generate a new token on your app server and call `renewToken` to pass the new token to the SDK. - - When an token expires, the subsequent logic varies depending on the connection state of the SDK: - - - If the is in the `CONNECTION_STATE_CONNECTED` state, users receive the `onTokenExpired` callback and the `onConnectionStateChanged` callback caused by `CONNECTION_CHANGE_REASON_TOKEN_EXPIRED (9)`, notifying them that the connection state of the SDK switches to `CONNECTION_STATE_ABORTED`. In this case, users need to log in again via the `login` method. - - If the is in the `CONNECTION_STATE_RECONNECTING` state, users receive the `onTokenExpired` callback when the network reconnects. In this case, users need to renew the token via the `renewToken` method. - - Although you can use the onTokenPrivilegeWillExpire and onTokenExpired callbacks to handle token expiration conditions, Agora recommends that you regularly renew the token (such as every hour) to keep the token valid. - - The names of methods, callbacks, and enums mentioned in the above section only apply to C++. Refer to the API documentation for names in other platforms. - -- **AccessToken** - - a token is valid for 24 hours. +#### Parameter consistency - When the is in the `CONNECTION_STATE_CONNECTED` state, the user remains online even if the token expires. If a user logs in with an expired token, the returns the `LOGIN_ERR_TOKEN_EXPIRED` error. +The parameters used to generate the token need to be consistent with the ones you used to launch . - The triggers the `onTokenExpired` callback only when a token expires and the is in the `CONNECTION_STATE_RECONNECTING` state. The callback is triggered only once. Upon receiving this callback, you can generate a new token on your app server, and call `renewToken` to pass the new token to the SDK. +#### App certificate and token +To use the token for authentication, you need to enable the app certificate for your project on . Once a project has enabled the app certificate, you must use tokens to authenticate its users. diff --git a/flexible-classroom/develop/classroom-security.md b/flexible-classroom/develop/classroom-security.md index 3b548e2b1..d8a428071 100644 --- a/flexible-classroom/develop/classroom-security.md +++ b/flexible-classroom/develop/classroom-security.md @@ -29,7 +29,7 @@ Agora Flexible Classroom uses the token for end user authenticatio The app developer can enable token authentication (App Certificate) in . When enabled, all user’s request to join a classroom must be done with a valid token. - For more information on how to enable token authentication, see [Secure authentication with tokens](authentication-workflow). -- For how to generate a token on the app backend, see [Secure authentication with tokens](authentication-workflow). +- For how to generate a token on the app backend, see [Secure authentication with tokens](authentication-workflow#token-generator-libraries). ## Data encryption and storage diff --git a/flexible-classroom/get-started/enable-flexible-classroom.mdx b/flexible-classroom/get-started/enable-flexible-classroom.mdx index e35a0ab3b..bfbcfcf5d 100644 --- a/flexible-classroom/get-started/enable-flexible-classroom.mdx +++ b/flexible-classroom/get-started/enable-flexible-classroom.mdx @@ -235,7 +235,7 @@ Configure your AWS S3 account as follows: { "Sid":"Stmt1622700872941", "Effect":"Allow", - "Principal":"", + "Principal":"*", "Action":["s3:GetObject","s3:PutObject"], "Resource":"arn:aws-cn:s3:::agora-adc-artifacts/" } diff --git a/flexible-classroom/restful-api/classroom-api.mdx b/flexible-classroom/restful-api/classroom-api.mdx index 19985da9a..4a177bfe2 100644 --- a/flexible-classroom/restful-api/classroom-api.mdx +++ b/flexible-classroom/restful-api/classroom-api.mdx @@ -57,7 +57,7 @@ Pass in the following parameters in the request body: | Parameter | Type | Description | | :--------------------------------------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `roomType` | String | (Required) The type of the classroom. You can set the value to :
  • `0`: One-to-one classroom.
  • `2`: Lecture hall.
  • `4`: Small classroom.
Once set, this parameter value cannot be changed. | +| `roomType` | String | (Required) The type of the classroom. You can set the value to :
  • `0`: One-to-one classroom.
  • `2`: Lecture hall.
  • `4`: Small classroom.
  • `10`: Small cloud classroom.
Once set, this parameter value cannot be changed. | | `roomName` | String | (Required) The name of the classroom. The maximum length of this parameter is 64 characters. | | `roomProperties` | Object | (Optional) The properties of the classroom. It includes the name of the room, room number whiteboard plug-in configuration, chat plug-in configuration, room opening, end time, duration, configuration of the number of people who raise their hands to connect to the microphone, the maximum number of people to connect to the microphone, and the switch status configuration of the device for students to join the room by default, etc. | | `roomProperties.schedule` | Object | (Optional) The schedule of the classroom. | @@ -82,13 +82,13 @@ Pass in the following parameters in the request body: | `roleConfig.2.defaultStream.videoState` | Integer | (Optional) The video state of the default stream of the student:
  • `0`: Disabled.
  • `1`: Enabled.
  • | | `roleConfig.2.defaultStream.audioState` | Integer | (Optional) The audio state of the default stream of the student:
  • `0`: Disabled.
  • `1`: Enabled.
  • | -To create a Cloud Classroom, followings are the required parameters: +To create a small cloud classroom, the following are the required parameters: ```json { ... "roomName":"{roomName}", - "roomType":4, + "roomType":10, "roleConfig":{ "2":{ "defaultStream":{ @@ -208,7 +208,7 @@ curl -X GET 'https://api.sd-rtn.com/{region}/edu/apps/{yourAppId}/v2/rooms/test_ | `code` | Integer | Request status code:
    • 0: The request succeeds.
    • Non-zero: The request fails.
    | | `msg` | String | Detailed information about the code. | | `ts` | Number | The current Unix timestamp (in milliseconds) of the server in UTC. | -|`data` | Object | The returned object, which contains the following data:
    • `roomUuid`: String, room ID.
    • `roomName`: String, room name.
    • `createTime`: Integer, room creation timestamp.
    • `roomProperties`: Object, room attributes.
      • `roomType`: Integer, room type.
        • `0`: 1 to 1.
        • `2`: Large classroom.
        • `4`: Small classroom.
      • `schedule`: Object, lesson plan.
        • `state`: Integer, room state.
          • `0`: Not started.
          • `1`: Started.
          • `2`: Ended.
          • `3`: Closed.
        • `startTime`: Integer, starting time.
        • `endTime`: Integer, end time.
        • `closeTime`: Integer, closing time.
      • `widgets`: Object, component collection.
        • `netlessBoard`: Object, whiteboard component.
          • `extra`: Object, extended information.
            • `boardAppId`: String, whiteboard App ID.
            • `boardId`: String, whiteboard room ID.
            • `boardToken`: String, whiteboard room Token.
            • `boardRegion`: String, whiteboard area.
          • `state`: Integer, component state.
            • `0`: Integer, not activated.
            • `1`: Integer, activated.
        • `easemobIM`: Object, chat room component.
          • `extra`: Object, extended information.
            • `orgName`: String, organization name.
            • `appName`: String, app name.
            • `chatRoomId`: String, chat room ID.
            • `appKey`: String, app Key.
          • `state`: Integer, component state.
            • 0: Integer, not activated.
            • 1: Integer, activated.
    | +|`data` | Object | The returned object, which contains the following data:
    • `roomUuid`: String, room ID.
    • `roomName`: String, room name.
    • `createTime`: Integer, room creation timestamp.
    • `roomProperties`: Object, room attributes.
      • `roomType`: Integer, room type.
        • `0`: 1 to 1.
        • `2`: Large classroom.
        • `4`: Small classroom.
        • `10`: Small cloud classroom.
      • `schedule`: Object, lesson plan.
        • `state`: Integer, room state.
          • `0`: Not started.
          • `1`: Started.
          • `2`: Ended.
          • `3`: Closed.
        • `startTime`: Integer, starting time.
        • `endTime`: Integer, end time.
        • `closeTime`: Integer, closing time.
      • `widgets`: Object, component collection.
        • `netlessBoard`: Object, whiteboard component.
          • `extra`: Object, extended information.
            • `boardAppId`: String, whiteboard App ID.
            • `boardId`: String, whiteboard room ID.
            • `boardToken`: String, whiteboard room Token.
            • `boardRegion`: String, whiteboard area.
          • `state`: Integer, component state.
            • `0`: Integer, not activated.
            • `1`: Integer, activated.
        • `easemobIM`: Object, chat room component.
          • `extra`: Object, extended information.
            • `orgName`: String, organization name.
            • `appName`: String, app name.
            • `chatRoomId`: String, chat room ID.
            • `appKey`: String, app Key.
          • `state`: Integer, component state.
            • 0: Integer, not activated.
            • 1: Integer, activated.
    | #### Response example diff --git a/media-gateway/develop/_category_.json b/media-gateway/develop/_category_.json new file mode 100644 index 000000000..bee160082 --- /dev/null +++ b/media-gateway/develop/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 3, + "label": "Develop", + "collapsible": true, + "link": null +} diff --git a/media-gateway/develop/receive-notifications.mdx b/media-gateway/develop/receive-notifications.mdx new file mode 100644 index 000000000..2ea7e8053 --- /dev/null +++ b/media-gateway/develop/receive-notifications.mdx @@ -0,0 +1,14 @@ +--- +title: 'Receive notifications about channel events' +sidebar_position: 1 +type: docs +description: > + Receive notification of channel events in real time. +--- + + +import Ncs from '@docs/shared/notification-center-service/_notification_center_service.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/get-started/_category_.json b/media-gateway/get-started/_category_.json new file mode 100644 index 000000000..8d46f797b --- /dev/null +++ b/media-gateway/get-started/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 2, + "label": "Get started", + "collapsible": true, + "link": null +} diff --git a/media-gateway/get-started/enable-media-gateway.mdx b/media-gateway/get-started/enable-media-gateway.mdx new file mode 100644 index 000000000..f4252d4b5 --- /dev/null +++ b/media-gateway/get-started/enable-media-gateway.mdx @@ -0,0 +1,13 @@ +--- +title: 'Enable Media Gateway' +sidebar_position: 2 +type: docs +description: > + Enable Media Gateway on Agora Console +--- + +import EnableMG from '@docs/shared/media-gateway/get-started/enable-media-gateway.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/get-started/quickstart.mdx b/media-gateway/get-started/quickstart.mdx new file mode 100644 index 000000000..420485cc3 --- /dev/null +++ b/media-gateway/get-started/quickstart.mdx @@ -0,0 +1,13 @@ +--- +title: 'Media Gateway quickstart' +sidebar_position: 1 +type: docs +description: > + Stream directly with RTMP/SRT protocol to Agora RTC channels. +--- + +import MEDIAGateway from '@docs/shared/media-gateway/get-started/_quickstart.mdx'; + +export const toc = [{}]; + + diff --git a/media-gateway/overview/_category_.json b/media-gateway/overview/_category_.json new file mode 100644 index 000000000..9874239b6 --- /dev/null +++ b/media-gateway/overview/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 1, + "label": "Overview", + "collapsible": true, + "link": null +} diff --git a/media-gateway/overview/core-concepts.mdx b/media-gateway/overview/core-concepts.mdx new file mode 100644 index 000000000..d12bcbf7a --- /dev/null +++ b/media-gateway/overview/core-concepts.mdx @@ -0,0 +1,14 @@ +--- +title: 'Core concepts' +sidebar_position: 2 +type: docs +platform_selector: false +description: > + Ideas that are central to developing with Agora. +--- + +import CoreConcepts from '@docs/shared/common/_core-concepts.mdx'; + +export const toc = [{}]; + + diff --git a/media-gateway/overview/pricing.mdx b/media-gateway/overview/pricing.mdx new file mode 100644 index 000000000..a2d093202 --- /dev/null +++ b/media-gateway/overview/pricing.mdx @@ -0,0 +1,13 @@ +--- +title: 'Pricing' +sidebar_position: 4 +type: docs +description: > + Unit pricing for Media Gateway services +--- + +import Pricing from '@docs/shared/media-gateway/reference/pricing.mdx'; + +export const toc = [{}] + + \ No newline at end of file diff --git a/media-gateway/overview/product-features.mdx b/media-gateway/overview/product-features.mdx new file mode 100644 index 000000000..259636cd0 --- /dev/null +++ b/media-gateway/overview/product-features.mdx @@ -0,0 +1,38 @@ +--- +title: 'Media Gateway features' +sidebar_position: 3 +type: docs +platform_selector: false +description: > + The key features of Agora Media Gateway +--- + + enables users to push content to Agora SD-RTN™ using standard streaming protocols such as RTMP and SRT. The channel host automatically publishes this streamed content to the correct channel. With , you can employ advanced transcoding capabilities on media streams for enhanced distribution. + +The following figure shows the overall architecture of : + +![Product Architecture](/images/media-gateway/media-gateway-flow.svg) + +## Product features + + supports the following features: + +| Feature | Description | +|--------------------------------------------|---| +| Media input | Supports generating a streaming key through RESTful API or a local encryption algorithm, and pushes the source stream directly to Agora's gateway service. After a successful push, the media stream is automatically played in the channel for remote users. | +| Multiple media streaming formats/protocols |
    • Video codec format: H.264, H.265
    • Audio codec format: AAC
    • Push protocol: RTMP, SRT
    • Media formats: FLV, MPEG-TS
    | +| Custom transcoding parameters | Supports enabling transcoding for media streams input into the channel. If you enable transcoding, you can set parameters such as resolution, frame rate, bitrate, and whether to enable large and small streams. | +| Restricted access area | When activating , you specify the access area to ensure the transmission quality of the media stream. | +| Server event notification callback | Agora provides message notification services. After activating , you will receive event notifications. | + +## Applicable scenarios + +In ultra-high-definition scenarios, the main signal is generally processed by the content provider and then pushed to Agora through the RTMP protocol (suitable for low bitrates) or the SRT protocol (suitable for high bitrates). enables you to add source streams to SD-RTN™ with low latency while ensuring high stability. Some sample scenarios for the use of include: + +| Scenario | Description | +|---|---| +| Commentary from influencers/celebrities | Inject high-definition video streams into interactive channels. Multiple hosts can watch and interact in real time in different places. | +| Low-latency distribution | Distribute content to viewers faster and more reliably than with a CDN. | +| Recording and live broadcasting| The teacher records the content in advance and injects it into a live classroom. All students and teaching assistants can watch the teacher's content, and students can communicate and interact in real time with each other and and with teaching assistants. | +| 24-hour chat room | Background music is played 24 hours a day and is not interrupted when switching hosts. | + diff --git a/media-gateway/overview/product-overview.mdx b/media-gateway/overview/product-overview.mdx new file mode 100644 index 000000000..4fa432d77 --- /dev/null +++ b/media-gateway/overview/product-overview.mdx @@ -0,0 +1,54 @@ +--- +title: 'Product overview' +sidebar_position: 1 +platform_selector: false +description: > + Stream directly with RTMP/SRT protocol to Agora RTC channels.. +--- + + + + allows users to directly push media streams into Agora’s Real-Time Voice and Video channels using the +RTMP/SRT protocol. To facilitate distribution, Media Gateway also allows users to perform advanced transcoding +processing on media streams. + + \ No newline at end of file diff --git a/media-gateway/overview/release-notes.mdx b/media-gateway/overview/release-notes.mdx new file mode 100644 index 000000000..47e1bcbd7 --- /dev/null +++ b/media-gateway/overview/release-notes.mdx @@ -0,0 +1,14 @@ +--- +title: 'Release notes' +sidebar_position: 5 +type: docs +description: > + Shows Media Gateway's past releases. +template: 'platform' +--- + +import ReleaseNotes from '@docs/shared/media-gateway/reference/_release-notes.mdx'; + +export const toc = [{}]; + + diff --git a/media-gateway/reference/_category_.json b/media-gateway/reference/_category_.json new file mode 100644 index 000000000..d540fd6db --- /dev/null +++ b/media-gateway/reference/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 4, + "label": "Reference", + "collapsible": true, + "link": null +} diff --git a/media-gateway/reference/best-practice.mdx b/media-gateway/reference/best-practice.mdx new file mode 100644 index 000000000..84f9e06d3 --- /dev/null +++ b/media-gateway/reference/best-practice.mdx @@ -0,0 +1,13 @@ +--- +title: 'Integration best practice' +sidebar_position: 2 +type: docs +description: > + Best practice for using Media Gateway and its RESTful API. +--- + +import BestPractice from '@docs/shared/media-gateway/reference/_best-practice.mdx'; + +export const toc = [{}]; + + diff --git a/media-gateway/reference/glossary.mdx b/media-gateway/reference/glossary.mdx new file mode 100644 index 000000000..97b410dce --- /dev/null +++ b/media-gateway/reference/glossary.mdx @@ -0,0 +1,14 @@ +--- +title: 'Glossary' +sidebar_position: 5 +type: docs +platform_selector: false +description: > + A list of terms used in Agora documentation. +--- + +import Glossary from '@docs/shared/common/_glossary.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/manage-agora-account.mdx b/media-gateway/reference/manage-agora-account.mdx new file mode 100644 index 000000000..1d540df9f --- /dev/null +++ b/media-gateway/reference/manage-agora-account.mdx @@ -0,0 +1,14 @@ +--- +title: 'Agora account management' +sidebar_position: 3 +type: docs +platform_selector: false +description: > + Create, manage and update your Agora account. +--- + +import ManageAccount from '@docs/shared/common/_manage-agora-account.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/_category_.json b/media-gateway/reference/rest-api/_category_.json new file mode 100644 index 000000000..a46dec1f6 --- /dev/null +++ b/media-gateway/reference/rest-api/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 1, + "label": "RESTful API", + "collapsible": true, + "link": null +} diff --git a/media-gateway/reference/rest-api/endpoints/_category_.json b/media-gateway/reference/rest-api/endpoints/_category_.json new file mode 100644 index 000000000..931c763d3 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 2, + "label": "Endpoints", + "collapsible": true, + "link": null +} diff --git a/media-gateway/reference/rest-api/endpoints/flow-configuration-template/_category_.json b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/_category_.json new file mode 100644 index 000000000..7dc7d29f9 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 2, + "label": "Flow configuration templates", + "collapsible": true, + "link": null +} diff --git a/media-gateway/reference/rest-api/endpoints/flow-configuration-template/create-reset-template.mdx b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/create-reset-template.mdx new file mode 100644 index 000000000..01c7ded79 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/create-reset-template.mdx @@ -0,0 +1,14 @@ +--- +title: 'Create or reset template' +sidebar_position: 1 +type: docs +platform_selector: false +description: > + API reference for creating or resetting a flow configuration template +--- + +import CreateTemplate from '@docs/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/create-reset-template.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/flow-configuration-template/delete-template.mdx b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/delete-template.mdx new file mode 100644 index 000000000..cd497a4ec --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/delete-template.mdx @@ -0,0 +1,14 @@ +--- +title: 'Delete template' +sidebar_position: 3 +type: docs +platform_selector: false +description: > + API reference for deleting a flow configuration template +--- + +import DeleteTemplate from '@docs/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/delete-template.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/flow-configuration-template/set-global-template.mdx b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/set-global-template.mdx new file mode 100644 index 000000000..80bf95d1a --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/set-global-template.mdx @@ -0,0 +1,14 @@ +--- +title: 'Set global template' +sidebar_position: 4 +type: docs +platform_selector: false +description: > + API reference for setting a global flow configuration template +--- + +import SetGlobalTemplate from '@docs/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/set-global-template.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/flow-configuration-template/update-template.mdx b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/update-template.mdx new file mode 100644 index 000000000..3babfc0d3 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/flow-configuration-template/update-template.mdx @@ -0,0 +1,14 @@ +--- +title: 'Update template' +sidebar_position: 2 +type: docs +platform_selector: false +description: > + API reference for updating a flow configuration template +--- + +import UpdateTemplate from '@docs/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/update-template.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/message-notification-service/_category_.json b/media-gateway/reference/rest-api/endpoints/message-notification-service/_category_.json new file mode 100644 index 000000000..8f86d589b --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/message-notification-service/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 4, + "label": "Message notification service", + "collapsible": true, + "link": null +} diff --git a/media-gateway/reference/rest-api/endpoints/message-notification-service/query-ip-address.mdx b/media-gateway/reference/rest-api/endpoints/message-notification-service/query-ip-address.mdx new file mode 100644 index 000000000..6f169a4e0 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/message-notification-service/query-ip-address.mdx @@ -0,0 +1,14 @@ +--- +title: 'Query notification service IP address' +sidebar_position: 1 +type: docs +platform_selector: false +description: > + API reference for querying the Notifications IP addresses +--- + +import QueryIpAddress from '@docs/shared/media-gateway/reference/rest-api/endpoints/message-notification-service/query-ip-address.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/streaming-information/_category_.json b/media-gateway/reference/rest-api/endpoints/streaming-information/_category_.json new file mode 100644 index 000000000..787d03247 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/streaming-information/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 3, + "label": "Streaming information", + "collapsible": true, + "link": null +} diff --git a/media-gateway/reference/rest-api/endpoints/streaming-information/force-disconnection.mdx b/media-gateway/reference/rest-api/endpoints/streaming-information/force-disconnection.mdx new file mode 100644 index 000000000..4d2765048 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/streaming-information/force-disconnection.mdx @@ -0,0 +1,14 @@ +--- +title: 'Force disconnect' +sidebar_position: 3 +type: docs +platform_selector: false +description: > + API reference for forced disconnection +--- + +import ForceDisconnect from '@docs/shared/media-gateway/reference/rest-api/endpoints/streaming-information/force-disconnection.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-information.mdx b/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-information.mdx new file mode 100644 index 000000000..2e1fa8bd2 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-information.mdx @@ -0,0 +1,14 @@ +--- +title: 'Query streaming information' +sidebar_position: 2 +type: docs +platform_selector: false +description: > + API reference for querying streaming information +--- + +import QueryStreamingInfo from '@docs/shared/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-information.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-list.mdx b/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-list.mdx new file mode 100644 index 000000000..2bcdb9d0c --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-list.mdx @@ -0,0 +1,14 @@ +--- +title: 'Query streaming list' +sidebar_position: 1 +type: docs +platform_selector: false +description: > + API reference for querying the streaming list +--- + +import QueryStreamingList from '@docs/shared/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-list.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/streaming-key/_category_.json b/media-gateway/reference/rest-api/endpoints/streaming-key/_category_.json new file mode 100644 index 000000000..6e3e4742e --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/streaming-key/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 1, + "label": "Streaming key", + "collapsible": true, + "link": null +} diff --git a/media-gateway/reference/rest-api/endpoints/streaming-key/create-streaming-key.mdx b/media-gateway/reference/rest-api/endpoints/streaming-key/create-streaming-key.mdx new file mode 100644 index 000000000..d7a54840a --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/streaming-key/create-streaming-key.mdx @@ -0,0 +1,14 @@ +--- +title: 'Create streaming key' +sidebar_position: 1 +type: docs +platform_selector: false +description: > + API reference for creating a streaming key +--- + +import CreateStreamingKey from '@docs/shared/media-gateway/reference/rest-api/endpoints/streaming-key/create-streaming-key.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/streaming-key/delete-streaming-key.mdx b/media-gateway/reference/rest-api/endpoints/streaming-key/delete-streaming-key.mdx new file mode 100644 index 000000000..d8468f651 --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/streaming-key/delete-streaming-key.mdx @@ -0,0 +1,14 @@ +--- +title: 'Delete streaming key' +sidebar_position: 3 +type: docs +platform_selector: false +description: > + API reference for deleting a streaming key +--- + +import DeleteStreamingKey from '@docs/shared/media-gateway/reference/rest-api/endpoints/streaming-key/delete-streaming-key.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/endpoints/streaming-key/query-streaming-key-information.mdx b/media-gateway/reference/rest-api/endpoints/streaming-key/query-streaming-key-information.mdx new file mode 100644 index 000000000..842a476bb --- /dev/null +++ b/media-gateway/reference/rest-api/endpoints/streaming-key/query-streaming-key-information.mdx @@ -0,0 +1,14 @@ +--- +title: 'Query streaming key' +sidebar_position: 2 +type: docs +platform_selector: false +description: > + API reference for querying information about a streaming key +--- + +import QueryStreamingKeyInfo from '@docs/shared/media-gateway/reference/rest-api/endpoints/streaming-key/query-streaming-key-information.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/limitations.mdx b/media-gateway/reference/rest-api/limitations.mdx new file mode 100644 index 000000000..41bf768eb --- /dev/null +++ b/media-gateway/reference/rest-api/limitations.mdx @@ -0,0 +1,14 @@ +--- +title: 'Limitations' +sidebar_position: 5 +type: docs +platform_selector: false +description: > + Limitations imposed on the Media Gateway RESTful APIs +--- + +import Limitations from '@docs/shared/media-gateway/reference/rest-api/limitations.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/overview.mdx b/media-gateway/reference/rest-api/overview.mdx new file mode 100644 index 000000000..e1dbc84e8 --- /dev/null +++ b/media-gateway/reference/rest-api/overview.mdx @@ -0,0 +1,14 @@ +--- +title: 'Overview' +sidebar_position: 1 +type: docs +platform_selector: false +description: > + Intro to the Media Gateway RESTful APIs +--- + +import Overview from '@docs/shared/media-gateway/reference/rest-api/overview.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/response-status-codes.mdx b/media-gateway/reference/rest-api/response-status-codes.mdx new file mode 100644 index 000000000..e4eeaa2d2 --- /dev/null +++ b/media-gateway/reference/rest-api/response-status-codes.mdx @@ -0,0 +1,15 @@ +--- +title: 'Response status codes' +sidebar_position: 4 +type: docs +platform_selector: false +description: > + Response status codes of the Media Gateway RESTful APIs +--- + + +import StatusCodes from '@docs/shared/media-gateway/reference/rest-api/response-status-codes.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/rest-api/webhooks/_category_.json b/media-gateway/reference/rest-api/webhooks/_category_.json new file mode 100644 index 000000000..c7ee0d362 --- /dev/null +++ b/media-gateway/reference/rest-api/webhooks/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 3, + "label": "Webhooks", + "collapsible": true, + "link": null +} \ No newline at end of file diff --git a/media-gateway/reference/rest-api/webhooks/media-gateway-event-type.mdx b/media-gateway/reference/rest-api/webhooks/media-gateway-event-type.mdx new file mode 100644 index 000000000..32c32a1cf --- /dev/null +++ b/media-gateway/reference/rest-api/webhooks/media-gateway-event-type.mdx @@ -0,0 +1,14 @@ +--- +title: 'Media Gateway event type' +sidebar_position: 1 +type: docs +platform_selector: false +description: > + Media Gateway event types and descriptions +--- + +import MediaGatewayEvents from '@docs/shared/media-gateway/reference/rest-api/webhooks/media-gateway-event-type.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/media-gateway/reference/restful-authentication.mdx b/media-gateway/reference/restful-authentication.mdx new file mode 100644 index 000000000..cab09745f --- /dev/null +++ b/media-gateway/reference/restful-authentication.mdx @@ -0,0 +1,13 @@ +--- +title: 'RESTful authentication' +sidebar_position: 1 +type: docs +description: > + Set up basic or HMAC authentication for RESTful API calls +--- + +import DOC from '@docs/shared/common/_restful-authentication.mdx'; + +export const toc = [{}] + + \ No newline at end of file diff --git a/media-gateway/reference/security.mdx b/media-gateway/reference/security.mdx new file mode 100644 index 000000000..8025337ee --- /dev/null +++ b/media-gateway/reference/security.mdx @@ -0,0 +1,14 @@ +--- +title: 'Security' +sidebar_position: 4 +type: docs +platform_selector: false +description: > + How Agora handles security. +--- + +import Security from '@docs/shared/common/_security.mdx'; + +export const toc = [{}]; + + \ No newline at end of file diff --git a/shared/chat-sdk/client-api/chat-group/manage-chat-groups/project-implementation/flutter.mdx b/shared/chat-sdk/client-api/chat-group/manage-chat-groups/project-implementation/flutter.mdx index e5ea68d64..1c031784f 100644 --- a/shared/chat-sdk/client-api/chat-group/manage-chat-groups/project-implementation/flutter.mdx +++ b/shared/chat-sdk/client-api/chat-group/manage-chat-groups/project-implementation/flutter.mdx @@ -234,16 +234,89 @@ To monitor the chat group events, users can listen for the callbacks in the `Cha Refer to the following code sample to listen for chat group events: ```dart - // Add the group event handler. + /// Add a group event listener. ChatClient.getInstance.groupManager.addEventHandler( - "UNIQUE_HANDLER_ID", - ChatGroupEventHandler(), - ); + 'UNIQUE_HANDLER_ID', + ChatGroupEventHandler( + /// Occurs when a member is added to the chat group admin list. + onAdminAddedFromGroup: (groupId, admin) {}, + + /// Occurs when an admin is removed from the chat group admin list. + onAdminRemovedFromGroup: (groupId, admin) {}, + + /// Occurs when all chat group members are muted or unmuted. + onAllGroupMemberMuteStateChanged: (groupId, isAllMuted) {}, + + /// Occurs when a member is added to the chat group allow list. + onAllowListAddedFromGroup: (groupId, members) {}, + + /// Occurs when a member is removed from the chat group allow list. + onAllowListRemovedFromGroup: (groupId, members) {}, + + /// Occurs when a member updates the chat group announcement. + onAnnouncementChangedFromGroup: (groupId, announcement) {}, + + /// Occurs when custom attributes of a group member are updated. + onAttributesChangedOfGroupMember: (groupId, userId, attributes, operatorId) {}, + + /// Occurs when an invitee accepts a group invitation automatically. + onAutoAcceptInvitationFromGroup: (groupId, inviter, inviteMessage) {}, + + /// Occurs when the group function is disabled or enabled. + onDisableChanged: (groupId, isDisable) {}, + + /// Occurs when the chat group owner disbands a chat group. + onGroupDestroyed: (groupId, groupName) {}, + + /// Occurs when an invitee accepts a group invitation. + onInvitationAcceptedFromGroup: (groupId, invitee, reason) {}, + + /// Occurs when an invitee declines a group invitation. + onInvitationDeclinedFromGroup: (groupId, invitee, reason) {}, - ... + /// Occurs when an invitee receives a group invitation. + onInvitationReceivedFromGroup: (groupId, groupName, inviter, reason) {}, - // Remove the group event handler. - ChatClient.getInstance.groupManager.removeEventHandler("UNIQUE_HANDLER_ID"); + /// Occurs when a member leaves a chat group. + onMemberExitedFromGroup: (groupId, member) {}, + + /// Occurs when a user joins a chat group. + onMemberJoinedFromGroup: (groupId, member) {}, + + /// Occurs when a member is added to the chat group mute list. + onMuteListAddedFromGroup: (groupId, mutes, muteExpire) {}, + + /// Occurs when a member is removed from the chat group mute list. + onMuteListRemovedFromGroup: (groupId, mutes) {}, + + /// Occurs when the chat group owner is changed. + onOwnerChangedFromGroup: (groupId, newOwner, oldOwner) {}, + + /// Occurs when a join request is accepted. + onRequestToJoinAcceptedFromGroup: (groupId, groupName, accepter) {}, + + /// Occurs when a join request is declined. + onRequestToJoinDeclinedFromGroup: (groupId, groupName, decliner, reason, applicant) {}, + + /// Occurs when a join request is received. + onRequestToJoinReceivedFromGroup: (groupId, groupName, applicant, reason) {}, + + /// Occurs when a member uploads a chat group shared file. + onSharedFileAddedFromGroup: (groupId, sharedFile) {}, + + /// Occurs when a member deletes a chat group shared file. + onSharedFileDeletedFromGroup: (groupId, fileId) {}, + + /// Occurs when the specifications of a chat group is changed. + onSpecificationDidUpdate: (group) {}, + + /// Occurs when a member is removed from a chat group. + onUserRemovedFromGroup: (groupId, groupName) {}, + ), + ); + //... + /// Removes a group event listener. + ChatClient.getInstance.groupManager.removeEventHandler('UNIQUE_HANDLER_ID'); ``` \ No newline at end of file diff --git a/shared/chat-sdk/client-api/chat-room/manage-chatrooms/project-implementation/flutter.mdx b/shared/chat-sdk/client-api/chat-room/manage-chatrooms/project-implementation/flutter.mdx index 68dd6e838..aeda6b60c 100644 --- a/shared/chat-sdk/client-api/chat-room/manage-chatrooms/project-implementation/flutter.mdx +++ b/shared/chat-sdk/client-api/chat-room/manage-chatrooms/project-implementation/flutter.mdx @@ -109,16 +109,62 @@ To monitor the chat room events, you can listen for the callbacks in the `ChatRo The following code sample shows how to add and remove the chat room listener: ```dart - // Adds the chat room event handler. + /// Add a chat room event listener. ChatClient.getInstance.chatRoomManager.addEventHandler( - "UNIQUE_HANDLER_ID", - ChatRoomEventHandler(), - ); + 'UNIQUE_HANDLER_ID',, + ChatRoomEventHandler(), + /// Occurs when a member is added to the chat room admin list. + onAdminAddedFromChatRoom: (roomId, admin) {}, + + /// Occurs when a member is removed from the chat room admin list. + onAdminRemovedFromChatRoom: (roomId, admin) {}, + + /// Occurs when the state of muting all the chat room members changes. + onAllChatRoomMemberMuteStateChanged: (roomId, isAllMuted) {}, + + /// Occurs when a member is added to the chat room allow list. + onAllowListAddedFromChatRoom: (roomId, members) {}, + + /// Occurs when a member is removed from the chat room allow list. + onAllowListRemovedFromChatRoom: (roomId, members) {}, + + /// Occurs when the chat room announcement is changed. + onAnnouncementChangedFromChatRoom: (roomId, announcement) {}, + + /// Occurs when custom chat room attributes are removed. + onAttributesRemoved: (roomId, removedKeys, from) {}, + + /// Occurs when custom chat room attributes are changed. + onAttributesUpdated: (roomId, attributes, from) {}, - ... + /// Occurs when the chat room instance is destroyed. + onChatRoomDestroyed: (roomId, roomName) {}, - // Removes the chat room event handler. - ChatClient.getInstance.chatRoomManager.removeEventHandler("UNIQUE_HANDLER_ID"); + /// Occurs when a member leaves the chat room. + onMemberExitedFromChatRoom: (roomId, roomName, participant) {}, + + /// Occurs when a new member joins the chat room. + onMemberJoinedFromChatRoom: (roomId, participant) {}, + + /// Occurs when a member is added to the chat room mute list. + onMuteListAddedFromChatRoom: (roomId, mutes, expireTime) {}, + + /// Occurs when a member is removed from the chat room mute list. + onMuteListRemovedFromChatRoom: (roomId, mutes) {}, + + /// Occurs when the chat room ownership is transferred. + onOwnerChangedFromChatRoom: (roomId, newOwner, oldOwner) {}, + + ///Occurs when a chat room member is removed. + onRemovedFromChatRoom: (roomId, roomName, participant, reason) {}, + + /// Occurs when the specifications of a chat room is changed. + onSpecificationChanged: (room) {}, + ), + ); +// ... +/// Remove a chat room event listener. +ChatClient.getInstance.chatRoomManager.removeEventHandler('UNIQUE_HANDLER_ID'); ``` \ No newline at end of file diff --git a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/android.mdx b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/android.mdx index 0751415a9..2e6ec99c3 100644 --- a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/android.mdx +++ b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/android.mdx @@ -158,8 +158,6 @@ private void doAsyncFetchPinnedConversationsFromServer(final int limit, final St Call `removeMessagesFromServer` to delete historical messages one way from the server. You can remove a maximum of 50 messages from the server each time. Once the messages are deleted, you can no longer retrieve them from the server. The deleted messages are automatically removed from your local device. Other chat users can still get the messages from the server. -
    To use this function, you need to contact [support@agora.io](mailto:support@agora.io) to enable it.
    - ```java Conversation conversation = ChatClient.getInstance().chatManager().getConversation(username); // Delete messages by timestamp diff --git a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/flutter.mdx b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/flutter.mdx index 1902d73ab..79bd3c51f 100644 --- a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/flutter.mdx +++ b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/flutter.mdx @@ -94,8 +94,6 @@ ChatCursorResult result = Call `deleteRemoteMessagesBefore` or `deleteRemoteMessagesWithIds` to delete historical messages one way from the server. You can remove a maximum of 50 messages from the server each time. Once the messages are deleted, you can no longer retrieve them from the server. The deleted messages are automatically removed from your local device. Other chat users can still get the messages from the server. -
    To use this function, you need to contact [support@agora.io](mailto:support@agora.io) to enable it.
    - ```dart try { // Delete messages by timestamp diff --git a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/ios.mdx b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/ios.mdx index 46d503d63..de3f279f9 100644 --- a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/ios.mdx +++ b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/ios.mdx @@ -73,8 +73,6 @@ Refer to the following code example to get a list of pinned conversations from t Call `removeMessagesFromServerWithTimeStamp` or `removeMessagesFromServerMessageIds` to delete historical messages one way from the server. You can remove a maximum of 50 messages from the server each time. Once the messages are deleted, you can no longer retrieve them from the server. The deleted messages are automatically removed from your local device. Other chat users can still get the messages from the server. -
    To use this function, you need to contact [support@agora.io](mailto:support@agora.io) to enable it.
    - ```objective-c // Delete messages by timestamp AgoraChatConversation* conversation = [AgoraChatClient.sharedClient.chatManager getConversationWithConvId:@"conversationId"]; diff --git a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/web.mdx b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/web.mdx index 73e079219..be7ce51ce 100644 --- a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/web.mdx +++ b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/web.mdx @@ -76,8 +76,6 @@ connection.getServerPinnedConversations({pageSize:50, cursor: ''}) Call `removeHistoryMessages` to delete historical messages one way from the server. You can remove a maximum of 20 messages from the server each time. Once the messages are deleted, you can no longer retrieve them from the server. Other chat users can still get the messages from the server. -
    To use this function, you need to contact [support@agora.io](mailto:support@agora.io) to enable it.
    - ```javascript // Delete messages by timestamp connection.removeHistoryMessages({targetId: 'userId', chatType: 'singleChat', beforeTimeStamp: Date.now()}) diff --git a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/windows.mdx b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/windows.mdx index bfd508d13..f1eb83d95 100644 --- a/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/windows.mdx +++ b/shared/chat-sdk/client-api/messages/retrieve-messages/project-implementation/windows.mdx @@ -130,8 +130,6 @@ SDKClient.Instance.ChatManager.GetConversationsFromServerWithCursor(pinOnly, cur Call `RemoveMessagesFromServer` to delete historical messages one way from the server. You can remove a maximum of 50 messages from the server each time. Once the messages are deleted, you can no longer retrieve them from the server. The deleted messages are automatically removed from your local device. Other chat users can still get the messages from the server. -
    To use this function, you need to contact [support@agora.io](mailto:support@agora.io) to enable it.
    - ```csharp SDKClient.Instance.ChatManager.RemoveMessagesFromServer(convId, ctype, time, new CallBack( onSuccess: () => diff --git a/shared/chat-sdk/develop/offline-push/project-implementation/android.mdx b/shared/chat-sdk/develop/offline-push/project-implementation/android.mdx index 887ebbda8..743438439 100644 --- a/shared/chat-sdk/develop/offline-push/project-implementation/android.mdx +++ b/shared/chat-sdk/develop/offline-push/project-implementation/android.mdx @@ -4,29 +4,29 @@ This section guides you through how to integrate FCM with Chat. -### 1. Create an Android project in Firebase +For devices using the Android system, if FCM and push services from other manufacturers are enabled at the same time, FCM push services will be used first. -1. Log in to [Firebase console](https://console.firebase.google.com/), and click **Add project**. +### 1. Create a project in Firebase -2. In the **Create a project** page, enter a project name, and click **Create project**. +1. Log in to the [Firebase console](https://console.firebase.google.com/) and [add a project](https://firebase.google.com/docs/android/setup/#create-firebase-project). -
    You can toggle off **Enable Google Analytics for this project** if this option is not needed.
    +1. [Register the application](https://firebase.google.com/docs/android/setup/#register-app) in the project. -3. After the project is ready, click **Continue** to redirect to the project page, and click the **Android** icon to register an Android project. + In the **Download and then add config file** step of the **Add Firebase to your Android app** page, click **Download google-services.json** and put the file into your Android app module root directory. -4. In the **Add Firebase to your Android app** page, perform the following operations: - 1. In the **Register app** step, enter an Android package name, app nickname (optional), and debug signing certificate SHA-1 (optional), and click **Register app**. - 2. In the **Download google-services.json** step, download `google-services.json`, move this file into your Android app module root directory, and click **Next**. - 3. In the **Add Firebase SDK** step, modify your `build.gradle` files to use Firebase, and click **Next**. - 4. In the **Next steps** step, click **Continue to console** to go back to the project page. + ![push_fcm_download_googleservice](/images/chat/push_fcm_download_googleservice.png) -5. In the project page, click the Android project you have created. +1. Query the sender ID. On the **Project settings** page, select the **Cloud Messaging** tab and view **Sender ID**. When uploading the FCM certificate to , set the certificate name to the FCM sender ID. -6. In the **Project settings** page, select the **Cloud Messaging** tab, and locate the **Server key** and **Sender ID**. + ![push_fcm_senderid.png](/images/chat/push_fcm_senderid.png) -![1649906356504](https://web-cdn.agora.io/docs-files/1649906356504) +1. On the **Project settings** page, select the **Service accounts** tab and click **Generate new private key** to generate a JSON file. Save this file and upload it to when using the V1 certificate. -### 2. Upload FCM certificate to Agora Console + ![push_fcm_private_key](/images/chat/push_fcm_private_key.png) + +### 2. Upload FCM certificate to + +After successfully logging into Chat, you can upload the FCM push certificate to : 1. Log in to , and click **Project Management** in the left navigation bar. @@ -36,11 +36,41 @@ This section guides you through how to integrate FCM with Chat. 4. On the project config page, select **Features** > **Push Certificate** and click **Add Push Certificate**. -5. In the pop-up window, select the **GOOGLE** tab, and configure the following fields: - - **Certificate Name**: Fill in the [Sender ID](#token). - - **Push Key**: Fill in the [Server Key](#token). +5. In the pop-up window, select the **Google** tab, and configure the following fields: + + ![push_fcm_add_certificate](/images/chat/push_fcm_add_certificate.png) + + | Parameter | Type | Required | Description | + | :--------- | :----- | :------- | :----------------------- | + | **Certificate Type** | | No | Select whether to use a V1 certificate or a legacy certificate.
    • **V1**: Recommended. You need to configure a **Private Key**.
    • **Legacy**: Will soon be deprecated. You need to configure a **Push Key**.
    | + | **Private Key** | file | Yes | Click **Generate new private key** on the **Project settings** > **Service accounts** page of the [Firebase Console](https://console.firebase.google.com) to generate the `.json` file, then upload it to . | + | **Push Key** | String | Yes | FCM Server Key. Obtain the server key in the **Cloud Messaging API (Legacy)** area of the **Project settings** > **Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com).

    **This parameter is only valid for legacy certificates.**| + | **Certificate Name** | String | Yes | The sender ID configured for the FCM.
    • For the new version of the certificate, you can find the sender ID on the **Project settings** > **Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com).
    • For legacy certificates, go to the ***Project settings > Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com), and get the sender ID in the **Cloud Messaging API (Legacy)** area.

    The certificate name is the only condition used by the Agora server to determine which push channel the target device uses, so ensure that the sender set when integrating FCM in Chat is consistent with what is set here. | + | **Sound** | String | No | The ringtone flag for when the receiver gets the push notification. | + | **Push Priority** | | No| Message delivery priority. See [Setting the priority of a message](https://firebase.google.cn/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message). | + | **Push Msg Type** | | No| The type of the message sent to the client through FCM. See [Message types](https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages):
    • **Data**: Data message, processed by the client application.
    • **Notification**: Notification message, automatically processed by FCM SDK.
    • **Both**: Notification messages and data messages can be sent through the FCM client.
    | + +#### Switch from legacy to the V1 certificate + +The legacy HTTP or XMPP API is being retired on June 20, 2024. In view of this, switch to the latest FCM API (HTTP v1) version of the certificate as soon as possible. See [Firebase Console](https://console.firebase.google.com) for details. + +Make sure that the uploaded V1 certificate is available, as the legacy one will be deleted upon upload. If the new certificate is not available, the push will fail. + +Take the following steps to switch from the old to the new certificate: + +1. Click **Edit** in the **Action** column of the old certificate on the **Push Certificate** page. + + ![push_fcm_oldcertificate_edit](/images/chat/push_fcm_oldcertificate_edit.png) + +1. In the **Google** tab of the **Edit Push Certificate** window, switch the **Certificate Type** to **V1**. + + ![push_fcm_oldcertificate_switch](/images/chat/push_fcm_oldcertificate_switch.png) + +1. Click **Upload** to upload the locally saved V1 certificate file (.json). + + ![push_fcm_newcertificate_upload](/images/chat/push_fcm_newcertificate_upload.png) - +1. Click **OK** to complete the switch. ### 3. Enable FCM in Chat diff --git a/shared/chat-sdk/develop/offline-push/project-implementation/flutter.mdx b/shared/chat-sdk/develop/offline-push/project-implementation/flutter.mdx index e5ff10a58..43883c673 100644 --- a/shared/chat-sdk/develop/offline-push/project-implementation/flutter.mdx +++ b/shared/chat-sdk/develop/offline-push/project-implementation/flutter.mdx @@ -4,26 +4,33 @@ This section guides you through how to integrate FCM with Chat. -### 1. Create a Flutter project in Firebase +### 1. Create a project in Firebase -1. Log in to [Firebase console](https://console.firebase.google.com/), and click **Add project**. +1. Log in to the [Firebase console](https://console.firebase.google.com/) and click **Add project**. -2. In the **Create a project** page, enter a project name, and click **Create project**. +1. In the **Create a project** page, enter a project name, and click **Create project**.
    You can toggle off Enable Google Analytics for this project if this option is not needed.
    -3. After the project is ready, click **Continue** to redirect to the project page, and click the **Flutter** icon and follow the **Firebase CLI** to setting your project. +1. After the project is ready, click **Continue** to redirect to the project page. Then click the **Flutter** icon and follow the **Firebase CLI** to set your project. -4. In the **Project settings** page, perform the following operations: - - For Android apps, find the **Android apps** in **Your apps**, and set your Android app according to **See SDK instructions**. - - For iOS apps, find the **Apple apps** in **Your apps**, and set your Apple app according to **See SDK instructions**. +1. In the **Project settings** page, perform the following operations: -5. In the project page, click the project you have created. + - For Android apps, find the **Android apps** in **Your apps**, and set your Android app according to the SDK instructions. + - For iOS apps, find the **Apple apps** in **Your apps**, and set your Apple app according to the SDK instructions. -6. In the **Project settings** page, select the **Cloud Messaging** tab, and locate the **Server key** and **Sender ID**. +1. In the project page, click the project you have created. -![1649906356504](https://web-cdn.agora.io/docs-files/1649906356504) +1. Query the sender ID. On the **Project settings** page, select the **Cloud Messaging** tab and view **Sender ID**. When uploading the FCM certificate to , set the certificate name to the FCM sender ID. -### 2. Upload FCM certificate to Agora Console + ![push_fcm_senderid.png](/images/chat/push_fcm_senderid.png) + +1. On the **Project settings** page, select the **Service accounts** tab and click **Generate new private key** to generate a JSON file. Save this file and upload it to when using the V1 certificate. + + ![push_fcm_private_key](/images/chat/push_fcm_private_key.png) + +### 2. Upload FCM certificate to + +After successfully logging into Chat, you can upload the FCM push certificate to : 1. Log in to , and click **Project Management** in the left navigation bar. @@ -33,10 +40,42 @@ This section guides you through how to integrate FCM with Chat. 4. On the project config page, select **Features** > **Push Certificate** and click **Add Push Certificate**. -5. In the pop-up window, select the **GOOGLE** tab, and configure the following fields: - - **Certificate Name**: Fill in the [Sender ID](#token). - - **Push Key**: Fill in the [Server Key](#token). - +5. In the pop-up window, select the **Google** tab, and configure the following fields: + + ![push_fcm_add_certificate](/images/chat/push_fcm_add_certificate.png) + + | Parameter | Type | Required | Description | + | :--------- | :----- | :------- | :----------------------- | + | **Certificate Type** | | No | Select whether to use a V1 certificate or a legacy certificate.
    • **V1**: Recommended. You need to configure a **Private Key**.
    • **Legacy**: Will soon be deprecated. You need to configure a **Push Key**.
    | + | **Private Key** | file | Yes | Click **Generate new private key** on the **Project settings** > **Service accounts** page of the [Firebase Console](https://console.firebase.google.com) to generate the `.json` file, then upload it to . | + | **Push Key** | String | Yes | FCM Server Key. Obtain the server key in the **Cloud Messaging API (Legacy)** area of the **Project settings** > **Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com).

    **This parameter is only valid for legacy certificates.**| + | **Certificate Name** | String | Yes | The sender ID configured for the FCM.
    • For the new version of the certificate, you can find the sender ID on the **Project settings** > **Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com).
    • For legacy certificates, go to the ***Project settings > Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com), and get the sender ID in the **Cloud Messaging API (Legacy)** area.

    The certificate name is the only condition used by the Agora server to determine which push channel the target device uses, so ensure that the sender set when integrating FCM in Chat is consistent with what is set here. | + | **Sound** | String | No | The ringtone flag for when the receiver gets the push notification. | + | **Push Priority** | | No| Message delivery priority. See [Setting the priority of a message](https://firebase.google.cn/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message). | + | **Push Msg Type** | | No| The type of the message sent to the client through FCM. See [Message types](https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages):
    • **Data**: Data message, processed by the client application.
    • **Notification**: Notification message, automatically processed by FCM SDK.
    • **Both**: Notification messages and data messages can be sent through the FCM client.
    | + +#### Switch from legacy to the V1 certificate + +The legacy HTTP or XMPP API is being retired on June 20, 2024. In view of this, switch to the latest FCM API (HTTP v1) version of the certificate as soon as possible. See [Firebase Console](https://console.firebase.google.com) for details. + +Make sure that the uploaded V1 certificate is available, as the legacy one will be deleted upon upload. If the new certificate is not available, the push will fail. + +Take the following steps to switch from the old to the new certificate: + +1. Click **Edit** in the **Action** column of the old certificate on the **Push Certificate** page. + + ![push_fcm_oldcertificate_edit](/images/chat/push_fcm_oldcertificate_edit.png) + +1. In the **Google** tab of the **Edit Push Certificate** window, switch the **Certificate Type** to **V1**. + + ![push_fcm_oldcertificate_switch](/images/chat/push_fcm_oldcertificate_switch.png) + +1. Click **Upload** to upload the locally saved V1 certificate file (.json). + + ![push_fcm_newcertificate_upload](/images/chat/push_fcm_newcertificate_upload.png) + +1. Click **OK** to complete the switch. + ### 3. Enable FCM in Chat diff --git a/shared/chat-sdk/develop/offline-push/project-implementation/react-native.mdx b/shared/chat-sdk/develop/offline-push/project-implementation/react-native.mdx index 44e554c62..8fe3dc0a4 100644 --- a/shared/chat-sdk/develop/offline-push/project-implementation/react-native.mdx +++ b/shared/chat-sdk/develop/offline-push/project-implementation/react-native.mdx @@ -8,21 +8,32 @@ This section guides you through how to integrate FCM with Chat. 1. Log in to [Firebase console](https://console.firebase.google.com/), and click **Add project**. -2. On the **Create a project** page, enter a project name, and proceed with prompts. The `Sender Id` and `Server Key` are required for Cloud Messaging. +1. On the **Create a project** page, enter a project name, and proceed with prompts. -After the project is created, add an `iOS` application or an `Android` application according to the following steps: +1. Query the sender ID. On the **Project settings** page, select the **Cloud Messaging** tab and view **Sender ID**. When uploading the FCM certificate to , set the certificate name to the FCM sender ID. -- Add an `iOS` app + ![push_fcm_senderid.png](/images/chat/push_fcm_senderid.png) + +1. On the **Project settings** page, select the **Service accounts** tab and click **Generate new private key** to generate a JSON file. Save this file and upload it to when using the V1 certificate. + + ![push_fcm_private_key](/images/chat/push_fcm_private_key.png) + +1. After the project is created, add an `iOS` application or an `Android` application according to the following steps: + +- Add an `iOS` app: 1. The package name is the same as that of the `iOS` app; 2. Once created, move the downloaded `GoogleService-Info.plist` file to the root directory of the `Xcode` project, and add it to all targets; 3. Upload the `APNs` certificate on the Cloud Messaging page. -- Add an `Android` app +- Add an `Android` app: 1. The package name is the same as that of the `Android` app; 2. Once created, move the downloaded `google-services.json` file to your module (application level) root directory. +For detailed FCM configurations, you can see the [React Native Firebase document](https://rnfirebase.io/). + +### 2. Upload FCM certificate to -### 2. Upload FCM certificate to Agora Console +After successfully logging into Chat, you can upload the FCM push certificate to : 1. Log in to , and click **Project Management** in the left navigation bar. @@ -33,10 +44,40 @@ After the project is created, add an `iOS` application or an `Android` applicati 4. On the project config page, select **Features** > **Push Certificate** and click **Add Push Certificate**. 5. In the pop-up window, select the **Google** tab, and configure the following fields: - - **Certificate Name**: Fill in the [Sender ID](#token). - - **Push Key**: Fill in the [Server Key](#token). - + ![push_fcm_add_certificate](/images/chat/push_fcm_add_certificate.png) + + | Parameter | Type | Required | Description | + | :--------- | :----- | :------- | :----------------------- | + | **Certificate Type** | | No | Select whether to use a V1 certificate or a legacy certificate.
    • **V1**: Recommended. You need to configure a **Private Key**.
    • **Legacy**: Will soon be deprecated. You need to configure a **Push Key**.
    | + | **Private Key** | file | Yes | Click **Generate new private key** on the **Project settings** > **Service accounts** page of the [Firebase Console](https://console.firebase.google.com) to generate the `.json` file, then upload it to . | + | **Push Key** | String | Yes | FCM Server Key. Obtain the server key in the **Cloud Messaging API (Legacy)** area of the **Project settings** > **Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com).

    **This parameter is only valid for legacy certificates.**| + | **Certificate Name** | String | Yes | The sender ID configured for the FCM.
    • For the new version of the certificate, you can find the sender ID on the **Project settings** > **Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com).
    • For legacy certificates, go to the ***Project settings > Cloud Messaging** page of the [Firebase Console](https://console.firebase.google.com), and get the sender ID in the **Cloud Messaging API (Legacy)** area.

    The certificate name is the only condition used by the Agora server to determine which push channel the target device uses, so ensure that the sender set when integrating FCM in Chat is consistent with what is set here. | + | **Sound** | String | No | The ringtone flag for when the receiver gets the push notification. | + | **Push Priority** | | No| Message delivery priority. See [Setting the priority of a message](https://firebase.google.cn/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message). | + | **Push Msg Type** | | No| The type of the message sent to the client through FCM. See [Message types](https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages):
    • **Data**: Data message, processed by the client application.
    • **Notification**: Notification message, automatically processed by FCM SDK.
    • **Both**: Notification messages and data messages can be sent through the FCM client.
    | + +#### Switch from legacy to the V1 certificate + +The legacy HTTP or XMPP API is being retired on June 20, 2024. In view of this, switch to the latest FCM API (HTTP v1) version of the certificate as soon as possible. See [Firebase Console](https://console.firebase.google.com) for details. + +Make sure that the uploaded V1 certificate is available, as the legacy one will be deleted upon upload. If the new certificate is not available, the push will fail. + +Take the following steps to switch from the old to the new certificate: + +1. Click **Edit** in the **Action** column of the old certificate on the **Push Certificate** page. + + ![push_fcm_oldcertificate_edit](/images/chat/push_fcm_oldcertificate_edit.png) + +1. In the **Google** tab of the **Edit Push Certificate** window, switch the **Certificate Type** to **V1**. + + ![push_fcm_oldcertificate_switch](/images/chat/push_fcm_oldcertificate_switch.png) + +1. Click **Upload** to upload the locally saved V1 certificate file (.json). + + ![push_fcm_newcertificate_upload](/images/chat/push_fcm_newcertificate_upload.png) + +1. Click **OK** to complete the switch. ### 3. Enable FCM in Chat diff --git a/shared/chat-sdk/reference/_callbacks-events.mdx b/shared/chat-sdk/reference/_callbacks-events.mdx index 175d46121..aa01b1ab0 100644 --- a/shared/chat-sdk/reference/_callbacks-events.mdx +++ b/shared/chat-sdk/reference/_callbacks-events.mdx @@ -31,7 +31,7 @@ When a user logs in to the Chat app, the Chat server sends a callback to your ap | Field | Data Type | Description | | --- | --- | --- | -| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{file_uuid}`, where the value of `file_uuid` is randomly generated. | +| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{uuid}`, where the value of `uuid` is randomly generated. | | `reason` | String | The reason that triggers the callback. `login` indicates that a user logs in to the app. | | `security` | String | The signature in the callback request used to confirm whether this callback is sent from the Chat server. The signature is the MD5 hash of the `{callId} + {secret} + {timestamp}` string, where the value of `secret` can be found on .| | `os` | String | The operating system of the device. Valid values: `ios`, `android`, `linux`, `win`, and `other.` | @@ -65,7 +65,7 @@ When a user logs out of the Chat app, the Chat server sends a callback to your a | Field | Data Type | Description | | --- | --- | --- | -| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{file_uuid}`, where the value of `file_uuid` is randomly generated. | +| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{uuid}`, where the value of `uuid` is randomly generated. | | `reason` | String | The reason that triggers the callback. `logout` indicates that a user logs out of the app. | | `security` | String | The signature in the callback request used to confirm whether this callback is sent from the Chat server. The signature is the MD5 hash of the `{callId} + {secret} + {timestamp}` string, where the value of `secret` can be found on .| | `os` | String | The operating system of the device. Valid values: `ios`, `android`, `linux`, `win`, and `other.` | @@ -98,7 +98,7 @@ When a user logs out of the Chat app due to being kicked out by another device, | Field | Data Type | Description | | --- | --- | --- | -| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{file_uuid}`, where the value of `file_uuid` is randomly generated. | +| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{uuid}`, where the value of `uuid` is randomly generated. | | `reason` | String | The reason that triggers the callback. `replaced` indicates that a user logs out of the app due to being kicked out by another device. | | `security` | String | The signature in the callback request used to confirm whether this callback is sent from the Chat server. The signature is the MD5 hash of the `{callId} + {secret} + {timestamp}` string, where the value of `secret` can be found on .| | `os` | String | The operating system of the device. Valid values: `ios`, `android`, `linux`, `win`, and `other.` | @@ -119,7 +119,7 @@ When a user sends a message in a one-to-one chat, chat group, or chat room of th ```json { - "callId":"{appkey}_{file_uuid}", + "callId":"{appkey}_{uuid}", "eventType":"chat_offline", "timestamp":1600060847294, "chat_type":"groupchat", @@ -137,7 +137,7 @@ When a user sends a message in a one-to-one chat, chat group, or chat room of th | Field | Data Type | Description | | -- | -- | -- | -| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{file_uuid}`, where the value of `file_uuid` is randomly generated. | +| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{uuid}`, where the value of `uuid` is randomly generated. | | `eventType` | String | The message type of the callback.
    • `chat`: Uplink messages. The messages that are about to be sent by the Chat server to end devices.
    • `chat_offline`: Offline messages. The messages that are not sent by the Chat server as end users are offline.
    | | `timestamp` | Long | The Unix timestamp when the Chat server receives the callback event, in milliseconds. | | `chat_type` | String | The type of chat.
    • `chat`: One-to-one chats.
    • `groupchat`: Chat groups and chat rooms.
    | @@ -392,7 +392,7 @@ When a user recalls a message in a one-to-one chat, chat group, or chat room of | Field | Data Type | Description | | --- | --- | --- | -| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{file_uuid}`, where the value of `file_uuid` is randomly generated. | +| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{uuid}`, where the value of `uuid` is randomly generated. | | `eventType` | String | The message type of the callback.
    • `chat`: Uplink messages. The messages that are about to be sent by the Chat server to end devices.
    • `chat_offline`: Offline messages. The messages that are not sent by the Chat server as the end user is offline.
    | | `timestamp` | Long | The Unix timestamp when the Chat server receives the callback event, in milliseconds. | | `chat_type` | String | The type of chat.
    • `chat`: One-to-one chats.
    • `groupchat`: Chat groups and chat rooms.
    | @@ -1051,7 +1051,7 @@ When a user performs operations on the contacts in the Chat app, the Chat server | Field | Data Type | Description | | --- | --- | --- | | `chat_type` | String | The type of the event. `roster` indicates an event occurred in user contacts. | -| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{file_uuid}`, where the value of `file_uuid` is randomly generated. | +| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{uuid}`, where the value of `uuid` is randomly generated. | | `eventType` | String | The message type of the callback.
    • `chat`: Uplink messages. The messages that are about to be sent by the Chat server to end devices.
    • `chat_offline`: Offline messages. The messages that are not sent by the Chat server as the end user is offline.
    | | `timestamp` | Long | The Unix timestamp when the Chat server receives the callback event, in milliseconds. | | `from` | String | The user who operates the contact. | @@ -1198,7 +1198,7 @@ When a user sends an receipt, the Chat server sends a callback to your app serve | Field | Data Type | Description | | :---------- | :------- | :----------------------------------------------------------- | | `chat_type` | String | The type of the event.
    • `read_ack`: Read receipts.
    • `delivery_ack`: Delivery receipts.
    | -| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{file_uuid}`, where the value of `file_uuid` is randomly generated. | +| `callId` | String | The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{uuid}`, where the value of `uuid` is randomly generated. | | `security` | String | The signature in the callback request used to confirm whether this callback is sent from the Chat server. The signature is the MD5 hash of the `{callId} + {secret} + {timestamp}` string, where the value of `secret` can be found on .| | `payload` | Object | The structure of the callback event that contains the following fields:
    • `ext`: The message extension field.
    • `ack_message_id`: The message ID of the receipt callback.
    • `bodies`: The message body.
    | | `host` | String | The domain name assigned by the Chat service to access RESTful APIs. | @@ -1207,4 +1207,49 @@ When a user sends an receipt, the Chat server sends a callback to your app serve | `to` | String | The ID of the user who receives the receipt. | | `eventType` | String | The message type of the callback.
    • `chat`: Uplink messages. The messages that are about to be sent by the Chat server to end devices.
    • `chat_offline`: Offline messages. The messages that are not sent by the Chat server as the end user is offline.
    | | `timestamp` | long | The Unix timestamp when the Chat server receives the callback event, in milliseconds. | -| `msg_id` | String | The message ID of the receipt. | \ No newline at end of file +| `msg_id` | String | The message ID of the receipt. | + +## Content moderation result + +When the message moderation is complete, the Chat server sends the moderation result to your app server. + +The sample code is as follows: + +```json + { + "callId": "100220419126072#demo_54ae7e93-xxxx-xxxx-92f5-323e33187243", + "moderationResult": "PASS", + "providerResult": "PASS", + "security": "1f4857f120b2789b7d0abcd372c4f9e8", + "messageType": "txt", + "messageId": "1F4MX6iSdI7VFnN7Hm0vrcr3Uwr", + "targetType": "chat", + "appkey": "100220419126072#lydemo", + "source": { + + }, + "eventType": "moderation", + "from": "qa2", + "to": "qa1", + "url": "", + "msg": "Hello", + "timestamp": 1668766253245 +} +``` + +| Parameter | Type | Description | +| :------------ | :----- | :----------------------------------------------- | +| `callId` | String| The ID of the callback. The unique identifier assigned to each callback, in the format of `{appKey}_{uuid}`, where the value of `uuid` is randomly generated.| +| `moderationResult` | String | The message handling result:
    - `PASS`:Send the message.
    - `REJECT`: Reject sending the message.
    - `EXCHANGE`: Replace the sensitive content in the message.
    - `RECALL`: Recall the voice or video that is sent. | +| `providerResult` | String | The message moderation result:
    - `PASS`: The message does not contain inappropriate content.
    - `REVIEWED`:The message is suspected of containing inappropriate content.
    - `REJECT`:The message contains inappropriate content. | +| `security` | String | The signature in the callback request used to confirm whether this callback is sent from the Chat server. The signature is the MD5 hash of the `{callId} + {secret} + {timestamp}` string, where the value of secret can be found on . | +| `messageType` | String | The message text:
    - `txt`: Text message.
    - `img`: Image message.
    - `audio`: Voice message.
    - `video`: Video message.
    - `custom`: Custom message. | +| `messageId` | String | Message ID. | +| `targetType` | String | Conversation type:
    - `chat: One-to-one chat.
    - `groupchat`: Group chat.
    - `chatroom`: Chat room. | +| `appkey` | String | The key of the app. The unique identifier assigned to each app by the Chat service. | +| `eventType` | String | The event type, which is `moderation` for the moderation service. | +| `from` | String | The user ID of the message sender. | +| `to` | String | The message recipient:
    - One-to-one chat: User ID of the message recipient.
    - Group chat: Group ID.
    - Chat room: Chat room ID.| +| `msg` | String | The content of the text message. This parameter is valid only when `messageType` is `txt`. | +| `url` | String | The URL of the attachment message, like a voice, video, or image message. This parameter is valid only when `messageType` is `img`, `audio`, or `video`. | +| `timestamp` | Number | The Unix timestamp when the Chat server receives the callback event, in milliseconds. | \ No newline at end of file diff --git a/shared/chat-sdk/reference/_http-status-codes.mdx b/shared/chat-sdk/reference/_http-status-codes.mdx index 44e27dfd4..55f713b04 100644 --- a/shared/chat-sdk/reference/_http-status-codes.mdx +++ b/shared/chat-sdk/reference/_http-status-codes.mdx @@ -21,7 +21,6 @@ This status code indicates that the API request could not be understood by the s | `400` | `illegal_argument` | "Entity 'user' requires a property named username." | The error message returned because the username is not specified when registering users. | | `400` | `illegal_argument` | "Password or pin must provided." | The error message returned because the password is not specified when registering users. | | `400` | `illegal_argument` | "New password is required. Old password is required." | The error message returned because the new password or old password is not provided when changing passwords. | -| `400` | `illegal_argument` | "Group member `{username}` doesn’t exist." | The error message returned because the specified username does not exist when adding users to a chat group. | | `400` | `illegal_argument` | "This is an invalid request." | The error message returned because the request URL, the request header, or the request body is invalid. | | `400` | `illegal_argument` | "'From' can't be empty." | The error message returned because the sender is not specified when sending messages. | | `400` | `illegal_argument` | "'Target_type' can only be 'users' or 'chatgroups' or 'chatrooms'." | The error message returned because the values other than `users`, `chatgroups`, or `chatrooms` is passed to `target_type` when sending messages | @@ -73,7 +72,8 @@ This status code indicates that the specified resources of the API request could | Status code | Error code | Error message | Description | | :----- | :------------ | :----------------------------------------------------------- | :------------------------------------------------| | `404` | `organization_application_not_found` | "Could not find application for `{org_url}` from URI: `{app_url}`/token." | The error message returned because the specified organization or application does not exist. | -| `404` | `service_resource_not_found` | "Service resource not found." | The error message returned because the specified user, chat group, or chat room does not exist. | +| `404` | `service_resource_not_found` | "Service resource not found." | The error message returned in one of the following scenarios:
    • The specified user does not exist when you call APIs related to the user system.
    • The specified group does not exist when you call group-related APIs.
    • The specified chat room does not exist when you call APIs related to the chat room.
    | +| `404` | `resource_not_found` | "username XXXX doesn't exist" | The specified user does not exist. For example, the user that you invite to join the group during group creation does not exist. | | `404` | `service_resource_not_found` | "Service resource not found." | The error message returned because either the specified user being queried or removed does not exist, or dirty data blocks the proper read operation. To address the dirty read problem, you can pass in the UUID to delete the existing user and register with the same username again. | | `404` | `storage_object_not_found` | "Failed to find chat message history download url for appkey: `{app_key}`, time: `{yyyymmddhh}`." | The error message returned because no chat history exists within the queried time period. To double check, [submit a ticket](https://agora-ticket.agora.io/) to Agora Support. | @@ -88,7 +88,7 @@ This status code indicates that the API request is larger than the server can pr | Status code | Error code | Error message | Description | | :----- | :------------ | :----------------------------------------------------------- | :------------------------------------------------| -| `413` | `Request Entity Too Large` | "Request Entity Too Large." | The error message returned because the size of the client request exceeds the maximum size limit of the server. For example, the message body exceeds 5 KB or the uploaded files exceed 10 MB. | +| `413` | `Request Entity Too Large` | "Request Entity Too Large." | The error message returned because the size of the uploaded message attachment exceeds the upper limit. | ### 415 Unsupported Media Type This status code indicates that the format of the API request is not supported by the server. diff --git a/shared/chat-sdk/restful-api/_message-management.mdx b/shared/chat-sdk/restful-api/_message-management.mdx index d8da30778..ac02b765e 100644 --- a/shared/chat-sdk/restful-api/_message-management.mdx +++ b/shared/chat-sdk/restful-api/_message-management.mdx @@ -1067,7 +1067,7 @@ If the returned HTTP status code is not `200`, the request fails. You can refer ```shell # Replace {YourAppToken} with the app token generated on your server, and the path of file with the local full path where the file to be uploaded is located -curl -L -X POST 'https://XXXX/XXXX/XXXX/chatfiles' -H 'Authorization: Bearer ' -H 'Content-Type: multipart/form-data; boundary=---WebKitFormBoundary7MA4YWxkTrZu0gW' -H 'restrict-access: true' -F 'file="@/Users/test/9.2/agora/image/IMG_2953.JPG"' +curl -X POST 'https://XXXX/XXXX/XXXX/chatfiles' -H 'Authorization: Bearer ' -H 'Content-Type: multipart/form-data; boundary=---WebKitFormBoundary7MA4YWxkTrZu0gW' -H 'restrict-access: true' -F 'file="@/Users/test/9.2/agora/image/IMG_2953.JPG"' ``` #### Response example diff --git a/shared/chat-sdk/restful-api/_offline-push-configuration.mdx b/shared/chat-sdk/restful-api/_offline-push-configuration.mdx index af9acc6b5..0e8aac0ad 100644 --- a/shared/chat-sdk/restful-api/_offline-push-configuration.mdx +++ b/shared/chat-sdk/restful-api/_offline-push-configuration.mdx @@ -57,12 +57,16 @@ For each App Key, the total call frequency limit of this method and the method t ### HTTP request ```html -PUT https://{host}/{org_name}/{app_name}/users/{username} +PUT https://{host}/{org_name}/{app_name}/users/{userId} ``` #### Path parameter -For the descriptions of path parameters, see [Common Parameters](#request). +| Parameter | Type | Description | Required | +|:---------------| :------ | :------- |:------------------| +| `userId` | String | The user ID of the current user. | Yes | + +For the descriptions of other path parameters, see [Common Parameters](#param). #### Request header @@ -141,17 +145,22 @@ For each App Key, the total call frequency limit of this method and the method t ### HTTP request ```html -PUT https://{host}/{org_name}/{app_name}/users/{username} +PUT https://{host}/{org_name}/{app_name}/users/{userId} ``` #### Path parameter -For the descriptions of path parameters, see [Common Parameters](#request). +| Parameter | Type | Description | Required | +|:---------------| :------ | :------- |:------------------| +| `userId` | String | The user ID of the current user. | Yes | + +For the descriptions of other path parameters, see [Common Parameters](#param). #### Request header | Parameter | Type | Description | Required | | :----- | :----- | :------- | -------- | +| `Content-Type` | String | The content type. Set it as `application/json`. | Yes | | `Authorization` | String | The authentication token of the user or administrator, in the format of `Bearer ${YourAppToken}`, where `Bearer` is a fixed character, followed by an English space, and then the obtained token value. | Yes | #### Request body @@ -187,7 +196,10 @@ If the returned HTTP status code is not `200`, the request fails. You can refer #### Request example ```bash -curl -X PUT -H "Authorization: Bearer " -i https://XXXX/XXXX/XXXX/users/a -d '{"notification_display_style": "1"}' +curl -X PUT https://XXXX/XXXX/XXXX/users/XXXX \ +-H 'Content-Type: application/json' \ +-H "Authorization: Bearer " \ +-d '{"notification_display_style": "1"}' ``` #### Response example @@ -197,7 +209,7 @@ curl -X PUT -H "Authorization: Bearer " -i https://XXXX/XXXX/XXXX/ "action" : "put", "application" : "17d59e50-XXXX-XXXX-8092-0dc80c0f5e99", "path" : "/users", - "uri" : "https://XXXX/XXXX/XXXX/users", + "uri" : "https://XXXX/XXXX/XXXX/users/XXXX", "entities" : [ { "uuid" : "3b8c9890-XXXX-XXXX-9d88-f50bf55cafad", @@ -234,6 +246,7 @@ PUT https://{host}/{org}/{app}/users/{username}/notification/{chattype}/{key} | Parameter | Type | Description | Required | | :----- | :----- | :------- | -------- | +| `userId` | String | The user ID of the current user. | Yes | | `chattype` | String | The type of the chat:
  • `user`: One-to-one chats.
  • `chatgroup`: Group chats.
  • | Yes | | `key` | String | The identifier of the chat:
  • If `type` is set to `user`, `key` indicates the user ID of the peer user.
  • If `type` is set to `chatgroup`, `key` indicates the ID of the chat group.
  • | Yes | @@ -279,10 +292,10 @@ If the returned HTTP status code is not `200`, the request fails. You can refer #### Request example ```bash -curl -L -X PUT 'http://XXXX/XXXX/XXXX/users/{username}/notification/user/{key}' \ +curl -L -X PUT 'http://XXXX/XXXX/XXXX/users/XXXX/notification/user/XXXX' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ ---data-raw '{ +-d '{ "type":"NONE", "ignoreInterval":"21:30-08:00", "ignoreDuration":86400000 @@ -294,7 +307,7 @@ curl -L -X PUT 'http://XXXX/XXXX/XXXX/users/{username}/notification/user/{key}' ```json { "path": "/users", - "uri": "https://XXXX/XXXX/XXXX/users/notification/user/hxtest", + "uri": "https://XXXX/XXXX/XXXX/users/notification/user/XXXX", "timestamp": 1647503749918, "organization": "XXX", "application": "17fe201b-XXXX-XXXX-83df-1ed1ebd7b227", @@ -319,13 +332,14 @@ For each App Key, the call frequency limit of this method is 100 per second. ### HTTP request ```html -GET https://{host}/{org_name}/{app_name}/users/{username}/notification/{chattype}/{key} +GET https://{host}/{org_name}/{app_name}/users/{userId}/notification/{chattype}/{key} ``` #### Path parameter | Parameter | Type | Description | Required | | :----- | :----- | :------- | -------- | +| `userId` | String | The user ID of the current user. | Yes | | `chattype` | String | The type of the chat:
  • `user`: One-to-one chats.
  • `chatgroup`: Group chats.
  • | Yes | | `key` | String | The identifier of the chat:
  • If `type` is set to `user`, `key` indicates the user ID of the peer user.
  • If `type` is set to `chatgroup`, `key` indicates the ID of the chat group.
  • | Yes | @@ -358,7 +372,7 @@ If the returned HTTP status code is not `200`, the request fails. You can refer #### Request example ```bash -curl -L -X GET 'https://XXXX/XXXX/XXXX/users/{username}/notification/chatgroup/{key}' \ +curl -L -X GET 'https://XXXX/XXXX/XXXX/users/XXXX/notification/chatgroup/XXXX' \ -H 'Authorization: Bearer ' ``` @@ -392,11 +406,15 @@ For each App Key, the call frequency limit of this method is 100 per second. ### HTTP request ```html -PUT https://{host}/{org_name}/{app_name}/users/{username}/notification/language +PUT https://{host}/{org_name}/{app_name}/users/{userId}/notification/language ``` #### Path parameter +| Parameter | Type | Description | Required | +| :----- | :----- | :------- | -------- | +| `userId` | String | The user ID of the current user. | Yes | + For the descriptions of path parameters, see [Common Parameters](#request). #### Request header @@ -431,10 +449,10 @@ If the returned HTTP status code is not `200`, the request fails. You can refer #### Request example ```bash -curl -L -X PUT 'https://XXXX/XXXX/XXXX/users/{username}/notification/language' \ +curl -L -X PUT 'https://XXXX/XXXX/XXXX/users/XXXX/notification/language' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ ---data-raw '{ +-d '{ "translationLanguage":"EU" }' ``` @@ -444,7 +462,7 @@ curl -L -X PUT 'https://XXXX/XXXX/XXXX/users/{username}/notification/language' \ ```json { "path": "/users", - "uri": "https://XXXX/XXXX/XXXX/users/notification/language", + "uri": "https://XXXX/XXXX/XXXX/users/XXXX/notification/language", "timestamp": 1648089630244, "organization": "XXXX", "application": "17fe201b-XXXX-XXXX-83df-1ed1ebd7b227", @@ -467,18 +485,21 @@ For each App Key, the call frequency limit of this method is 100 per second. ### HTTP request ```html -GET https://{host}/{org}/{app}/users/{username}/notification/language +GET https://{host}/{org}/{app}/users/{userId}/notification/language ``` #### Path parameter +| Parameter | Type | Description | Required | +| :----- | :----- | :------- | -------- | +| `userId` | String | The user ID of the current user. | Yes | + For the descriptions of path parameters, see [Common Parameters](#request). #### Request header | Parameter | Type | Description | Required | | :----- | :----- | :------- | -------- | -| `Content-Type` | String | The content type. Set it as `application/json`. | Yes | | `Authorization` | String | The authentication token of the user or administrator, in the format of `Bearer ${YourAppToken}`, where `Bearer` is a fixed character, followed by an English space, and then the obtained token value. | Yes | ### HTTP response @@ -500,7 +521,7 @@ If the returned HTTP status code is not `200`, the request fails. You can refer #### Request example ```bash -curl -L -X GET 'https://XXXX/XXXX/XXXX/users/{username}/notification/language' \ +curl -L -X GET 'https://XXXX/XXXX/XXXX/users/XXXX/notification/language' \ -H 'Authorization: Bearer ' ``` @@ -509,7 +530,7 @@ curl -L -X GET 'https://XXXX/XXXX/XXXX/users/{username}/notification/language' \ ```json { "path": "/users", - "uri": "https://XXXX/XXXX/XXXX/users/notification/language", + "uri": "https://XXXX/XXXX/XXXX/users/XXXX/notification/language", "timestamp": 1648089630244, "organization": "XXXX", "application": "17fe201b-XXXX-XXXX-83df-1ed1ebd7b227", @@ -580,7 +601,7 @@ If the returned HTTP status code is not `200`, the request fails. You can refer curl -X POST 'https://XXXX/XXXX/XXXX/notification/template' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ ---data-raw '{ +-d '{ "name": "test7", "title_pattern": "Hello,{0}", "content_pattern": "Test,{0}" @@ -658,7 +679,7 @@ If the returned HTTP status code is not `200`, the request fails. You can refer #### Request example ```bash -curl -X GET 'https://XXXX/XXXX/XXXX/notification/template/{name}' \ +curl -X GET 'https://XXXX/XXXX/XXXX/notification/template/XXXX' \ -H 'Authorization: Bearer ' ``` @@ -666,7 +687,7 @@ curl -X GET 'https://XXXX/XXXX/XXXX/notification/template/{name}' \ ```json { - "uri": "https://XXXX/XXXX/XXXX/notification/template/test7", + "uri": "https://XXXX/XXXX/XXXX/notification/template/XXXX", "timestamp": 1646989686393, "organization": "XXXX", "application": "17fe201b-XXXX-XXXX-83df-1ed1ebd7b227", @@ -733,7 +754,7 @@ If the returned HTTP status code is not `200`, the request fails. You can refer #### Request example ```bash -curl -X DELETE 'https://XXXX/XXXX/XXXX/notification/template' \ +curl -X DELETE 'https://XXXX/XXXX/XXXX/notification/template/XXXX' \ -H 'Authorization: Bearer ' ``` @@ -741,7 +762,7 @@ curl -X DELETE 'https://XXXX/XXXX/XXXX/notification/template' \ ```json { - "uri": "https://XXXX/XXXX/XXXX/notification/template", + "uri": "https://XXXX/XXXX/XXXX/notification/template/XXXX", "timestamp": 1646989686393, "organization": "XXXX", "application": "17fe201b-XXXX-XXXX-83df-1ed1ebd7b227", diff --git a/shared/common/_restful-authentication.mdx b/shared/common/_restful-authentication.mdx index d9fcf9ac7..6498e1f4b 100644 --- a/shared/common/_restful-authentication.mdx +++ b/shared/common/_restful-authentication.mdx @@ -11,7 +11,7 @@ Available REST authentication methods are: - **Basic HTTP authentication** - You need to generate a Base64-encoded credential with the Customer ID and Customer Secret provided by and pass the credential to the `Authorization` parameter in the request header. + You need to generate a Base64-encoded credential with the customer ID and customer secret provided by and pass the credential to the `Authorization` parameter in the request header. @@ -20,6 +20,12 @@ Available REST authentication methods are: + +- **HMAC HTTP authentication** + + You need to generate a signature through the HMAC-SHA256 algorithm and pass the signature and related information to the `Authorization` parameter in the request header. This option is recommended since it has a higher security level. + + Implement authentication on the server; otherwise, you may encounter the risk of data leakage. @@ -27,19 +33,19 @@ Implement authentication on the server; otherwise, you may encounter the risk of ### Generate Customer ID and Customer Secret -To generate a set of Customer ID and Customer Secret, do the following: +To generate a set of customer ID and customer secret, do the following: 1. In , click **Developer Toolkit** > **RESTful API**. ![RESTful API](/images/common/console-restful-api.png) -2. Click **Add a Secret**. A set of Customer ID and Customer Secret is generated. +2. Click **Add a secret**, and click **OK**. A set of customer ID and customer secret is generated. 3. Click **Download** in the **Customer Secret** column. Read the pop-up window carefully, and save the downloaded `key_and_secret.txt` file in a secure location. -4. Use the Customer ID (key) and Customer Secret (secret) to generate a Base64-encoded credential, and pass the Base64-encoded credential to the `Authorization` parameter in the HTTP request header. +4. Use the customer ID (key) and customer secret (secret) to generate a Base64-encoded credential, and pass the Base64-encoded credential to the `Authorization` parameter in the HTTP request header. -You can download the Customer Secret from the only once. Be sure to keep it secure. +You can download the customer secret from only once. Be sure to keep it secure. ### Basic authentication sample code @@ -351,3 +357,60 @@ print(data.decode("utf-8"))`} + + +## Implement HMAC HTTP authentication + +To implement HMAC HTTP authentication, you need the following information: + +- App ID +- Customer ID and customer secret + +### HMAC authentication sample code + +The following sample code demonstrates how to generate the value of the `Authorization` field: + +```javascript +const crypto = require('crypto'); +const http = require('http'); + +// The app ID of your Agora project +appid = "" +// The customer ID obtained from the RESTful API of the Agora Console +customer_username = "" +// The customer secret obtained from the RESTful API of the Agora Console +customer_secret = "" +// Request package body +data = "" + +function hashData(data) { + const hash = crypto.createHash('sha256'); + hash.update(data); + return hash.digest('base64'); +} +function signData(data) { + const hmac = crypto.createHmac('sha256', customer_secret); + hmac.update(data); + return hmac.digest('base64'); +} + +date = (new Date()).toUTCString(); +reqpath = `/cn/v1/projects/${appid}/rtls/ingress/appconfig`; +reqline = `GET ${reqpath} HTTP/1.1`; +// Calculate the SHA-256 hash +bodySign = hashData(args.data); +digest = `SHA-256=${bodySign}`; +// Generate signature +signingStr = `host: ${host}\ndate: ${date}\n${reqline}\ndigest: ${digest}`; +sign = signData(signingStr); + +auth = `hmac username="${customer_username}", ` +auth += `algorithm="hmac-sha256", ` +auth += `headers="host date request-line digest", ` +auth += `signature="${sign}"`; + +console.log(`Authorization: ${auth}`); +``` + + + diff --git a/shared/extensions-marketplace/virtual-background.mdx b/shared/extensions-marketplace/virtual-background.mdx index 9cb9278c3..20941b3c6 100644 --- a/shared/extensions-marketplace/virtual-background.mdx +++ b/shared/extensions-marketplace/virtual-background.mdx @@ -20,22 +20,23 @@ Try out the [online demo](https://webdemo-global.agora.io/index.html) for [Virtu | Feature | Example | | ---- | ---- | -| Blurred background and image background | ![](https://web-cdn.agora.io/docs-files/1647325748630) | +| Blurred background and image background | ![](/images/extensions-marketplace/blurred-background.jpg) | | Video/Animated background | | -| Portrait-in-picture | ![portrait-in-picture](/images/video-sdk/portrait-in-picture.png) Allows the presenter to use slides as the virtual background while superimposing their video. The effect is similar to a weather news cast on television, preventing interruptions during a layout toggle. | +| Portrait-in-picture | ![portrait-in-picture](/images/extensions-marketplace/portrait-in-picture.jpg) Allows the presenter to use slides as the virtual background while superimposing their video. The effect is similar to a weather news cast on television, preventing interruptions during a layout toggle. | | Feature | Example | | ---- | ---- | -| Blurred background and image background | ![](https://web-cdn.agora.io/docs-files/1647325748630) | +| Blurred background and image background | ![](/images/extensions-marketplace/blurred-background.jpg) | | Video/Animated background | | -| Portrait-in-picture | ![portrait-in-picture](/images/video-sdk/portrait-in-picture.png) Allows the presenter to use slides as the virtual background while superimposing their video. The effect is similar to a weather news cast on television, preventing interruptions during a layout toggle. | +| Portrait-in-picture | ![portrait-in-picture](/images/extensions-marketplace/portrait-in-picture.jpg) Allows the presenter to use slides as the virtual background while superimposing their video. The effect is similar to a weather news cast on television, preventing interruptions during a layout toggle. | |Together Mode | ![together-mode](/images/video-sdk/together-mode.png) Allows the presenter to segment the portrait in the remote video, transmit it locally, and customize the display. | + Want to test ? Try the online demo. diff --git a/shared/flexible-classroom/classroom-sdk/js.mdx b/shared/flexible-classroom/classroom-sdk/js.mdx index 94ee776d2..c14ff64b2 100644 --- a/shared/flexible-classroom/classroom-sdk/js.mdx +++ b/shared/flexible-classroom/classroom-sdk/js.mdx @@ -116,6 +116,11 @@ export type ConfigParams = { | `appId` | (Required) The Agora App ID. See [Get the Agora App ID](../get-started/manage-agora-account#get-the-app-id). | | `region` | (Optional) The region where the classrooms is located. Agora recommends you set a region close to the region of the object storage service for your courseware or recording files, because cross-region transmission of large static resources can lead to delay. For example, if your S3 service is in North America, you should set this parameter to `NA`. All Smart Classroom clients must set the same area, otherwise they cannot communicate with each other. All clients must use the same region, otherwise, they may fail to communicate with each other. Flexible Classroom supports the following regions:
  • `CN`: Mainland China
  • `AP`: Asia Pacific
  • `EU`: Europe
  • `NA`: North America
  • | +### ListenerCallback + +```typescript +export type ListenerCallback = (evt: AgoraEduClassroomEvent, ...args: unknown[]) => void; +``` ### LaunchOption @@ -160,7 +165,7 @@ export type LaunchOption = { | `roleType` | (Required) The role of the user in the classroom. See [`EduRoleTypeEnum`](#eduroletypeenum). | | `roomType` | (Required) The classroom type. See [`EduRoomTypeEnum`](#eduroomtypeenum). | | `roomServiceType` | (Optional) The service type of big classrooms. See [EduRoomServiceTypeEnum](#eduroomservicetypeenum). | -| `listener` | (Required) The state of classroom launching.
  • `ready`: The classroom is ready.
  • `destroyed`: The classroom has been destroyed.
  • | +| `listener` | (Required) Classroom event callback, please refer to the event type for details. | | `pretest` | (Required) Whether to enable the pre-class device test:
  • `true`: Enable the pre-class device test. After this function is enabled, end users can see a page for the device test before entering the classroom. They can check whether their camera, microphone, and speaker can work properly.
  • `false`: Disable the pre-class device test.
  • | | `language` | (Required) The UI language. See [`LanguageEnum`](#languageenum). | | `startTime` | (Required) The start time (ms) of the class, determined by the first user joining the classroom. | diff --git a/shared/flexible-classroom/integrate-flexible-classroom-fcr/web.mdx b/shared/flexible-classroom/integrate-flexible-classroom-fcr/web.mdx index 5440550d5..9b6d45b54 100644 --- a/shared/flexible-classroom/integrate-flexible-classroom-fcr/web.mdx +++ b/shared/flexible-classroom/integrate-flexible-classroom-fcr/web.mdx @@ -86,7 +86,7 @@ If you are satisfied with the default UI of Cloud Classroom and do not want to c userUuid: "user id", userName: "user name", roomUuid: "room id", - roomType: 4, // Room type: 4 is for small classes, currently only small classes are supported. + roomType: 10, // Room type: 10 for Cloud Class. roomName: "room name", pretest: true, // Whether to enable pre-class equipment detection token: "rtm token", // In a test environment, you can use temporary RTM Token; in a production or security environment, it is strongly recommended that you use a server-generated RTM Token. @@ -124,84 +124,81 @@ If you are satisfied with the default UI of Cloud Classroom and do not want to c ```html - - - - - - - - - - - -
    - + + + + + +
    + - + + ``` diff --git a/shared/media-gateway/get-started/_quickstart.mdx b/shared/media-gateway/get-started/_quickstart.mdx new file mode 100644 index 000000000..e084cb28c --- /dev/null +++ b/shared/media-gateway/get-started/_quickstart.mdx @@ -0,0 +1,142 @@ +import * as data from '@site/data/variables'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +To push online media streams as live video source streams into channels using , you need to obtain a server domain name and streaming key. Taking the OBS streaming software as an example, you configure the server's domain name and streaming key in the following way: + +![Server settings](/images/media-gateway/obs-server-setting.png) + +This page explains how to obtain the server domain name and generate a streaming key. + +## Prerequisites + +In order to follow this procedure you must: + +- Have a project that implements an RTC product ([Interactive Live Streaming](../../interactive-live-streaming/overview/product-overview), [Broadcast Streaming](../../broadcast-streaming/overview/product-overview), [Video Calling](../../video-calling/overview/product-overview), [Voice Calling](../../voice-calling/overview/product-overview)) +- Generate app ID, app certificate, customer ID, and customer secret +- Pass basic HTTP or HMAC authentication + +## Get server domain name + +You can use ’s unified domain name or your own one. The server appends the `/live` suffix to the domain name. + +- The 's unified domain name is `rtls-ingress-prod-.agoramdn.com`. Replace `` with the code for your geographical region. + + The supported regions and their codes are: + + * `na`: North America + * `eu`: Europe + * `ap`: Asia, except Mainland China + * `cn`: Mainland China + +- To use your own domain name, [contact technical support](mailto:support@agora.io) for configuration. + +## Get streaming key + +The stream key generation method depends on whether you use the 's domain name or a custom domain name. + + - If you use 's domain name, create a stream key using the RESTful API. + - If you use your own domain name, you can either call the RESTful API or generate the key locally. + +### Generate streaming key with RESTful API + +Create and publish the streaming key by calling the following endpoint: + +`PUT https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/streamkeys` + +See [API reference](../reference/rest-api/endpoints/streaming-key/create-streaming-key) for details. + +### Generate streaming key locally + +Before starting, please make sure you have contacted technical support and configured your domain name. + +To generate a stream key locally, you use the following information: + +* The app ID of the project from . +* The app certificate corresponding to your app ID. +* The channel name (`channelName`). +* The user ID (`uid`) of the host in the channel. +* The effective duration of the stream key, in seconds (`expiresAfter`). +* (Optional) The associated flow configuration template (`template`). See [API reference](../reference/rest-api/endpoints/streaming-key/create-streaming-key) for details. + +The following Node.js sample code demonstrates how to generate a stream key locally. + +The following example code relies on the `msgpack-lite` module. If you haven't installed it yet, execute `npm install msgpack-lite` and run `node app.js` in the project root directory . + +```javascript +const crypto = require('crypto'); +const msgpack = require('msgpack-lite'); + +appcert = "" // Your app certificate from Agora +channel = ""; // The Video SDK channel name +uid = ""; // The UID of the host in the channel +expiresAfter = 86400; // Valid duration of stream key (seconds) + +const expiresAt = Math.floor(Date.now() / 1000) + expiresAfter; + +const rtcInfo = { + C: channel, + U: uid, + E: expiresAt, + // If you are not sure whether to use the flow configuration template, keep the following line commented + // T: templateId, +}; + +// Serialize using msgpack +const data = msgpack.encode(rtcInfo); + +// Randomly generate an initialization vector +const iv = crypto.randomBytes(16); + +// Use app certificate as encryption key +const key = Buffer.from(appcert, 'hex'); + +// Create an AES-128 CTR encryptor +const encrypter = crypto.createCipheriv('aes-128-ctr', key, iv); + +// Encrypt the data +const encrypted = Buffer.concat([iv, encrypter.update(data), encrypter.final()]); + +// Base64 conversion +const streamkey = encrypted.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''); + +console.log(`streamkey is ${streamkey}`); +``` + +## Recommended config for web client communication + +In case of intercommunication with the web client, transcoding is not enabled by default. To ensure the best experience for web viewers, make sure that the streaming software uses the following encoding parameters: + +- Key frame interval (GOP): `2s` +- Video profile: `baseline` +- x264 options: `threads=6` +- Frame rate (FPS): At 1080 resolution, the frame rate must not exceed 30; for resolutions below that, the frame rate must not exceed 60 (if not necessary, 30 is sufficient). + +Taking the OBS streaming software as an example, configure it as shown below: + +1. On the **Settings > Output > Live** page, configure the video profile, keyframe interval, and x264 options. + + ![Encoder settings](/images/media-gateway/obs-encoder-settings.png) + +1. On the **Settings > Video** page, configure common frame rates. + + ![FPS settings](/images/media-gateway/obs-fps-setting.png) + +## Next steps + +After completing the configuration, you can push RTMP or SRT protocol streams to channels, and these streams will be published to the corresponding channels by the host. + +By default, after the receives the pushed stream, it will not transcode it and will directly publish it to the channel. If you want to transcode the streams, use the stream configuration template API to implement related functions. + + + + + + + + + + + + + diff --git a/shared/media-gateway/get-started/enable-media-gateway.mdx b/shared/media-gateway/get-started/enable-media-gateway.mdx new file mode 100644 index 000000000..bcced40e0 --- /dev/null +++ b/shared/media-gateway/get-started/enable-media-gateway.mdx @@ -0,0 +1,22 @@ +import * as data from '@site/data/variables'; + +To use , you first need to activate and configure it. This page explains how to do this in . + +## Prerequisites + +In order to follow this procedure you must: + +- Have a project that implements an RTC product ([Interactive Live Streaming](../../interactive-live-streaming/overview/product-overview), [Broadcast Streaming](../../broadcast-streaming/overview/product-overview), [Video Calling](../../video-calling/overview/product-overview), [Voice Calling](../../voice-calling/overview/product-overview)) +- Be logged into + +### Enable + +To enable , take the following steps: + +1. Obtain your app ID, app certificate, customer ID, and customer secret. See [Agora account management](../reference/manage-agora-account) for details. + +1. Open **My Projects** and click to edit the project for which you need . + +1. Under **All Features**, select **Media Gateway** and toggle to enable it. + +![Enable Media Gateway](/images/media-gateway/enable-media-gateway.png) \ No newline at end of file diff --git a/shared/media-gateway/reference/_best-practice.mdx b/shared/media-gateway/reference/_best-practice.mdx new file mode 100644 index 000000000..eb1dc73ed --- /dev/null +++ b/shared/media-gateway/reference/_best-practice.mdx @@ -0,0 +1,43 @@ +import SwitchDomainName from '@docs/shared/common/_switch-domain-name.mdx'; +import Quota from '@docs/shared/media-gateway/reference/quota.mdx'; + +This document presents the best practice to reliably integrate in your app. Before reading this document, follow the [ quickstart](../get-started/quickstart) to understand the basic process of using . + + + +## Ensure high availability of streaming services + +To ensure high availability of streaming services, and to avoid outages caused by regional network failures, Agora provides alternate domain names. Implement the following best practice to switch to an alternate domain name: + +1. Based on the geographical location of your source stream, use the primary domain name from the following table: + + | Geographical area | Primary domain name | Alternate domain name | + |:----|:----------------------------|:----------------------------| + | North America | `rtls-ingress-prod-na.agoramdn.com` | `rtls-ingress-prod-backup-na.agoramdn.com` | + | Europe | `rtls-ingress-prod-eu.agoramdn.com` | `rtls-ingress-prod-backup-eu.agoramdn.com` | + | Asia except Mainland China | `rtls-ingress-prod-ap.agoramdn.com` | `rtls-ingress-prod-backup-ap.agoramdn.com` | + | Chinese mainland | `rtls-ingress-prod-cn.agoramdn.com` | `rtls-ingress-prod-backup-cn.agoramdn.com` | + +1. If the request using the primary domain name fails, use the same domain to try again. + +1. If the attempt still fails again, try the alternate domain name. + +## Ensure high availability of REST services + +Implement the following best practice: + + + +## Troubleshooting checklist + +Refer to the following checklist to quickly confirm if each integration requirement for ensuring the connectivity and reliability of the service has been met. + +| # | Importance | Check | +|:--|:-----------|:------------| +| 1 | required | The service has been enabled for your App ID. | +| 2 | required | The API call rate is below the maximum limit. See [API Call Limits](#api-call-limits) for details. | +| 3 | required | The number of concurrent tasks in a project is less than 50. For details, see the [maximum number of concurrent tasks](#maximum-number-of-concurrent-tasks). | +| 4 | required |
    • The `region` is set to the geographical region of your media stream source.
    • The `region` code is in lowercase.
    | +| 5 | optional | If calling the RESTful API fails, troubleshoot as follows:
    • Use a back-off strategy.
    • Check the [error code](rest-api/response-status-codes).
    If the above troubleshooting methods do not solve your issue, contact [Agora technical support](mailto:support@agora.io) with the `X-Request-ID` from the response header. | +| 6 | optional | If streaming fails using the RTMP/SRT protocol, please follow the steps below to troubleshoot:
    • Ensure that the stream key has not expired.
    • If you are using OBS streaming software, check that the frame loss rate is normal.
    If the above troubleshooting methods do not solve your issue, contact [Agora technical support](mailto:support@agora.io) with your streaming domain name and `streamKey` values.| +| 7 | Optional | If the streaming service or REST service is unavailable due to network failure, follow the following solutions to troubleshoot:
    • Try again using the current primary domain name.
    • Change to the backup domain name and try again.
    If the above troubleshooting methods do not solve your issue, contact [Agora technical support](mailto:support@agora.io) with your streaming domain name and `streamKey` values.| diff --git a/shared/media-gateway/reference/_release-notes.mdx b/shared/media-gateway/reference/_release-notes.mdx new file mode 100644 index 000000000..556f8ccc7 --- /dev/null +++ b/shared/media-gateway/reference/_release-notes.mdx @@ -0,0 +1,12 @@ +This page provides the release notes for . + +## 2024.6.21 + + reaches General Availability (GA) status with the following core functions: + +- Pushing media streams into . +- Supporting RTMP/SRT streaming protocols, H.264/H.265 video codecs, and AAC audio codec. +- Customizing transcoding options, including video resolution, frame rate, and bitrate. + + + diff --git a/shared/media-gateway/reference/pricing.mdx b/shared/media-gateway/reference/pricing.mdx new file mode 100644 index 000000000..fee717106 --- /dev/null +++ b/shared/media-gateway/reference/pricing.mdx @@ -0,0 +1,8 @@ +The unit pricing for services is as follows: + +|Usage |Unit price, US$ | +|-------------------------|----------------| +|Audio |0.99/1000 min | +|Video with transcoding |5.99/1000 min | +|Video without transcoding|2.99/1000 min | + diff --git a/shared/media-gateway/reference/quota.mdx b/shared/media-gateway/reference/quota.mdx new file mode 100644 index 000000000..f7db78d0b --- /dev/null +++ b/shared/media-gateway/reference/quota.mdx @@ -0,0 +1,19 @@ +## API call limits + +The Agora server limits the call rate of the API, and returns the `429 (Too Many Requests)` status code when the limit rate is exceeded. If you have higher call rate requirements, please contact [Agora technical support](mailto:support@agora.io). + +| API | Calling rate limit per project | +|:----|:-----------------------------| +| `Create` | 50 per second. | +| `Delete` | 50 per second. | +| `Query` | 100 per second. | +| `Update` | 50 per second. | + +## Maximum number of concurrent tasks + +The limitation for concurrent streams is the following: + +- 10 for streams with video transcoding +- 50 for streams without transcoding. + +For higher quotas, please contact [Agora technical support](mailto:support@agora.io). \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/_category_.json b/shared/media-gateway/reference/rest-api/_category_.json new file mode 100644 index 000000000..a46dec1f6 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 1, + "label": "RESTful API", + "collapsible": true, + "link": null +} diff --git a/shared/media-gateway/reference/rest-api/authorization.mdx b/shared/media-gateway/reference/rest-api/authorization.mdx new file mode 100644 index 000000000..da6f3947b --- /dev/null +++ b/shared/media-gateway/reference/rest-api/authorization.mdx @@ -0,0 +1,13 @@ +- HTTP Basic Authentication + + Every time you send an HTTP request, you must pass in a credential in the `Authorization` field in the HTTP request header. See [RESTful Authentication](/media-gateway/reference/restful-authentication#implement-basic-http-authentication) on how to generate it. + + Basic authentication is a simple authentication scheme built into the HTTP protocol. To use it, send your HTTP requests with an `Authorization` header that contains the word Basic followed by a space and a base64-encoded string `username:password`. + + Example: `Authorization: Basic ZGVtbzpwQDU1dzByZA==` + +- HTTP HMAC Authentication + + Every time you send an HTTP request, you must pass in an API key in the `Authorization` field in the HTTP request header. See [RESTful Authentication](/media-gateway/reference/restful-authentication#implement-hmac-http-authentication) on how to generate it. + + Example: `Authorization: 123` diff --git a/shared/media-gateway/reference/rest-api/endpoints/_category_.json b/shared/media-gateway/reference/rest-api/endpoints/_category_.json new file mode 100644 index 000000000..65866d26f --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 1, + "label": "Endpoints", + "collapsible": true, + "link": null +} diff --git a/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/_category_.json b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/_category_.json new file mode 100644 index 000000000..7dc7d29f9 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 2, + "label": "Flow configuration templates", + "collapsible": true, + "link": null +} diff --git a/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/create-reset-template.mdx b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/create-reset-template.mdx new file mode 100644 index 000000000..11373ebc4 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/create-reset-template.mdx @@ -0,0 +1,115 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method creates or resets a flow configuration template. + +### Prototype + +- Method: `PUT` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/stream-templates/:templateId` + +In the template, you can configure transcoding parameters for video or audio streams, as well as parameters for mitigating network latency. + +Up to 10 flow configuration templates can be created under an app ID, each with a unique `templatedId`. Specify the `templateId` when creating a template; if a template corresponding to this ID already exists, the existing template will be reset with the incoming body data. + +There are two ways to use flow configuration templates, which can be used in combination: + +- Specify a global template for the app ID: All streaming keys under the app ID will use this template by default. +- Specify a configuration template for a specific streaming key: When using this key to push streams, the specific template will be used. + +By default, a template is not set for the app ID. That is, video transcoding is not enabled. + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | +| `templateId` | String | Required | The flow configuration template ID. The value can only include the following characters: a-z, A-Z, 0-9, and the length cannot exceed 12 bytes. The value of the flow configuration template ID can be set according to your business scenario. For example, `"720p"` and `"1080p"` for different target resolutions, or `"gameA"` and `"gameB"`for different game scenarios.| + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +**Request body** + +The request body consists of a JSON Object type `settings` and includes the following fields: + +| Parameter | Data type | Required/Optional | Description | +| :------------ | :-------- |:----------------- | :---------------------- | +| `transcoding` | Object | Optional | Audio and video transcoding parameter configuration.
    • `video`: Object, video transcoding parameters. Includes the following fields:
      • `enabled`: Whether to enable video transcoding. Disabled by default.
      • `codec`: String, the codec format for transcoding. Supported values are `H.264` (default) and `VP8`.
      • `width`: Number, the width in the encoding resolution. The value range is 2 to 1920.
      • `height` Number, the height in the encoding resolution. The value range is 2 to 1920.
      • `fps`: Number, the video encoding frame rate in fps. The value range is 1 to 60.
      • `simulcastStream`: Object, video stream configuration. If provided, enable the low-quality stream and specify the transcoding parameters for it.
        • `width`: Number, the width of the video stream in px. The value range is 2 to 1920. The value of this parameter must be less than `video.width`.
        • `height` Number, the height of the video stream. The value range is 2 to 1920.The value of this parameter must be less than `video.height`.
        • `fps`: Number, the frame rate of the video stream in fps. The value range is 1 to 160. The value of this parameter must be less than or equal to `video.fps`.
        • `bitrate`: The bitrate of the low-quality video stream, in Kbps. The value of this parameter must be less than `video.bitrate`.
      • `bitrate`: Video encoding bitrate in Kbps.
        • If the low-quality stream is enabled (`simulcastStream` is provided), then this field is required and the value must be greater than `simulcastStream.bitrate`.
        • If the low-quality video stream is not enabled, this field is optional. If not filled in, an appropriate bitrate will be set automatically based on the `width`, `height`, and `fps` values. See the following table:
          Resolution (width × height, px)Frame rate (fps)Bitrate (Kbps)
          640 × 36015680
          640 × 360301030
          848 × 48015920
          848 × 480301400
          960 × 540151100
          960 × 540301670
          1280 × 720151600
          1280 × 720302400
          1920 × 1080152500
          1920 × 1080303780
          1920 × 1080605730
          When the low-quality stream is not enabled, it is recommended to use the automatically set bitrate.
    • `audio`: Object, audio transcoding parameters. Includes the following fields:
      • `enabled`: Boolean, whether to enable audio transcoding. Enabled by default.
      • `profile`: Number, encoded audio scenarios. The default value is `0`, which means 48 KHz sampling rate, music encoding, mono, and the maximum encoding rate is 64 Kbps. If you want to set other settings profile, please [contact technical support](mailto:support@agora.io).
      • `bitrate`: Number, the encoding bitrate in Kbps. If left blank, it is determined by the `profile` value. The range is 64 to 320.
    | +| `jitterBuffer`| Object | Optional | Network jitter buffer. Only takes effect when video transcoding is enabled.
    • `size`: Number, the maximum length in ms. The default value is 500, which means that will add 500 ms to the end-to-end delay to reduce lag caused by network jitter.
    • `maxSize`: Number, the maximum length in ms. The default value is 1000. Make sure that the value of this field is greater than `jitterBuffer.size`. When `jitterBuffer` exceeds this value, will enable acceleration until it returns to `jitterBuffer.size`.
    | + + +### Request example + +```shell +curl --location -g --request PUT 'https://api.agora.io/{{region}}/v1/projects/{{appId}}/rtls/ingress/stream-templates/{{templateId}}' \ +--data '{ + "settings": { + "transcoding": { + "video": { + "enabled": true, + "codec": "H.264", + "width": 1280, + "height": 720, + "fps": 24, + "bitrate": 2200, + "simulcastStream": { + "width": 960, + "height": 540, + "fps": 24, + "bitrate": 1670 + } + }, + "audio": { + "enabled": false, + "profile": 3 + } + }, + "jitterBuffer": { + "size": 500, + "maxSize": 800 + } + } +}' +``` + + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status": "success" +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/delete-template.mdx b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/delete-template.mdx new file mode 100644 index 000000000..690ec0bf7 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/delete-template.mdx @@ -0,0 +1,67 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method deletes a flow configuration template. + +### Prototype + +- Method: `DELETE` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/stream-templates/:templateId` + +
    • After deletion, the stream currently being pushed using the template will not be affected and will still be pushed according to the template parameters. Deletion will take effect from the next push, including normal push and disconnection/reconnection).
    • If the template associated with the streaming key is deleted, the global template under the app ID will be used by default. If no global template is configured, streaming will be performed according to the no-template setting, that is, video transcoding will not be enabled.
    + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | +| `templateId` | String | Required | The flow configuration template ID. The value can only include the following characters: a-z, A-Z, 0-9, and the length cannot exceed 12 bytes. The value of the flow configuration template ID can be set according to your business scenario. For example, `"720p"` and `"1080p"` for different target resolutions, or `"gameA"` and `"gameB"`for different game scenarios.| + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +### Request example + +```shell +curl --location -g --request DELETE 'https://api.agora.io/{{region}}/v1/projects/{{appId}}/rtls/ingress/stream-templates/{{templateId}}' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status": "success" +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/set-global-template.mdx b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/set-global-template.mdx new file mode 100644 index 000000000..d4ad26b6d --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/set-global-template.mdx @@ -0,0 +1,80 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method sets a global flow configuration template, that is, the template that applies to all streaming keys under the app ID. + +### Prototype + +- Method: `PUT` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/appconfig` + +Before calling this API, [create a flow configuration template](create-reset-template). + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +**Request body** + +The request body consists of a JSON Object type `settings` and includes the following fields: + +| Parameter | Data type | Required/Optional | Description | +| :------------ | :-------- |:----------------- | :---------------------- | +| `defaultStreamTemplate` | String | Required | The flow configuration template ID. For users of the beta version: Previously this API could also be used to set the transcoding parameters. Now it is recommended that you use the [template creation API](create-reset-template) instead. If you have used this API to set `transcoding`, the current flow is the following:
    • If you reset `defaultStreamTemplate`, the `transcoding` previously set through this API will automatically become invalid, and the parameters in the new template will prevail.
    • If you do not reset `defaultStreamTemplate`, the `transcoding` previously set through this API will remain as the default global configuration for this app ID.
    | + + +### Request example + +```shell +curl --location -g --request PUT 'https://api.agora.io/{{region}}/v1/projects/{{appId}}/rtls/ingress/appconfig' \ +--data '{ + "settings": { + "defaultStreamTemplate": "720p" + } +}' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status": "success" +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/update-template.mdx b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/update-template.mdx new file mode 100644 index 000000000..df159ccb5 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/flow-configuration-template/update-template.mdx @@ -0,0 +1,99 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method updates a flow configuration template. + +### Prototype + +- Method: `PATCH` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/stream-templates/:templateId` + +
    • This interface can only be called if the flow configuration template already exists.
    • Modifications to a flow configuration template will only take effect after the stream is re-pushed. Considering the synchronization delay between the gateway and the database, wait 3 minutes after calling this interface before re-pushing the stream.
    + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | +| `templateId` | String | Required | The flow configuration template ID. The value can only include the following characters: a-z, A-Z, 0-9, and the length cannot exceed 12 bytes. The value of the flow configuration template ID can be set according to your business scenario. For example, `"720p"` and `"1080p"` for different target resolutions, or `"gameA"` and `"gameB"`for different game scenarios.| + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +**Request body** + +The request body consists of a JSON Object type `settings` and includes the following fields: + +| Parameter | Data type | Required/Optional | Description | +| :------------ | :-------- |:----------------- | :---------------------- | +| `transcoding` | Object | Optional | Audio and video transcoding parameter configuration.
    • `video`: Object, video transcoding parameters. Includes the following fields:
      • `enabled`: Whether to enable video transcoding. Disabled by default.
      • `codec`: String, the codec format for transcoding. Supported values are `H.264` (default) and `VP8`.
      • `width`: Number, the width in the encoding resolution. The value range is 2 to 1920.
      • `height` Number, the height in the encoding resolution. The value range is 2 to 1920.
      • `fps`: Number, the video encoding frame rate in fps. The value range is 1 to 60.
      • `simulcastStream`: Object, video stream configuration. If provided, enable the low-quality stream and specify the transcoding parameters for it.
        • `width`: Number, the width of the video stream in px. The value range is 2 to 1920. The value of this parameter must be less than `video.width`.
        • `height` Number, the height of the video stream. The value range is 2 to 1920.The value of this parameter must be less than `video.height`.
        • `fps`: Number, the frame rate of the video stream in fps. The value range is 1 to 160. The value of this parameter must be less than or equal to `video.fps`.
        • `bitrate`: The bitrate of the low-quality video stream, in Kbps. The value of this parameter must be less than `video.bitrate`.
      • `bitrate`: Video encoding bitrate in Kbps.
        • If the low-quality stream is enabled (`simulcastStream` is provided), then this field is required and the value must be greater than `simulcastStream.bitrate`.
        • If the low-quality video stream is not enabled, this field is optional. If not filled in, an appropriate bitrate will be set automatically based on the `width`, `height`, and `fps` values. See the following table:
          Resolution (width × height, px)Frame rate (fps)Bitrate (Kbps)
          640 × 36015680
          640 × 360301030
          848 × 48015920
          848 × 480301400
          960 × 540151100
          960 × 540301670
          1280 × 720151600
          1280 × 720302400
          1920 × 1080152500
          1920 × 1080303780
          1920 × 1080605730
          When the low-quality stream is not enabled, it is recommended to use the automatically set bitrate.
    • `audio`: Object, audio transcoding parameters. Includes the following fields:
      • `enabled`: Boolean, whether to enable audio transcoding. Enabled by default.
      • `profile`: Number, encoded audio scenarios. The default value is `0`, which means 48 KHz sampling rate, music encoding, mono, and the maximum encoding rate is 64 Kbps. If you want to set other settings profile, please [contact technical support](mailto:support@agora.io).
      • `bitrate`: Number, the encoding bitrate in Kbps. If left blank, it is determined by the `profile` value. The range is 64 to 320.
    | +| `jitterBuffer`| Object | Optional | Network jitter buffer. Only takes effect when video transcoding is enabled.
    • `size`: Number, the maximum length in ms. The default value is 500, which means that will add 500 ms to the end-to-end delay to reduce lag caused by network jitter.
    • `maxSize`: Number, the maximum length in ms. The default value is 1000. Make sure that the value of this field is greater than `jitterBuffer.size`. When `jitterBuffer` exceeds this value, will enable acceleration until it returns to `jitterBuffer.size`.
    | + +
    • To ensure a successful request, do not set the required fields to `null` or leave them empty.
    • The parameters supported for the update are the following: `transcoding.video`, `transcoding.audio`, and `jitterBuffer`. This means that, for example, if you only want to update the `fps` field of `transcoding.video`, you need to pass in the entire `transcoding.video` field with the modified `fps` field and other fields unchanged.
    • `transcoding.video`, `transcoding.audio`, and `jitterBuffer` are independent of each other. If only `transcoding.video` is passed in, then only its parameters will be updated and the parameters of `transcoding.audio` and `jitterBuffer` will not be affected.
    + +### Request example + +```shell +curl --location -g --request PUT 'https://api.agora.io/{{region}}/v1/projects/{{appId}}/rtls/ingress/stream-templates/{{templateId}}' \ +--data ' +{ + "settings": { + "transcoding": { + "video": { + "enabled": true, + "codec": "H.264", + "width": 1280, + "height": 720, + "fps": 24, + "bitrate": 2200, + "simulcastStream": { + "width": 960, + "height": 540, + "fps": 24, + "bitrate": 1670 + } + } + } + } +}' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status": "success" +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/message-notification-service/_category_.json b/shared/media-gateway/reference/rest-api/endpoints/message-notification-service/_category_.json new file mode 100644 index 000000000..8f86d589b --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/message-notification-service/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 4, + "label": "Message notification service", + "collapsible": true, + "link": null +} diff --git a/shared/media-gateway/reference/rest-api/endpoints/message-notification-service/query-ip-address.mdx b/shared/media-gateway/reference/rest-api/endpoints/message-notification-service/query-ip-address.mdx new file mode 100644 index 000000000..8b6008d91 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/message-notification-service/query-ip-address.mdx @@ -0,0 +1,732 @@ +import CodeBlock from '@theme/CodeBlock'; + +When using Agora real-time audio and video, you can use the service to receive channel events. + +After activating the service, when a channel event occurs, the server will deliver the event notification to your message receiving server. + +If your server is behind a firewall, you need to call the IP address query API to retrieve the IP addresses of and configure your firewall to trust all these IP addresses. + +Agora adjusts the IP addresses every 24 hours. Best practice is to call this endpoint at least every 24 hours and automatically update the firewall configuration. + +### Prototype + +* Method: `GET` +* Endpoint: `https://api.agora.io/v2/ncs/ip` + +### Request parameters + +**Authentication** + +- HTTP Basic Authentication + + Every time you send an HTTP request, you must pass in a credential in the `Authorization` field in the HTTP request header. See [RESTful Authentication](../../../restful-authentication#implement-basic-http-authentication) on how to generate it. + + Basic authentication is a simple authentication scheme built into the HTTP protocol. To use it, send your HTTP requests with an `Authorization` header that contains the word Basic followed by a space and a base64-encoded string `username:password`. + + Example: `Authorization: Basic ZGVtbzpwQDU1dzByZA==` + +### Request examples + +Use one of the following code examples to test this request: + +
    +Shell + + -
    + curl + + + {`curl --request GET \\ + --url http://api.sd-rtn.com/v2/ncs/ip \\ + --header 'Accept: application/json' \\ + --header 'Authorization: '`} + +
    + + -
    + HTTPie + + + {`http GET http://api.sd-rtn.com/v2/ncs/ip \\ + Accept:application/json \\ + Authorization:''`} + +
    + + -
    + wget + + + {`wget --quiet \\ + --method GET \\ + --header 'Authorization: ' \\ + --header 'Accept: application/json' \\ + --output-document \\ + - http://api.sd-rtn.com/v2/ncs/ip`} + +
    +
    + +
    +Javascript + + -
    + Fetch + + + {`const url = 'http://api.sd-rtn.com/v2/ncs/ip'; + const options = {method: 'GET', headers: {Authorization: '', Accept: 'application/json'}}; + + try { + const response = await fetch(url, options); + const data = await response.json(); + console.log(data); + } catch (error) { + console.error(error); + }`} + +
    + + -
    + XMLHTTPRequest + + + {`const data = null; + + const xhr = new XMLHttpRequest(); + xhr.withCredentials = true; + + xhr.addEventListener('readystatechange', function () { + if (this.readyState === this.DONE) { + console.log(this.responseText); + } + }); + + xhr.open('GET', 'http://api.sd-rtn.com/v2/ncs/ip'); + xhr.setRequestHeader('Authorization', ''); + xhr.setRequestHeader('Accept', 'application/json'); + + xhr.send(data);`} + +
    + + -
    + jQuery + + + {`const settings = { + async: true, + crossDomain: true, + url: 'http://api.sd-rtn.com/v2/ncs/ip', + method: 'GET', + headers: { + Authorization: '', + Accept: 'application/json' + } + }; + + $.ajax(settings).done(function (response) { + console.log(response); + });`} + +
    + + -
    + Axios + + + {`import axios from 'axios'; + + const options = { + method: 'GET', + url: 'http://api.sd-rtn.com/v2/ncs/ip', + headers: {Authorization: '', Accept: 'application/json'} + }; + + try { + const { data } = await axios.request(options); + console.log(data); + } catch (error) { + console.error(error); + }`} + +
    +
    + +
    +Node + + -
    + Native + + + {`const http = require('http'); + + const options = { + method: 'GET', + hostname: 'api.sd-rtn.com', + port: null, + path: '/v2/ncs/ip', + headers: { + Authorization: '', + Accept: 'application/json' + } + }; + + const req = http.request(options, function (res) { + const chunks = []; + + res.on('data', function (chunk) { + chunks.push(chunk); + }); + + res.on('end', function () { + const body = Buffer.concat(chunks); + console.log(body.toString()); + }); + }); + + req.end();`} + +
    + + -
    + Request + + + {`const request = require('request'); + + const options = { + method: 'GET', + url: 'http://api.sd-rtn.com/v2/ncs/ip', + headers: {Authorization: '', Accept: 'application/json'} + }; + + request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); + });`} + +
    + + -
    + Unirest + + + {`const unirest = require('unirest'); + + const req = unirest('GET', 'http://api.sd-rtn.com/v2/ncs/ip'); + + req.headers({ + Authorization: '', + Accept: 'application/json' + }); + + req.end(function (res) { + if (res.error) throw new Error(res.error); + + console.log(res.body); + });`} + +
    + + -
    + Fetch + + {`const fetch = require('node-fetch'); + + const url = 'http://api.sd-rtn.com/v2/ncs/ip'; + const options = {method: 'GET', headers: {Authorization: '', Accept: 'application/json'}}; + + try { + const response = await fetch(url, options); + const data = await response.json(); + console.log(data); + } catch (error) { + console.error(error); + }`} + +
    + + -
    + Axios + + + {`const axios = require('axios').default; + + const options = { + method: 'GET', + url: 'http://api.sd-rtn.com/v2/ncs/ip', + headers: {Authorization: '', Accept: 'application/json'} + }; + + try { + const { data } = await axios.request(options); + console.log(data); + } catch (error) { + console.error(error); + }`} + +
    +
    + +
    +Python + + -
    + Python 3 + + + {`import http.client + + conn = http.client.HTTPConnection("api.sd-rtn.com") + + headers = { + 'Authorization': "", + 'Accept': "application/json" + } + + conn.request("GET", "/v2/ncs/ip", headers=headers) + + res = conn.getresponse() + data = res.read() + + print(data.decode("utf-8"))`} + +
    + + -
    + Requests + + + {`import requests + + url = "http://api.sd-rtn.com/v2/ncs/ip" + + headers = { + "Authorization": "", + "Accept": "application/json" + } + + response = requests.get(url, headers=headers) + + print(response.json())`} + +
    +
    + +
    +Go + + + {`package main + + import ( + "fmt" + "net/http" + "io" + ) + + func main() { + + url := "http://api.sd-rtn.com/v2/ncs/ip" + + req, _ := http.NewRequest("GET", url, nil) + + req.Header.Add("Authorization", "") + req.Header.Add("Accept", "application/json") + + res, _ := http.DefaultClient.Do(req) + + defer res.Body.Close() + body, _ := io.ReadAll(res.Body) + + fmt.Println(res) + fmt.Println(string(body)) + + }`} + +
    + +
    +C + + {`CURL *hnd = curl_easy_init(); + +curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET"); +curl_easy_setopt(hnd, CURLOPT_URL, "http://api.sd-rtn.com/v2/ncs/ip"); + +struct curl_slist *headers = NULL; +headers = curl_slist_append(headers, "Authorization: "); +headers = curl_slist_append(headers, "Accept: application/json"); +curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers); + +CURLcode ret = curl_easy_perform(hnd);`} + +
    + +
    +Objective-C + + + {`#import + +NSDictionary *headers = @{ @"Authorization": @"", + @"Accept": @"application/json" }; + +NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://api.sd-rtn.com/v2/ncs/ip"] + cachePolicy:NSURLRequestUseProtocolCachePolicy + timeoutInterval:10.0]; +[request setHTTPMethod:@"GET"]; +[request setAllHTTPHeaderFields:headers]; + +NSURLSession *session = [NSURLSession sharedSession]; +NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error) { + NSLog(@"%@", error); + } else { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; + NSLog(@"%@", httpResponse); + } + }]; +[dataTask resume];`} + +
    + +
    +OCaml + + + {`open Cohttp_lwt_unix +open Cohttp +open Lwt + +let uri = Uri.of_string "http://api.sd-rtn.com/v2/ncs/ip" in +let headers = Header.add_list (Header.init ()) [ + ("Authorization", ""); + ("Accept", "application/json"); +] in + +Client.call ~headers \`GET uri +\>\>= fun (res, body_stream) -\> + (* Do stuff with the result *)`} + +
    + +
    +C# + -
    + HTTPClient + + + {`using System.Net.Http.Headers; + var client = new HttpClient(); + var request = new HttpRequestMessage + { + Method = HttpMethod.Get, + RequestUri = new Uri("http://api.sd-rtn.com/v2/ncs/ip"), + Headers = + { + { "Authorization", "" }, + { "Accept", "application/json" }, + }, + }; + using (var response = await client.SendAsync(request)) + { + response.EnsureSuccessStatusCode(); + var body = await response.Content.ReadAsStringAsync(); + Console.WriteLine(body); + }`} + +
    + + -
    + RestSharp + + + {`var client = new RestClient("http://api.sd-rtn.com/v2/ncs/ip"); + var request = new RestRequest(Method.GET); + request.AddHeader("Authorization", ""); + request.AddHeader("Accept", "application/json"); + IRestResponse response = client.Execute(request);`} + +
    +
    + + +
    +Java + -
    + AsyncHttp + + + {`AsyncHttpClient client = new DefaultAsyncHttpClient(); + client.prepare("GET", "http://api.sd-rtn.com/v2/ncs/ip") + .setHeader("Authorization", "") + .setHeader("Accept", "application/json") + .execute() + .toCompletableFuture() + .thenAccept(System.out::println) + .join(); + + client.close();`} + +
    + + -
    + NetHttp + + + {`HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("http://api.sd-rtn.com/v2/ncs/ip")) + .header("Authorization", "") + .header("Accept", "application/json") + .method("GET", HttpRequest.BodyPublishers.noBody()) + .build(); + HttpResponse response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); + System.out.println(response.body());`} + +
    + + -
    + OkHttp + + + {`OkHttpClient client = new OkHttpClient(); + + Request request = new Request.Builder() + .url("http://api.sd-rtn.com/v2/ncs/ip") + .get() + .addHeader("Authorization", "") + .addHeader("Accept", "application/json") + .build(); + + Response response = client.newCall(request).execute();`} + +
    + + -
    + Unirest + + + {`HttpResponse response = Unirest.get("http://api.sd-rtn.com/v2/ncs/ip") + .header("Authorization", "") + .header("Accept", "application/json") + .asString();`} + +
    +
    + +
    +Http 1.1 + + + {`GET /v2/ncs/ip HTTP/1.1 +Authorization: +Accept: application/json +Host: api.sd-rtn.com`} + +
    + +
    +Clojure + + + {`(require '[clj-http.client :as client]) + +(client/get "http://api.sd-rtn.com/v2/ncs/ip" {:headers {:Authorization ""} + :accept :json})`} + +
    + +
    +Kotlin + + + {`val client = OkHttpClient() + +val request = Request.Builder() + .url("http://api.sd-rtn.com/v2/ncs/ip") + .get() + .addHeader("Authorization", "") + .addHeader("Accept", "application/json") + .build() + +val response = client.newCall(request).execute()`} + +
    + +
    +PHP + -
    + cURL + + + {` "http://api.sd-rtn.com/v2/ncs/ip", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_HTTPHEADER => [ + "Accept: application/json", + "Authorization: " + ], + ]); + + $response = curl_exec($curl); + $err = curl_error($curl); + + curl_close($curl); + + if ($err) { + echo "cURL Error #:" . $err; + } else { + echo $response; + }`} + +
    + + -
    + Guzzle + + + {`request('GET', 'http://api.sd-rtn.com/v2/ncs/ip', [ + 'headers' => [ + 'Accept' => 'application/json', + 'Authorization' => '', + ], + ]); + + echo $response->getBody();`} + +
    +
    + +
    +PowerShell + -
    + WebRequest + + + {`$headers=@{} + $headers.Add("Authorization", "") + $headers.Add("Accept", "application/json") + $response = Invoke-WebRequest -Uri 'http://api.sd-rtn.com/v2/ncs/ip' -Method GET -Headers $headers`} + +
    + + -
    + RestMethod + + + {`$headers=@{} + $headers.Add("Authorization", "") + $headers.Add("Accept", "application/json") + $response = Invoke-RestMethod -Uri 'http://api.sd-rtn.com/v2/ncs/ip' -Method GET -Headers $headers`} + +
    +
    + +
    +R + + + {`library(httr) + +url <- "http://api.sd-rtn.com/v2/ncs/ip" + +response <- VERB("GET", url, add_headers('Authorization' = ''), content_type("application/octet-stream"), accept("application/json")) + +content(response, "text")`} + +
    + +
    +Ruby + + {`require 'uri' +require 'net/http' + +url = URI("http://api.sd-rtn.com/v2/ncs/ip") + +http = Net::HTTP.new(url.host, url.port) + +request = Net::HTTP::Get.new(url) +request["Authorization"] = '' +request["Accept"] = 'application/json' + +response = http.request(request) +puts response.read_body`} + +
    + +
    +Swift + + {`import Foundation + +let headers = [ + "Authorization": "", + "Accept": "application/json" +] + +let request = NSMutableURLRequest(url: NSURL(string: "http://api.sd-rtn.com/v2/ncs/ip")! as URL, + cachePolicy: .useProtocolCachePolicy, + timeoutInterval: 10.0) +request.httpMethod = "GET" +request.allHTTPHeaderFields = headers + +let session = URLSession.shared +let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in + if (error != nil) { + print(error as Any) + } else { + let httpResponse = response as? HTTPURLResponse + print(httpResponse) + } +}) + +dataTask.resume()`} + +
    + +### Response parameters + +For details about possible response status codes, see [Response status codes](../../response-status-code). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :-------- | :------ | :----------------------------------------------------------- | +| `data` | Object |
    • `service`
      • `hosts`
        • `primaryIP`: The IP address of the server. When you receive a response, you need to add the IP address (or list of IP addresses) from this field to the whitelist.
    | + +### Response example + + + {`{ + "data": { + "service": { + "hosts": [ + { + "primaryIP": "string" + } + ] + } + } +}`} + \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/streaming-information/_category_.json b/shared/media-gateway/reference/rest-api/endpoints/streaming-information/_category_.json new file mode 100644 index 000000000..787d03247 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/streaming-information/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 3, + "label": "Streaming information", + "collapsible": true, + "link": null +} diff --git a/shared/media-gateway/reference/rest-api/endpoints/streaming-information/force-disconnection.mdx b/shared/media-gateway/reference/rest-api/endpoints/streaming-information/force-disconnection.mdx new file mode 100644 index 000000000..18c6f7d7b --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/streaming-information/force-disconnection.mdx @@ -0,0 +1,77 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method disconnects an ongoing stream based on SID. + +### Prototype + +- Method: `DELETE` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/online-streams/:sid` + +You can combine this method with [deleting the streaming key](../streaming-key/delete-streaming-key) to implement the function of disabling the stream. Deleting the streaming key only removes it from the database. You can no longer use the streaming key, but you cannot disconnect the ongoing push. To disconnect, use one of the following methods: + +1. Call to [delete the streaming key](../streaming-key/delete-streaming-key) and then call this method to disconnect the ongoing push. + + Make sure to delete the streaming key first; otherwise, after using this API to force a disconnection, the push software will immediately reconnect. A new push session, corresponding to a new SID, will be generated, and the disconnection will fail. + +1. Call to [kick the user out of the channel](/video-calling/reference/channel-management-rest-api). This API can also force the user to disconnect. If the kicking API has been integrated, you can continue to use it to disconnect the stream. + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | +| `sid` | String | Required | The streaming session ID is the unique identifier for each initiated streaming task. It can be obtained by [querying the streaming list](query-streaming-list) or receiving the payload of the [message notification callback](../../../../develop/receive-notifications).| + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +### Request example + +```shell +curl --request DELETE \ + --url https://api.agora.io/region/v1/projects/appId/rtls/ingress/online-streams/sid \ + --header 'Accept: application/json' \ + --header 'Authorization: Basic 123' \ + --header 'X-Request-ID: ' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status" : "string" +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-information.mdx b/shared/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-information.mdx new file mode 100644 index 000000000..af40ba254 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-information.mdx @@ -0,0 +1,94 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method queries an ongoing push based on SID. + +### Prototype + +- Method: `GET` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/online-streams/:sid` + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | +| `sid` | String | Required | The streaming session ID is the unique identifier for each initiated streaming task. It can be obtained by [querying the streaming list](query-streaming-list) or receiving the payload of the [message notification callback](../../../../develop/receive-notifications).| + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +### Request example + +```shell +curl --request GET \ + --url https://api.agora.io/region/v1/projects/appId/rtls/ingress/online-streams/sid \ + --header 'Accept: application/json' \ + --header 'Authorization: Basic 123' \ + --header 'X-Request-ID: ' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | +| `data` | Object | Includes the following fields:
    • `sid`: String, a streaming session ID. A unique `sid` will be generated for each stream.
    • `channel`: String. The name of the channel associated with the streaming key.
    • `uid`: String, the user UID in the channel associated with the streaming key.
    • `url`: String, the push address in the `$domain/live/$streamkey` format.
    • `status`: String, the flow status. Possible values are the following:
      • `"Started"`: Connection has been established, waiting to stream audio and video.
      • `"Running"`: Is being streamed.
    | +| `beginAt` | String | Streaming start time in the "2024-01-01 01:01:01.001" format. | +| `bitrate` | Integer | The source stream bitrate (audio + video) of the pushed stream, in Kbps.| +| `video` | Object | Video stream parameters, returned only if the status is `"Running"`:
    • `width`: Number, video width in pixels.
    • `height`: Number, video height in pixels.
    • `fps`: Video frame rate in frames per second.
    | +| `audio` | Object | Audio stream parameters, returned only if the status is `"Running"`:
    • `channels`: Number, the number of audio channels.
    • `sampleRate`: Number, audio sampling rate in Hz.
    | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status" : "string" , + "data" : [ + { + "sid" : "string" , + "channel" : "string" , + "uid" : "string" , + "url" : "string" , + "status" : "string" , + "beginAt" : "string" , + "bitrate" : 0 , + "video" : { + "width" : 0 , + "height" : 0 , + "fps" : 0 + } , + "audio" : { + "channels" : 0 , + "sampleRate" : 0 + } + } + ] +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-list.mdx b/shared/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-list.mdx new file mode 100644 index 000000000..4c473e2d7 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/streaming-information/query-streaming-list.mdx @@ -0,0 +1,76 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method queries a streaming key information, such as the associated UID, channel name, validity period, and so on. + +### Prototype + +- Method: `GET` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/online-streams` + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +### Request example + +```shell +curl --request GET \ + --url https://api.agora.io/region/v1/projects/appId/rtls/ingress/online-streams \ + --header 'Accept: application/json' \ + --header 'Authorization: Basic 123' \ + --header 'X-Request-ID: ' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | +| `data` | Object | Includes the following fields:
    • `streamKey`: String, the queried streaming key.
    • `channel`: String. The name of the channel associated with the streaming key.
    • `uid`: String, the user UID in the channel associated with the streaming key.
    • `expiresAfter`: Integer, the validity period of the streaming key from the time of creation, in seconds.
    • `createdAt`: String, the Unix timestamp for when the streaming key was created, in seconds.
    | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status" : "success" , + "data" : { + "streamKey" : "2dfMTR****fys" , + "channel" : "shx001" , + "uid" : "1001" , + "expiresAfter" : 0 , + "createdAt" : "1686820170" + } +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/streaming-key/_category_.json b/shared/media-gateway/reference/rest-api/endpoints/streaming-key/_category_.json new file mode 100644 index 000000000..6e3e4742e --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/streaming-key/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 1, + "label": "Streaming key", + "collapsible": true, + "link": null +} diff --git a/shared/media-gateway/reference/rest-api/endpoints/streaming-key/create-streaming-key.mdx b/shared/media-gateway/reference/rest-api/endpoints/streaming-key/create-streaming-key.mdx new file mode 100644 index 000000000..aed2e0786 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/streaming-key/create-streaming-key.mdx @@ -0,0 +1,95 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method creates a streaming key. + +### Prototype + +- Method: `POST` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/streamkeys` + +Create a key before streaming to ensure that the media stream is pushed to the correct channel and under the correct host ID. + +Keep the created streaming key secure to prevent unauthorized streaming to the channel. + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the stream key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +**Request body** + +The request body consists of a JSON Object type `settings` and includes the following fields: + +| Parameter | Data type | Required/Optional | Description | +| :------------ | :-------- |:----------------- | :---------------------- | +|`channel` | String | Required | The channel name. The string length must be less than 64 bytes. The following character sets are supported (89 characters in total):
    • All lowercase English letters (a-z)
    • All uppercase English letters (AZ)
    • Numbers 0-9
    • Space
    • `!`, `#`, `$`, `%`, `&`, `(`, `)`, `+`, `-`, `:`, `;`, `<`, `=`, `.`, `>`, `?`, `@`, `[`, `]`, `^`, `_`, `{`, `}`, `\|`, `~`, `,`.
    You can leave this field empty. A random integer UID will be used to enter the channel, in the format of `"GR-xxxx"`. The specific UID value can be obtained by [querying the streaming list](../streaming-information/query-streaming-list) or [receiving notifications about events](../../../../develop/receive-notifications).| +|`uid` | String | Required | The host user UID in the channel. Can be a numeric ID or a string ID. For numeric IDs, the value range is from 1 to 232 -1, that is, 4294967295. A greater value will be recognized as a string. For string IDs, the value cannot exceed 255 bytes or be empty. The following character sets are supported (89 characters in total):
    • All lowercase English letters (a-z)
    • All uppercase English letters (AZ)
    • Numbers 0-9
    • Space
    • `!`, `#`, `$`, `%`, `&`, `(`, `)`, `+`, `-`, `:`, `;`, `<`, `=`, `.`, `>`, `?`, `@`, `[`, `]`, `^`, `_`, `{`, `}`, `\|`, `~`, `,`.
    You can leave this field empty or pass in `0`. A random integer UID will be used to enter the channel. The specific UID value can be obtained by [querying the streaming list](../streaming-information/query-streaming-list) or [receiving notifications about events](../../../../develop/receive-notifications). The `channel` and `uid` parameters cannot be empty or `0` at the same time. Examples of the entered `uid` values and the actual ID values:
    • `"123"` - integer UID, `123`
    • `"0123"` - integer UID, `123`
    • `"4294967295"` - integer UID, `4294967295`,
    • `"4294967296"` - string UID, `"4294967296"`,
    • `"123abc"` - string UID, `"123abc"`.
    | +|`expiresAfter` | Number | Required | The validity period of the created streaming key in seconds, from the time of creation. If set to `0`, the streaming key will always be valid. To ensure a successful request, do not leave this field empty or set to null.| +|`templateId` | String | Optional | The associated flow configuration template ID. For details, see [template API documentation](../flow-configuration-template/create-reset-template). Do not provide this field if you have not created a configuration template. If not provided, the default configuration will be used.| + +### Request example + +```shell +curl --location -g 'https://api.agora.io/{{region}}/v1/projects/{{appId}}/rtls/ingress/streamkeys' \ +--data '{ + "settings": { + "channel": "demo", + "uid": "100", + "expiresAfter": 3600, + "templateId": "1080p" + } +}' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | +| `data` | Object | Includes the following fields:
    • `streamKey`: String, the newly created streaming key.
    • `channel`: String. The name of the channel associated with the streaming key.
    • `uid`: String, the user UID in the channel associated with the streaming key.
    • `expiresAfter`: Integer, the validity period of the streaming key from the time of creation, in seconds.
    • `createdAt`: String, the Unix timestamp for when the streaming key was created, in seconds.
    | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status": "success" , "success", + "data"{: { + "streamKey": "2dfMTR****fys", + "channel": "shx001", + "uid": "1001", + "expiresAfter": 0, + "createdAt": "1686820170" + } +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/streaming-key/delete-streaming-key.mdx b/shared/media-gateway/reference/rest-api/endpoints/streaming-key/delete-streaming-key.mdx new file mode 100644 index 000000000..7bbee0710 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/streaming-key/delete-streaming-key.mdx @@ -0,0 +1,69 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method deletes a streaming key. + +### Prototype + +- Method: `DELETE` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/streamkeys/:streamkey` + +Call to delete unused streaming keys. After a streaming key is deleted, you can no longer use it to push streams. If the deleted streaming key is still in use, the ongoing stream is not affected. To disable the ongoing stream immediately, use the SID to [force a disconnection](../streaming-information/force-disconnection). + +This API can also be used to revoke streaming keys generated by a script. For a complete key revocation, make sure to call this API across all configured regions. + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | +|`streamkey` | String | Required | The streaming key to be deleted.| + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +### Request example + +```shell +curl --location -g --request DELETE 'https://api.agora.io/{{region}}/v1/projects/{{appId}}/rtls/ingress/streamkeys/{{streamKey}}' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status": "success" "success" +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/endpoints/streaming-key/query-streaming-key-information.mdx b/shared/media-gateway/reference/rest-api/endpoints/streaming-key/query-streaming-key-information.mdx new file mode 100644 index 000000000..07b13de8d --- /dev/null +++ b/shared/media-gateway/reference/rest-api/endpoints/streaming-key/query-streaming-key-information.mdx @@ -0,0 +1,74 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; +import CodeBlock from '@theme/CodeBlock'; + +This method queries a streaming key information, such as the associated UID, channel name, validity period, and so on. + +### Prototype + +- Method: `GET` +- Endpoint: `https://api.agora.io/:region/v1/projects/:appId/rtls/ingress/streamkeys/:streamkey` + +### Request parameters + +**Authentication** + + + +**Path parameters** + +| Parameter | Data type | Required/Optional | Description | +| :---------- | :------- |:----------------- | :---------------------- | +| `appId` | String | Required | The app ID provided by to each developer. After creating a project in , you can get an app ID. The app ID is a unique identifier for a project. | +| `region` | String | Required | Create an area for pushing the streaming key. supports creation of stream keys by region. Currently, the following regions are supported:
    • `na`: North America
    • `eu`: Europe
    • `ap`: Asia, except mainland China
    • `cn`: Mainland China
    Make sure that:
    • The `region` value is the same as for the input source stream.
    • The domain names for setting the `region` parameter and streaming are the same.
    • The `region` value is in the lowercase.
    | +| `streamkey` | String | Required | The streaming key for which you need information.| + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. After passing in this field, the server will return this field in the response header. It is recommended to assign `X-Request-ID` a value. If no value is assigned, the server will automatically generate a UUID and pass it in. | + +### Request example + +```shell +curl --location 'https://api.agora.io/ap/v1/projects/9d2498880e934632b38b0a68fa2f1622/rtls/ingress/streamkeys/:streamkey +' +``` + +### Response parameters + +**Headers** + +| Header | Data type | Description | +| :------------- | :------- |:----------------------- | +| `X-Request-ID` | String | The UUID (Universally Unique Identifier) of the request. The value is in its `X-Request-ID` header. If a request error occurs, print the value in the log to troubleshoot the problem. A `401 (Unauthorized)` response status code means that there is no such field in the response header.| + +**Response body** + +For details about possible response status codes, see [Response status codes](../../response-status-codes). + +If the status code is not `200`, the request fails. See the `message` field in the response body for the reason for this failure. + +If the status code is `200`, the request succeeds, and the response body includes the following parameters: + +| Parameter | Type | Description | +| :--------------- | :----- | :----------------------------------------------------------------- | +| `status` | String | The status of this request. `success` means the request succeeds. | +| `data` | Object | Includes the following fields:
    • `streamKey`: String, the queried streaming key.
    • `channel`: String. The name of the channel associated with the streaming key.
    • `uid`: String, the user UID in the channel associated with the streaming key.
    • `expiresAfter`: Integer, the validity period of the streaming key from the time of creation, in seconds.
    • `createdAt`: String, the Unix timestamp for when the streaming key was created, in seconds.
    | + +### Response example + +The following is a response example for a successful request: + +```json +{ + "status" : "success" , + "data" : { + "streamKey" : "2dfMTR****fys" , + "channel" : "shx001" , + "uid" : "1001" , + "expiresAfter" : 0 , + "createdAt" : "1686820170" + } +} +``` \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/limitations.mdx b/shared/media-gateway/reference/rest-api/limitations.mdx new file mode 100644 index 000000000..899ed7428 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/limitations.mdx @@ -0,0 +1,5 @@ +import Quota from '@docs/shared/media-gateway/reference/quota.mdx'; + +This pages provides the limitations applied for the service. + + diff --git a/shared/media-gateway/reference/rest-api/overview.mdx b/shared/media-gateway/reference/rest-api/overview.mdx new file mode 100644 index 000000000..5defc548c --- /dev/null +++ b/shared/media-gateway/reference/rest-api/overview.mdx @@ -0,0 +1,31 @@ +import Authorization from '@docs/shared/media-gateway/reference/rest-api/authorization.mdx'; + +## Base URL + +ALl requests are sent to `https://api.agora.io/`. + +## Authentication + + + +## RESTful API overview + + can push media streams to using standard push protocols (RTMP and SRT), and then publish them to the corresponding channels as the host. includes the following sets of APIs: + +- Streaming key API + + Before pushing streams, you need to create a streaming key to ensure that the media stream is pushed to the correct channel and under the correct host UID. This set of RESTful APIs allows you to create, query, and delete streaming keys. + +- Flow configuration template API + + When using to push streams into a channel, you can control the pre-processing of the stream with a flow configuration template. For example, enable audio or video transcoding and set transcoding parameters. You can also create a global configuration template for an app ID or a particular streaming key. This set of RESTful APIs allows you to create, query, and delete flow configuration templates. + +- Streaming information API + + This set of RESTful APIs allows you to query the list of streams being pushed under the specified app ID, including the domain name used, the streaming key, and the basic parameters of the audio and video streams (resolution, bit rate, number of channels, sampling rate, GOP, and other information). You can also forcefully disconnect the pushed stream. + +Make sure that the channel profile is set to live broadcasting, not communication. Otherwise, will fail. See [channel profile](../../overview/core-concepts#channel-profile) for details. + +To let you monitor the status of , provides the service. After activating , you can receive relevant event callbacks using [webhooks](webhooks/media-gateway-event-type). Because frequently updates the IP address of the server, you need to regularly [query its IP address](endpoints/message-notification-service/query-ip-address) and update your firewall whitelist configuration. + +In case of problems, refer to [Integration best practice](../best-practice) to check whether the settings and restrictions have been handled correctly. \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/response-status-codes.mdx b/shared/media-gateway/reference/rest-api/response-status-codes.mdx new file mode 100644 index 000000000..ebee956d5 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/response-status-codes.mdx @@ -0,0 +1,55 @@ +After sending an HTTP request, the server will return a status code. Based on this status code, you can determine whether the request was successful and the reason for the possible failure: + +- If the status code is `2XX`, the request was successful. +- If the status code is not `2XX`, the request has failed. Troubleshoot the problem based on the `message` field content in the response message body. + +This page describes the status codes, the corresponding error reasons, and possible solutions. + +## Streaming key + +| Status code | Message example | Reason | Solution | +|---|---|---|---| +| 200 OK | / | Request successful. | / | +| 400 Bad Request |
    • Invalid settings.
    • Invalid 'channel' format.
    • Streaming key exists in region:na.
    | Request parameter error. | Troubleshoot based on the specific content of the `message` field. | +| 401 Unauthorized | Invalid authentication credentials. | RESTful API authentication has failed. | Retry [HTTP basic or HMAC authentication](../restful-authentication). | +| 403 Forbidden |
    • is not enabled for this project. Contact us to enable.
    • Stream does not belong to this app ID.
    |
    • The service has not been activated.
    • The queried streaming key does not belong to the corresponding app ID.
    |
    • Contact technical support to activate the service.
    • Check if the passed in streaming key and app ID match.
    | +| 404 Not Found | Resource not found and destroyed. | The requested resource does not exist. | Check whether the passed in streaming key is correct. | +| 409 Conflict | Resource with the same name already exists. | Too many concurrent requests. | Use a back-off strategy and try again. For example, wait for 1 second before trying again for the first time, then wait for 3 seconds to try for the second time, and 6 seconds for the third. | +| 429 Too Many Requests |
    • Request rate limit exceeded.
    • Resources quota limit exceeded.
    • No available resources.
    | Internal server error. | Use a back-off strategy and try again. For example, wait for 1 second before trying again for the first time, then wait for 3 seconds to try for the second time, and 6 seconds for the third. | +| 500 Unknown | Internal error. Contact us to help fix it. | Internal server error. | Use a back-off strategy and try again. For example, wait for 1 second before trying again for the first time, then wait for 3 seconds to try for the second time, and 6 seconds for the third. | +| 503 Service Unavailable |
    • Service overload. Retry with the back-off strategy and contact us to fix it.
    • Service unavailable temporarily. Retry with the back-off strategy.
    | Internal server error. | Use a back-off strategy and try again. For example, wait for 1 second before trying again for the first time, then wait for 3 seconds to try for the second time, and 6 seconds for the third. | +| 504 Gateway Timeout | Gateway timeout. Query to check whether the player has been created, or to create another one instead. | Internal server error. | Use a backoff strategy and try again. For example, wait for 1 second before trying again for the first time, then wait for 3 seconds to try for the second time, and 6 seconds for the third. | + +## Flow configuration template + +| Status code | Message example | Reason | Solution | +|---|---|---|---| +| 200 OK | / | Request successful. | / | +| 400 Bad Request |
    • Invalid settings.
    • Invalid template ID.
    • Missing field: "transcoding.video.enabled"
    • .
    • Unsupported codec: "AV1".
    | Request parameter error. | Refer to the `message` field in the HTTP response body to troubleshoot. | +| 401 Unauthorized | Invalid authentication credentials. | RESTful API authentication has failed. | Retry [HTTP basic or HMAC authentication](../restful-authentication). | +| 403 Forbidden |
    • is not enabled for this project. Contact us to enable.
    • Too many templates have been created.
    |
    • The service has not been activated.
    • Too many flow configuration templates have been created.
    |
    • Contact technical support to activate .
    • Delete unused flow configuration templates.
    | +| 404 Not Found | Stream template not found. | The requested resource does not exist. | Check whether the passed in `templateId` is correct. | +| 429 Too Many Requests |
    • Request rate limit exceeded.
    • Resources quota limit exceeded.
    • No available resources.
    | Too many concurrent requests. | Try again with a back-off strategy. | +| 500 Unknown | Internal error. Contact us to fix it. | Internal server error. | Try again with a back-off strategy. | +| 502 Bad Gateway | Internal errors. Contact us to troubleshoot. | Internal server error. | Try again with a back-off strategy. | +| 503 Service Unavailable |
    • Service overload. Retry with the back-off strategy and contact us to fix it.
    • Service unavailable temporarily. Retry with the back-off strategy.
    | Internal server error. | Try again with a back-off strategy.| +| 504 Gateway Timeout | Gateway timeout. Query to check whether the task has been created, or to create another one instead. | Internal server error. | Try again with a back-off strategy. | + +## Information query + +| Status code | Message example | Reason | Solution | +|---|---|---|---| +| 200 OK | / | Request successful. | / | +| 400 Bad Request |
    • Invalid body.
    • Invalid app ID.
    • SID is missing.
    | Request parameter error. | Refer to the `message` field in the HTTP response body to troubleshoot. | +| 401 Unauthorized | Invalid authentication credentials. | RESTful API authentication has failed. | Retry [HTTP basic or HMAC authentication](../restful-authentication). | +| 403 Forbidden | is not enabled for this project. Contact us to enable. | The service has not been activated. | Contact technical support to activate . | +| 404 Not Found | / | The requested resource does not exist. | Please check whether the passed-in SID is correct. | +| 429 Too Many Requests |
    • Request rate limit exceeded.
    • Resources quota limit exceeded.
    • No available resources.
    | Too many concurrent requests. | Try again with a back-off strategy. | +| 500 Unknown | Some internal error happened. Contact us to help fix it. | Internal server error. | Try again with a back-off strategy. | +| 502 Bad gateway | Internal errors. Contact us for troubleshooting. | Internal server error. | Try again with a back-off strategy. | +| 503 Service Unavailable |
    • Service overload. Retry with a back-off strategy, and contact us to help fix it.
    • Service unavailable temporarily. Retry with back off strategy.
    | Internal server error. | Try again with a back-off strategy. | +| 504 Gateway Timeout | Gateway timeout. Query to check whether the task has been created, or to create another one instead. | Internal server error. | Try again with a backoff strategy.| + + + + diff --git a/shared/media-gateway/reference/rest-api/webhooks/_category_.json b/shared/media-gateway/reference/rest-api/webhooks/_category_.json new file mode 100644 index 000000000..c7ee0d362 --- /dev/null +++ b/shared/media-gateway/reference/rest-api/webhooks/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 3, + "label": "Webhooks", + "collapsible": true, + "link": null +} \ No newline at end of file diff --git a/shared/media-gateway/reference/rest-api/webhooks/media-gateway-event-type.mdx b/shared/media-gateway/reference/rest-api/webhooks/media-gateway-event-type.mdx new file mode 100644 index 000000000..3f8aa957a --- /dev/null +++ b/shared/media-gateway/reference/rest-api/webhooks/media-gateway-event-type.mdx @@ -0,0 +1,156 @@ +After enabling the service, the server will send a channel event notification callback to your server using the HTTPS POST request method. When the value of the `product_id` parameter in the callback request body is `10`, it means that the event is returned. + +This page introduces the types and descriptions for all events returned in the channel event callback. + +### 1 live_stream_connected + +The gateway has received the RTMP or SRT stream and successfully entered the channel. + +Payload example: + +```json +{ + "sid": "55df7402-8778-11ee-92ed-07ec2e86c928", + "region": "na", + "streamKey": "7B***Qbs", + "rtcInfo": { + "channel": "123", + "uid": "1234" + }, + "beginAt": "2023-11-21T02:27:31Z" +} +``` + +The payload contains the following fields: + +| Field | Data type | Description | +|-------------|-----------|-------------| +| `sid` | String | The unique ID of each streaming session. | +| `region` | String | The server area that has received the pushed stream. | +| `streamKey` | String | The used streaming key. | +| `rtcInfo` | Object | RTC information:
    • `channel`: The channel name.
    • `uid`: The host UID. Supports integer and string data types.
    | +| `beginAt` | String | The start time of the streaming in the `RFC3339` format. | + +This event is usually followed by a corresponding `live_stream_disconnected` event. + +### 2 live_stream_dicconnected + +The gateway was disconnected (actively or passively) and left the channel. + +Payload example: + +```json +{ + "sid": "55df7402-8778-11ee-92ed-07ec2e86c928", + "region": "na", + "streamKey": "7B***Qbs", + "rtcInfo": { + "channel": "123", + "uid": "1234" + }, + "beginAt": "2023-11-21T02:27:31Z", + "endAt": "2023-11-21T03:27:31Z" +} +``` + +The payload contains the following fields: + +| Field | Data type | Description | +|-------------|-----------|-------------| +| `sid` | String | The unique ID of each streaming session. | +| `region` | String | The server area that has received the pushed stream. | +| `streamKey` | String | The used streaming key. | +| `rtcInfo` | Object | RTC information:
    • `channel`: The channel name.
    • `uid`: The host UID. Supports integer and string data types.
    | +| `beginAt` | String | The start time of the streaming in the `RFC3339` format. | +| `endAt` | String | The end time of the streaming in the `RFC3339` format. | + +### 3 live_stream_aborted + +The gateway has received an RTMP or SRT stream but terminated it for some reason. + +Payload example: + +```json +{ + "sid": "55df7402-8778-11ee-92ed-07ec2e86c928", + "region": "na", + "streamKey": "7B***Qbs", + "rtcInfo": { + "channel": "123", + "uid": "1234" + }, + "beginAt": "2023-11-21T02:27:31Z", + "errorCode": 100, + "reason": "invalid" +} +``` + +The payload contains the following fields: + +| Field | Data type | Description | +|-------------|-----------|-------------| +| `sid` | String | The unique ID of each streaming session. | +| `region` | String | The server area that has received the pushed stream. | +| `streamKey` | String | The used streaming key. | +| `rtcInfo` | Object | RTC information:
    • `channel`: The channel name.
    • `uid`: The host UID. Supports integer and string data types.
    | +| `beginAt` | String | The start time of the streaming in the `RFC3339` format. | +| `errorCode` | Number | The stream termination error code. | +| `reason` | String | The error message. | + +This event may be sent alone or between the `connected` and `disconnected` events. + +The possible values for the `errorCode` field include the following: + +| Value | Description | Recommended actions | +|------ | ----------- | ------------------- | +| `1` | Illegal `streamKey`. For example, `channelName` is empty or contains illegal characters. | Check the `streamKey` format, especially for locally generated ones. | +| `2` | Invalid `streamKey` (expired or deleted) | Create a new `streamKey` and try again. | +| `3` | No permission to use this `streamKey`. For example, the customer-defined domain name and `streamKey` under the associated app ID do not match. | Check whether the `streamKey` matches the domain name used for the push.| +| `4` | Number of concurrent streams exceeds the limit. | Wait and retry. | +| `5` | Conflict detected, for example, pushing to the same channel and at the same. | If the streams are not being pushed at the same time, try again 5-10 seconds later. | +| `6` | The stream attribute exceeds the limit (currently applies to bitrate only). | Check the streaming software configuration and lower the target bitrate. | +| `7` | Streaming without any audio or video data for more than 10 seconds | Check whether the last push exited abnormally, and then try again. | +| `8` | Failed to join channel | The `reason` field will provide the specific error reason, for example: `"connect to rtc failed, reason:$N"`. Refer to the API documentation for details. | +| `9` | Disconnected from the main network. Specific reasons need to be investigated by contacting technical support. | Try again several times. If you still have problems, [contact technical support](mailto:support@agora.io) to confirm whether the app certificate provided during activation is valid. | +| `10` | Unknown internal service error. Specific reasons need to be investigated by contacting technical support. | Try again a few times. If you still have problems, [contact technical support](mailto:support@agora.io). | + +### 4 live_profile_updated + +Stream properties have been updated. For example, the first audio or video frame has been received or the audio or video profile has changed. + +Payload example: + +```json +{ + "sid": "55df7402-8778-11ee-92ed-07ec2e86c928", + "region": "na", + "streamKey": "7B***Qbs", + "rtcInfo": { + "channel": "123", + "uid": "1234" + }, + "videoProfile": { + "codec": "H.264", + "width": 1920, + "height": 1080 + }, + "audioProfile": { + "sampleRate": 48000, + "channels": 2 + }, + "beginAt": "2023-11-21T02:27:31Z" +} +``` + +The payload contains the following fields: + +| Field | Data type | Description | +|-------------|-----------|-------------| +| `sid` | String | The unique ID of each streaming session. | +| `region` | String | The server area that has received the pushed stream. | +| `streamKey` | String | The used streaming key. | +| `rtcInfo` | Object | RTC information:
    • `channel`: The channel name.
    • `uid`: The host UID. Supports integer and string data types.
    | +| `videoProfile` | Object | Video properties. Not applicable for audio-only streams.
    • `codec`: Video codec format, such as `"H.264"`, `"H.265"`, `"VP8"`, `"VP9"`, `"AV1"`, and so on.
    • `width`: Video width.
    • `height`: Video height.
    | +| `audioProfile` | Object | Audio properties:
    • `sampleRate`: The sampling rate in Hz.
    • `channels`: The number of channels.
    | +| `beginAt` | String | The start time of the streaming in the `RFC3339` format. | + diff --git a/shared/notification-center-service/_notification_center_service.mdx b/shared/notification-center-service/_notification_center_service.mdx index 85edb84bf..94ac87a66 100644 --- a/shared/notification-center-service/_notification_center_service.mdx +++ b/shared/notification-center-service/_notification_center_service.mdx @@ -12,7 +12,9 @@ A webhook is a user-defined callback over HTTP. You use webhooks to notify your Using you subscribe to specific events for your project and tell the URL of the webhooks you have configured to receive these events. sends notifications of your events to your webhooks every time they occur. Your server authenticates the notification and returns `200 Ok` to confirm reception. You use the information in the JSON payload of each notification to give the best user experience to your users. + The following figure illustrates the workflow when is enabled for the specific events you subscribe to: + ![rtc-channel](/images/shared/ncs-worflow.svg) @@ -30,7 +32,7 @@ The following figure illustrates the workflow when is enable ![media-push](/images/notification-center-service/ncs-media-push.svg) -1. A user commits an action that creates an event. For example, creates a channel. +1. A user commits an action that creates an event. 1. sends an HTTPS POST request to your webhook. 1. Your server validates the request signature, then sends a response to within 10 seconds. The response body must be in JSON. diff --git a/shared/notification-center-service/redundant-notifications.mdx b/shared/notification-center-service/redundant-notifications.mdx index 44663342a..0126af5e0 100644 --- a/shared/notification-center-service/redundant-notifications.mdx +++ b/shared/notification-center-service/redundant-notifications.mdx @@ -19,7 +19,7 @@ Refer to the following steps to use the `clientSeq` field to enable your server 1. Enable Agora , and subscribe to RTC channel event callbacks. Best practice is to subscribe to the following event types according to your scenario: * In the `LIVE_BROADCASTING` profile: `103`, `104`, `105`, `106`, `111`, and `112`. - * In the `COMMUNICATION` profile: `107`, `108`, `111`, and `112`. + * In the `COMMUNICATION` profile: `103`, `104`, `111`, and `112`. 1. Use the channel event callbacks to get the latest status updates about the following at your server: diff --git a/shared/signaling/cloud-proxy/index.mdx b/shared/signaling/cloud-proxy/index.mdx index d0960c8a8..76cc06d9f 100644 --- a/shared/signaling/cloud-proxy/index.mdx +++ b/shared/signaling/cloud-proxy/index.mdx @@ -4,6 +4,12 @@ import ProjectImplement from '@docs/shared/signaling/cloud-proxy/project-impleme import ProjectTest from '@docs/shared/signaling/cloud-proxy/project-test/index.mdx'; import Reference from '@docs/shared/signaling/cloud-proxy/reference/index.mdx'; + + +Cloud Proxy is not available for this platform yet. + + + You use a proxy connection to ensure reliable connectivity for your users when they connect from an environment with a restricted network. ## Understand the tech @@ -39,7 +45,7 @@ The steps you need to implement in your are: To follow this page, you must: -- Setup the [ reference app](/en/signaling/develop/get-started-sdk#project-setup) +- Set up the [ reference app](/en/signaling/develop/get-started-sdk#project-setup) - Contact support@agora.io and enable for your project. @@ -72,3 +78,4 @@ This section contains information that completes the information in this page, o product. + \ No newline at end of file diff --git a/shared/signaling/geofencing/project-test/index.mdx b/shared/signaling/geofencing/project-test/index.mdx index 9764f25ce..014fb7eec 100644 --- a/shared/signaling/geofencing/project-test/index.mdx +++ b/shared/signaling/geofencing/project-test/index.mdx @@ -23,4 +23,6 @@ To test the geofencing functionality: * Whitelist certain domains * Allow all IP addresses - * Open the firewall ports defined in IP addresses for Cloud Proxy. \ No newline at end of file + + * Open the firewall ports defined in IP addresses for Cloud Proxy. + \ No newline at end of file diff --git a/shared/signaling/reference/api-ref/android/_enumv-en.mdx b/shared/signaling/reference/api-ref/android/_enumv-en.mdx index 823d12ba8..c14fc94d3 100644 --- a/shared/signaling/reference/api-ref/android/_enumv-en.mdx +++ b/shared/signaling/reference/api-ref/android/_enumv-en.mdx @@ -215,6 +215,7 @@ import * as config from '../shared/_configuration.mdx' | :----------: | ---------------------------------------------------------- | | {enumv.proxytypenone[props.ag_platform]} | `0`: Do not enable the proxy. | | {enumv.proxytypehttp[props.ag_platform]} | `1`: Enable the proxy for the HTTP protocol. | +| {enumv.proxytypetcp[props.ag_platform]} | `2`: Enable cloud proxy for the TCP protocol. | #### {enumv.storageeventtype[props.ag_platform]} diff --git a/shared/signaling/reference/api-ref/ios/_enumv-en.mdx b/shared/signaling/reference/api-ref/ios/_enumv-en.mdx index 823d12ba8..c14fc94d3 100644 --- a/shared/signaling/reference/api-ref/ios/_enumv-en.mdx +++ b/shared/signaling/reference/api-ref/ios/_enumv-en.mdx @@ -215,6 +215,7 @@ import * as config from '../shared/_configuration.mdx' | :----------: | ---------------------------------------------------------- | | {enumv.proxytypenone[props.ag_platform]} | `0`: Do not enable the proxy. | | {enumv.proxytypehttp[props.ag_platform]} | `1`: Enable the proxy for the HTTP protocol. | +| {enumv.proxytypetcp[props.ag_platform]} | `2`: Enable cloud proxy for the TCP protocol. | #### {enumv.storageeventtype[props.ag_platform]} diff --git a/shared/signaling/reference/api-ref/linux-cpp/_enumv-en.mdx b/shared/signaling/reference/api-ref/linux-cpp/_enumv-en.mdx index 93e895207..5dfc141d4 100644 --- a/shared/signaling/reference/api-ref/linux-cpp/_enumv-en.mdx +++ b/shared/signaling/reference/api-ref/linux-cpp/_enumv-en.mdx @@ -213,6 +213,7 @@ import * as config from '../shared/_configuration.mdx' | :----------: | ---------------------------------------------------------- | | {enumv.proxytypenone[props.ag_platform]} | `0`: Do not enable the proxy. | | {enumv.proxytypehttp[props.ag_platform]} | `1`: Enable the proxy for the HTTP protocol. | +| {enumv.proxytypetcp[props.ag_platform]} | `2`: Enable cloud proxy for the TCP protocol. | #### {enumv.storageeventtype[props.ag_platform]} diff --git a/shared/signaling/reference/api-ref/shared/_enumv.mdx b/shared/signaling/reference/api-ref/shared/_enumv.mdx index f5f57b116..ad74d63db 100644 --- a/shared/signaling/reference/api-ref/shared/_enumv.mdx +++ b/shared/signaling/reference/api-ref/shared/_enumv.mdx @@ -238,6 +238,14 @@ export const proxytypehttp = { unity: "HTTP", cpp: "RTM_PROXY_TYPE_HTTP", }; +export const proxytypetcp = { + android: "CLOUD_TCP", + ios: "AgoraRtmProxyTypeCloudTcp", + javascript: "", + linux: "", + unity: "", + cpp: "RTM_PROXY_TYPE_CLOUD_TCP", +}; export const encryptionmode = { android: "RtmEncryptionMode", ios: "AgoraRtmEncryptionMode", diff --git a/shared/signaling/reference/api-ref/web/_configuration-en.javascript.mdx b/shared/signaling/reference/api-ref/web/_configuration-en.javascript.mdx index ac8c02324..8fc2b8792 100644 --- a/shared/signaling/reference/api-ref/web/_configuration-en.javascript.mdx +++ b/shared/signaling/reference/api-ref/web/_configuration-en.javascript.mdx @@ -52,10 +52,7 @@ class RTM( ```javascript const { RTM } = AgoraRTM; -const rtm = new RTM( - appId : "myAppId", - userId : "Tony" -); +const rtm = new RTM("yourAppId", "Tony"); ``` @@ -77,7 +74,7 @@ You can create a {config.rtm[props.ag_platform]} instance as follow const { RTMConfig } = AgoraRTM; ``` -| Property | Type | Required | Default | 描述 | +| Property | Type | Required | Default | Description | | :---------------: | :--------: | :------: | :-----: | ---------------------------------------- | | `token` | string | Optional | - | A dynamic key, usually generated by a token server. | | `encryptionMode` | string | Optional | - | Encryption mode for end-to-end messages. If you do not set this property or set it as {enumv.encryptionmodenone[props.ag_platform]}, end-to-end encryption is disabled. For details, see Encryption Mode. | @@ -87,8 +84,7 @@ const { RTMConfig } = AgoraRTM; | `presenceTimeout` | number | optional | `300` | Presence timeout in seconds, and the value range is [10,300]. | | `logUpload` | boolean | Optional | `false` | Whether to upload logs to the server:
    • true: Enable log upload
    • false: Disable log upload.
    | | `logLevel` | string | Optional | - | Set the output level of SDK log. For details, see log output level. | -| `cloudProxy` | boolean | Optional | `false` | Whether to enable the cloud proxy:
    • true: Enable.
    • false: Disable.
    | - +| `cloudProxy` | boolean | Optional | `false` | Whether to enable the cloud proxy:
    • true: Enable.
    • false: Disable.
    Note: This feature applys to the message channel only. | #### Basic Usage ```js @@ -104,7 +100,7 @@ const rtmConfig = { cloudProxy : false, useStringUserId : false }; -const rtm = new RTM( "myAppId", "Tony", rtmConfig); +const rtm = new RTM( "yourAppId", "Tony", rtmConfig); ``` ### Event Listeners @@ -134,7 +130,7 @@ rtm.addEventListener("message", event => { const channelType = event.channelType; // The channel type. Should be "STREAM" or "MESSAGE" . const channelName = event.channelName; // The channel this message comes from const topic = event.topicName; // The Topic this message comes from, it is valid when the channelType is "STREAM". - const messageType = event.messageType; // The message type. Should be "sting" or "binary" . + const messageType = event.messageType; // The message type. Should be "STRING" or "BINARY" . const customType = event.customType; // User defined type const publisher = event.publisher; // Message publisher const message = event.message; // Message payload diff --git a/shared/signaling/release-notes/android.mdx b/shared/signaling/release-notes/android.mdx index 5ed79fdc8..560b53404 100644 --- a/shared/signaling/release-notes/android.mdx +++ b/shared/signaling/release-notes/android.mdx @@ -10,6 +10,27 @@ import * as presence from '@docs/shared/signaling/reference/api-ref/shared/_pres import * as storage from '@docs/shared/signaling/reference/api-ref/shared/_storage.mdx' import * as lock from '@docs/shared/signaling/reference/api-ref/shared/_lock.mdx' +### v2.1.12 + +v2.1.12 was released on July 2, 2024. + +#### Improvements + +This release includes the following improvements: + +- For data synchronization errors caused by network issues, this release introduces a user logout mechanism, which ensures that the SDK automatically logs out of the Signaling system. +- Unsubscribing from a message channel during network disconnection will no longer return an error. + +#### Fixed issues + +This release fixed the following issues: + +- During a disconnection with the Signaling system under poor network conditions, the user experienced errors when unsubscribing from a message channel. +- Under poor network conditions, the user occasionally failed to receive callbacks after a successful login. +- After reconnecting from a disconnection, the user occasionally could not receive the {config.onstorageevent[props .ag_platform]} event notification. +- After reconnecting from a disconnection, the SDK occasionally failed to restore subscription relationships in the stream channel. +- Occasional failure to receive topic messages from web clients. + ### v2.1.11 v2.1.11 was released on May 13, 2024. diff --git a/shared/signaling/release-notes/ios.mdx b/shared/signaling/release-notes/ios.mdx index 15eb5cd89..259619798 100644 --- a/shared/signaling/release-notes/ios.mdx +++ b/shared/signaling/release-notes/ios.mdx @@ -9,6 +9,27 @@ import * as presence from '@docs/shared/signaling/reference/api-ref/shared/_pres import * as storage from '@docs/shared/signaling/reference/api-ref/shared/_storage.mdx' import * as lock from '@docs/shared/signaling/reference/api-ref/shared/_lock.mdx' +### v2.1.12 + +v2.1.12 was released on July 2, 2024. + +#### Improvements + +This release includes the following improvements: + +- For data synchronization errors caused by network issues, this release introduces a user logout mechanism, which ensures that the SDK automatically logs out of the Signaling system. +- Unsubscribing from a message channel during network disconnection will no longer return an error. + +#### Fixed issues + +This release fixed the following issues: + +- During a disconnection with the Signaling system under poor network conditions, the user experienced errors when unsubscribing from a message channel. +- Under poor network conditions, the user occasionally failed to receive callbacks after a successful login. +- After reconnecting from a disconnection, the user occasionally could not receive the {config.onstorageevent[props.ag_platform]} event notification. +- After reconnecting from a disconnection, the SDK occasionally failed to restore subscription relationships in the stream channel. +- Occasional failure to receive topic messages from web clients. + ### v2.1.11 v2.1.11 was released on May 13, 2024. diff --git a/shared/signaling/release-notes/linux-cpp.mdx b/shared/signaling/release-notes/linux-cpp.mdx index 2db95463b..ea9d84194 100644 --- a/shared/signaling/release-notes/linux-cpp.mdx +++ b/shared/signaling/release-notes/linux-cpp.mdx @@ -10,6 +10,28 @@ import * as lock from '@docs/shared/signaling/reference/api-ref/shared/_lock.mdx +### v2.1.12 + +v2.1.12 was released on July 2, 2024. + +#### Improvements + +This release includes the following improvements: + +- For data synchronization errors caused by network issues, this release introduces a user logout mechanism, which ensures that the SDK automatically logs out of the Signaling system. +- Unsubscribing from a message channel during network disconnection will no longer return an error. + +#### Fixed issues + +This release fixed the following issues: + +- During a disconnection with the Signaling system under poor network conditions, the user experienced errors when unsubscribing from a message channel. +- Under poor network conditions, the user occasionally failed to receive callbacks after a successful login. +- After reconnecting from a disconnection, the user occasionally could not receive the {config.onstorageevent[props.ag_platform]} event notification. +- After reconnecting from a disconnection, the SDK occasionally failed to restore subscription relationships in the stream channel. +- Occasional failure to receive topic messages from web clients. + + ### v2.1.11 v2.1.11 was released on May 13, 2024. diff --git a/shared/signaling/release-notes/web.mdx b/shared/signaling/release-notes/web.mdx index 3eda18e33..ae60da190 100644 --- a/shared/signaling/release-notes/web.mdx +++ b/shared/signaling/release-notes/web.mdx @@ -10,6 +10,25 @@ import * as lock from '@docs/shared/signaling/reference/api-ref/shared/_lock.mdx +### v2.1.10 + +v2.1.10 was released on July 2, 2024. + +#### Improvements + +This release improves the error code prompt for failed `login` method calls. For example, when you enable token authentication but use an app ID for initialization, the `RTM_ERROR_INVALID_TOKEN (-10005)` error code is returned during login. + +#### Fixed issues + +This release addresses the following issues: + +- In scenarios involving frequent setting and retrieving of locks, the user experienced occasional inaccuracies in the `lock` event notification. +- After reconnecting from a disconnection, the SDK occasionally failed to initialize the presence service when calling the `subscribe` method. +- Occasional message reception failure in apps developed using the Vite framework. +- After joining a channel and reconnecting from a disconnection, the user failed to receive the `lock` and `storage` event notifications. +- Occasional duplicate receipt of the `storage` event notifications with the `UPDATE` type when updating the user metadata. +- Occasional duplicate receipt of the `lock` event notifications with the `REMOVED` type when removing locks. + ### v2.1.9 v2.1.9 was released on March 12, 2024. diff --git a/shared/variables/global.js b/shared/variables/global.js index d01fce61d..cfea30570 100644 --- a/shared/variables/global.js +++ b/shared/variables/global.js @@ -165,6 +165,8 @@ export const ACC = 'Acceleration'; export const ACCM = 'Media Accelerator'; export const ACCG = 'Global Accelerator'; +export const MG = 'Media Gateway'; + export const TEMPL = 'Templates'; export const RTEE = 'Extensions'; diff --git a/shared/variables/product.js b/shared/variables/product.js index a16379ade..9848329a7 100644 --- a/shared/variables/product.js +++ b/shared/variables/product.js @@ -97,6 +97,13 @@ const data = { PRODUCT: 'Media Push' }, + 'media-gateway': { + NAME: 'Media Gateway', + PATH: 'media-gateway', + SDK: 'Media Gateway', + PRODUCT: 'Media Gateway' + }, + 'agora-chat': { NAME: 'Chat', PATH: 'agora-chat', diff --git a/shared/video-sdk/get-started/get-started-sdk/index.mdx b/shared/video-sdk/get-started/get-started-sdk/index.mdx index 491d2e942..6b42716f2 100644 --- a/shared/video-sdk/get-started/get-started-sdk/index.mdx +++ b/shared/video-sdk/get-started/get-started-sdk/index.mdx @@ -55,11 +55,13 @@ To start a session, implement the following steps in your : Please refer to [Agora account management](../get-started/manage-agora-account) for details. ## Set up your project + This section shows you how to set up a new project and integrate the . ## Implement + This section guides you through the implementation of basic real-time audio and video interaction in your . diff --git a/shared/video-sdk/get-started/get-started-sdk/project-implementation/android.mdx b/shared/video-sdk/get-started/get-started-sdk/project-implementation/android.mdx index a950b545a..0a637c100 100644 --- a/shared/video-sdk/get-started/get-started-sdk/project-implementation/android.mdx +++ b/shared/video-sdk/get-started/get-started-sdk/project-implementation/android.mdx @@ -18,25 +18,28 @@ To use the sample code, copy the following lines into the `/app/src/main/java/co -{`import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; - +{` import android.Manifest; import android.content.pm.PackageManager; +import android.os.Bundle; import android.view.SurfaceView; import android.widget.FrameLayout; +import android.widget.Toast; -import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import io.agora.rtc2.ChannelMediaOptions; import io.agora.rtc2.Constants; import io.agora.rtc2.IRtcEngineEventHandler; import io.agora.rtc2.RtcEngine; import io.agora.rtc2.RtcEngineConfig; import io.agora.rtc2.video.VideoCanvas; -import io.agora.rtc2.ChannelMediaOptions; public class MainActivity extends AppCompatActivity { - // Fill in the app ID from Agora Console + // Fill in the App ID obtained from the Agora Console private String appId = ""; // Fill in the channel name private String channelName = ""; @@ -46,17 +49,33 @@ public class MainActivity extends AppCompatActivity { private RtcEngine mRtcEngine; private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() { + // Callback when successfully joining the channel + @Override + public void onJoinChannelSuccess(String channel, int uid, int elapsed) { + super.onJoinChannelSuccess(channel, uid, elapsed); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "Join channel success", Toast.LENGTH_SHORT).show(); + }); + } + + // Callback when a remote user or host joins the current channel @Override - // Monitor remote users in the channel and obtain their uid public void onUserJoined(int uid, int elapsed) { - runOnUiThread(new Runnable() { - @Override - public void run() { - // After obtaining uid, set up the remote video view - setupRemoteVideo(uid); - } + runOnUiThread(() -> { + // When a remote user joins the channel, display the remote video stream for the specified uid + setupRemoteVideo(uid); }); } + + // Callback when a remote user or host leaves the current channel + @Override + public void onUserOffline(int uid, int reason) { + super.onUserOffline(uid, reason); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "User offline: " + uid, Toast.LENGTH_SHORT).show(); + }); + } + }; private void initializeAndJoinChannel() { @@ -91,8 +110,8 @@ public class MainActivity extends AppCompatActivity { // In the video calling scenario, set the channel profile to CHANNEL_PROFILE_COMMUNICATION options.channelProfile = Constants.CHANNEL_PROFILE_COMMUNICATION; - // Use the temporary token to join the channel - // Specify the user ID yourself and ensure it is unique within the channel + // Join the channel using a temporary token and channel name, setting uid to 0 means the engine will randomly generate a username + // The onJoinChannelSuccess callback will be triggered upon success mRtcEngine.joinChannel(token, channelName, 0, options); } @@ -135,6 +154,15 @@ public class MainActivity extends AppCompatActivity { return true; } + // System permission request callback + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (checkPermissions()) { + initializeAndJoinChannel(); + } + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -147,6 +175,15 @@ public class MainActivity extends AppCompatActivity { } } + // System permission request callback + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (checkPermissions()) { + initializeAndJoinChannel(); + } + } + @Override protected void onDestroy() { super.onDestroy(); @@ -161,22 +198,24 @@ public class MainActivity extends AppCompatActivity { -{`import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; - -import android.Manifest; +{`import android.Manifest; import android.content.pm.PackageManager; +import android.os.Bundle; import android.view.SurfaceView; import android.widget.FrameLayout; +import android.widget.Toast; -import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import io.agora.rtc2.ChannelMediaOptions; import io.agora.rtc2.Constants; import io.agora.rtc2.IRtcEngineEventHandler; import io.agora.rtc2.RtcEngine; import io.agora.rtc2.RtcEngineConfig; import io.agora.rtc2.video.VideoCanvas; -import io.agora.rtc2.ChannelMediaOptions; public class MainActivity extends AppCompatActivity { // Fill in the app ID from Agora Console @@ -189,15 +228,30 @@ public class MainActivity extends AppCompatActivity { private RtcEngine mRtcEngine; private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() { + // Callback when successfully joining the channel + @Override + public void onJoinChannelSuccess(String channel, int uid, int elapsed) { + super.onJoinChannelSuccess(channel, uid, elapsed); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "Join channel success", Toast.LENGTH_SHORT).show(); + }); + } + + // Callback when a remote user or host joins the current channel @Override - // Monitor remote users in the channel and obtain their uid public void onUserJoined(int uid, int elapsed) { - runOnUiThread(new Runnable() { - @Override - public void run() { - // After obtaining uid, set up the remote video view - setupRemoteVideo(uid); - } + runOnUiThread(() -> { + // When a remote user joins the channel, display the remote video stream for the specified uid + setupRemoteVideo(uid); + }); + } + + // Callback when a remote user or host leaves the current channel + @Override + public void onUserOffline(int uid, int reason) { + super.onUserOffline(uid, reason); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "User offline: " + uid, Toast.LENGTH_SHORT).show(); }); } }; @@ -280,6 +334,15 @@ public class MainActivity extends AppCompatActivity { return true; } + // System permission request callback + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (checkPermissions()) { + initializeAndJoinChannel(); + } + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -306,22 +369,24 @@ public class MainActivity extends AppCompatActivity { -{`import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; - -import android.Manifest; +{`import android.Manifest; import android.content.pm.PackageManager; +import android.os.Bundle; import android.view.SurfaceView; import android.widget.FrameLayout; +import android.widget.Toast; -import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import io.agora.rtc2.ChannelMediaOptions; import io.agora.rtc2.Constants; import io.agora.rtc2.IRtcEngineEventHandler; import io.agora.rtc2.RtcEngine; import io.agora.rtc2.RtcEngineConfig; import io.agora.rtc2.video.VideoCanvas; -import io.agora.rtc2.ChannelMediaOptions; public class MainActivity extends AppCompatActivity { // Fill in the app ID from Agora Console @@ -334,15 +399,30 @@ public class MainActivity extends AppCompatActivity { private RtcEngine mRtcEngine; private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() { + // Callback when successfully joining the channel + @Override + public void onJoinChannelSuccess(String channel, int uid, int elapsed) { + super.onJoinChannelSuccess(channel, uid, elapsed); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "Join channel success", Toast.LENGTH_SHORT).show(); + }); + } + + // Callback when a remote user or host joins the current channel @Override - // Monitor remote users in the channel and obtain their uid public void onUserJoined(int uid, int elapsed) { - runOnUiThread(new Runnable() { - @Override - public void run() { - // After obtaining uid, set up the remote video view - setupRemoteVideo(uid); - } + runOnUiThread(() -> { + // When a remote user joins the channel, display the remote video stream for the specified uid + setupRemoteVideo(uid); + }); + } + + // Callback when a remote user or host leaves the current channel + @Override + public void onUserOffline(int uid, int reason) { + super.onUserOffline(uid, reason); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "User offline: " + uid, Toast.LENGTH_SHORT).show(); }); } }; @@ -425,6 +505,15 @@ public class MainActivity extends AppCompatActivity { return true; } + // System permission request callback + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (checkPermissions()) { + initializeAndJoinChannel(); + } + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -456,19 +545,22 @@ public class MainActivity extends AppCompatActivity { Complete sample code for real-time -{`import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; - +{` import android.Manifest; import android.content.pm.PackageManager; - import android.os.Bundle; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import io.agora.rtc2.ChannelMediaOptions; import io.agora.rtc2.Constants; import io.agora.rtc2.IRtcEngineEventHandler; import io.agora.rtc2.RtcEngine; import io.agora.rtc2.RtcEngineConfig; -import io.agora.rtc2.ChannelMediaOptions; public class MainActivity extends AppCompatActivity { @@ -484,9 +576,25 @@ public class MainActivity extends AppCompatActivity { private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() { @Override - // Listen for remote hosts in the channel to obtain the UID information of the hosts + public void onJoinChannelSuccess(String channel, int uid, int elapsed) { + super.onJoinChannelSuccess(channel, uid, elapsed); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "Join channel success", Toast.LENGTH_SHORT).show(); + }); + } + @Override public void onUserJoined(int uid, int elapsed) { + super.onUserJoined(uid, elapsed); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "User joined: " + uid, Toast.LENGTH_SHORT).show(); + }); } + @Override + public void onUserOffline(int uid, int reason) { + super.onUserOffline(uid, reason); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "User offline: " + uid, Toast.LENGTH_SHORT).show(); + }); }; private void initializeAndJoinChannel() { @@ -504,12 +612,13 @@ public class MainActivity extends AppCompatActivity { // Create a ChannelMediaOptions object and configure it ChannelMediaOptions options = new ChannelMediaOptions(); - // Set the channel profile to BROADCASTING (live broadcasting scenario) - options.channelProfile = Constants.CHANNEL_PROFILE_COMMUNICATION; // Set the user role to BROADCASTER (host) or AUDIENCE (audience) options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER; + // Set the channel profile to BROADCASTING (live broadcasting scenario) + options.channelProfile = Constants.CHANNEL_PROFILE_COMMUNICATION; - // Join the channel using a temporary Token, specify the user ID, and ensure its uniqueness within the channel + // Join the channel using a temporary token and channel name, setting uid to 0 means the engine will randomly generate a username + // The onJoinChannelSuccess callback will be triggered upon success mRtcEngine.joinChannel(token, channelName, 0, options); } @@ -553,6 +662,14 @@ public class MainActivity extends AppCompatActivity { } } + // System permission request callback + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (checkPermissions()) { + initializeAndJoinChannel(); + } + } @Override protected void onDestroy() { @@ -729,10 +846,33 @@ mRtcEngine = RtcEngine.create(config); private RtcEngine mRtcEngine; private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() { - @Override - // Listen for remote hosts within the channel and obtain their UID information - public void onUserJoined(int uid, int elapsed) { - } + // Callback when successfully joining the channel + @Override + public void onJoinChannelSuccess(String channel, int uid, int elapsed) { + super.onJoinChannelSuccess(channel, uid, elapsed); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "Join channel success", Toast.LENGTH_SHORT).show(); + }); + } + + // Callback when a remote user or host joins the current channel + @Override + // Listen for remote hosts in the channel to get the host's uid information + public void onUserJoined(int uid, int elapsed) { + super.onUserJoined(uid, elapsed); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "User joined: " + uid, Toast.LENGTH_SHORT).show(); + }); + } + + // Callback when a remote user or host leaves the current channel + @Override + public void onUserOffline(int uid, int reason) { + super.onUserOffline(uid, reason); + runOnUiThread(() -> { + Toast.makeText(MainActivity.this, "User offline: " + uid, Toast.LENGTH_SHORT).show(); + }); + } }; // Create an RtcEngineConfig object and configure it diff --git a/shared/video-sdk/get-started/get-started-sdk/project-implementation/unity.mdx b/shared/video-sdk/get-started/get-started-sdk/project-implementation/unity.mdx index 6d9e1bf89..4fbe7349f 100644 --- a/shared/video-sdk/get-started/get-started-sdk/project-implementation/unity.mdx +++ b/shared/video-sdk/get-started/get-started-sdk/project-implementation/unity.mdx @@ -1,3 +1,7 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + The following figure illustrates the essential steps: @@ -15,14 +19,17 @@ This section shows you how to import the libraries required to implement Agora-Unity-RTC-SDK > Code > Rtc** , right-click and select **Create > C# Script**. This creates a file `NewBehaviourScript.cs` in your **Assets**. Rename the file to {props.fileName} and open the file. - 1. Import the `UnityEngine.UI` namespace to access UI components: + 1. Import the Unity namespaces to access UI components: ```c# + using UnityEngine; using UnityEngine.UI; ``` -2. Get Android permissions +2. Get device permissions + + Since version 2018.3, Unity does not actively obtain device permissions from the user. You call the `CheckPermission` method to obtain permissions. This step is only required for the Android platform. 1. In Assets/Agora-Unity-RTC-SDK/Code/Rtc/{props.fileName}, add the following code after `UnityEngine.UI;`: @@ -52,21 +59,25 @@ This section shows you how to import the libraries required to implement + + If your target platform is iOS or macOS, the provides a post-build script in the `BL_BuildPostProcess.cs` folder. After you build and export your project from the Unity Editor as an iOS project, the script automatically adds camera and microphone permissions to the `Info.plist` file without manual processing. + + + +1. Bind the script to the Canvas. -1. Bind the script to the Canvas. In `Assets/Agora-Unity-RTC-SDK/Code/Rtc` , select the {props.fileName} file, and drag it to the Canvas. In the **Inspector** panel you see that the file has been bound to the Canvas. + In `Assets/Agora-Unity-RTC-SDK/Code/Rtc` , select the {props.fileName} file, and drag it to the Canvas. In the **Inspector** panel you see that the file is bound to the Canvas. ### Import Agora classes​ @@ -95,11 +106,11 @@ internal IRtcEngine RtcEngine; ```csharp -// Insert your App ID. +// Fill in your app ID private string _appID = ""; -// Insert your channel name. +// Fill in your channel name private string _channelName = ""; -// Insert Token. +// Fill in a temporary token private string _token = ""; internal IRtcEngine RtcEngine; ```` @@ -107,15 +118,17 @@ internal IRtcEngine RtcEngine; ### Create and initialize an `IRtcEngine` instance -Before calling other Agora APIs, you create and initialize an `IRtcEngine` instance. Call `CreateAgoraRtcEngine` to create the instance. In Assets/Agora-Unity-RTC-SDK/Code/Rtc/{props.fileName}, add the following code after `CheckPermissions`: +Create and initialize `IRtcEngine`. Before calling other Agora APIs, you need to create and initialize an `IRtcEngine` instance. Call `CreateAgoraRtcEngine` to create the `IRtcEngine` instance. In `Assets/AgoraEngine/Scripts/JoinChannelAudio.cs`, add the following code after `CheckPermissions`: ```c# -private void SetupVideoSDKEngine() -{ +private void SetupVideoSDKEngine() { // Create an IRtcEngine instance RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine(); - RtcEngineContext context = new RtcEngineContext(_appID, 0,CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING, AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT); + RtcEngineContext context = new RtcEngineContext(); + context.appId = _appID; + context.channelProfile = CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING; + context.audioScenario = AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT; // Initialize the instance RtcEngine.Initialize(context); } @@ -123,11 +136,13 @@ private void SetupVideoSDKEngine() ```c# -private void SetupAudioSDKEngine() -{ +private void SetupAudioSDKEngine() { // Create an IRtcEngine instance RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine(); - RtcEngineContext context = new RtcEngineContext(_appID, 0,CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING, AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT); + RtcEngineContext context = new RtcEngineContext(); + context.appId = _appID; + context.channelProfile = CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING; + context.audioScenario = AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT; // Initialize the instance RtcEngine.Initialize(context); } @@ -137,72 +152,64 @@ private void SetupAudioSDKEngine() ### Set up an event handler Create an instance of the user event handler class and set it as the engine event handler. In Assets/Agora-Unity-RTC-SDK/Code/Rtc/{props.fileName}, add the following code after `SetupVideoSDKEngine()`: + ```c# // Create a user event handler instance and set it as the engine event handler -private void InitEventHandler() -{ +private void InitEventHandler() { UserEventHandler handler = new UserEventHandler(this); RtcEngine.InitEventHandler(handler); } // Implement your own EventHandler class by inheriting the IRtcEngineEventHandler interface class implementation -internal class UserEventHandler : IRtcEngineEventHandler -{ +internal class UserEventHandler : IRtcEngineEventHandler { private readonly JoinChannelVideo _videoSample; - internal UserEventHandler(JoinChannelVideo videoSample) - { + internal UserEventHandler(JoinChannelVideo videoSample) { _videoSample = videoSample; } // error callback - public override void OnError(int err, string msg) - { + public override void OnError(int err, string msg) { } // Triggered when a local user successfully joins the channel - public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed) - { - _videoSample.LocalView.SetForUser(0,""); + public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed) { + _videoSample.LocalView.SetForUser(0,""); } } ``` + Create an instance of the user event handler class and set it as the engine event handler. In Assets/Agora-Unity-RTC-SDK/Code/Rtc/{props.fileName}, add the following code after `SetupSDKEngine()`: + ```csharp -// Create an instance of the user callback class and set the callback. -private void InitEventHandler() -{ +// Create an instance of the user callback class and set the callback +private void InitEventHandler() { UserEventHandler handler = new UserEventHandler(this); RtcEngine.InitEventHandler(handler); } -// Implement your own callback class, which can inherit from the IRtcEngineEventHandler interface class. -internal class UserEventHandler : IRtcEngineEventHandler -{ +// Implement your own callback class, which can inherit from the IRtcEngineEventHandler interface class +internal class UserEventHandler : IRtcEngineEventHandler { private readonly JoinChannelAudio _audioSample; - internal UserEventHandler(JoinChannelAudio audioSample) - { + internal UserEventHandler(JoinChannelAudio audioSample) { _audioSample = audioSample; } - // Error callback. - public override void OnError(int err, string msg) - { - } - // Triggered when the local user successfully joins the channel. - public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed) - { + // Error callback + public override void OnError(int err, string msg) { } + + // Triggered when the local user successfully joins the channel + public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed) { Debug.Log("OnJoinChannelSuccess _channelName"); } - // Triggered when a remote user successfully joins the channel. - public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed) - { + + // Triggered when a remote user successfully joins the channel + public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed) { Debug.Log("Remote user joined"); } - // Triggered when a remote user leaves the current channel. - public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason) - { - } + + // Triggered when a remote user leaves the current channel + public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason) { } } ``` @@ -210,9 +217,9 @@ internal class UserEventHandler : IRtcEngineEventHandler ### Set up the UI UI elements are referenced in Assets/Agora-Unity-RTC-SDK/Code/Rtc/{props.fileName}. To set up the user interface, add the following code before `SetupVideoSDKEngine()`: + ```c# -private void SetupUI() -{ +private void SetupUI() { GameObject go = GameObject.Find("LocalView"); LocalView = go.AddComponent(); go.transform.Rotate(0.0f, 0.0f, -180.0f); @@ -228,9 +235,9 @@ private void SetupUI() UI elements are referenced in Assets/Agora-Unity-RTC-SDK/Code/Rtc/{props.fileName}. To set up the user interface, add the following code before `SetupSDKEngine()`: + ```csharp -private void SetupUI() -{ +private void SetupUI() { GameObject go = GameObject.Find("Leave"); go.GetComponent