sidechat.js 2.6.1 → 2.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/.github/workflows/static.yml +0 -0
  2. package/README.md +0 -0
  3. package/dist/classes/SidechatAPIClient.d.ts +63 -47
  4. package/dist/classes/SidechatAPIClient.d.ts.map +1 -1
  5. package/dist/classes/SidechatAPIError.d.ts +0 -0
  6. package/dist/classes/SidechatAPIError.d.ts.map +0 -0
  7. package/dist/classes/SidechatColorList.d.ts +0 -0
  8. package/dist/classes/SidechatColorList.d.ts.map +0 -0
  9. package/dist/index.cjs +1421 -1349
  10. package/dist/index.d.mts +0 -0
  11. package/dist/index.d.ts +0 -0
  12. package/dist/index.d.ts.map +0 -0
  13. package/dist/index.mjs +1421 -1349
  14. package/dist/types/SidechatTypes.d.ts +0 -0
  15. package/dist/types/SidechatTypes.d.ts.map +0 -0
  16. package/docs/sidechat.js/2.5.6/SidechatAPIClient.html +0 -0
  17. package/docs/sidechat.js/2.5.6/SidechatAPIError.html +0 -0
  18. package/docs/sidechat.js/2.5.6/SidechatColorList.html +0 -0
  19. package/docs/sidechat.js/2.5.6/classes_SidechatAPIClient.js.html +0 -0
  20. package/docs/sidechat.js/2.5.6/classes_SidechatAPIError.js.html +0 -0
  21. package/docs/sidechat.js/2.5.6/classes_SidechatColorList.js.html +0 -0
  22. package/docs/sidechat.js/2.5.6/data/search.json +0 -0
  23. package/docs/sidechat.js/2.5.6/fonts/Inconsolata-Regular.ttf +0 -0
  24. package/docs/sidechat.js/2.5.6/fonts/OpenSans-Regular.ttf +0 -0
  25. package/docs/sidechat.js/2.5.6/fonts/WorkSans-Bold.ttf +0 -0
  26. package/docs/sidechat.js/2.5.6/global.html +0 -0
  27. package/docs/sidechat.js/2.5.6/index.html +0 -0
  28. package/docs/sidechat.js/2.5.6/scripts/core.js +0 -0
  29. package/docs/sidechat.js/2.5.6/scripts/core.min.js +0 -0
  30. package/docs/sidechat.js/2.5.6/scripts/resize.js +0 -0
  31. package/docs/sidechat.js/2.5.6/scripts/search.js +0 -0
  32. package/docs/sidechat.js/2.5.6/scripts/search.min.js +0 -0
  33. package/docs/sidechat.js/2.5.6/scripts/third-party/Apache-License-2.0.txt +0 -0
  34. package/docs/sidechat.js/2.5.6/scripts/third-party/fuse.js +0 -0
  35. package/docs/sidechat.js/2.5.6/scripts/third-party/hljs-line-num-original.js +0 -0
  36. package/docs/sidechat.js/2.5.6/scripts/third-party/hljs-line-num.js +0 -0
  37. package/docs/sidechat.js/2.5.6/scripts/third-party/hljs-original.js +0 -0
  38. package/docs/sidechat.js/2.5.6/scripts/third-party/hljs.js +0 -0
  39. package/docs/sidechat.js/2.5.6/scripts/third-party/popper.js +0 -0
  40. package/docs/sidechat.js/2.5.6/scripts/third-party/tippy.js +0 -0
  41. package/docs/sidechat.js/2.5.6/scripts/third-party/tocbot.js +0 -0
  42. package/docs/sidechat.js/2.5.6/scripts/third-party/tocbot.min.js +0 -0
  43. package/docs/sidechat.js/2.5.6/styles/clean-jsdoc-theme-base.css +0 -0
  44. package/docs/sidechat.js/2.5.6/styles/clean-jsdoc-theme-dark.css +0 -0
  45. package/docs/sidechat.js/2.5.6/styles/clean-jsdoc-theme-light.css +0 -0
  46. package/docs/sidechat.js/2.5.6/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  47. package/docs/sidechat.js/2.5.6/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  48. package/docs/sidechat.js/2.5.6/styles/clean-jsdoc-theme.min.css +0 -0
  49. package/docs/sidechat.js/2.5.6/tutorial-Authentication.html +0 -0
  50. package/docs/sidechat.js/2.5.6/tutorial-Email Registration.html +0 -0
  51. package/docs/sidechat.js/2.5.6/types_SidechatTypes.js.html +0 -0
  52. package/docs/sidechat.js/2.6.0/SidechatAPIClient.html +0 -0
  53. package/docs/sidechat.js/2.6.0/SidechatAPIError.html +0 -0
  54. package/docs/sidechat.js/2.6.0/SidechatColorList.html +0 -0
  55. package/docs/sidechat.js/2.6.0/classes_SidechatAPIClient.js.html +0 -0
  56. package/docs/sidechat.js/2.6.0/classes_SidechatAPIError.js.html +0 -0
  57. package/docs/sidechat.js/2.6.0/classes_SidechatColorList.js.html +0 -0
  58. package/docs/sidechat.js/2.6.0/data/search.json +0 -0
  59. package/docs/sidechat.js/2.6.0/fonts/Inconsolata-Regular.ttf +0 -0
  60. package/docs/sidechat.js/2.6.0/fonts/OpenSans-Regular.ttf +0 -0
  61. package/docs/sidechat.js/2.6.0/fonts/WorkSans-Bold.ttf +0 -0
  62. package/docs/sidechat.js/2.6.0/global.html +0 -0
  63. package/docs/sidechat.js/2.6.0/index.html +0 -0
  64. package/docs/sidechat.js/2.6.0/scripts/core.js +0 -0
  65. package/docs/sidechat.js/2.6.0/scripts/core.min.js +0 -0
  66. package/docs/sidechat.js/2.6.0/scripts/resize.js +0 -0
  67. package/docs/sidechat.js/2.6.0/scripts/search.js +0 -0
  68. package/docs/sidechat.js/2.6.0/scripts/search.min.js +0 -0
  69. package/docs/sidechat.js/2.6.0/scripts/third-party/Apache-License-2.0.txt +0 -0
  70. package/docs/sidechat.js/2.6.0/scripts/third-party/fuse.js +0 -0
  71. package/docs/sidechat.js/2.6.0/scripts/third-party/hljs-line-num-original.js +0 -0
  72. package/docs/sidechat.js/2.6.0/scripts/third-party/hljs-line-num.js +0 -0
  73. package/docs/sidechat.js/2.6.0/scripts/third-party/hljs-original.js +0 -0
  74. package/docs/sidechat.js/2.6.0/scripts/third-party/hljs.js +0 -0
  75. package/docs/sidechat.js/2.6.0/scripts/third-party/popper.js +0 -0
  76. package/docs/sidechat.js/2.6.0/scripts/third-party/tippy.js +0 -0
  77. package/docs/sidechat.js/2.6.0/scripts/third-party/tocbot.js +0 -0
  78. package/docs/sidechat.js/2.6.0/scripts/third-party/tocbot.min.js +0 -0
  79. package/docs/sidechat.js/2.6.0/styles/clean-jsdoc-theme-base.css +0 -0
  80. package/docs/sidechat.js/2.6.0/styles/clean-jsdoc-theme-dark.css +0 -0
  81. package/docs/sidechat.js/2.6.0/styles/clean-jsdoc-theme-light.css +0 -0
  82. package/docs/sidechat.js/2.6.0/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  83. package/docs/sidechat.js/2.6.0/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  84. package/docs/sidechat.js/2.6.0/styles/clean-jsdoc-theme.min.css +0 -0
  85. package/docs/sidechat.js/2.6.0/tutorial-Authentication.html +0 -0
  86. package/docs/sidechat.js/2.6.0/tutorial-Email Registration.html +0 -0
  87. package/docs/sidechat.js/2.6.0/types_SidechatTypes.js.html +0 -0
  88. package/docs/sidechat.js/2.6.1/SidechatAPIClient.html +0 -0
  89. package/docs/sidechat.js/2.6.1/SidechatAPIError.html +0 -0
  90. package/docs/sidechat.js/2.6.1/SidechatColorList.html +0 -0
  91. package/docs/sidechat.js/2.6.1/classes_SidechatAPIClient.js.html +0 -0
  92. package/docs/sidechat.js/2.6.1/classes_SidechatAPIError.js.html +0 -0
  93. package/docs/sidechat.js/2.6.1/classes_SidechatColorList.js.html +0 -0
  94. package/docs/sidechat.js/2.6.1/data/search.json +0 -0
  95. package/docs/sidechat.js/2.6.1/fonts/Inconsolata-Regular.ttf +0 -0
  96. package/docs/sidechat.js/2.6.1/fonts/OpenSans-Regular.ttf +0 -0
  97. package/docs/sidechat.js/2.6.1/fonts/WorkSans-Bold.ttf +0 -0
  98. package/docs/sidechat.js/2.6.1/global.html +0 -0
  99. package/docs/sidechat.js/2.6.1/index.html +0 -0
  100. package/docs/sidechat.js/2.6.1/scripts/core.js +0 -0
  101. package/docs/sidechat.js/2.6.1/scripts/core.min.js +0 -0
  102. package/docs/sidechat.js/2.6.1/scripts/resize.js +0 -0
  103. package/docs/sidechat.js/2.6.1/scripts/search.js +0 -0
  104. package/docs/sidechat.js/2.6.1/scripts/search.min.js +0 -0
  105. package/docs/sidechat.js/2.6.1/scripts/third-party/Apache-License-2.0.txt +0 -0
  106. package/docs/sidechat.js/2.6.1/scripts/third-party/fuse.js +0 -0
  107. package/docs/sidechat.js/2.6.1/scripts/third-party/hljs-line-num-original.js +0 -0
  108. package/docs/sidechat.js/2.6.1/scripts/third-party/hljs-line-num.js +0 -0
  109. package/docs/sidechat.js/2.6.1/scripts/third-party/hljs-original.js +0 -0
  110. package/docs/sidechat.js/2.6.1/scripts/third-party/hljs.js +0 -0
  111. package/docs/sidechat.js/2.6.1/scripts/third-party/popper.js +0 -0
  112. package/docs/sidechat.js/2.6.1/scripts/third-party/tippy.js +0 -0
  113. package/docs/sidechat.js/2.6.1/scripts/third-party/tocbot.js +0 -0
  114. package/docs/sidechat.js/2.6.1/scripts/third-party/tocbot.min.js +0 -0
  115. package/docs/sidechat.js/2.6.1/styles/clean-jsdoc-theme-base.css +0 -0
  116. package/docs/sidechat.js/2.6.1/styles/clean-jsdoc-theme-dark.css +0 -0
  117. package/docs/sidechat.js/2.6.1/styles/clean-jsdoc-theme-light.css +0 -0
  118. package/docs/sidechat.js/2.6.1/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  119. package/docs/sidechat.js/2.6.1/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  120. package/docs/sidechat.js/2.6.1/styles/clean-jsdoc-theme.min.css +0 -0
  121. package/docs/sidechat.js/2.6.1/tutorial-Authentication.html +0 -0
  122. package/docs/sidechat.js/2.6.1/tutorial-Email Registration.html +0 -0
  123. package/docs/sidechat.js/2.6.1/types_SidechatTypes.js.html +0 -0
  124. package/docs/sidechat.js/2.6.4/SidechatAPIClient.html +3 -0
  125. package/docs/sidechat.js/2.6.4/SidechatAPIError.html +3 -0
  126. package/docs/sidechat.js/{2.5.4/SidechatAPIError.html → 2.6.4/SidechatColorList.html} +2 -2
  127. package/docs/sidechat.js/{2.5.5 → 2.6.4}/classes_SidechatAPIClient.js.html +184 -9
  128. package/docs/sidechat.js/{2.5.4 → 2.6.4}/classes_SidechatAPIError.js.html +2 -2
  129. package/docs/sidechat.js/{2.5.4 → 2.6.4}/classes_SidechatColorList.js.html +2 -2
  130. package/docs/sidechat.js/2.6.4/data/search.json +1 -0
  131. package/docs/sidechat.js/{2.5.1 → 2.6.4}/fonts/Inconsolata-Regular.ttf +0 -0
  132. package/docs/sidechat.js/{2.5.1 → 2.6.4}/fonts/OpenSans-Regular.ttf +0 -0
  133. package/docs/sidechat.js/{2.5.1 → 2.6.4}/fonts/WorkSans-Bold.ttf +0 -0
  134. package/docs/sidechat.js/2.6.4/global.html +3 -0
  135. package/docs/sidechat.js/{2.5.3 → 2.6.4}/index.html +2 -2
  136. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/core.js +0 -0
  137. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/core.min.js +0 -0
  138. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/resize.js +0 -0
  139. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/search.js +0 -0
  140. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/search.min.js +0 -0
  141. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/Apache-License-2.0.txt +0 -0
  142. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/fuse.js +0 -0
  143. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/hljs-line-num-original.js +0 -0
  144. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/hljs-line-num.js +0 -0
  145. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/hljs-original.js +0 -0
  146. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/hljs.js +0 -0
  147. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/popper.js +0 -0
  148. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/tippy.js +0 -0
  149. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/tocbot.js +0 -0
  150. package/docs/sidechat.js/{2.5.1 → 2.6.4}/scripts/third-party/tocbot.min.js +0 -0
  151. package/docs/sidechat.js/{2.5.1 → 2.6.4}/styles/clean-jsdoc-theme-base.css +0 -0
  152. package/docs/sidechat.js/{2.5.1 → 2.6.4}/styles/clean-jsdoc-theme-dark.css +0 -0
  153. package/docs/sidechat.js/{2.5.1 → 2.6.4}/styles/clean-jsdoc-theme-light.css +0 -0
  154. package/docs/sidechat.js/{2.5.1 → 2.6.4}/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  155. package/docs/sidechat.js/{2.5.1 → 2.6.4}/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  156. package/docs/sidechat.js/{2.5.1 → 2.6.4}/styles/clean-jsdoc-theme.min.css +0 -0
  157. package/docs/sidechat.js/{2.5.4 → 2.6.4}/tutorial-Authentication.html +2 -2
  158. package/docs/sidechat.js/{2.5.4 → 2.6.4}/tutorial-Email Registration.html +2 -2
  159. package/docs/sidechat.js/{2.5.3 → 2.6.4}/types_SidechatTypes.js.html +51 -7
  160. package/docs/sidechat.js/2.6.5/SidechatAPIClient.html +3 -0
  161. package/docs/sidechat.js/2.6.5/SidechatAPIError.html +3 -0
  162. package/docs/sidechat.js/{2.5.5/SidechatAPIError.html → 2.6.5/SidechatColorList.html} +2 -2
  163. package/docs/sidechat.js/{2.5.4 → 2.6.5}/classes_SidechatAPIClient.js.html +1427 -1238
  164. package/docs/sidechat.js/{2.5.5 → 2.6.5}/classes_SidechatAPIError.js.html +2 -2
  165. package/docs/sidechat.js/{2.5.2 → 2.6.5}/classes_SidechatColorList.js.html +2 -2
  166. package/docs/sidechat.js/2.6.5/data/search.json +1 -0
  167. package/docs/sidechat.js/{2.5.2 → 2.6.5}/fonts/Inconsolata-Regular.ttf +0 -0
  168. package/docs/sidechat.js/{2.5.2 → 2.6.5}/fonts/OpenSans-Regular.ttf +0 -0
  169. package/docs/sidechat.js/{2.5.2 → 2.6.5}/fonts/WorkSans-Bold.ttf +0 -0
  170. package/docs/sidechat.js/2.6.5/global.html +3 -0
  171. package/docs/sidechat.js/{2.5.4 → 2.6.5}/index.html +2 -2
  172. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/core.js +0 -0
  173. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/core.min.js +0 -0
  174. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/resize.js +0 -0
  175. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/search.js +0 -0
  176. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/search.min.js +0 -0
  177. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/Apache-License-2.0.txt +0 -0
  178. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/fuse.js +0 -0
  179. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/hljs-line-num-original.js +0 -0
  180. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/hljs-line-num.js +0 -0
  181. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/hljs-original.js +0 -0
  182. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/hljs.js +0 -0
  183. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/popper.js +0 -0
  184. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/tippy.js +0 -0
  185. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/tocbot.js +0 -0
  186. package/docs/sidechat.js/{2.5.2 → 2.6.5}/scripts/third-party/tocbot.min.js +0 -0
  187. package/docs/sidechat.js/{2.5.2 → 2.6.5}/styles/clean-jsdoc-theme-base.css +0 -0
  188. package/docs/sidechat.js/{2.5.2 → 2.6.5}/styles/clean-jsdoc-theme-dark.css +0 -0
  189. package/docs/sidechat.js/{2.5.2 → 2.6.5}/styles/clean-jsdoc-theme-light.css +0 -0
  190. package/docs/sidechat.js/{2.5.2 → 2.6.5}/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  191. package/docs/sidechat.js/{2.5.2 → 2.6.5}/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  192. package/docs/sidechat.js/{2.5.2 → 2.6.5}/styles/clean-jsdoc-theme.min.css +0 -0
  193. package/docs/sidechat.js/{2.5.5 → 2.6.5}/tutorial-Authentication.html +2 -2
  194. package/docs/sidechat.js/{2.5.5 → 2.6.5}/tutorial-Email Registration.html +2 -2
  195. package/docs/sidechat.js/{2.5.2 → 2.6.5}/types_SidechatTypes.js.html +51 -7
  196. package/docs/tutorials/Authentication.md +0 -0
  197. package/docs/tutorials/Email Registration.md +0 -0
  198. package/jsdoc.json +0 -0
  199. package/package.json +55 -54
  200. package/rollup.config.mjs +0 -0
  201. package/src/classes/SidechatAPIClient.js +1426 -1355
  202. package/src/classes/SidechatAPIError.js +0 -0
  203. package/src/classes/SidechatColorList.js +0 -0
  204. package/src/index.js +0 -0
  205. package/src/tests/colorTest.js +0 -0
  206. package/src/tests/commentTest.js +0 -0
  207. package/src/tests/directMessageTest.js +0 -0
  208. package/src/tests/logInTest.js +0 -0
  209. package/src/tests/postTest.js +0 -0
  210. package/src/tests/updatesTest.js +0 -0
  211. package/src/types/SidechatTypes.js +0 -0
  212. package/tsconfig.json +0 -0
  213. package/docs/sidechat.js/2.5.1/SidechatAPIClient.html +0 -3
  214. package/docs/sidechat.js/2.5.1/SidechatAPIError.html +0 -3
  215. package/docs/sidechat.js/2.5.1/SidechatColorList.html +0 -3
  216. package/docs/sidechat.js/2.5.1/classes_SidechatAPIClient.js.html +0 -1188
  217. package/docs/sidechat.js/2.5.1/classes_SidechatAPIError.js.html +0 -16
  218. package/docs/sidechat.js/2.5.1/classes_SidechatColorList.js.html +0 -79
  219. package/docs/sidechat.js/2.5.1/data/search.json +0 -1
  220. package/docs/sidechat.js/2.5.1/global.html +0 -3
  221. package/docs/sidechat.js/2.5.1/index.html +0 -4
  222. package/docs/sidechat.js/2.5.1/tutorial-Authentication.html +0 -14
  223. package/docs/sidechat.js/2.5.1/tutorial-Email Registration.html +0 -6
  224. package/docs/sidechat.js/2.5.1/types_SidechatTypes.js.html +0 -160
  225. package/docs/sidechat.js/2.5.2/SidechatAPIClient.html +0 -3
  226. package/docs/sidechat.js/2.5.2/SidechatAPIError.html +0 -3
  227. package/docs/sidechat.js/2.5.2/SidechatColorList.html +0 -3
  228. package/docs/sidechat.js/2.5.2/classes_SidechatAPIClient.js.html +0 -1188
  229. package/docs/sidechat.js/2.5.2/classes_SidechatAPIError.js.html +0 -16
  230. package/docs/sidechat.js/2.5.2/data/search.json +0 -1
  231. package/docs/sidechat.js/2.5.2/global.html +0 -3
  232. package/docs/sidechat.js/2.5.2/index.html +0 -4
  233. package/docs/sidechat.js/2.5.2/tutorial-Authentication.html +0 -14
  234. package/docs/sidechat.js/2.5.2/tutorial-Email Registration.html +0 -6
  235. package/docs/sidechat.js/2.5.3/SidechatAPIClient.html +0 -3
  236. package/docs/sidechat.js/2.5.3/SidechatAPIError.html +0 -3
  237. package/docs/sidechat.js/2.5.3/SidechatColorList.html +0 -3
  238. package/docs/sidechat.js/2.5.3/classes_SidechatAPIClient.js.html +0 -1180
  239. package/docs/sidechat.js/2.5.3/classes_SidechatAPIError.js.html +0 -16
  240. package/docs/sidechat.js/2.5.3/classes_SidechatColorList.js.html +0 -79
  241. package/docs/sidechat.js/2.5.3/data/search.json +0 -1
  242. package/docs/sidechat.js/2.5.3/fonts/Inconsolata-Regular.ttf +0 -0
  243. package/docs/sidechat.js/2.5.3/fonts/OpenSans-Regular.ttf +0 -0
  244. package/docs/sidechat.js/2.5.3/fonts/WorkSans-Bold.ttf +0 -0
  245. package/docs/sidechat.js/2.5.3/global.html +0 -3
  246. package/docs/sidechat.js/2.5.3/scripts/core.js +0 -726
  247. package/docs/sidechat.js/2.5.3/scripts/core.min.js +0 -23
  248. package/docs/sidechat.js/2.5.3/scripts/resize.js +0 -90
  249. package/docs/sidechat.js/2.5.3/scripts/search.js +0 -265
  250. package/docs/sidechat.js/2.5.3/scripts/search.min.js +0 -6
  251. package/docs/sidechat.js/2.5.3/scripts/third-party/Apache-License-2.0.txt +0 -202
  252. package/docs/sidechat.js/2.5.3/scripts/third-party/fuse.js +0 -9
  253. package/docs/sidechat.js/2.5.3/scripts/third-party/hljs-line-num-original.js +0 -369
  254. package/docs/sidechat.js/2.5.3/scripts/third-party/hljs-line-num.js +0 -1
  255. package/docs/sidechat.js/2.5.3/scripts/third-party/hljs-original.js +0 -5171
  256. package/docs/sidechat.js/2.5.3/scripts/third-party/hljs.js +0 -1
  257. package/docs/sidechat.js/2.5.3/scripts/third-party/popper.js +0 -5
  258. package/docs/sidechat.js/2.5.3/scripts/third-party/tippy.js +0 -1
  259. package/docs/sidechat.js/2.5.3/scripts/third-party/tocbot.js +0 -672
  260. package/docs/sidechat.js/2.5.3/scripts/third-party/tocbot.min.js +0 -1
  261. package/docs/sidechat.js/2.5.3/styles/clean-jsdoc-theme-base.css +0 -1159
  262. package/docs/sidechat.js/2.5.3/styles/clean-jsdoc-theme-dark.css +0 -412
  263. package/docs/sidechat.js/2.5.3/styles/clean-jsdoc-theme-light.css +0 -482
  264. package/docs/sidechat.js/2.5.3/styles/clean-jsdoc-theme-scrollbar.css +0 -30
  265. package/docs/sidechat.js/2.5.3/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -1
  266. package/docs/sidechat.js/2.5.3/styles/clean-jsdoc-theme.min.css +0 -1
  267. package/docs/sidechat.js/2.5.3/tutorial-Authentication.html +0 -14
  268. package/docs/sidechat.js/2.5.3/tutorial-Email Registration.html +0 -6
  269. package/docs/sidechat.js/2.5.4/SidechatAPIClient.html +0 -3
  270. package/docs/sidechat.js/2.5.4/SidechatColorList.html +0 -3
  271. package/docs/sidechat.js/2.5.4/data/search.json +0 -1
  272. package/docs/sidechat.js/2.5.4/fonts/Inconsolata-Regular.ttf +0 -0
  273. package/docs/sidechat.js/2.5.4/fonts/OpenSans-Regular.ttf +0 -0
  274. package/docs/sidechat.js/2.5.4/fonts/WorkSans-Bold.ttf +0 -0
  275. package/docs/sidechat.js/2.5.4/global.html +0 -3
  276. package/docs/sidechat.js/2.5.4/scripts/core.js +0 -726
  277. package/docs/sidechat.js/2.5.4/scripts/core.min.js +0 -23
  278. package/docs/sidechat.js/2.5.4/scripts/resize.js +0 -90
  279. package/docs/sidechat.js/2.5.4/scripts/search.js +0 -265
  280. package/docs/sidechat.js/2.5.4/scripts/search.min.js +0 -6
  281. package/docs/sidechat.js/2.5.4/scripts/third-party/Apache-License-2.0.txt +0 -202
  282. package/docs/sidechat.js/2.5.4/scripts/third-party/fuse.js +0 -9
  283. package/docs/sidechat.js/2.5.4/scripts/third-party/hljs-line-num-original.js +0 -369
  284. package/docs/sidechat.js/2.5.4/scripts/third-party/hljs-line-num.js +0 -1
  285. package/docs/sidechat.js/2.5.4/scripts/third-party/hljs-original.js +0 -5171
  286. package/docs/sidechat.js/2.5.4/scripts/third-party/hljs.js +0 -1
  287. package/docs/sidechat.js/2.5.4/scripts/third-party/popper.js +0 -5
  288. package/docs/sidechat.js/2.5.4/scripts/third-party/tippy.js +0 -1
  289. package/docs/sidechat.js/2.5.4/scripts/third-party/tocbot.js +0 -672
  290. package/docs/sidechat.js/2.5.4/scripts/third-party/tocbot.min.js +0 -1
  291. package/docs/sidechat.js/2.5.4/styles/clean-jsdoc-theme-base.css +0 -1159
  292. package/docs/sidechat.js/2.5.4/styles/clean-jsdoc-theme-dark.css +0 -412
  293. package/docs/sidechat.js/2.5.4/styles/clean-jsdoc-theme-light.css +0 -482
  294. package/docs/sidechat.js/2.5.4/styles/clean-jsdoc-theme-scrollbar.css +0 -30
  295. package/docs/sidechat.js/2.5.4/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -1
  296. package/docs/sidechat.js/2.5.4/styles/clean-jsdoc-theme.min.css +0 -1
  297. package/docs/sidechat.js/2.5.4/types_SidechatTypes.js.html +0 -180
  298. package/docs/sidechat.js/2.5.5/SidechatAPIClient.html +0 -3
  299. package/docs/sidechat.js/2.5.5/SidechatColorList.html +0 -3
  300. package/docs/sidechat.js/2.5.5/classes_SidechatColorList.js.html +0 -79
  301. package/docs/sidechat.js/2.5.5/data/search.json +0 -1
  302. package/docs/sidechat.js/2.5.5/fonts/Inconsolata-Regular.ttf +0 -0
  303. package/docs/sidechat.js/2.5.5/fonts/OpenSans-Regular.ttf +0 -0
  304. package/docs/sidechat.js/2.5.5/fonts/WorkSans-Bold.ttf +0 -0
  305. package/docs/sidechat.js/2.5.5/global.html +0 -3
  306. package/docs/sidechat.js/2.5.5/index.html +0 -4
  307. package/docs/sidechat.js/2.5.5/scripts/core.js +0 -726
  308. package/docs/sidechat.js/2.5.5/scripts/core.min.js +0 -23
  309. package/docs/sidechat.js/2.5.5/scripts/resize.js +0 -90
  310. package/docs/sidechat.js/2.5.5/scripts/search.js +0 -265
  311. package/docs/sidechat.js/2.5.5/scripts/search.min.js +0 -6
  312. package/docs/sidechat.js/2.5.5/scripts/third-party/Apache-License-2.0.txt +0 -202
  313. package/docs/sidechat.js/2.5.5/scripts/third-party/fuse.js +0 -9
  314. package/docs/sidechat.js/2.5.5/scripts/third-party/hljs-line-num-original.js +0 -369
  315. package/docs/sidechat.js/2.5.5/scripts/third-party/hljs-line-num.js +0 -1
  316. package/docs/sidechat.js/2.5.5/scripts/third-party/hljs-original.js +0 -5171
  317. package/docs/sidechat.js/2.5.5/scripts/third-party/hljs.js +0 -1
  318. package/docs/sidechat.js/2.5.5/scripts/third-party/popper.js +0 -5
  319. package/docs/sidechat.js/2.5.5/scripts/third-party/tippy.js +0 -1
  320. package/docs/sidechat.js/2.5.5/scripts/third-party/tocbot.js +0 -672
  321. package/docs/sidechat.js/2.5.5/scripts/third-party/tocbot.min.js +0 -1
  322. package/docs/sidechat.js/2.5.5/styles/clean-jsdoc-theme-base.css +0 -1159
  323. package/docs/sidechat.js/2.5.5/styles/clean-jsdoc-theme-dark.css +0 -412
  324. package/docs/sidechat.js/2.5.5/styles/clean-jsdoc-theme-light.css +0 -482
  325. package/docs/sidechat.js/2.5.5/styles/clean-jsdoc-theme-scrollbar.css +0 -30
  326. package/docs/sidechat.js/2.5.5/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -1
  327. package/docs/sidechat.js/2.5.5/styles/clean-jsdoc-theme.min.css +0 -1
  328. package/docs/sidechat.js/2.5.5/types_SidechatTypes.js.html +0 -180
package/dist/index.mjs CHANGED
@@ -213,1355 +213,1427 @@ class SidechatAPIError extends Error {
213
213
  }
214
214
  }
215
215
 
216
- /**
217
- * API client class for making requests to Sidechat's private API. You'll need to [authenticate]{@tutorial Authentication} before using most of the methods.
218
- * @class
219
- * @since 2.0.0-alpha.0
220
- */
221
- class SidechatAPIClient {
222
- /**
223
- * User bearer token
224
- * @type {SidechatAuthToken}
225
- * */
226
- userToken;
227
-
228
- /**
229
- * Default headers for every API request
230
- * @type {Object}
231
- * @static
232
- * @constant
233
- */
234
- defaultHeaders = {
235
- Accept: "application/json",
236
- "Content-Type": "application/json",
237
- "App-Version": "6.0.0",
238
- Dnt: 1,
239
- };
240
-
241
- /**
242
- * Root URL for every API request
243
- * @type {String}
244
- * @default "https://api.sidechat.lol"
245
- */
246
- apiRoot = "https://api.sidechat.lol";
247
-
248
- /**
249
- * Create a new instance of the API client
250
- * @param {SidechatAuthToken} [token] - user bearer token
251
- * @param {String} rootUrl - custom API root URL for mocking or using other server
252
- */
253
- constructor(token = "", rootUrl = "") {
254
- if (token) {
255
- this.userToken = token;
256
- }
257
- if (rootUrl) {
258
- this.apiRoot = rootUrl;
259
- }
260
- }
261
-
262
- /**
263
- * Manually set the currently signed in user's token. Generally try to avoid this and instead either pass a token to the constructor or login automatically through the auth functions
264
- * @method
265
- * @param {SidechatAuthToken} token - user bearer token
266
- */
267
- setToken = (token) => {
268
- this.userToken = token;
269
- };
270
-
271
- /**
272
- * Manually set the root URL for all API requests. This can be used for mocking requests or redirecting them to a different server
273
- * @method
274
- * @param {String} url - new root URL to set
275
- * @since 2.3.9
276
- */
277
- setAPIRoot = (url) => {
278
- this.apiRoot = url;
279
- };
280
-
281
- /**
282
- * Run an arbitrary API request using the current client's authentication
283
- * @method
284
- * @param {String} endpoint - API endpoint to request (e.g. "/v1/posts")
285
- * @param {"GET"|"POST"|"PUT"|"DELETE"|"PATCH"|"OPTIONS"} [method] - HTTP method to use
286
- * @param {Object} [body] - body to send with the request
287
- * @param {Object} [headers] - custom headers to send with the request
288
- * @param {Boolean} [stripHeaders] - remove the default headers from the request
289
- * @since 2.4.9
290
- */
291
- sendRequest = (
292
- endpoint,
293
- method = "GET",
294
- body = undefined,
295
- headers = {},
296
- stripHeaders = false
297
- ) => {
298
- let requestHeaders = this.defaultHeaders;
299
- if (stripHeaders) {
300
- headers = {};
301
- }
302
- requestHeaders = { ...requestHeaders, ...headers };
303
- return fetch(`${this.apiRoot}${endpoint}`, {
304
- headers: { Authorization: `Bearer ${this.userToken}`, ...requestHeaders },
305
- body: body,
306
- method: method,
307
- });
308
- };
309
-
310
- /**
311
- * Initiate the login process with a phone number. Should be followed up with verifySMSCode().
312
- * @method
313
- * @since 1.0.0
314
- * @param {Number} phoneNumber - US phone number (WITHOUT +1) to send verification code to
315
- */
316
- loginViaSMS = async (phoneNumber) => {
317
- try {
318
- const res = await fetch(`${this.apiRoot}/v1/login_register`, {
319
- method: "POST",
320
- headers: this.defaultHeaders,
321
- body: JSON.stringify({
322
- phone_number: `+1${phoneNumber}`,
323
- version: 3,
324
- }),
325
- });
326
- const json = await res.json();
327
- return json;
328
- } catch (err) {
329
- console.error(err);
330
- throw new SidechatAPIError("Failed to request SMS verification.");
331
- }
332
- };
333
-
334
- /**
335
- * Verify the code sent via SMS with loginViaSMS(). If this function succeeds, the user will be authenticated for future requests.
336
- * @method
337
- * @since 1.0.0
338
- * @param {Number} phoneNumber - US phone number (WITHOUT +1) that verification code was sent to
339
- * @param {String} code - the verification code
340
- */
341
- verifySMSCode = async (phoneNumber, code) => {
342
- try {
343
- const res = await fetch(`${this.apiRoot}/v1/verify_phone_number`, {
344
- method: "POST",
345
- headers: this.defaultHeaders,
346
- body: JSON.stringify({
347
- phone_number: `+1${phoneNumber}`,
348
- code: code.toUpperCase(),
349
- }),
350
- });
351
- const json = await res.json();
352
- if (json?.logged_in_user?.token) {
353
- this.userToken = json.logged_in_user.token;
354
- }
355
- return json;
356
- } catch (err) {
357
- console.error(err);
358
- throw new SidechatAPIError("Failed verify this code.");
359
- }
360
- };
361
-
362
- /**
363
- * Set the user's age. If this function succeeds, the user will be authenticated for future requests.
364
- * @method
365
- * @since 1.0.0
366
- * @param {Number} age - user's age in years
367
- * @param {String} registrationID - the registration ID generated by verifySMSCode()
368
- */
369
- setAge = async (age, registrationID) => {
370
- if (age < 13) {
371
- throw new SidechatAPIError("You're too young to use Offsides.");
372
- }
373
- try {
374
- const res = await fetch(`${this.apiRoot}/v1/complete_registration`, {
375
- method: "POST",
376
- headers: this.defaultHeaders,
377
- body: JSON.stringify({
378
- age: Number(age),
379
- registration_id: registrationID,
380
- }),
381
- });
382
- const json = await res.json();
383
- if (json.token) {
384
- this.userToken = json.token;
385
- }
386
- return json;
387
- } catch (err) {
388
- console.error(err);
389
- throw new SidechatAPIError("Failed verify this code.");
390
- }
391
- };
392
-
393
- /**
394
- * Initiate the email setup process. Should be followed up with checkEmailVerification().
395
- * @method
396
- * @since 1.0.0
397
- * @param {String} email - school email address to send verification code to
398
- * @tutorial Email Registration
399
- */
400
- registerEmail = async (email) => {
401
- if (!this.userToken) {
402
- throw new SidechatAPIError("User is not authenticated.");
403
- }
404
- try {
405
- const res = await fetch(`${this.apiRoot}/v2/users/register_email`, {
406
- method: "POST",
407
- headers: {
408
- ...this.defaultHeaders,
409
- Authorization: `Bearer ${this.userToken}`,
410
- },
411
- body: JSON.stringify({
412
- email: email,
413
- }),
414
- });
415
- const json = await res.json();
416
- if (json.message) {
417
- throw new SidechatAPIError(json.message);
418
- }
419
- return json;
420
- } catch (err) {
421
- console.error(err);
422
- throw new SidechatAPIError("Failed to request email verification.");
423
- }
424
- };
425
-
426
- /**
427
- * Check is the user's email is verified.
428
- * @method
429
- * @since 1.0.0
430
- */
431
- checkEmailVerification = async () => {
432
- if (!this.userToken) {
433
- throw new SidechatAPIError("User is not authenticated.");
434
- }
435
- try {
436
- const res = await fetch(`${this.apiRoot}/v1/users/check_email_verified`, {
437
- method: "GET",
438
- headers: {
439
- ...this.defaultHeaders,
440
- Authorization: `Bearer ${this.userToken}`,
441
- },
442
- });
443
- const json = await res.json();
444
- if (json.verified_email_updates_response) {
445
- return json.verified_email_updates_response;
446
- } else {
447
- throw new SidechatAPIError(json?.message || "Email is not verified.");
448
- }
449
- } catch (err) {
450
- console.error(err);
451
- throw new SidechatAPIError("Email is not verified.");
452
- }
453
- };
454
-
455
- /**
456
- * Set the device ID of the current user
457
- * @method
458
- * @since 1.0.0
459
- * @param {String} deviceId - the device ID to set
460
- */
461
- setDeviceID = async (deviceID) => {
462
- if (!this.userToken) {
463
- throw new SidechatAPIError("User is not authenticated.");
464
- }
465
- try {
466
- const res = await fetch(`${this.apiRoot}/v1/register_device_token`, {
467
- method: "POST",
468
- headers: {
469
- ...this.defaultHeaders,
470
- Authorization: `Bearer ${this.userToken}`,
471
- },
472
- body: JSON.stringify({
473
- build_type: "release",
474
- bundle_id: "com.flowerave.sidechat",
475
- device_token: deviceID,
476
- }),
477
- });
478
- const json = await res.json();
479
- return json;
480
- } catch (err) {
481
- console.error(err);
482
- throw new SidechatAPIError("Failed verify this code.");
483
- }
484
- };
485
-
486
- /**
487
- * Get updated status for user and group
488
- * @method
489
- * @since 1.0.0
490
- * @deprecated since 2.1.0, will be removed by 3.0.0. Please use `getUpdates` instead!
491
- * @param {String} [groupID] - ID of a specific group to retrieve info from. Falls back to user's primary group.
492
- */
493
- getUserAndGroup = async (groupID = "") => {
494
- const json = await this.getUpdates(groupID);
495
- return json;
496
- };
497
-
498
- /**
499
- * Get updated status for user and group
500
- * @method
501
- * @since 2.1.0
502
- * @param {String} [groupID] - ID of a specific group to retrieve info from. Falls back to user's primary group.
503
- */
504
- getUpdates = async (groupID = "") => {
505
- if (!this.userToken) {
506
- throw new SidechatAPIError("User is not authenticated.");
507
- }
508
- try {
509
- const res = await fetch(
510
- `${this.apiRoot}/v1/updates?group_id=${groupID}`,
511
- {
512
- method: "GET",
513
- headers: {
514
- ...this.defaultHeaders,
515
- Authorization: `Bearer ${this.userToken}`,
516
- },
517
- }
518
- );
519
- const json = await res.json();
520
- return json;
521
- } catch (err) {
522
- console.error(err);
523
- throw new SidechatAPIError(`Failed to get posts from group.`);
524
- }
525
- };
526
-
527
- /**
528
- * Fetches posts from the specified category in a group
529
- * @method
530
- * @since 1.0.0
531
- * @param {String} groupID - group ID
532
- * @param {"hot"|"recent"|"top"} category - category to filter posts
533
- * @param {SidechatCursorString} [cursor] - cursor string
534
- * @returns {SidechatPostsAndCursor} List of posts and cursor
535
- */
536
- getGroupPosts = async (groupID, category = "hot", cursor) => {
537
- if (!this.userToken) {
538
- throw new SidechatAPIError("User is not authenticated.");
539
- }
540
- try {
541
- const res = await fetch(
542
- `${this.apiRoot}/v1/posts?${cursor ? "cursor=" + encodeURIComponent(cursor) + "&" : ""
543
- }group_id=${groupID}&type=${category}`,
544
- {
545
- method: "GET",
546
- headers: {
547
- ...this.defaultHeaders,
548
- Authorization: `Bearer ${this.userToken}`,
549
- },
550
- }
551
- );
552
- const json = await res.json();
553
- return json;
554
- } catch (err) {
555
- console.error(err);
556
- throw new SidechatAPIError(`Failed to get posts from group.`);
557
- }
558
- };
559
-
560
- /**
561
- * Upvote or downvote, or unvote a post
562
- * @method
563
- * @since 2.0.0-alpha.0
564
- * @param {String} postID - post ID to vote on
565
- * @param {SidechatVoteString} action - whether to upvote, downvote, or reset vote
566
- */
567
- setVote = async (postID, action) => {
568
- if (!this.userToken) {
569
- throw new SidechatAPIError("User is not authenticated.");
570
- }
571
- try {
572
- const res = await fetch(`${this.apiRoot}/v1/posts/set_vote`, {
573
- method: "POST",
574
- headers: {
575
- ...this.defaultHeaders,
576
- Authorization: `Bearer ${this.userToken}`,
577
- },
578
- body: JSON.stringify({
579
- post_id: postID,
580
- vote_status: action,
581
- }),
582
- });
583
- const json = await res.json();
584
- return json;
585
- } catch (err) {
586
- console.error(err);
587
- throw new SidechatAPIError(`Failed to change the vote on post.`);
588
- }
589
- };
590
-
591
- /**
592
- * Fetches a single post with just its ID
593
- * @method
594
- * @since 2.3.0
595
- * @param {String} postID - ID of post to fetch
596
- * @param {Boolean} includeDeleted - undocumented
597
- * @returns {SidechatPostOrComment} post object
598
- */
599
- getPost = async (postID, includeDeleted = false) => {
600
- if (!this.userToken) {
601
- throw new SidechatAPIError("User is not authenticated.");
602
- }
603
- try {
604
- const res = await fetch(
605
- `${this.apiRoot}/v1/posts/get?include_deleted=${includeDeleted}&post_id=${postID}`,
606
- {
607
- method: "GET",
608
- headers: {
609
- ...this.defaultHeaders,
610
- Authorization: `Bearer ${this.userToken}`,
611
- },
612
- }
613
- );
614
- const json = await res.json();
615
- return json.post;
616
- } catch (err) {
617
- console.error(err);
618
- throw new SidechatAPIError(`Failed to get post from ID.`);
619
- }
620
- };
621
-
622
- /**
623
- * Fetches the posts or comments that the user has created
624
- * @method
625
- * @since 2.3.5
626
- * @param {"posts"|"comments"} contentType - type of user content to fetch
627
- * @returns {SidechatPostOrComment[]} post object
628
- */
629
- getUserContent = async (contentType) => {
630
- if (!this.userToken) {
631
- throw new SidechatAPIError("User is not authenticated.");
632
- }
633
- if (contentType == "posts") {
634
- contentType = "my_posts";
635
- } else if (contentType == "comments") {
636
- contentType = "my_comments";
637
- }
638
- try {
639
- const res = await fetch(`${this.apiRoot}/v1/posts&type=${contentType}`, {
640
- method: "GET",
641
- headers: {
642
- ...this.defaultHeaders,
643
- Authorization: `Bearer ${this.userToken}`,
644
- },
645
- });
646
- const json = await res.json();
647
- return json.posts;
648
- } catch (err) {
649
- console.error(err);
650
- throw new SidechatAPIError(`Failed to get content from user.`);
651
- }
652
- };
653
-
654
- /**
655
- * Get all the commments on a post
656
- * @method
657
- * @since 2.0.0-alpha.0
658
- * @param {String} postID - post ID to get comments for
659
- * @returns {SidechatPostOrComment[]} list of comments
660
- */
661
- getPostComments = async (postID) => {
662
- if (!this.userToken) {
663
- throw new SidechatAPIError("User is not authenticated.");
664
- }
665
- try {
666
- const res = await fetch(
667
- `${this.apiRoot}/v1/posts/comments/?post_id=${postID}`,
668
- {
669
- method: "GET",
670
- headers: {
671
- ...this.defaultHeaders,
672
- Authorization: `Bearer ${this.userToken}`,
673
- },
674
- }
675
- );
676
- const json = await res.json();
677
- // Function to preprocess the comments and organize them into a nested structure
678
- function preprocessComments(apiComments) {
679
- // Map to store comments by their IDs for efficient lookup
680
- const commentMap = new Map();
681
- // List to store top-level comments
682
- const topLevelComments = [];
683
-
684
- // Iterate through the API comments
685
- apiComments.forEach((comment) => {
686
- // Store the comment in the map with its ID as the key
687
- commentMap.set(comment.id, comment);
688
- // Get the parent comment using the reply_post_id
689
- const parentComment = commentMap.get(comment.reply_post_id);
690
- // Check if the comment is a top-level comment
691
- if (
692
- !parentComment ||
693
- comment.reply_post_id === comment.parent_post_id
694
- ) {
695
- // If it's a top-level comment, push it to the topLevelComments array
696
- topLevelComments.push(comment);
697
- } else {
698
- // If it's a reply, add it to the parent comment's replies array
699
- if (!parentComment.replies) parentComment.replies = [];
700
- parentComment.replies.push(comment);
701
- }
702
- });
703
-
704
- // Flatten the nested structure and return a single list of comments
705
- return flattenComments(topLevelComments);
706
- }
707
-
708
- // Function to flatten nested comments into a single list
709
- function flattenComments(comments) {
710
- // Use reduce to flatten the nested comments array into a single list
711
- return comments.reduce((flatComments, comment) => {
712
- // Push the current comment to the flatComments array
713
- flatComments.push(comment);
714
- // If the current comment has replies, recursively flatten them and push to the flatComments array
715
- if (comment.replies)
716
- flatComments.push(...flattenComments(comment.replies));
717
- // Return the flatComments array
718
- return flatComments;
719
- }, []);
720
- }
721
-
722
- const sortedComments = preprocessComments(json.posts);
723
- return sortedComments;
724
- } catch (err) {
725
- console.error(err);
726
- throw new SidechatAPIError(`Failed to get comments on post.`);
727
- }
728
- };
729
-
730
- /**
731
- * Gets groups to be displayed on the "Explore Groups" page
732
- * @method
733
- * @since 2.0.0-alpha.0
734
- * @param {Boolean} onePage - whether or not results should be returned as a single page
735
- * @returns {SidechatGroup[]}
736
- */
737
- getAvailableGroups = async (onePage = true) => {
738
- if (!this.userToken) {
739
- throw new SidechatAPIError("User is not authenticated.");
740
- }
741
- try {
742
- const res = await fetch(`${this.apiRoot}/v1/groups/explore`, {
743
- method: "GET",
744
- headers: {
745
- ...this.defaultHeaders,
746
- "App-Version": onePage ? "0" : this.defaultHeaders["App-Version"],
747
- Authorization: `Bearer ${this.userToken}`,
748
- },
749
- });
750
- const json = await res.json();
751
- return await json.groups;
752
- } catch (err) {
753
- console.error(err);
754
- throw new SidechatAPIError(`Failed to get groups from explore.`);
755
- }
756
- };
757
-
758
- /**
759
- * Searches for new groups based on a query keyword
760
- * @method
761
- * @since 2.6.0
762
- * @param {String} query - the string to search for. This will be encoded, so strings with spaces and special characters are okay.
763
- * @returns {SidechatGroup[]}
764
- */
765
- searchAvailableGroups = async (query) => {
766
- if (!this.userToken) {
767
- throw new SidechatAPIError("User is not authenticated.");
768
- }
769
- try {
770
- const res = await fetch(`${this.apiRoot}/v1/groups/explore/search?term=${encodeURIComponent(query)}`, {
771
- method: "GET",
772
- headers: {
773
- ...this.defaultHeaders,
774
- Authorization: `Bearer ${this.userToken}`,
775
- },
776
- });
777
- const json = await res.json();
778
- return await json.results;
779
- } catch (err) {
780
- console.error(err);
781
- throw new SidechatAPIError(`Failed to search groups.`);
782
- }
783
- };
784
-
785
- /**
786
- * Retrieves the entire accessible asset library. Be warned that as of the time of this documentation, it's a 1.5MB JSON download and this request is very expensive.
787
- * @method
788
- * @since 2.0.6
789
- * @returns {SidechatLibraryAsset[]}
790
- */
791
- getAssetLibrary = async () => {
792
- if (!this.userToken) {
793
- throw new SidechatAPIError("User is not authenticated.");
794
- }
795
- try {
796
- const res = await fetch(`${this.apiRoot}/v1/assets/library`, {
797
- method: "GET",
798
- headers: {
799
- ...this.defaultHeaders,
800
- Authorization: `Bearer ${this.userToken}`,
801
- },
802
- });
803
- const json = await res.json();
804
- return await json.items;
805
- } catch (err) {
806
- console.error(err);
807
- throw new SidechatAPIError(`Failed to get asset library.`);
808
- }
809
- };
810
-
811
- /**
812
- * Gets the current authenticated user and a list of the groups of which they are members.
813
- * @method
814
- * @since 2.1.0
815
- * @returns {SidechatCurrentUser}
816
- */
817
- getCurrentUser = async () => {
818
- if (!this.userToken) {
819
- throw new SidechatAPIError("User is not authenticated.");
820
- }
821
- try {
822
- const res = await fetch(`${this.apiRoot}/v1/users/me`, {
823
- method: "GET",
824
- headers: {
825
- ...this.defaultHeaders,
826
- Authorization: `Bearer ${this.userToken}`,
827
- },
828
- });
829
- const json = await res.json();
830
- return await json;
831
- } catch (err) {
832
- console.error(err);
833
- throw new SidechatAPIError(`Failed to get asset library.`);
834
- }
835
- };
836
-
837
- /**
838
- * Gets the metadata of a group from its ID
839
- * @method
840
- * @since 2.1.0
841
- * @param {String} [groupID] - alphanumeric ID of a group to get. Falls back to user's primary group.
842
- * @returns {SidechatGroup}
843
- */
844
- getGroupMetadata = async (groupID = "") => {
845
- if (!this.userToken) {
846
- throw new SidechatAPIError("User is not authenticated.");
847
- }
848
- try {
849
- const res = await fetch(`${this.apiRoot}/v1/groups/${groupID}`, {
850
- method: "GET",
851
- headers: {
852
- ...this.defaultHeaders,
853
- Authorization: `Bearer ${this.userToken}`,
854
- },
855
- });
856
- const json = await res.json();
857
- return await json.group;
858
- } catch (err) {
859
- console.error(err);
860
- throw new SidechatAPIError(`Failed to get group metadata.`);
861
- }
862
- };
863
-
864
- /**
865
- * Joins or leaves a group
866
- * @method
867
- * @param {String} groupID - alphanumeric ID of group to join or leave
868
- * @param {Boolean} isMember - whether or not the user should be a member of the group
869
- * @since 2.3.8
870
- */
871
- setGroupMembership = async (groupID, isMember) => {
872
- if (!this.userToken) {
873
- throw new SidechatAPIError("User is not authenticated.");
874
- }
875
- try {
876
- const res = await fetch(
877
- `${this.apiRoot}/v1/groups/${isMember ? "join" : "leave"}`,
878
- {
879
- method: "POST",
880
- headers: {
881
- ...this.defaultHeaders,
882
- Authorization: `Bearer ${this.userToken}`,
883
- },
884
- body: JSON.stringify({
885
- group_id: groupID,
886
- }),
887
- }
888
- );
889
- const json = await res.json();
890
- return await json;
891
- } catch (err) {
892
- console.error(err);
893
- throw new SidechatAPIError(`Failed to modify group membership.`);
894
- }
895
- };
896
-
897
- /**
898
- * Creates a comment on a post
899
- * @method
900
- * @since 2.2.0
901
- * @param {String} parentPostID - alphanumeric ID of post on which this comment is made
902
- * @param {String} text - text content of comment
903
- * @param {String} groupID - alphanumeric ID of group in which the parent post resides
904
- * @param {String} [replyCommentID] - alphanumeric ID of comment to reply to. Falls back to parentPostID
905
- * @param {String} [topLevelReplyID] - alphanumeric ID of the top-level comment to reply to. Used only when replying to replies. Falls back to parentPostID
906
- * @param {SidechatSimpleAsset[]} [assetList] - list of assets to attach
907
- * @param {Boolean} [disableDMs] - prevent direct messages being sent to comment's author
908
- * @param {Boolean} [anonymous] - whether or not to hide user's name and icon on comment
909
- * @returns {SidechatPostOrComment} created comment
910
- */
911
- createComment = async (
912
- parentPostID,
913
- text,
914
- groupID,
915
- replyCommentID,
916
- topLevelReplyID,
917
- assetList = [],
918
- disableDMs = false,
919
- anonymous = false
920
- ) => {
921
- if (!this.userToken) {
922
- throw new SidechatAPIError("User is not authenticated.");
923
- }
924
- try {
925
- const res = await fetch(`${this.apiRoot}/v1/posts`, {
926
- method: "POST",
927
- headers: {
928
- ...this.defaultHeaders,
929
- Authorization: `Bearer ${this.userToken}`,
930
- },
931
- body: JSON.stringify({
932
- type: "comment",
933
- assets: assetList,
934
- group_ids: [groupID],
935
- text: text,
936
- reply_post_id: topLevelReplyID || replyCommentID || parentPostID,
937
- reply_comment_post_id: replyCommentID || parentPostID,
938
- parent_post_id: parentPostID,
939
- dms_disabled: disableDMs,
940
- using_identity: !anonymous,
941
- }),
942
- });
943
- const json = await res.json();
944
- return await json.comment;
945
- } catch (err) {
946
- console.error(err);
947
- throw new SidechatAPIError(`Failed to post comment.`);
948
- }
949
- };
950
-
951
- /**
952
- * Creates a new post in the specified group
953
- * @method
954
- * @since 2.2.0
955
- * @param {String} text - text content of comment
956
- * @param {String} groupID - alphanumeric ID of group in which the parent post resides
957
- * @param {SidechatSimpleAsset[]} [assetList] - list of assets to attach.
958
- * @param {Boolean} [disableDMs] - prevent direct messages from being sent to post's author
959
- * @param {Boolean} [disableComments] - whether or not comments should be disabled on post
960
- * @param {Boolean} [anonymous] - whether or not to hide user's name and icon on post
961
- * @returns {SidechatPostOrComment} the created post
962
- */
963
- createPost = async (
964
- text,
965
- groupID,
966
- assetList = [],
967
- disableDMs = false,
968
- disableComments = false,
969
- anonymous = false,
970
- repostId = undefined
971
- ) => {
972
- if (!this.userToken) {
973
- throw new SidechatAPIError("User is not authenticated.");
974
- }
975
- try {
976
- const res = await fetch(`${this.apiRoot}/v1/posts`, {
977
- method: "POST",
978
- headers: {
979
- ...this.defaultHeaders,
980
- Authorization: `Bearer ${this.userToken}`,
981
- },
982
- body: JSON.stringify({
983
- type: "post",
984
- assets: assetList,
985
- group_ids: [groupID],
986
- text: text,
987
- attachments: [],
988
- dms_disabled: disableDMs,
989
- comments_disabled: disableComments,
990
- using_identity: !anonymous,
991
- quote_post_id: repostId
992
- }),
993
- });
994
- const json = await res.json();
995
- return await json.posts[0];
996
- } catch (err) {
997
- console.error(err);
998
- throw new SidechatAPIError(`Failed to make post.`);
999
- }
1000
- };
1001
-
1002
- /**
1003
- * Deletes a post or comment that the user created
1004
- * @method
1005
- * @since 2.2.0
1006
- * @param {String} postOrCommentID - alphanumeric ID of post to delete
1007
- */
1008
- deletePostOrComment = async (postOrCommentID) => {
1009
- if (!this.userToken) {
1010
- throw new SidechatAPIError("User is not authenticated.");
1011
- }
1012
- try {
1013
- const res = await fetch(`${this.apiRoot}/v1/posts/delete`, {
1014
- method: "POST",
1015
- headers: {
1016
- ...this.defaultHeaders,
1017
- Authorization: `Bearer ${this.userToken}`,
1018
- },
1019
- body: JSON.stringify({
1020
- post_id: postOrCommentID,
1021
- }),
1022
- });
1023
- const json = await res.json();
1024
- return await json;
1025
- } catch (err) {
1026
- console.error(err);
1027
- throw new SidechatAPIError(`Failed to delete post.`);
1028
- }
1029
- };
1030
-
1031
- /**
1032
- * Votes on a poll attached to a post
1033
- * @method
1034
- * @param {String} pollId - alphanumeric ID of poll to vote on
1035
- * @param {Number} choiceIndex - index of the choice to vote on
1036
- * @since 2.5.4
1037
- */
1038
- voteOnPoll = async (pollId, choiceIndex) => {
1039
- if (!this.userToken) {
1040
- throw new SidechatAPIError("User is not authenticated.");
1041
- }
1042
- try {
1043
- const res = await fetch(`${this.apiRoot}/v1/polls/vote`, {
1044
- method: "POST",
1045
- headers: {
1046
- ...this.defaultHeaders,
1047
- Authorization: `Bearer ${this.userToken}`,
1048
- },
1049
- body: JSON.stringify({
1050
- poll_id: pollId,
1051
- choice: choiceIndex,
1052
- }),
1053
- });
1054
- const json = await res.json();
1055
- return await json;
1056
- } catch (err) {
1057
- console.error(err);
1058
- throw new SidechatAPIError(`Failed to vote on poll`);
1059
- }
1060
- };
1061
-
1062
- /**
1063
- * Marks that the user has viewed results on a poll. Note that this does not actually return the results of the poll.
1064
- * @method
1065
- * @param {String} pollId - alphanumeric ID of poll to vote on
1066
- * @since 2.5.4
1067
- */
1068
- viewPollResults = async (pollId) => {
1069
- if (!this.userToken) {
1070
- throw new SidechatAPIError("User is not authenticated.");
1071
- }
1072
- try {
1073
- const res = await fetch(`${this.apiRoot}/v1/polls/view_results`, {
1074
- method: "POST",
1075
- headers: {
1076
- ...this.defaultHeaders,
1077
- Authorization: `Bearer ${this.userToken}`,
1078
- },
1079
- body: JSON.stringify({
1080
- poll_id: pollId,
1081
- }),
1082
- });
1083
- const json = await res.json();
1084
- return await json;
1085
- } catch (err) {
1086
- console.error(err);
1087
- throw new SidechatAPIError(`Failed to mark poll results as viewed.`);
1088
- }
1089
- };
1090
-
1091
- /**
1092
- * Uploads an asset to AWS S3 for use in posts and comments. Currently photos only
1093
- * @method
1094
- * @param {String} uri - URI of the asset to upload
1095
- * @param {String} mimeType - mimetype of the asset (e.g. "image/png")
1096
- * @param {String} [name] - filename of the asset
1097
- * @returns {String} URL of the uploaded asset
1098
- * @since 2.5.1
1099
- */
1100
- uploadAsset = async (uri, mimeType, name = "") => {
1101
- if (!this.userToken) {
1102
- throw new SidechatAPIError("User is not authenticated.");
1103
- }
1104
-
1105
- let imageType = mimeType.split("/")[1];
1106
- if (!["png", "jpeg", "gif"].includes(imageType)) {
1107
- throw new SidechatAPIError("Unsupported image format.");
1108
- }
1109
-
1110
- const data = new FormData();
1111
- data.append("image", {
1112
- name: name,
1113
- type: mimeType,
1114
- uri: uri,
1115
- });
1116
-
1117
- const urlReq = await this.sendRequest(`/v1/assets/upload_url?content_type=${imageType}`);
1118
- const urlJson = await urlReq.json();
1119
-
1120
- try {
1121
- const uploadReq = await fetch(urlJson.upload_url, {
1122
- body: data.getAll("image")[0],
1123
- method: "PUT",
1124
- headers: {
1125
- "Content-Type": mimeType,
1126
- },
1127
- });
1128
- if (uploadReq.status == 200) {
1129
- return `${this.apiRoot}/v1/assets/library/${urlJson.asset_id}`;
1130
- } else {
1131
- throw new SidechatAPIError(
1132
- `Couldn't upload image - error ${uploadReq.status}`
1133
- );
1134
- }
1135
- } catch (e) {
1136
- throw new SidechatAPIError(e.message);
1137
- }
1138
- };
1139
-
1140
- /**
1141
- * Sets the conversation icon of a user
1142
- * @method
1143
- * @since 2.2.1
1144
- * @param {String} userID - alphanumeric ID of user
1145
- * @param {String} emoji - emoji to set as icon
1146
- * @param {String} primaryColor - hex string (including #) of primary color
1147
- * @param {String} secondaryColor - hex string (including #) of secondary color
1148
- */
1149
- setUserIcon = async (userID, emoji, primaryColor, secondaryColor) => {
1150
- if (!this.userToken) {
1151
- throw new SidechatAPIError("User is not authenticated.");
1152
- }
1153
- try {
1154
- const res = await fetch(`${this.apiRoot}/v1/users/${userID}`, {
1155
- method: "PATCH",
1156
- headers: {
1157
- ...this.defaultHeaders,
1158
- "App-Version": "0",
1159
- Authorization: `Bearer ${this.userToken}`,
1160
- },
1161
- body: JSON.stringify({
1162
- conversation_icon: {
1163
- emoji: emoji,
1164
- secondary_color: secondaryColor,
1165
- is_migrated: true,
1166
- color: primaryColor,
1167
- },
1168
- }),
1169
- });
1170
- const json = await res.json();
1171
- return await json;
1172
- } catch (err) {
1173
- console.error(err);
1174
- throw new SidechatAPIError(`Failed to set icon.`);
1175
- }
1176
- };
1177
-
1178
- /**
1179
- * Sets the bio text of a user
1180
- * @method
1181
- * @since 2.5.6
1182
- * @param {String} userID - alphanumeric ID of user
1183
- * @param {String} bio - text to set as bio
1184
- */
1185
- setUserBio = async (userID, bio) => {
1186
- if (!this.userToken) {
1187
- throw new SidechatAPIError("User is not authenticated.");
1188
- }
1189
- try {
1190
- const res = await fetch(`${this.apiRoot}/v1/users/${userID}`, {
1191
- method: "PATCH",
1192
- headers: {
1193
- ...this.defaultHeaders,
1194
- "App-Version": "5.4.22",
1195
- Authorization: `Bearer ${this.userToken}`,
1196
- },
1197
- body: JSON.stringify({
1198
- bio: bio
1199
- }),
1200
- });
1201
- const json = await res.json();
1202
- return await json;
1203
- } catch (err) {
1204
- console.error(err);
1205
- throw new SidechatAPIError(`Failed to set bio.`);
1206
- }
1207
- };
1208
-
1209
- /**
1210
- * Checks if user can set their username to a string
1211
- * @method
1212
- * @since 2.3.6
1213
- * @param {String} username - string to check
1214
- * @returns {Boolean} whether or not username is valid and unused
1215
- */
1216
- checkUsername = async (username) => {
1217
- if (!this.userToken) {
1218
- throw new SidechatAPIError("User is not authenticated.");
1219
- }
1220
- try {
1221
- const res = await fetch(
1222
- `${this.apiRoot}/v1/users/username?username=${username}`,
1223
- {
1224
- method: "GET",
1225
- headers: {
1226
- ...this.defaultHeaders,
1227
- Authorization: `Bearer ${this.userToken}`,
1228
- },
1229
- }
1230
- );
1231
- if (res?.status == 200 || res?.status == 204) {
1232
- return true;
1233
- } else {
1234
- return false;
1235
- }
1236
- } catch (err) {
1237
- console.error(err);
1238
- throw new SidechatAPIError(`Failed to check username.`);
1239
- }
1240
- };
1241
-
1242
- /**
1243
- * Changes the username of the current user
1244
- * @method
1245
- * @since 2.3.6
1246
- * @param {String} userID - alphanumeric ID of user
1247
- * @param {String} username - new username to set
1248
- */
1249
- setUsername = async (userID, username) => {
1250
- if (!this.userToken) {
1251
- throw new SidechatAPIError("User is not authenticated.");
1252
- }
1253
- try {
1254
- const res = await fetch(`${this.apiRoot}/v1/users/${userID}`, {
1255
- method: "PATCH",
1256
- headers: {
1257
- ...this.defaultHeaders,
1258
- Authorization: `Bearer ${this.userToken}`,
1259
- },
1260
- body: JSON.stringify({
1261
- username: username,
1262
- }),
1263
- });
1264
- const json = await res.json();
1265
- return await json.user;
1266
- } catch (err) {
1267
- console.error(err);
1268
- throw new SidechatAPIError(`Failed to set icon.`);
1269
- }
1270
- };
1271
-
1272
- /**
1273
- * Fetches a public user profile
1274
- * @method
1275
- * @since 2.6.0
1276
- * @param {String} username - username of the user to fetch
1277
- * @returns {SidechatProfile}
1278
- */
1279
- getUserProfile = async (username) => {
1280
- if (!this.userToken) {
1281
- throw new SidechatAPIError("User is not authenticated.");
1282
- }
1283
- try {
1284
- const res = await fetch(`${this.apiRoot}/v1/groups/username?username=${username}`, {
1285
- method: "GET",
1286
- headers: {
1287
- ...this.defaultHeaders,
1288
- Authorization: `Bearer ${this.userToken}`,
1289
- }
1290
- });
1291
- const json = await res.json();
1292
- return await json.group;
1293
- } catch (err) {
1294
- console.error(err);
1295
- throw new SidechatAPIError(`Failed to set icon.`);
1296
- }
1297
- };
1298
-
1299
- /**
1300
- * Fetches a public user's posts
1301
- * @method
1302
- * @since 2.6.0
1303
- * @param {String} username - username of the user to fetch
1304
- * @returns {SidechatPostOrComment[]}
1305
- */
1306
- getUserPosts = async (username) => {
1307
- if (!this.userToken) {
1308
- throw new SidechatAPIError("User is not authenticated.");
1309
- }
1310
- try {
1311
- const res = await fetch(`${this.apiRoot}/v1/users/posts?username=${username}`, {
1312
- method: "GET",
1313
- headers: {
1314
- ...this.defaultHeaders,
1315
- Authorization: `Bearer ${this.userToken}`,
1316
- }
1317
- });
1318
- const json = await res.json();
1319
- return await json.posts;
1320
- } catch (err) {
1321
- console.error(err);
1322
- throw new SidechatAPIError(`Failed to set icon.`);
1323
- }
1324
- };
1325
-
1326
- /**
1327
- * Marks an activity item as read
1328
- * @method
1329
- * @since 2.3.2
1330
- * @param {String} activityID - alphanumeric ID of activity object
1331
- */
1332
- readActivity = async (activityID) => {
1333
- if (!this.userToken) {
1334
- throw new SidechatAPIError("User is not authenticated.");
1335
- }
1336
- try {
1337
- const res = await fetch(`${this.apiRoot}/v1/activity/seen`, {
1338
- method: "POST",
1339
- headers: {
1340
- ...this.defaultHeaders,
1341
- Authorization: `Bearer ${this.userToken}`,
1342
- },
1343
- body: JSON.stringify({
1344
- ids: [activityID],
1345
- }),
1346
- });
1347
- const json = await res.json();
1348
- return await json;
1349
- } catch (err) {
1350
- console.error(err);
1351
- throw new SidechatAPIError(`Failed to mark activity as read.`);
1352
- }
1353
- };
1354
-
1355
- /**
1356
- * Retrieves joinable group chats
1357
- * @method
1358
- * @since 2.3.5
1359
- */
1360
- getGroupChats = async () => {
1361
- if (!this.userToken) {
1362
- throw new SidechatAPIError("User is not authenticated.");
1363
- }
1364
- try {
1365
- const res = await fetch(`${this.apiRoot}/v1/chats/explore`, {
1366
- method: "GET",
1367
- headers: {
1368
- ...this.defaultHeaders,
1369
- Authorization: `Bearer ${this.userToken}`,
1370
- },
1371
- });
1372
- const json = await res.json();
1373
- return await json.chats;
1374
- } catch (err) {
1375
- console.error(err);
1376
- throw new SidechatAPIError(`Failed to get groupchats.`);
1377
- }
1378
- };
1379
-
1380
- /**
1381
- * Joins a group chat. To mimic the official client, use the user's display name and icon by default.
1382
- * @method
1383
- * @param {String} groupChatID - alphanumeric ID of group chat to join
1384
- * @param {String} displayName - display name to use in chat
1385
- * @param {String} emoji - emoji to use as icon
1386
- * @param {String} primaryColor - hex string of primary color
1387
- * @param {String} secondaryColor - hex string of secondary color
1388
- * @since 2.3.5
1389
- */
1390
- joinGroupChat = async (
1391
- groupChatID,
1392
- displayName,
1393
- emoji,
1394
- primaryColor,
1395
- secondaryColor
1396
- ) => {
1397
- if (!this.userToken) {
1398
- throw new SidechatAPIError("User is not authenticated.");
1399
- }
1400
- try {
1401
- const res = await fetch(`${this.apiRoot}/v1/chats/groups/join`, {
1402
- method: "POST",
1403
- headers: {
1404
- ...this.defaultHeaders,
1405
- Authorization: `Bearer ${this.userToken}`,
1406
- },
1407
- body: JSON.stringify({
1408
- chat_id: groupChatID,
1409
- identity: {
1410
- display_name: displayName,
1411
- emoji: emoji,
1412
- secondary_color: secondaryColor,
1413
- color: primaryColor,
1414
- },
1415
- }),
1416
- });
1417
- const json = await res.json();
1418
- return await json;
1419
- } catch (err) {
1420
- console.error(err);
1421
- throw new SidechatAPIError(`Failed to join groupchat.`);
1422
- }
1423
- };
1424
-
1425
- /**
1426
- * Gets a list of the user's direct messages
1427
- * @method
1428
- * @returns {SidechatDirectThread[]}
1429
- * @since 2.4.4
1430
- */
1431
- getDMs = async () => {
1432
- if (!this.userToken) {
1433
- throw new SidechatAPIError("User is not authenticated.");
1434
- }
1435
- try {
1436
- const res = await fetch(`${this.apiRoot}/v1/chats`, {
1437
- method: "GET",
1438
- headers: {
1439
- ...this.defaultHeaders,
1440
- Authorization: `Bearer ${this.userToken}`,
1441
- },
1442
- });
1443
- const json = await res.json();
1444
- const list = await json.chats;
1445
- let r = [];
1446
- list.forEach((o) => {
1447
- r.push(o.chat);
1448
- });
1449
- return await r;
1450
- } catch (err) {
1451
- console.error(err);
1452
- throw new SidechatAPIError(`Failed to fetch DMs.`);
1453
- }
1454
- };
1455
-
1456
- /**
1457
- * Gets a single direct message thread
1458
- * @method
1459
- * @param {String} id - alphanumeric ID of the chat to fetch
1460
- * @returns {SidechatDirectThread}
1461
- * @since 2.4.4
1462
- */
1463
- getDMThread = async (id) => {
1464
- if (!this.userToken) {
1465
- throw new SidechatAPIError("User is not authenticated.");
1466
- }
1467
- try {
1468
- const res = await fetch(
1469
- `${this.apiRoot}/v1/chats/messages?chat_id=${id}`,
1470
- {
1471
- method: "GET",
1472
- headers: {
1473
- ...this.defaultHeaders,
1474
- Authorization: `Bearer ${this.userToken}`,
1475
- },
1476
- }
1477
- );
1478
- const json = await res.json();
1479
- return await json.chat;
1480
- } catch (err) {
1481
- console.error(err);
1482
- throw new SidechatAPIError(`Failed to fetch DM thread.`);
1483
- }
1484
- };
1485
-
1486
- /**
1487
- * Sends a message to an existing direct message thread - note that you must first use startDM() to start a thread.
1488
- * @method
1489
- * @param {String} chatID - alphanumeric ID of the chat to send to
1490
- * @param {String} text - text content of message
1491
- * @param {String} clientID - alphanumeric device ID
1492
- * @param {SidechatAsset[]} assets - array of assets to send
1493
- * @param {Boolean} anonymous - whether the DM should be sent anonymously
1494
- * @since 2.4.4
1495
- */
1496
- sendDM = async (chatID, text, clientID, assets = [], anonymous = false) => {
1497
- if (!this.userToken) {
1498
- throw new SidechatAPIError("User is not authenticated.");
1499
- }
1500
- try {
1501
- const res = await fetch(`${this.apiRoot}/v1/chats/send`, {
1502
- method: "POST",
1503
- headers: {
1504
- ...this.defaultHeaders,
1505
- Authorization: `Bearer ${this.userToken}`,
1506
- },
1507
- body: JSON.stringify({
1508
- chat_id: chatID,
1509
- text: text,
1510
- client_id: clientID,
1511
- anonymous: anonymous,
1512
- assets: assets,
1513
- }),
1514
- });
1515
- const json = await res.json();
1516
- return await json;
1517
- } catch (err) {
1518
- console.error(err);
1519
- throw new SidechatAPIError(`Failed to send message.`);
1520
- }
1521
- };
1522
-
1523
- /**
1524
- * Creates a new direct message thread
1525
- * @method
1526
- * @param {String} text - text content of message
1527
- * @param {String} clientID - alphanumeric ID of devide
1528
- * @param {String} postID - alphanumeric ID of post or comment
1529
- * @param {Boolean} anonymous - whether the DM should be sent anonymously
1530
- * @param {"feed"} postContext - context of post (mostly undocumented, defaults to "feed")
1531
- * @since 2.4.4
1532
- */
1533
- startDM = async (
1534
- text,
1535
- clientID,
1536
- postID,
1537
- anonymous = false,
1538
- postContext = "feed"
1539
- ) => {
1540
- if (!this.userToken) {
1541
- throw new SidechatAPIError("User is not authenticated.");
1542
- }
1543
- try {
1544
- const res = await fetch(`${this.apiRoot}/v1/chats/start`, {
1545
- method: "POST",
1546
- headers: {
1547
- ...this.defaultHeaders,
1548
- Authorization: `Bearer ${this.userToken}`,
1549
- },
1550
- body: JSON.stringify({
1551
- text: text,
1552
- client_id: clientID,
1553
- post_id: postID,
1554
- anonymous: anonymous,
1555
- post_context: postContext,
1556
- }),
1557
- });
1558
- const json = await res.json();
1559
- return await json;
1560
- } catch (err) {
1561
- console.error(err);
1562
- throw new SidechatAPIError(`Failed to start DM.`);
1563
- }
1564
- };
216
+ /** @import * as types from "../types/SidechatTypes.js" */
217
+
218
+ /**
219
+ * API client class for making requests to Sidechat's private API. You'll need to [authenticate]{@tutorial Authentication} before using most of the methods.
220
+ * @class
221
+ * @since 2.0.0-alpha.0
222
+ */
223
+ class SidechatAPIClient {
224
+ /**
225
+ * User bearer token
226
+ * @type {types.SidechatAuthToken}
227
+ * */
228
+ userToken;
229
+
230
+ /**
231
+ * Default headers for every API request
232
+ * @type {Object}
233
+ * @static
234
+ * @constant
235
+ */
236
+ defaultHeaders = {
237
+ Accept: "application/json",
238
+ "Content-Type": "application/json",
239
+ "App-Version": "6.0.0",
240
+ Dnt: 1,
241
+ };
242
+
243
+ /**
244
+ * Root URL for every API request
245
+ * @type {String}
246
+ * @default "https://api.sidechat.lol"
247
+ */
248
+ apiRoot = "https://api.sidechat.lol";
249
+
250
+ /**
251
+ * Create a new instance of the API client
252
+ * @param {types.SidechatAuthToken} [token] - user bearer token
253
+ * @param {String} rootUrl - custom API root URL for mocking or using other server
254
+ */
255
+ constructor(token = "", rootUrl = "") {
256
+ if (token) {
257
+ this.userToken = token;
258
+ }
259
+ if (rootUrl) {
260
+ this.apiRoot = rootUrl;
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Manually set the currently signed in user's token. Generally try to avoid this and instead either pass a token to the constructor or login automatically through the auth functions
266
+ * @method
267
+ * @param {types.SidechatAuthToken} token - user bearer token
268
+ */
269
+ setToken = (token) => {
270
+ this.userToken = token;
271
+ };
272
+
273
+ /**
274
+ * Manually set the root URL for all API requests. This can be used for mocking requests or redirecting them to a different server
275
+ * @method
276
+ * @param {String} url - new root URL to set
277
+ * @since 2.3.9
278
+ */
279
+ setAPIRoot = (url) => {
280
+ this.apiRoot = url;
281
+ };
282
+
283
+ /**
284
+ * Run an arbitrary API request using the current client's authentication
285
+ * @method
286
+ * @param {String} endpoint - API endpoint to request (e.g. "/v1/posts")
287
+ * @param {"GET"|"POST"|"PUT"|"DELETE"|"PATCH"|"OPTIONS"} [method] - HTTP method to use
288
+ * @param {Object} [body] - body to send with the request
289
+ * @param {Object} [headers] - custom headers to send with the request
290
+ * @param {Boolean} [stripHeaders] - remove the default headers from the request
291
+ * @since 2.4.9
292
+ */
293
+ sendRequest = (
294
+ endpoint,
295
+ method = "GET",
296
+ body = undefined,
297
+ headers = {},
298
+ stripHeaders = false
299
+ ) => {
300
+ let requestHeaders = this.defaultHeaders;
301
+ if (stripHeaders) {
302
+ headers = {};
303
+ }
304
+ requestHeaders = { ...requestHeaders, ...headers };
305
+ return fetch(`${this.apiRoot}${endpoint}`, {
306
+ headers: { Authorization: `Bearer ${this.userToken}`, ...requestHeaders },
307
+ body: body,
308
+ method: method,
309
+ });
310
+ };
311
+
312
+ /**
313
+ * Initiate the login process with a phone number. Should be followed up with verifySMSCode().
314
+ * @method
315
+ * @since 1.0.0
316
+ * @param {Number} phoneNumber - US phone number (WITHOUT +1) to send verification code to
317
+ */
318
+ loginViaSMS = async (phoneNumber) => {
319
+ try {
320
+ const res = await fetch(`${this.apiRoot}/v1/login_register`, {
321
+ method: "POST",
322
+ headers: this.defaultHeaders,
323
+ body: JSON.stringify({
324
+ phone_number: `+1${phoneNumber}`,
325
+ version: 3,
326
+ }),
327
+ });
328
+ const json = await res.json();
329
+ return json;
330
+ } catch (err) {
331
+ console.error(err);
332
+ throw new SidechatAPIError("Failed to request SMS verification.");
333
+ }
334
+ };
335
+
336
+ /**
337
+ * Verify the code sent via SMS with loginViaSMS(). If this function succeeds, the user will be authenticated for future requests.
338
+ * @method
339
+ * @since 1.0.0
340
+ * @param {Number} phoneNumber - US phone number (WITHOUT +1) that verification code was sent to
341
+ * @param {String} code - the verification code
342
+ */
343
+ verifySMSCode = async (phoneNumber, code) => {
344
+ try {
345
+ const res = await fetch(`${this.apiRoot}/v1/verify_phone_number`, {
346
+ method: "POST",
347
+ headers: this.defaultHeaders,
348
+ body: JSON.stringify({
349
+ phone_number: `+1${phoneNumber}`,
350
+ code: code.toUpperCase(),
351
+ }),
352
+ });
353
+ const json = await res.json();
354
+ if (json?.logged_in_user?.token) {
355
+ this.userToken = json.logged_in_user.token;
356
+ }
357
+ return json;
358
+ } catch (err) {
359
+ console.error(err);
360
+ throw new SidechatAPIError("Failed verify this code.");
361
+ }
362
+ };
363
+
364
+ /**
365
+ * Set the user's age. If this function succeeds, the user will be authenticated for future requests.
366
+ * @method
367
+ * @since 1.0.0
368
+ * @param {Number} age - user's age in years
369
+ * @param {String} registrationID - the registration ID generated by verifySMSCode()
370
+ */
371
+ setAge = async (age, registrationID) => {
372
+ if (age < 13) {
373
+ throw new SidechatAPIError("You're too young to use Offsides.");
374
+ }
375
+ try {
376
+ const res = await fetch(`${this.apiRoot}/v1/complete_registration`, {
377
+ method: "POST",
378
+ headers: this.defaultHeaders,
379
+ body: JSON.stringify({
380
+ age: Number(age),
381
+ registration_id: registrationID,
382
+ }),
383
+ });
384
+ const json = await res.json();
385
+ if (json.token) {
386
+ this.userToken = json.token;
387
+ }
388
+ return json;
389
+ } catch (err) {
390
+ console.error(err);
391
+ throw new SidechatAPIError("Failed verify this code.");
392
+ }
393
+ };
394
+
395
+ /**
396
+ * Initiate the email setup process. Should be followed up with checkEmailVerification().
397
+ * @method
398
+ * @since 1.0.0
399
+ * @param {String} email - school email address to send verification code to
400
+ * @tutorial Email Registration
401
+ */
402
+ registerEmail = async (email) => {
403
+ if (!this.userToken) {
404
+ throw new SidechatAPIError("User is not authenticated.");
405
+ }
406
+ try {
407
+ const res = await fetch(`${this.apiRoot}/v2/users/register_email`, {
408
+ method: "POST",
409
+ headers: {
410
+ ...this.defaultHeaders,
411
+ Authorization: `Bearer ${this.userToken}`,
412
+ },
413
+ body: JSON.stringify({
414
+ email: email,
415
+ }),
416
+ });
417
+ const json = await res.json();
418
+ if (json.message) {
419
+ throw new SidechatAPIError(json.message);
420
+ }
421
+ return json;
422
+ } catch (err) {
423
+ console.error(err);
424
+ throw new SidechatAPIError("Failed to request email verification.");
425
+ }
426
+ };
427
+
428
+ /**
429
+ * Check is the user's email is verified.
430
+ * @method
431
+ * @since 1.0.0
432
+ */
433
+ checkEmailVerification = async () => {
434
+ if (!this.userToken) {
435
+ throw new SidechatAPIError("User is not authenticated.");
436
+ }
437
+ try {
438
+ const res = await fetch(`${this.apiRoot}/v1/users/check_email_verified`, {
439
+ method: "GET",
440
+ headers: {
441
+ ...this.defaultHeaders,
442
+ Authorization: `Bearer ${this.userToken}`,
443
+ },
444
+ });
445
+ const json = await res.json();
446
+ if (json.verified_email_updates_response) {
447
+ return json.verified_email_updates_response;
448
+ } else if (json.changing_phone_number_verified_email_user) {
449
+ return json.changing_phone_number_verified_email_user;
450
+ } else {
451
+ throw new SidechatAPIError(json?.message || "Email is not verified.");
452
+ }
453
+ } catch (err) {
454
+ console.error(err);
455
+ throw new SidechatAPIError("Email is not verified.");
456
+ }
457
+ };
458
+
459
+ /**
460
+ * Set the device ID of the current user
461
+ * @method
462
+ * @since 1.0.0
463
+ * @param {String} deviceId - the device ID to set
464
+ */
465
+ setDeviceID = async (deviceID) => {
466
+ if (!this.userToken) {
467
+ throw new SidechatAPIError("User is not authenticated.");
468
+ }
469
+ try {
470
+ const res = await fetch(`${this.apiRoot}/v1/register_device_token`, {
471
+ method: "POST",
472
+ headers: {
473
+ ...this.defaultHeaders,
474
+ Authorization: `Bearer ${this.userToken}`,
475
+ },
476
+ body: JSON.stringify({
477
+ build_type: "release",
478
+ bundle_id: "com.flowerave.sidechat",
479
+ device_token: deviceID,
480
+ }),
481
+ });
482
+ const json = await res.json();
483
+ return json;
484
+ } catch (err) {
485
+ console.error(err);
486
+ throw new SidechatAPIError("Failed verify this code.");
487
+ }
488
+ };
489
+
490
+ /**
491
+ * Get updated status for user and group
492
+ * @method
493
+ * @since 1.0.0
494
+ * @deprecated since 2.1.0, will be removed by 3.0.0. Please use `getUpdates` instead!
495
+ * @param {String} [groupID] - ID of a specific group to retrieve info from. Falls back to user's primary group.
496
+ */
497
+ getUserAndGroup = async (groupID = "") => {
498
+ const json = await this.getUpdates(groupID);
499
+ return json;
500
+ };
501
+
502
+ /**
503
+ * Get updated status for user and group
504
+ * @method
505
+ * @since 2.1.0
506
+ * @param {String} [groupID] - ID of a specific group to retrieve info from. Falls back to user's primary group.
507
+ */
508
+ getUpdates = async (groupID = "") => {
509
+ if (!this.userToken) {
510
+ throw new SidechatAPIError("User is not authenticated.");
511
+ }
512
+ try {
513
+ const res = await fetch(
514
+ `${this.apiRoot}/v1/updates?group_id=${groupID}`,
515
+ {
516
+ method: "GET",
517
+ headers: {
518
+ ...this.defaultHeaders,
519
+ Authorization: `Bearer ${this.userToken}`,
520
+ },
521
+ }
522
+ );
523
+ const json = await res.json();
524
+ return json;
525
+ } catch (err) {
526
+ console.error(err);
527
+ throw new SidechatAPIError(`Failed to get posts from group.`);
528
+ }
529
+ };
530
+
531
+ /**
532
+ * Fetches posts from the specified category in a group
533
+ * @method
534
+ * @since 1.0.0
535
+ * @param {String} groupID - group ID
536
+ * @param {"hot"|"recent"|"top"} category - category to filter posts
537
+ * @param {types.SidechatCursorString} [cursor] - cursor string
538
+ * @returns {Promise<types.SidechatPostsAndCursor>} List of posts and cursor
539
+ */
540
+ getGroupPosts = async (groupID, category = "hot", cursor) => {
541
+ if (!this.userToken) {
542
+ throw new SidechatAPIError("User is not authenticated.");
543
+ }
544
+ try {
545
+ const res = await fetch(
546
+ `${this.apiRoot}/v1/posts?${cursor ? "cursor=" + encodeURIComponent(cursor) + "&" : ""
547
+ }group_id=${groupID}&type=${category}`,
548
+ {
549
+ method: "GET",
550
+ headers: {
551
+ ...this.defaultHeaders,
552
+ Authorization: `Bearer ${this.userToken}`,
553
+ },
554
+ }
555
+ );
556
+ const json = await res.json();
557
+ return json;
558
+ } catch (err) {
559
+ console.error(err);
560
+ throw new SidechatAPIError(`Failed to get posts from group.`);
561
+ }
562
+ };
563
+
564
+ /**
565
+ * Upvote or downvote, or unvote a post
566
+ * @method
567
+ * @since 2.0.0-alpha.0
568
+ * @param {String} postID - post ID to vote on
569
+ * @param {types.SidechatVoteString} action - whether to upvote, downvote, or reset vote
570
+ */
571
+ setVote = async (postID, action) => {
572
+ if (!this.userToken) {
573
+ throw new SidechatAPIError("User is not authenticated.");
574
+ }
575
+ try {
576
+ const res = await fetch(`${this.apiRoot}/v1/posts/set_vote`, {
577
+ method: "POST",
578
+ headers: {
579
+ ...this.defaultHeaders,
580
+ Authorization: `Bearer ${this.userToken}`,
581
+ },
582
+ body: JSON.stringify({
583
+ post_id: postID,
584
+ vote_status: action,
585
+ }),
586
+ });
587
+ const json = await res.json();
588
+ return json;
589
+ } catch (err) {
590
+ console.error(err);
591
+ throw new SidechatAPIError(`Failed to change the vote on post.`);
592
+ }
593
+ };
594
+
595
+ /**
596
+ * Fetches a single post with just its ID
597
+ * @method
598
+ * @since 2.3.0
599
+ * @param {String} postID - ID of post to fetch
600
+ * @param {Boolean} includeDeleted - undocumented
601
+ * @returns {Promise<types.SidechatPostOrComment>} post object
602
+ */
603
+ getPost = async (postID, includeDeleted = false) => {
604
+ if (!this.userToken) {
605
+ throw new SidechatAPIError("User is not authenticated.");
606
+ }
607
+ try {
608
+ const res = await fetch(
609
+ `${this.apiRoot}/v1/posts/get?include_deleted=${includeDeleted}&post_id=${postID}`,
610
+ {
611
+ method: "GET",
612
+ headers: {
613
+ ...this.defaultHeaders,
614
+ Authorization: `Bearer ${this.userToken}`,
615
+ },
616
+ }
617
+ );
618
+ const json = await res.json();
619
+ return json.post;
620
+ } catch (err) {
621
+ console.error(err);
622
+ throw new SidechatAPIError(`Failed to get post from ID.`);
623
+ }
624
+ };
625
+
626
+ /**
627
+ * Fetches the posts or comments that the user has created
628
+ * @method
629
+ * @since 2.3.5
630
+ * @param {"posts"|"comments"} contentType - type of user content to fetch
631
+ * @returns {Promise<types.SidechatPostOrComment[]>} post object
632
+ */
633
+ getUserContent = async (contentType) => {
634
+ if (!this.userToken) {
635
+ throw new SidechatAPIError("User is not authenticated.");
636
+ }
637
+ if (contentType == "posts") {
638
+ contentType = "my_posts";
639
+ } else if (contentType == "comments") {
640
+ contentType = "my_comments";
641
+ }
642
+ try {
643
+ const res = await fetch(`${this.apiRoot}/v1/posts&type=${contentType}`, {
644
+ method: "GET",
645
+ headers: {
646
+ ...this.defaultHeaders,
647
+ Authorization: `Bearer ${this.userToken}`,
648
+ },
649
+ });
650
+ const json = await res.json();
651
+ return json.posts;
652
+ } catch (err) {
653
+ console.error(err);
654
+ throw new SidechatAPIError(`Failed to get content from user.`);
655
+ }
656
+ };
657
+
658
+ /**
659
+ * Get all the commments on a post
660
+ * @method
661
+ * @since 2.0.0-alpha.0
662
+ * @param {String} postID - post ID to get comments for
663
+ * @returns {Promise<types.SidechatPostOrComment[]>} list of comments
664
+ */
665
+ getPostComments = async (postID) => {
666
+ if (!this.userToken) {
667
+ throw new SidechatAPIError("User is not authenticated.");
668
+ }
669
+ try {
670
+ const res = await fetch(
671
+ `${this.apiRoot}/v1/posts/comments/?post_id=${postID}`,
672
+ {
673
+ method: "GET",
674
+ headers: {
675
+ ...this.defaultHeaders,
676
+ Authorization: `Bearer ${this.userToken}`,
677
+ },
678
+ }
679
+ );
680
+ const json = await res.json();
681
+ // Function to preprocess the comments and organize them into a nested structure
682
+ function preprocessComments(apiComments) {
683
+ // Map to store comments by their IDs for efficient lookup
684
+ const commentMap = new Map();
685
+ // List to store top-level comments
686
+ const topLevelComments = [];
687
+
688
+ // Iterate through the API comments
689
+ apiComments.forEach((comment) => {
690
+ // Store the comment in the map with its ID as the key
691
+ commentMap.set(comment.id, comment);
692
+ // Get the parent comment using the reply_post_id
693
+ const parentComment = commentMap.get(comment.reply_post_id);
694
+ // Check if the comment is a top-level comment
695
+ if (
696
+ !parentComment ||
697
+ comment.reply_post_id === comment.parent_post_id
698
+ ) {
699
+ // If it's a top-level comment, push it to the topLevelComments array
700
+ topLevelComments.push(comment);
701
+ } else {
702
+ // If it's a reply, add it to the parent comment's replies array
703
+ if (!parentComment.replies) parentComment.replies = [];
704
+ parentComment.replies.push(comment);
705
+ }
706
+ });
707
+
708
+ // Flatten the nested structure and return a single list of comments
709
+ return flattenComments(topLevelComments);
710
+ }
711
+
712
+ // Function to flatten nested comments into a single list
713
+ function flattenComments(comments) {
714
+ // Use reduce to flatten the nested comments array into a single list
715
+ return comments.reduce((flatComments, comment) => {
716
+ // Push the current comment to the flatComments array
717
+ flatComments.push(comment);
718
+ // If the current comment has replies, recursively flatten them and push to the flatComments array
719
+ if (comment.replies)
720
+ flatComments.push(...flattenComments(comment.replies));
721
+ // Return the flatComments array
722
+ return flatComments;
723
+ }, []);
724
+ }
725
+
726
+ const sortedComments = preprocessComments(json.posts);
727
+ return sortedComments;
728
+ } catch (err) {
729
+ console.error(err);
730
+ throw new SidechatAPIError(`Failed to get comments on post.`);
731
+ }
732
+ };
733
+
734
+ /**
735
+ * Gets groups to be displayed on the "Explore Groups" page
736
+ * @method
737
+ * @since 2.0.0-alpha.0
738
+ * @param {Boolean} onePage - whether or not results should be returned as a single page
739
+ * @returns {Promise<types.SidechatGroup[]>}
740
+ */
741
+ getAvailableGroups = async (onePage = true) => {
742
+ if (!this.userToken) {
743
+ throw new SidechatAPIError("User is not authenticated.");
744
+ }
745
+ try {
746
+ const res = await fetch(`${this.apiRoot}/v1/groups/explore`, {
747
+ method: "GET",
748
+ headers: {
749
+ ...this.defaultHeaders,
750
+ "App-Version": onePage ? "0" : this.defaultHeaders["App-Version"],
751
+ Authorization: `Bearer ${this.userToken}`,
752
+ },
753
+ });
754
+ const json = await res.json();
755
+ return await json.groups;
756
+ } catch (err) {
757
+ console.error(err);
758
+ throw new SidechatAPIError(`Failed to get groups from explore.`);
759
+ }
760
+ };
761
+
762
+ /**
763
+ * Searches for new groups based on a query keyword
764
+ * @method
765
+ * @since 2.6.0
766
+ * @param {String} query - the string to search for. This will be encoded, so strings with spaces and special characters are okay.
767
+ * @returns {Promise<types.SidechatGroup[]>}
768
+ */
769
+ searchAvailableGroups = async (query) => {
770
+ if (!this.userToken) {
771
+ throw new SidechatAPIError("User is not authenticated.");
772
+ }
773
+ try {
774
+ const res = await fetch(`${this.apiRoot}/v1/groups/explore/search?term=${encodeURIComponent(query)}`, {
775
+ method: "GET",
776
+ headers: {
777
+ ...this.defaultHeaders,
778
+ Authorization: `Bearer ${this.userToken}`,
779
+ },
780
+ });
781
+ const json = await res.json();
782
+ return await json.results;
783
+ } catch (err) {
784
+ console.error(err);
785
+ throw new SidechatAPIError(`Failed to search groups.`);
786
+ }
787
+ };
788
+
789
+ /**
790
+ * Retrieves the entire accessible asset library. Be warned that as of the time of this documentation, it's a 1.5MB JSON download and this request is very expensive.
791
+ * @method
792
+ * @since 2.0.6
793
+ * @returns {Promise<types.SidechatLibraryAsset[]>}
794
+ */
795
+ getAssetLibrary = async () => {
796
+ if (!this.userToken) {
797
+ throw new SidechatAPIError("User is not authenticated.");
798
+ }
799
+ try {
800
+ const res = await fetch(`${this.apiRoot}/v1/assets/library`, {
801
+ method: "GET",
802
+ headers: {
803
+ ...this.defaultHeaders,
804
+ Authorization: `Bearer ${this.userToken}`,
805
+ },
806
+ });
807
+ const json = await res.json();
808
+ return await json.items;
809
+ } catch (err) {
810
+ console.error(err);
811
+ throw new SidechatAPIError(`Failed to get asset library.`);
812
+ }
813
+ };
814
+
815
+ /**
816
+ * Gets the current authenticated user and a list of the groups of which they are members.
817
+ * @method
818
+ * @since 2.1.0
819
+ * @returns {Promise<types.SidechatCurrentUser>}
820
+ */
821
+ getCurrentUser = async () => {
822
+ if (!this.userToken) {
823
+ throw new SidechatAPIError("User is not authenticated.");
824
+ }
825
+ try {
826
+ const res = await fetch(`${this.apiRoot}/v1/users/me`, {
827
+ method: "GET",
828
+ headers: {
829
+ ...this.defaultHeaders,
830
+ Authorization: `Bearer ${this.userToken}`,
831
+ },
832
+ });
833
+ const json = await res.json();
834
+ return await json;
835
+ } catch (err) {
836
+ console.error(err);
837
+ throw new SidechatAPIError(`Failed to get asset library.`);
838
+ }
839
+ };
840
+
841
+ /**
842
+ * Gets the metadata of a group from its ID
843
+ * @method
844
+ * @since 2.1.0
845
+ * @param {String} [groupID] - alphanumeric ID of a group to get. Falls back to user's primary group.
846
+ * @returns {Promise<types.SidechatGroup>}
847
+ */
848
+ getGroupMetadata = async (groupID = "") => {
849
+ if (!this.userToken) {
850
+ throw new SidechatAPIError("User is not authenticated.");
851
+ }
852
+ try {
853
+ const res = await fetch(`${this.apiRoot}/v1/groups/${groupID}`, {
854
+ method: "GET",
855
+ headers: {
856
+ ...this.defaultHeaders,
857
+ Authorization: `Bearer ${this.userToken}`,
858
+ },
859
+ });
860
+ const json = await res.json();
861
+ return await json.group;
862
+ } catch (err) {
863
+ console.error(err);
864
+ throw new SidechatAPIError(`Failed to get group metadata.`);
865
+ }
866
+ };
867
+
868
+ /**
869
+ * Joins or leaves a group
870
+ * @method
871
+ * @param {String} groupID - alphanumeric ID of group to join or leave
872
+ * @param {Boolean} isMember - whether or not the user should be a member of the group
873
+ * @since 2.3.8
874
+ */
875
+ setGroupMembership = async (groupID, isMember) => {
876
+ if (!this.userToken) {
877
+ throw new SidechatAPIError("User is not authenticated.");
878
+ }
879
+ try {
880
+ const res = await fetch(
881
+ `${this.apiRoot}/v1/groups/${isMember ? "join" : "leave"}`,
882
+ {
883
+ method: "POST",
884
+ headers: {
885
+ ...this.defaultHeaders,
886
+ Authorization: `Bearer ${this.userToken}`,
887
+ },
888
+ body: JSON.stringify({
889
+ group_id: groupID,
890
+ }),
891
+ }
892
+ );
893
+ const json = await res.json();
894
+ return await json;
895
+ } catch (err) {
896
+ console.error(err);
897
+ throw new SidechatAPIError(`Failed to modify group membership.`);
898
+ }
899
+ };
900
+
901
+ /**
902
+ * Creates a comment on a post
903
+ * @method
904
+ * @since 2.2.0
905
+ * @param {String} parentPostID - alphanumeric ID of post on which this comment is made
906
+ * @param {String} text - text content of comment
907
+ * @param {String} groupID - alphanumeric ID of group in which the parent post resides
908
+ * @param {String} [replyCommentID] - alphanumeric ID of comment to reply to. Falls back to parentPostID
909
+ * @param {String} [topLevelReplyID] - alphanumeric ID of the top-level comment to reply to. Used only when replying to replies. Falls back to parentPostID
910
+ * @param {types.SidechatSimpleAsset[]} [assetList] - list of assets to attach
911
+ * @param {Boolean} [disableDMs] - prevent direct messages being sent to comment's author
912
+ * @param {Boolean} [anonymous] - whether or not to hide user's name and icon on comment
913
+ * @returns {Promise<types.SidechatPostOrComment>} created comment
914
+ */
915
+ createComment = async (
916
+ parentPostID,
917
+ text,
918
+ groupID,
919
+ replyCommentID,
920
+ topLevelReplyID,
921
+ assetList = [],
922
+ disableDMs = false,
923
+ anonymous = false
924
+ ) => {
925
+ if (!this.userToken) {
926
+ throw new SidechatAPIError("User is not authenticated.");
927
+ }
928
+ try {
929
+ const res = await fetch(`${this.apiRoot}/v1/posts`, {
930
+ method: "POST",
931
+ headers: {
932
+ ...this.defaultHeaders,
933
+ Authorization: `Bearer ${this.userToken}`,
934
+ },
935
+ body: JSON.stringify({
936
+ type: "comment",
937
+ assets: assetList,
938
+ group_ids: [groupID],
939
+ text: text,
940
+ reply_post_id: topLevelReplyID || replyCommentID || parentPostID,
941
+ reply_comment_post_id: replyCommentID || parentPostID,
942
+ parent_post_id: parentPostID,
943
+ dms_disabled: disableDMs,
944
+ using_identity: !anonymous,
945
+ }),
946
+ });
947
+ const json = await res.json();
948
+ return await json.comment;
949
+ } catch (err) {
950
+ console.error(err);
951
+ throw new SidechatAPIError(`Failed to post comment.`);
952
+ }
953
+ };
954
+
955
+ /**
956
+ * Creates a new post in the specified group
957
+ * @method
958
+ * @since 2.2.0
959
+ * @param {String} text - text content of comment
960
+ * @param {String} groupID - alphanumeric ID of group in which the parent post resides
961
+ * @param {types.SidechatSimpleAsset[]} [assetList] - list of assets to attach.
962
+ * @param {Boolean} [disableDMs] - prevent direct messages from being sent to post's author
963
+ * @param {Boolean} [disableComments] - whether or not comments should be disabled on post
964
+ * @param {Boolean} [anonymous] - whether or not to hide user's name and icon on post
965
+ * @param {Array<String>} [pollOptions] - List of poll options. If provided, a poll will be created with these options.
966
+ * @returns {Promise<types.SidechatPostOrComment>} the created post
967
+ */
968
+ createPost = async (
969
+ text,
970
+ groupID,
971
+ assetList = [],
972
+ disableDMs = false,
973
+ disableComments = false,
974
+ anonymous = false,
975
+ repostId = undefined,
976
+ pollOptions = undefined
977
+ ) => {
978
+ if (!this.userToken) {
979
+ throw new SidechatAPIError("User is not authenticated.");
980
+ }
981
+ try {
982
+ // Build the request body
983
+ const body = {
984
+ type: "post",
985
+ assets: assetList,
986
+ group_ids: [groupID],
987
+ text: text,
988
+ attachments: [],
989
+ dms_disabled: disableDMs,
990
+ comments_disabled: disableComments,
991
+ using_identity: !anonymous,
992
+ quote_post_id: repostId
993
+ };
994
+ // If pollOptions is provided and is a non-empty array, add poll_request
995
+ if (Array.isArray(pollOptions) && pollOptions.length > 0) {
996
+ body.poll_request = {
997
+ allows_view_results: true,
998
+ choices: pollOptions
999
+ };
1000
+ }
1001
+ const res = await fetch(`${this.apiRoot}/v1/posts`, {
1002
+ method: "POST",
1003
+ headers: {
1004
+ ...this.defaultHeaders,
1005
+ Authorization: `Bearer ${this.userToken}`,
1006
+ },
1007
+ body: JSON.stringify(body),
1008
+ });
1009
+ const json = await res.json();
1010
+ return await json.posts[0];
1011
+ } catch (err) {
1012
+ console.error(err);
1013
+ throw new SidechatAPIError(`Failed to make post.`);
1014
+ }
1015
+ };
1016
+
1017
+ /**
1018
+ * Deletes a post or comment that the user created
1019
+ * @method
1020
+ * @since 2.2.0
1021
+ * @param {String} postOrCommentID - alphanumeric ID of post to delete
1022
+ */
1023
+ deletePostOrComment = async (postOrCommentID) => {
1024
+ if (!this.userToken) {
1025
+ throw new SidechatAPIError("User is not authenticated.");
1026
+ }
1027
+ try {
1028
+ const res = await fetch(`${this.apiRoot}/v1/posts/delete`, {
1029
+ method: "POST",
1030
+ headers: {
1031
+ ...this.defaultHeaders,
1032
+ Authorization: `Bearer ${this.userToken}`,
1033
+ },
1034
+ body: JSON.stringify({
1035
+ post_id: postOrCommentID,
1036
+ }),
1037
+ });
1038
+ const json = await res.json();
1039
+ return await json;
1040
+ } catch (err) {
1041
+ console.error(err);
1042
+ throw new SidechatAPIError(`Failed to delete post.`);
1043
+ }
1044
+ };
1045
+
1046
+ /**
1047
+ * Votes on a poll attached to a post
1048
+ * @method
1049
+ * @param {String} pollId - alphanumeric ID of poll to vote on
1050
+ * @param {Number} choiceIndex - index of the choice to vote on
1051
+ * @since 2.5.4
1052
+ */
1053
+ voteOnPoll = async (pollId, choiceIndex) => {
1054
+ if (!this.userToken) {
1055
+ throw new SidechatAPIError("User is not authenticated.");
1056
+ }
1057
+ try {
1058
+ const res = await fetch(`${this.apiRoot}/v1/polls/vote`, {
1059
+ method: "POST",
1060
+ headers: {
1061
+ ...this.defaultHeaders,
1062
+ Authorization: `Bearer ${this.userToken}`,
1063
+ },
1064
+ body: JSON.stringify({
1065
+ poll_id: pollId,
1066
+ choice: choiceIndex,
1067
+ }),
1068
+ });
1069
+ const json = await res.json();
1070
+ return await json;
1071
+ } catch (err) {
1072
+ console.error(err);
1073
+ throw new SidechatAPIError(`Failed to vote on poll`);
1074
+ }
1075
+ };
1076
+
1077
+ /**
1078
+ * Marks that the user has viewed results on a poll. Note that this does not actually return the results of the poll.
1079
+ * @method
1080
+ * @param {String} pollId - alphanumeric ID of poll to vote on
1081
+ * @since 2.5.4
1082
+ */
1083
+ viewPollResults = async (pollId) => {
1084
+ if (!this.userToken) {
1085
+ throw new SidechatAPIError("User is not authenticated.");
1086
+ }
1087
+ try {
1088
+ const res = await fetch(`${this.apiRoot}/v1/polls/view_results`, {
1089
+ method: "POST",
1090
+ headers: {
1091
+ ...this.defaultHeaders,
1092
+ Authorization: `Bearer ${this.userToken}`,
1093
+ },
1094
+ body: JSON.stringify({
1095
+ poll_id: pollId,
1096
+ }),
1097
+ });
1098
+ const json = await res.json();
1099
+ return await json;
1100
+ } catch (err) {
1101
+ console.error(err);
1102
+ throw new SidechatAPIError(`Failed to mark poll results as viewed.`);
1103
+ }
1104
+ };
1105
+
1106
+ /**
1107
+ * Uploads an asset to AWS S3 for use in posts and comments. Currently photos only
1108
+ * @method
1109
+ * @param {String} uri - URI of the asset to upload
1110
+ * @param {String} mimeType - mimetype of the asset (e.g. "image/png")
1111
+ * @param {String} [name] - filename of the asset
1112
+ * @returns {Promise<String>} URL of the uploaded asset
1113
+ * @since 2.5.1
1114
+ */
1115
+ uploadAsset = async (uri, mimeType, name = "") => {
1116
+ if (!this.userToken) {
1117
+ throw new SidechatAPIError("User is not authenticated.");
1118
+ }
1119
+
1120
+ let imageType = mimeType.split("/")[1];
1121
+ if (!["png", "jpeg", "gif"].includes(imageType)) {
1122
+ throw new SidechatAPIError("Unsupported image format.");
1123
+ }
1124
+
1125
+ const data = new FormData();
1126
+ data.append("image", {
1127
+ name: name,
1128
+ type: mimeType,
1129
+ uri: uri,
1130
+ });
1131
+
1132
+ const urlReq = await this.sendRequest(`/v1/assets/upload_url?content_type=${imageType}`);
1133
+ const urlJson = await urlReq.json();
1134
+
1135
+ try {
1136
+ const uploadReq = await fetch(urlJson.upload_url, {
1137
+ body: data.getAll("image")[0],
1138
+ method: "PUT",
1139
+ headers: {
1140
+ "Content-Type": mimeType,
1141
+ },
1142
+ });
1143
+ if (uploadReq.status == 200) {
1144
+ return `${this.apiRoot}/v1/assets/library/${urlJson.asset_id}`;
1145
+ } else {
1146
+ throw new SidechatAPIError(
1147
+ `Couldn't upload image - error ${uploadReq.status}`
1148
+ );
1149
+ }
1150
+ } catch (e) {
1151
+ throw new SidechatAPIError(e.message);
1152
+ }
1153
+ };
1154
+
1155
+ /**
1156
+ * Sets the conversation icon of a user
1157
+ * @method
1158
+ * @since 2.2.1
1159
+ * @param {String} userID - alphanumeric ID of user
1160
+ * @param {String} emoji - emoji to set as icon
1161
+ * @param {String} primaryColor - hex string (including #) of primary color
1162
+ * @param {String} secondaryColor - hex string (including #) of secondary color
1163
+ */
1164
+ setUserIcon = async (userID, emoji, primaryColor, secondaryColor) => {
1165
+ if (!this.userToken) {
1166
+ throw new SidechatAPIError("User is not authenticated.");
1167
+ }
1168
+ try {
1169
+ const res = await fetch(`${this.apiRoot}/v1/users/${userID}`, {
1170
+ method: "PATCH",
1171
+ headers: {
1172
+ ...this.defaultHeaders,
1173
+ "App-Version": "0",
1174
+ Authorization: `Bearer ${this.userToken}`,
1175
+ },
1176
+ body: JSON.stringify({
1177
+ conversation_icon: {
1178
+ emoji: emoji,
1179
+ secondary_color: secondaryColor,
1180
+ is_migrated: true,
1181
+ color: primaryColor,
1182
+ },
1183
+ }),
1184
+ });
1185
+ const json = await res.json();
1186
+ return await json;
1187
+ } catch (err) {
1188
+ console.error(err);
1189
+ throw new SidechatAPIError(`Failed to set icon.`);
1190
+ }
1191
+ };
1192
+
1193
+ /**
1194
+ * Sets the bio text of a user
1195
+ * @method
1196
+ * @since 2.5.6
1197
+ * @param {String} userID - alphanumeric ID of user
1198
+ * @param {String} bio - text to set as bio
1199
+ */
1200
+ setUserBio = async (userID, bio) => {
1201
+ if (!this.userToken) {
1202
+ throw new SidechatAPIError("User is not authenticated.");
1203
+ }
1204
+ try {
1205
+ const res = await fetch(`${this.apiRoot}/v1/users/${userID}`, {
1206
+ method: "PATCH",
1207
+ headers: {
1208
+ ...this.defaultHeaders,
1209
+ "App-Version": "5.4.22",
1210
+ Authorization: `Bearer ${this.userToken}`,
1211
+ },
1212
+ body: JSON.stringify({
1213
+ bio: bio
1214
+ }),
1215
+ });
1216
+ const json = await res.json();
1217
+ return await json;
1218
+ } catch (err) {
1219
+ console.error(err);
1220
+ throw new SidechatAPIError(`Failed to set bio.`);
1221
+ }
1222
+ };
1223
+
1224
+ /**
1225
+ * Checks if user can set their username to a string
1226
+ * @method
1227
+ * @since 2.3.6
1228
+ * @param {String} username - string to check
1229
+ * @returns {Promise<Boolean>} whether or not username is valid and unused
1230
+ */
1231
+ checkUsername = async (username) => {
1232
+ if (!this.userToken) {
1233
+ throw new SidechatAPIError("User is not authenticated.");
1234
+ }
1235
+ try {
1236
+ const res = await fetch(
1237
+ `${this.apiRoot}/v1/users/username?username=${username}`,
1238
+ {
1239
+ method: "GET",
1240
+ headers: {
1241
+ ...this.defaultHeaders,
1242
+ Authorization: `Bearer ${this.userToken}`,
1243
+ },
1244
+ }
1245
+ );
1246
+ if (res?.status == 200 || res?.status == 204) {
1247
+ return true;
1248
+ } else {
1249
+ return false;
1250
+ }
1251
+ } catch (err) {
1252
+ console.error(err);
1253
+ throw new SidechatAPIError(`Failed to check username.`);
1254
+ }
1255
+ };
1256
+
1257
+ /**
1258
+ * Changes the username of the current user
1259
+ * @method
1260
+ * @since 2.3.6
1261
+ * @param {String} userID - alphanumeric ID of user
1262
+ * @param {String} username - new username to set
1263
+ */
1264
+ setUsername = async (userID, username) => {
1265
+ if (!this.userToken) {
1266
+ throw new SidechatAPIError("User is not authenticated.");
1267
+ }
1268
+ try {
1269
+ const res = await fetch(`${this.apiRoot}/v1/users/${userID}`, {
1270
+ method: "PATCH",
1271
+ headers: {
1272
+ ...this.defaultHeaders,
1273
+ Authorization: `Bearer ${this.userToken}`,
1274
+ },
1275
+ body: JSON.stringify({
1276
+ username: username,
1277
+ }),
1278
+ });
1279
+ const json = await res.json();
1280
+ return await json.user;
1281
+ } catch (err) {
1282
+ console.error(err);
1283
+ throw new SidechatAPIError(`Failed to set icon.`);
1284
+ }
1285
+ };
1286
+
1287
+ /**
1288
+ * Fetches a public user profile
1289
+ * @method
1290
+ * @since 2.6.0
1291
+ * @param {String} username - username of the user to fetch
1292
+ * @returns {Promise<types.SidechatProfile>}
1293
+ */
1294
+ getUserProfile = async (username) => {
1295
+ if (!this.userToken) {
1296
+ throw new SidechatAPIError("User is not authenticated.");
1297
+ }
1298
+ try {
1299
+ const res = await fetch(`${this.apiRoot}/v1/groups/username?username=${username}`, {
1300
+ method: "GET",
1301
+ headers: {
1302
+ ...this.defaultHeaders,
1303
+ Authorization: `Bearer ${this.userToken}`,
1304
+ }
1305
+ });
1306
+ const json = await res.json();
1307
+ return await json.group;
1308
+ } catch (err) {
1309
+ console.error(err);
1310
+ throw new SidechatAPIError(`Failed to set icon.`);
1311
+ }
1312
+ };
1313
+
1314
+ /**
1315
+ * Fetches a public user's posts
1316
+ * @method
1317
+ * @since 2.6.0
1318
+ * @param {String} username - username of the user to fetch
1319
+ * @returns {Promise<types.SidechatPostOrComment[]>}
1320
+ */
1321
+ getUserPosts = async (username) => {
1322
+ if (!this.userToken) {
1323
+ throw new SidechatAPIError("User is not authenticated.");
1324
+ }
1325
+ try {
1326
+ const res = await fetch(`${this.apiRoot}/v1/users/posts?username=${username}`, {
1327
+ method: "GET",
1328
+ headers: {
1329
+ ...this.defaultHeaders,
1330
+ Authorization: `Bearer ${this.userToken}`,
1331
+ }
1332
+ });
1333
+ const json = await res.json();
1334
+ return await json.posts;
1335
+ } catch (err) {
1336
+ console.error(err);
1337
+ throw new SidechatAPIError(`Failed to set icon.`);
1338
+ }
1339
+ };
1340
+
1341
+ /**
1342
+ * Marks an activity item as read
1343
+ * @method
1344
+ * @since 2.3.2
1345
+ * @param {String} activityID - alphanumeric ID of activity object
1346
+ */
1347
+ readActivity = async (activityID) => {
1348
+ if (!this.userToken) {
1349
+ throw new SidechatAPIError("User is not authenticated.");
1350
+ }
1351
+ try {
1352
+ const res = await fetch(`${this.apiRoot}/v1/activity/seen`, {
1353
+ method: "POST",
1354
+ headers: {
1355
+ ...this.defaultHeaders,
1356
+ Authorization: `Bearer ${this.userToken}`,
1357
+ },
1358
+ body: JSON.stringify({
1359
+ ids: [activityID],
1360
+ }),
1361
+ });
1362
+ const json = await res.json();
1363
+ return await json;
1364
+ } catch (err) {
1365
+ console.error(err);
1366
+ throw new SidechatAPIError(`Failed to mark activity as read.`);
1367
+ }
1368
+ };
1369
+
1370
+ /**
1371
+ * Retrieves joinable group chats
1372
+ * @method
1373
+ * @since 2.3.5
1374
+ */
1375
+ getGroupChats = async () => {
1376
+ if (!this.userToken) {
1377
+ throw new SidechatAPIError("User is not authenticated.");
1378
+ }
1379
+ try {
1380
+ const res = await fetch(`${this.apiRoot}/v1/chats/explore`, {
1381
+ method: "GET",
1382
+ headers: {
1383
+ ...this.defaultHeaders,
1384
+ Authorization: `Bearer ${this.userToken}`,
1385
+ },
1386
+ });
1387
+ const json = await res.json();
1388
+ return await json.chats;
1389
+ } catch (err) {
1390
+ console.error(err);
1391
+ throw new SidechatAPIError(`Failed to get groupchats.`);
1392
+ }
1393
+ };
1394
+
1395
+ /**
1396
+ * Joins a group chat. To mimic the official client, use the user's display name and icon by default.
1397
+ * @method
1398
+ * @param {String} groupChatID - alphanumeric ID of group chat to join
1399
+ * @param {String} displayName - display name to use in chat
1400
+ * @param {String} emoji - emoji to use as icon
1401
+ * @param {String} primaryColor - hex string of primary color
1402
+ * @param {String} secondaryColor - hex string of secondary color
1403
+ * @since 2.3.5
1404
+ */
1405
+ joinGroupChat = async (
1406
+ groupChatID,
1407
+ displayName,
1408
+ emoji,
1409
+ primaryColor,
1410
+ secondaryColor
1411
+ ) => {
1412
+ if (!this.userToken) {
1413
+ throw new SidechatAPIError("User is not authenticated.");
1414
+ }
1415
+ try {
1416
+ const res = await fetch(`${this.apiRoot}/v1/chats/groups/join`, {
1417
+ method: "POST",
1418
+ headers: {
1419
+ ...this.defaultHeaders,
1420
+ Authorization: `Bearer ${this.userToken}`,
1421
+ },
1422
+ body: JSON.stringify({
1423
+ chat_id: groupChatID,
1424
+ identity: {
1425
+ display_name: displayName,
1426
+ emoji: emoji,
1427
+ secondary_color: secondaryColor,
1428
+ color: primaryColor,
1429
+ },
1430
+ }),
1431
+ });
1432
+ const json = await res.json();
1433
+ return await json;
1434
+ } catch (err) {
1435
+ console.error(err);
1436
+ throw new SidechatAPIError(`Failed to join groupchat.`);
1437
+ }
1438
+ };
1439
+
1440
+ /**
1441
+ * Gets a list of the user's direct messages
1442
+ * @method
1443
+ * @returns {Promise<types.SidechatDirectThread[]>}
1444
+ * @since 2.4.4
1445
+ */
1446
+ getDMs = async () => {
1447
+ if (!this.userToken) {
1448
+ throw new SidechatAPIError("User is not authenticated.");
1449
+ }
1450
+ try {
1451
+ const res = await fetch(`${this.apiRoot}/v1/chats`, {
1452
+ method: "GET",
1453
+ headers: {
1454
+ ...this.defaultHeaders,
1455
+ Authorization: `Bearer ${this.userToken}`,
1456
+ },
1457
+ });
1458
+ const json = await res.json();
1459
+ const list = await json.chats;
1460
+ let r = [];
1461
+ list.forEach((o) => {
1462
+ r.push(o.chat);
1463
+ });
1464
+ return await r;
1465
+ } catch (err) {
1466
+ console.error(err);
1467
+ throw new SidechatAPIError(`Failed to fetch DMs.`);
1468
+ }
1469
+ };
1470
+
1471
+ /**
1472
+ * Gets a single direct message thread
1473
+ * @method
1474
+ * @param {String} id - alphanumeric ID of the chat to fetch
1475
+ * @returns {Promise<types.SidechatDirectThread>}
1476
+ * @since 2.4.4
1477
+ */
1478
+ getDMThread = async (id) => {
1479
+ if (!this.userToken) {
1480
+ throw new SidechatAPIError("User is not authenticated.");
1481
+ }
1482
+ try {
1483
+ const res = await fetch(
1484
+ `${this.apiRoot}/v1/chats/messages?chat_id=${id}`,
1485
+ {
1486
+ method: "GET",
1487
+ headers: {
1488
+ ...this.defaultHeaders,
1489
+ Authorization: `Bearer ${this.userToken}`,
1490
+ },
1491
+ }
1492
+ );
1493
+ const json = await res.json();
1494
+ return await json.chat;
1495
+ } catch (err) {
1496
+ console.error(err);
1497
+ throw new SidechatAPIError(`Failed to fetch DM thread.`);
1498
+ }
1499
+ };
1500
+
1501
+ /**
1502
+ * Sends a message to an existing direct message thread - note that you must first use startDM() to start a thread.
1503
+ * @method
1504
+ * @param {String} chatID - alphanumeric ID of the chat to send to
1505
+ * @param {String} text - text content of message
1506
+ * @param {String} clientID - alphanumeric device ID
1507
+ * @param {types.SidechatAsset[]} assets - array of assets to send
1508
+ * @param {Boolean} anonymous - whether the DM should be sent anonymously
1509
+ * @since 2.4.4
1510
+ */
1511
+ sendDM = async (chatID, text, clientID, assets = [], anonymous = false) => {
1512
+ if (!this.userToken) {
1513
+ throw new SidechatAPIError("User is not authenticated.");
1514
+ }
1515
+ try {
1516
+ const res = await fetch(`${this.apiRoot}/v1/chats/send`, {
1517
+ method: "POST",
1518
+ headers: {
1519
+ ...this.defaultHeaders,
1520
+ Authorization: `Bearer ${this.userToken}`,
1521
+ },
1522
+ body: JSON.stringify({
1523
+ chat_id: chatID,
1524
+ text: text,
1525
+ client_id: clientID,
1526
+ anonymous: anonymous,
1527
+ assets: assets,
1528
+ }),
1529
+ });
1530
+ const json = await res.json();
1531
+ return await json;
1532
+ } catch (err) {
1533
+ console.error(err);
1534
+ throw new SidechatAPIError(`Failed to send message.`);
1535
+ }
1536
+ };
1537
+
1538
+ /**
1539
+ * Creates a new direct message thread
1540
+ * @method
1541
+ * @param {String} text - text content of message
1542
+ * @param {String} clientID - alphanumeric ID of devide
1543
+ * @param {String} postID - alphanumeric ID of post or comment
1544
+ * @param {Boolean} anonymous - whether the DM should be sent anonymously
1545
+ * @param {"feed"} postContext - context of post (mostly undocumented, defaults to "feed")
1546
+ * @since 2.4.4
1547
+ */
1548
+ startDM = async (
1549
+ text,
1550
+ clientID,
1551
+ postID,
1552
+ anonymous = false,
1553
+ postContext = "feed"
1554
+ ) => {
1555
+ if (!this.userToken) {
1556
+ throw new SidechatAPIError("User is not authenticated.");
1557
+ }
1558
+ try {
1559
+ const res = await fetch(`${this.apiRoot}/v1/chats/start`, {
1560
+ method: "POST",
1561
+ headers: {
1562
+ ...this.defaultHeaders,
1563
+ Authorization: `Bearer ${this.userToken}`,
1564
+ },
1565
+ body: JSON.stringify({
1566
+ text: text,
1567
+ client_id: clientID,
1568
+ post_id: postID,
1569
+ anonymous: anonymous,
1570
+ post_context: postContext,
1571
+ }),
1572
+ });
1573
+ const json = await res.json();
1574
+ return await json;
1575
+ } catch (err) {
1576
+ console.error(err);
1577
+ throw new SidechatAPIError(`Failed to start DM.`);
1578
+ }
1579
+ };
1580
+
1581
+ /**
1582
+ * Hides posts from user
1583
+ * @method
1584
+ * @param {String} postID - alphanumeric ID of post to hide
1585
+ * @since 2.6.2
1586
+ */
1587
+ hidePostsFromUser = async (postID) => {
1588
+ if (!this.userToken) {
1589
+ throw new SidechatAPIError("User is not authenticated.");
1590
+ }
1591
+ try {
1592
+ const res = await fetch(`${this.apiRoot}/v1/posts/hide_posts_from_user`, {
1593
+ method: "POST",
1594
+ headers: {
1595
+ ...this.defaultHeaders,
1596
+ Authorization: `Bearer ${this.userToken}`,
1597
+ },
1598
+ body: JSON.stringify({
1599
+ post_id: postID,
1600
+ post_context: "feed",
1601
+ report: false
1602
+ }),
1603
+ });
1604
+ const json = await res.json();
1605
+ return await json;
1606
+ } catch (err) {
1607
+ console.error(err);
1608
+ throw new SidechatAPIError(`Failed to hide post.`);
1609
+ }
1610
+ };
1611
+
1612
+ /**
1613
+ * Unhides all posts from all users
1614
+ * @method
1615
+ * @since 2.6.2
1616
+ */
1617
+ unhidePostsFromAllUsers = async () => {
1618
+ if (!this.userToken) {
1619
+ throw new SidechatAPIError("User is not authenticated.");
1620
+ }
1621
+ try {
1622
+ const res = await fetch(`${this.apiRoot}/v1/users/unhide_all`, {
1623
+ method: "POST",
1624
+ headers: {
1625
+ ...this.defaultHeaders,
1626
+ Authorization: `Bearer ${this.userToken}`,
1627
+ },
1628
+ body: JSON.stringify({}),
1629
+ });
1630
+ const json = await res.json();
1631
+ return await json;
1632
+ } catch (err) {
1633
+ console.error(err);
1634
+ throw new SidechatAPIError(`Failed to unhide post.`);
1635
+ }
1636
+ };
1565
1637
  }
1566
1638
 
1567
1639
  /**