blob: b7a1928fc0dbc6a753bf867c21a86fed34d7d092 [file] [log] [blame]
Adrià Vilanova Martíneza10fff22021-06-29 21:07:40 +02001const CC_API_BASE_URL = 'https://support.google.com/s/community/api/';
2
Adrià Vilanova Martínezfeb28192021-08-07 23:31:17 +02003const apiErrors = {
4 0: 'OK',
5 1: 'CANCELLED',
6 2: 'UNKNOWN',
7 3: 'INVALID_ARGUMENT',
8 4: 'DEADLINE_EXCEEDED',
9 5: 'NOT_FOUND',
10 6: 'ALREADY_EXISTS',
11 7: 'PERMISSION_DENIED',
12 8: 'RESOURCE_EXHAUSTED',
13 9: 'FAILED_PRECONDITION',
14 10: 'ABORTED',
15 11: 'OUT_OF_RANGE',
avm9996347c407b2021-08-18 09:54:35 +020016 12: 'UNIMPLEMENTED',
Adrià Vilanova Martínezfeb28192021-08-07 23:31:17 +020017 13: 'INTERNAL',
18 14: 'UNAVAILABLE',
19 15: 'DATA_LOSS',
20 16: 'UNAUTHENTICATED',
21};
22
Adrià Vilanova Martínez9c418ab2024-12-05 15:34:40 +010023export const XClientHeader = 'X-Client';
24export const XClientValue = 'twpt';
25
Adrià Vilanova Martíneza10fff22021-06-29 21:07:40 +020026// Function to wrap calls to the Community Console API with intelligent error
27// handling.
Adrià Vilanova Martínezc41edf42021-07-18 02:06:55 +020028export function CCApi(
29 method, data, authenticated, authuser = 0,
30 returnUnauthorizedStatus = false) {
Adrià Vilanova Martínezfeb28192021-08-07 23:31:17 +020031 let authuserPart =
Adrià Vilanova Martíneza10fff22021-06-29 21:07:40 +020032 authuser == '0' ? '' : '?authuser=' + encodeURIComponent(authuser);
33
Adrià Vilanova Martínezbbc8d7c2024-04-21 16:28:05 +020034 let context;
Adrià Vilanova Martínez96382a92022-04-03 20:48:36 +020035 // #!if browser_target == 'gecko'
36 // See
37 // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#xhr_and_fetch
38 // and https://developer.mozilla.org/en-US/docs/Web/API/Window/content.
Adrià Vilanova Martínezbbc8d7c2024-04-21 16:28:05 +020039 context = window.content || window;
Adrià Vilanova Martínez96382a92022-04-03 20:48:36 +020040 // #!else
Adrià Vilanova Martínezbbc8d7c2024-04-21 16:28:05 +020041 context = window;
Adrià Vilanova Martínez96382a92022-04-03 20:48:36 +020042 // #!endif
43
44 return context
45 .fetch(CC_API_BASE_URL + method + authuserPart, {
46 'headers': {
47 'content-type': 'text/plain; charset=utf-8',
Adrià Vilanova Martínez9c418ab2024-12-05 15:34:40 +010048 // Used to exclude our requests from being handled by FetchProxy.
49 // FetchProxy will remove this header.
50 [XClientHeader]: XClientValue,
Adrià Vilanova Martínez96382a92022-04-03 20:48:36 +020051 },
52 'body': JSON.stringify(data),
53 'method': 'POST',
54 'mode': 'cors',
55 'credentials': (authenticated ? 'include' : 'omit'),
56 })
Adrià Vilanova Martíneza10fff22021-06-29 21:07:40 +020057 .then(res => {
58 if (res.status == 200 || res.status == 400) {
59 return res.json().then(data => ({
60 status: res.status,
61 body: data,
62 }));
63 } else {
64 throw new Error(
65 'Status code ' + res.status + ' was not expected when calling ' +
66 method + '.');
67 }
68 })
69 .then(res => {
70 if (res.status == 400) {
Adrià Vilanova Martínezc41edf42021-07-18 02:06:55 +020071 // If the canonicalCode is PERMISSION_DENIED:
72 if (returnUnauthorizedStatus && res.body?.[2] == 7)
73 return {
74 unauthorized: true,
75 };
76
Adrià Vilanova Martíneza10fff22021-06-29 21:07:40 +020077 throw new Error(
78 res.body[4] ||
79 ('Response status 400 for method ' + method + '. ' +
Adrià Vilanova Martínezfeb28192021-08-07 23:31:17 +020080 'Error code: ' +
81 (apiErrors[res.body?.[2]] ?? res.body?.[2] ?? 'unknown')));
Adrià Vilanova Martíneza10fff22021-06-29 21:07:40 +020082 }
83
Adrià Vilanova Martínezc41edf42021-07-18 02:06:55 +020084 if (returnUnauthorizedStatus)
85 return {
86 unauthorized: false,
87 body: res.body,
88 };
89
Adrià Vilanova Martíneza10fff22021-06-29 21:07:40 +020090 return res.body;
91 });
92}