request.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. import store from "@/store"
  2. import { parseQuery } from "./utils"
  3. import { IRequestLanguages } from "@/types"
  4. const MODE = import.meta.env.MODE
  5. let gatewayAddress = "https://api.agora.io"
  6. const BASE_URL = "https://service.agora.io/toolbox-overseas"
  7. // ---------------------------------------
  8. const appId = import.meta.env.VITE_AGORA_APP_ID
  9. const appCertificate = import.meta.env.VITE_AGORA_APP_CERTIFICATE
  10. const SUB_BOT_UID = "1000"
  11. const PUB_BOT_UID = "2000"
  12. let agoraToken = ""
  13. let genTokenTime = 0
  14. export async function apiGetAgoraToken(config: { uid: string | number; channel: string }) {
  15. if (!appCertificate) {
  16. return null
  17. }
  18. const { uid, channel } = config
  19. const url = `${BASE_URL}/v2/token/generate`
  20. const data = {
  21. appId,
  22. appCertificate,
  23. channelName: channel,
  24. expire: 7200,
  25. src: "web",
  26. types: [1, 2],
  27. uid: uid + "",
  28. }
  29. let resp = await fetch(url, {
  30. method: "POST",
  31. headers: {
  32. "Content-Type": "application/json",
  33. },
  34. body: JSON.stringify(data),
  35. })
  36. resp = (await resp.json()) || {}
  37. // @ts-ignore
  38. return resp?.data?.token || ""
  39. }
  40. const genAuthorization = async (config: { uid: string | number; channel: string }) => {
  41. if (agoraToken) {
  42. const curTime = new Date().getTime()
  43. if (curTime - genTokenTime < 1000 * 60 * 60) {
  44. return `agora token="${agoraToken}"`
  45. }
  46. }
  47. agoraToken = await apiGetAgoraToken(config)
  48. genTokenTime = new Date().getTime()
  49. return `agora token="${agoraToken}"`
  50. }
  51. // --------------- stt ----------------
  52. export const apiSTTAcquireToken = async (options: {
  53. channel: string
  54. uid: string | number
  55. }): Promise<any> => {
  56. const { channel, uid } = options
  57. const data: any = {
  58. instanceId: channel,
  59. }
  60. if (MODE == "test") {
  61. data.testIp = "218.205.37.49"
  62. data.testPort = 4447
  63. const queryParams = parseQuery(window.location.href)
  64. const denoise = queryParams?.denoise
  65. if (denoise == "true") {
  66. gatewayAddress = "https://service-staging.agora.io/speech-to-text-filter"
  67. data.testIp = "183.131.160.168"
  68. } else if (denoise == "false") {
  69. gatewayAddress = "https://service-staging.agora.io/speech-to-text"
  70. data.testIp = "114.236.138.39"
  71. }
  72. }
  73. const url = `${gatewayAddress}/v1/projects/${appId}/rtsc/speech-to-text/builderTokens`
  74. let res = await fetch(url, {
  75. method: "POST",
  76. headers: {
  77. "Content-Type": "application/json",
  78. Authorization: await genAuthorization(options),
  79. },
  80. body: JSON.stringify(data),
  81. })
  82. if (res.status == 200) {
  83. res = await res.json()
  84. return res
  85. } else {
  86. // status: 504
  87. // please enable the realtime transcription service for this appid
  88. console.error(res.status, res)
  89. throw new Error(res.toString())
  90. }
  91. }
  92. export const apiSTTStartTranscription = async (options: {
  93. uid: string | number
  94. channel: string
  95. languages: IRequestLanguages[]
  96. token: string
  97. }): Promise<{ taskId: string }> => {
  98. const { channel, languages, token, uid } = options
  99. const url = `${gatewayAddress}/v1/projects/${appId}/rtsc/speech-to-text/tasks?builderToken=${token}`
  100. let subBotToken = null
  101. let pubBotToken = null
  102. if (appCertificate) {
  103. const data = await Promise.all([
  104. apiGetAgoraToken({
  105. uid: SUB_BOT_UID,
  106. channel,
  107. }),
  108. apiGetAgoraToken({
  109. uid: PUB_BOT_UID,
  110. channel,
  111. }),
  112. ])
  113. subBotToken = data[0]
  114. pubBotToken = data[1]
  115. }
  116. const body: any = {
  117. languages: languages.map((item) => item.source),
  118. maxIdleTime: 60,
  119. rtcConfig: {
  120. channelName: channel,
  121. subBotUid: SUB_BOT_UID,
  122. pubBotUid: PUB_BOT_UID,
  123. },
  124. }
  125. if (subBotToken && pubBotToken) {
  126. body.rtcConfig.subBotToken = subBotToken
  127. body.rtcConfig.pubBotToken = pubBotToken
  128. }
  129. if (languages.find((item) => item.target.length)) {
  130. body.translateConfig = {
  131. forceTranslateInterval: 2,
  132. languages: languages.filter((item) => item.target.length),
  133. }
  134. }
  135. const res = await fetch(url, {
  136. method: "POST",
  137. headers: {
  138. "Content-Type": "application/json",
  139. Authorization: await genAuthorization({
  140. uid,
  141. channel,
  142. }),
  143. },
  144. body: JSON.stringify(body),
  145. })
  146. const data = await res.json()
  147. if (res.status !== 200) {
  148. throw new Error(data?.message || "start transcription failed")
  149. }
  150. return data
  151. }
  152. export const apiSTTStopTranscription = async (options: {
  153. taskId: string
  154. token: string
  155. uid: number | string
  156. channel: string
  157. }) => {
  158. const { taskId, token, uid, channel } = options
  159. const url = `${gatewayAddress}/v1/projects/${appId}/rtsc/speech-to-text/tasks/${taskId}?builderToken=${token}`
  160. await fetch(url, {
  161. method: "DELETE",
  162. headers: {
  163. "Content-Type": "application/json",
  164. Authorization: await genAuthorization({
  165. uid,
  166. channel,
  167. }),
  168. },
  169. })
  170. }
  171. export const apiSTTQueryTranscription = async (options: {
  172. taskId: string
  173. token: string
  174. uid: number | string
  175. channel: string
  176. }) => {
  177. const { taskId, token, uid, channel } = options
  178. const url = `${gatewayAddress}/v1/projects/${appId}/rtsc/speech-to-text/tasks/${taskId}?builderToken=${token}`
  179. const res = await fetch(url, {
  180. method: "GET",
  181. headers: {
  182. "Content-Type": "application/json",
  183. Authorization: await genAuthorization({
  184. uid,
  185. channel,
  186. }),
  187. },
  188. })
  189. return await res.json()
  190. }
  191. export const apiSTTUpdateTranscription = async (options: {
  192. taskId: string
  193. token: string
  194. uid: number | string
  195. channel: string
  196. updateMaskList: string[]
  197. data: any
  198. }) => {
  199. const { taskId, token, uid, channel, data, updateMaskList } = options
  200. const updateMask = updateMaskList.join(",")
  201. const url = `${gatewayAddress}/v1/projects/${appId}/rtsc/speech-to-text/tasks/${taskId}?builderToken=${token}&sequenceId=1&updateMask=${updateMask}`
  202. const body: any = {
  203. ...data,
  204. }
  205. const res = await fetch(url, {
  206. method: "PATCH",
  207. headers: {
  208. "Content-Type": "application/json",
  209. Authorization: await genAuthorization({
  210. uid,
  211. channel,
  212. }),
  213. },
  214. body: JSON.stringify(body),
  215. })
  216. return await res.json()
  217. }
  218. // --------------- gpt ----------------
  219. export const apiAiAnalysis = async (options: { system: string; userContent: string }) => {
  220. const url = import.meta.env.VITE_AGORA_GPT_URL
  221. if (!url) {
  222. throw new Error("VITE_AGORA_GPT_URL is not defined in env")
  223. }
  224. const res = await fetch(url, {
  225. method: "POST",
  226. headers: {
  227. "content-type": "application/json",
  228. },
  229. body: JSON.stringify(options),
  230. })
  231. return await res.json()
  232. }