Documentation for the Unity C# Library
Loading...
Searching...
No Matches
PlatformAPIHandler.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Net.Http;
4using System.Net.Http.Headers;
5using Newtonsoft.Json;
6using Newtonsoft.Json.Linq;
8using UnityEngine;
9
10namespace PixoVR.Apex
11{
28
29 public class APIHandler
30 {
31 public delegate void APIResponse(ResponseType type, HttpResponseMessage message, object responseData);
32 public APIResponse OnAPIResponse;
33
34 protected string URL = "";
35 protected HttpClient handlingClient = null;
36
37 // Move to a separate plugin
38 protected string webURL = "";
39 protected HttpClient webHandlingClient = null;
40
41 // Need to migrate to this in the future
42 protected string apiURL = "";
43 protected HttpClient apiHandlingClient = null;
44
45 public APIHandler()
46 : this(PlatformEndpoints.NorthAmerica_ProductionEnvironment) { }
47
48 public APIHandler(string endpointUrl)
49 {
50 handlingClient = new HttpClient();
51 SetEndpoint(endpointUrl);
52
53 webHandlingClient = new HttpClient();
54 apiHandlingClient = new HttpClient();
55 }
56
57 HttpResponseMessage HandleException(Exception exception)
58 {
59 Debug.LogWarning("Exception has occurred: " + exception.Message);
60 HttpResponseMessage badRequestResponse = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
61 OnAPIResponse.Invoke(ResponseType.RT_FAILED_RESPONSE, badRequestResponse, null);
62 return badRequestResponse;
63 }
64
65 public void SetEndpoint(string endpointUrl)
66 {
67 EnsureURLHasProtocol(ref endpointUrl);
68
69 URL = endpointUrl;
70 Debug.Log("[APIHandler] Set Endpoint to " + URL);
71 handlingClient.BaseAddress = new Uri(URL);
72 }
73
74 public void SetWebEndpoint(string endpointUrl)
75 {
76 EnsureURLHasProtocol(ref endpointUrl);
77
78 webURL = endpointUrl;
79 webHandlingClient.BaseAddress = new Uri(webURL);
80 }
81
82 public void SetPlatformEndpoint(string endpointUrl)
83 {
84 EnsureURLHasProtocol(ref endpointUrl);
85
86 apiURL = endpointUrl;
87 apiHandlingClient.BaseAddress = new Uri(apiURL);
88 }
89
90 private void EnsureURLHasProtocol(ref string url)
91 {
92 if (!url.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase))
93 {
94 if (url.StartsWith("http:", StringComparison.InvariantCultureIgnoreCase))
95 {
96#if UNITY_EDITOR
97 Debug.LogWarning("URL must be a secured http endpoint for production.");
98#else
99 Debug.LogError("URL must be a securated http endpoint.");
100#endif
101 }
102 else
103 {
104 url.Insert(0, "https://");
105 }
106 }
107 }
108
109 public async void Ping()
110 {
111 handlingClient.DefaultRequestHeaders.Clear();
112 handlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
113
114 HttpResponseMessage response;
115 try
116 {
117 response = await handlingClient.GetAsync("/ping");
118 }
119 catch (Exception ex)
120 {
121 response = HandleException(ex);
122 }
123
124 OnAPIResponse.Invoke(ResponseType.RT_PING, response, null);
125 }
126
127 public async void GenerateAssistedLogin(string authToken)
128 {
129 apiHandlingClient.DefaultRequestHeaders.Clear();
130 apiHandlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
131 apiHandlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
132
133 // Create the GraphQL request payload
134 var graphqlRequest = new
135 {
136 operationName = "generateAuthCode",
137 variables = new { input = new { } },
138 query = "mutation generateAuthCode($input: AuthCodeInput!) { generateAuthCode(input: $input) { code expiresAt __typename }}",
139 };
140
141 string jsonContent = JsonConvert.SerializeObject(graphqlRequest);
142 HttpContent requestContent = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
143 HttpResponseMessage response;
144 object responseContent;
145 try
146 {
147 response = await apiHandlingClient.PostAsync("/v2/query", requestContent);
148 string body = await response.Content.ReadAsStringAsync();
149 Debug.Log(body);
150
151 // Parse the GraphQL response structure
152 JObject jsonResponse = JObject.Parse(body);
153
154 if (jsonResponse["data"] != null && jsonResponse["data"]["generateAuthCode"] != null)
155 {
156 // Extract the relevant data from the GraphQL response
157 string code = jsonResponse["data"]["generateAuthCode"]["code"]?.ToString();
158 string expiresAt = jsonResponse["data"]["generateAuthCode"]["expiresAt"]?.ToString();
159
160 // Create the GeneratedAssistedLogin object with the extracted data
162 {
163 AssistedLogin = new AssistedLoginCode { AuthCode = code, Expires = expiresAt },
164 };
165
166 responseContent = assistedLogin;
167 }
168 else if (jsonResponse["errors"] != null)
169 {
170 // Handle GraphQL errors
171 string errorMessage = jsonResponse["errors"]?[0]?["message"]?.ToString() ?? "Unknown GraphQL error";
172 responseContent = new FailureResponse { Error = "true", Message = errorMessage };
173 }
174 else
175 {
176 // Fallback error handling
177 responseContent = new FailureResponse
178 {
179 Error = "true",
180 Message = "Invalid response format from server",
181 };
182 }
183 }
184 catch (Exception ex)
185 {
186 Debug.LogError($"Error generating assisted login: {ex.Message}");
187 response = new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError);
188 responseContent = new FailureResponse { Error = "true", Message = ex.Message };
189 }
190
191 OnAPIResponse.Invoke(ResponseType.RT_GEN_AUTH_LOGIN, response, responseContent);
192 }
193
194 public async void LoginWithToken(string token)
195 {
196 Debug.Log($"[Platform API] Logging in with token: {token}");
197 apiHandlingClient.DefaultRequestHeaders.Clear();
198 apiHandlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
199 apiHandlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
200
201 Debug.Log($"[Platform API] Sending login with a token.");
202 HttpResponseMessage response = await apiHandlingClient.GetAsync("/v2/auth/validate-signature");
203 string body = await response.Content.ReadAsStringAsync();
204 Debug.Log($"[Platform API] Body returned as {body}");
205 object responseContent = JsonConvert.DeserializeObject<UserLoginResponseContent>(body);
206 if ((responseContent as UserLoginResponseContent).HasErrored())
207 {
208 responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
209 }
210
211 Debug.Log($"[Platform API] Got a valid login response!");
212 object loginResponseContent = (responseContent as UserLoginResponseContent).User;
213
214 OnAPIResponse.Invoke(ResponseType.RT_LOGIN, response, loginResponseContent);
215 }
216
217 public async void Login(LoginData login)
218 {
219 Debug.Log("[Platform API] Calling Login.");
220 handlingClient.DefaultRequestHeaders.Clear();
221
222 HttpContent loginRequestContent = new StringContent(JsonUtility.ToJson(login));
223 loginRequestContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
224
225 Debug.Log("[Platform API] Call to post api login.");
226 HttpResponseMessage response = await handlingClient.PostAsync("/login", loginRequestContent);
227 string body = await response.Content.ReadAsStringAsync();
228 Debug.Log("[Platform API] Got response body.");
229 object responseContent = JsonConvert.DeserializeObject<LoginResponseContent>(body);
230 if ((responseContent as LoginResponseContent).HasErrored())
231 {
232 responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
233 }
234
235 Debug.Log("[Platform API] Response content deserialized.");
236 OnAPIResponse.Invoke(ResponseType.RT_LOGIN, response, responseContent);
237 }
238
239 public async void GetUserData(string authToken, int userId)
240 {
241 handlingClient.DefaultRequestHeaders.Clear();
242 handlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
243 handlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
244
245 HttpResponseMessage response = await handlingClient.GetAsync(string.Format("/user/{0}", userId));
246 string body = await response.Content.ReadAsStringAsync();
247 object responseContent = JsonConvert.DeserializeObject<GetUserResponseContent>(body);
248 GetUserResponseContent userInfo = responseContent as GetUserResponseContent;
249 if ((responseContent as GetUserResponseContent).HasErrored())
250 {
251 responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
252 }
253
254 OnAPIResponse.Invoke(ResponseType.RT_GET_USER, response, responseContent);
255 }
256
257 public async void GetUserModules(string authToken, int userId)
258 {
259 handlingClient.DefaultRequestHeaders.Clear();
260 handlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
261 handlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
262
263 UserModulesRequestData usersModulesRequest = new UserModulesRequestData();
264 usersModulesRequest.UserIds.Add(userId);
265 HttpContent loginRequestContent = new StringContent(JsonUtility.ToJson(usersModulesRequest));
266 loginRequestContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
267
268 HttpResponseMessage response = await handlingClient.PostAsync("/access/users", loginRequestContent);
269 string body = await response.Content.ReadAsStringAsync();
270 object responseContent = JsonConvert.DeserializeObject<GetUserModulesResponse>(body);
271 if ((responseContent as GetUserModulesResponse).HasErrored())
272 {
273 responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
274 }
275 else
276 {
277 (responseContent as GetUserModulesResponse).ParseData();
278 }
279
280 OnAPIResponse.Invoke(ResponseType.RT_GET_USER_MODULES, response, responseContent);
281 }
282
283 public async void JoinSession(string authToken, JoinSessionData joinData)
284 {
285 handlingClient.DefaultRequestHeaders.Clear();
286 handlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
287 handlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
288
289 HttpContent joinSessionRequestContent = new StringContent(joinData.ToJSON());
290 joinSessionRequestContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
291
292 HttpResponseMessage response = await handlingClient.PostAsync("/event", joinSessionRequestContent);
293 string body = await response.Content.ReadAsStringAsync();
294 object responseContent = JsonConvert.DeserializeObject<JoinSessionResponse>(body);
295 if ((responseContent as FailureResponse).HasErrored())
296 {
297 responseContent = null;
298 }
299 else
300 {
301 JoinSessionResponse joinSessionResponse = (responseContent as JoinSessionResponse);
302 joinSessionResponse.ParseData();
303 responseContent = joinSessionResponse;
304 }
305
306 OnAPIResponse.Invoke(ResponseType.RT_SESSION_JOINED, response, responseContent);
307 }
308
309 public async void GetModuleAccess(int moduleId, int userId, string serialNumber)
310 {
311 Debug.Log("[Platform API Handler] Get Module Access");
312 handlingClient.DefaultRequestHeaders.Clear();
313 handlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
314
315 string optionalParameters = "";
316 if (serialNumber.Length > 0)
317 {
318 optionalParameters = "?serial=" + serialNumber;
319 }
320
321 Debug.Log(
322 $"[{GetType().Name}] Checking module access at: "
323 + String.Format("/access/user/{0}/module/{1}{2}", userId, moduleId, optionalParameters)
324 );
325
326 HttpResponseMessage response = await handlingClient.GetAsync(
327 String.Format("/access/user/{0}/module/{1}{2}", userId, moduleId, optionalParameters)
328 );
329 string body = await response.Content.ReadAsStringAsync();
330
331 Debug.Log($"[{GetType().Name}] GetModuleAccess return body: {body}");
332 object responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
333 if (!(responseContent as FailureResponse).HasErrored())
334 {
335 responseContent = JsonConvert.DeserializeObject<UserAccessResponseContent>(body);
336 }
337 OnAPIResponse.Invoke(ResponseType.RT_GET_USER_ACCESS, response, responseContent);
338 }
339
340 public async void SendHeartbeat(string authToken, int sessionId)
341 {
342 apiHandlingClient.DefaultRequestHeaders.Clear();
343 apiHandlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
344 apiHandlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
345
346 HeartbeatData heartbeatData = new HeartbeatData(sessionId);
347
348 HttpContent heartbeatRequestContent = new StringContent(heartbeatData.ToJSON());
349 heartbeatRequestContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
350
351 HttpResponseMessage response = await apiHandlingClient.PostAsync(
352 "/heartbeat/pulse",
353 heartbeatRequestContent
354 );
355 string body = await response.Content.ReadAsStringAsync();
356 object responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
357 if ((responseContent as FailureResponse).HasErrored())
358 {
359 responseContent = null;
360 }
361
362 OnAPIResponse.Invoke(ResponseType.RT_HEARTBEAT, response, responseContent);
363 }
364
365 public async void CompleteSession(string authToken, CompleteSessionData completionData)
366 {
367 handlingClient.DefaultRequestHeaders.Clear();
368 handlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
369 handlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
370
371 HttpContent completeSessionRequestContent = new StringContent(completionData.ToJSON());
372 completeSessionRequestContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
373
374 HttpResponseMessage response = await handlingClient.PostAsync("/event", completeSessionRequestContent);
375 string body = await response.Content.ReadAsStringAsync();
376 object responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
377 if ((responseContent as FailureResponse).HasErrored())
378 {
379 responseContent = null;
380 }
381
382 OnAPIResponse.Invoke(ResponseType.RT_SESSION_COMPLETE, response, responseContent);
383 }
384
385 public async void SendSessionEvent(string authToken, SessionEventData sessionEvent)
386 {
387 handlingClient.DefaultRequestHeaders.Clear();
388 handlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
389 handlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
390
391 HttpContent sessionEventRequestContent = new StringContent(sessionEvent.ToJSON());
392 sessionEventRequestContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
393
394 HttpResponseMessage response = await handlingClient.PostAsync("/event", sessionEventRequestContent);
395 string body = await response.Content.ReadAsStringAsync();
396 object responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
397 if ((responseContent as FailureResponse).HasErrored())
398 {
399 responseContent = null;
400 }
401
402 OnAPIResponse.Invoke(ResponseType.RT_SESSION_EVENT, response, responseContent);
403 }
404
405 public async void GetModuleList(string authToken, string platform)
406 {
407 handlingClient.DefaultRequestHeaders.Clear();
408 handlingClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
409 handlingClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
410
411 string endpoint = "/modules";
412 if (platform != null && platform.Length > 0)
413 {
414 endpoint += $"?platform={platform}";
415 }
416
417 Debug.Log($"GetModuleList built endpoint: {endpoint}");
418
419 HttpResponseMessage response = await handlingClient.GetAsync(endpoint);
420 string body = await response.Content.ReadAsStringAsync();
421
422 try
423 {
424 var responseContent = JsonConvert.DeserializeObject<FailureResponse>(body);
425 OnAPIResponse.Invoke(ResponseType.RT_GET_MODULES_LIST, response, responseContent);
426 return;
427 }
428 catch (Exception ex)
429 {
430 Debug.LogWarning(ex);
431 }
432
433 List<OrgModule> orgModules = new List<OrgModule>();
434 JArray array = JArray.Parse(body);
435 if (array != null)
436 {
437 var tokens = array.Children();
438 foreach (JToken selectedToken in tokens)
439 {
440 OrgModule orgModule = ScriptableObject.CreateInstance<OrgModule>();
441 orgModule.Parse(selectedToken);
442 orgModules.Add(orgModule);
443 }
444 }
445
446 Debug.Log(orgModules.Count.ToString());
447 OnAPIResponse.Invoke(ResponseType.RT_GET_MODULES_LIST, response, orgModules);
448 }
449 }
450}
async void SendHeartbeat(string authToken, int sessionId)
APIHandler(string endpointUrl)
async void GetUserModules(string authToken, int userId)
HttpResponseMessage HandleException(Exception exception)
void EnsureURLHasProtocol(ref string url)
async void JoinSession(string authToken, JoinSessionData joinData)
async void LoginWithToken(string token)
async void CompleteSession(string authToken, CompleteSessionData completionData)
async void Login(LoginData login)
async void SendSessionEvent(string authToken, SessionEventData sessionEvent)
void SetPlatformEndpoint(string endpointUrl)
async void GetUserData(string authToken, int userId)
delegate void APIResponse(ResponseType type, HttpResponseMessage message, object responseData)
void SetEndpoint(string endpointUrl)
void SetWebEndpoint(string endpointUrl)
async void GetModuleAccess(int moduleId, int userId, string serialNumber)
async void GenerateAssistedLogin(string authToken)
async void GetModuleList(string authToken, string platform)
[Serializable]
Definition ApexTypes.cs:162
void Parse(JToken token)
Definition ApexTypes.cs:392