mastodon.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. // mastodon javascript lib
  2. // by @kirschn@pleasehug.me 2017
  3. // no fucking copyright
  4. // do whatever you want with it
  5. // but please don't hurt it (and keep this header)
  6. var MastodonAPI = function(config) {
  7. var apiBase = config.instance + "/api/v1/";
  8. return {
  9. setConfig: function (key, value) {
  10. config[key] = value;
  11. },
  12. getConfig: function(key) {
  13. return config[key];
  14. },
  15. get: function (endpoint) {
  16. var queryData,callback,queryStringAppend = "?";
  17. if (typeof arguments[1] === "function") {
  18. queryData = {};
  19. callback = arguments[1];
  20. } else {
  21. queryData = arguments[1];
  22. callback = arguments[2];
  23. }
  24. if(typeof queryData == "string") {
  25. queryStringAppend = queryData;
  26. }
  27. else {
  28. for (var i in queryData) {
  29. if (queryData.hasOwnProperty(i)) {
  30. if (typeof queryData[i] === "string") {
  31. queryStringAppend += queryData[i] + "&";
  32. } else if (typeof queryData[i] === "object") {
  33. queryStringAppend += queryData[i].name + "="+ queryData[i].data + "&";
  34. }
  35. }
  36. }
  37. }
  38. var xquerydata = queryData;
  39. $.ajax({
  40. url: apiBase + endpoint + queryStringAppend,
  41. type: "GET",
  42. headers: {"Authorization": "Bearer " + config.api_user_token},
  43. success: function(data, textStatus, xhr) {
  44. console.log("Successful GET API request to " +apiBase+endpoint);
  45. responce_headers = xhr.getAllResponseHeaders();
  46. callback(data,textStatus);
  47. },
  48. error: function(xhr, textStatus, errorThrown) {
  49. if(xhr.readyState == 0) {
  50. api.get(endpoint,queryStringAppend,callback);
  51. }
  52. else {
  53. if(xhr.responseText.length > 0) {
  54. putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);
  55. if ( xhr.status === 401 ) {
  56. location.href = "/logout";
  57. }
  58. }
  59. }
  60. }
  61. });
  62. },
  63. getArray: function (endpoint) {
  64. var queryData, callback,
  65. queryStringAppend = "?";
  66. if (typeof arguments[1] === "function") {
  67. queryData = {};
  68. callback = arguments[1];
  69. } else {
  70. queryData = arguments[1];
  71. callback = arguments[2];
  72. }
  73. for (var i in queryData) {
  74. if (queryData.hasOwnProperty(i)) {
  75. if (typeof queryData[i] === "string") {
  76. queryStringAppend += queryData[i] + "&";
  77. } else if (typeof queryData[i] === "object") {
  78. for ( var j in queryData[i].data ){
  79. queryStringAppend += queryData[i].name + "[]="+ queryData[i].data[j] + "&";
  80. }
  81. }
  82. }
  83. }
  84. $.ajax({
  85. url: apiBase + endpoint + queryStringAppend,
  86. type: "GET",
  87. headers: {"Authorization": "Bearer " + config.api_user_token},
  88. success: function(data, textStatus, xhr) {
  89. console.log("Successful GET API request to " +apiBase+endpoint);
  90. responce_headers = xhr.getAllResponseHeaders();
  91. callback(data,textStatus);
  92. },
  93. error: function(xhr, textStatus, errorThrown) {
  94. if(xhr.readyState == 0) {
  95. api.getArray(endpoint,queryData,callback);
  96. }
  97. else {
  98. putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);
  99. if ( xhr.status === 401 ) {
  100. location.href = "/logout";
  101. }
  102. }
  103. }
  104. });
  105. },
  106. getOther: function (domainAndEndpoint) {
  107. var queryData, callback,
  108. queryStringAppend = "?";
  109. if (typeof arguments[1] === "function") {
  110. queryData = {};
  111. callback = arguments[1];
  112. } else {
  113. queryData = arguments[1];
  114. callback = arguments[2];
  115. }
  116. for (var i in queryData) {
  117. if (queryData.hasOwnProperty(i)) {
  118. if (typeof queryData[i] === "string") {
  119. queryStringAppend += queryData[i] + "&";
  120. } else if (typeof queryData[i] === "object") {
  121. queryStringAppend += queryData[i].name + "="+ queryData[i].data + "&";
  122. }
  123. }
  124. }
  125. $.ajax({
  126. url: domainAndEndpoint + queryStringAppend,
  127. type: "GET",
  128. success: function(data, textStatus, xhr) {
  129. console.log("Successful GET API request to " +domainAndEndpoint);
  130. responce_headers = xhr.getAllResponseHeaders();
  131. callback(data,textStatus);
  132. },
  133. error: function(xhr, textStatus, errorThrown) {
  134. if(xhr.readyState == 0) {
  135. api.getOther(endpoint,queryData,callback);
  136. }
  137. else {
  138. putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);
  139. if ( xhr.status === 401 ) {
  140. location.href = "/logout";
  141. }
  142. }
  143. }
  144. });
  145. },
  146. post: function (endpoint) {
  147. var postData, callback;
  148. if (typeof arguments[1] === "function") {
  149. postData = {};
  150. callback = arguments[1];
  151. } else {
  152. postData = arguments[1];
  153. callback = arguments[2];
  154. }
  155. var requestHeaders = {"Authorization":"Bearer "+config.api_user_token};
  156. if(endpoint == "statuses") {
  157. if(arguments.length == 4) {
  158. var idempotencykey = arguments[3];
  159. }
  160. else {
  161. var idempotencykey = getRandom();
  162. }
  163. requestHeaders["Idempotency-Key"] = idempotencykey;
  164. }
  165. else {
  166. if(arguments.length == 4) {
  167. var errorback = arguments[3];
  168. }
  169. }
  170. $.ajax({
  171. url: apiBase + endpoint,
  172. type: "POST",
  173. data: postData,
  174. headers: requestHeaders,
  175. success: function(data, textStatus) {
  176. if(endpoint == "statuses") {
  177. $(".js_current_toots_count").html(++localStorage.current_statuses_count);
  178. }
  179. else if(endpoint.indexOf("/follow") != -1) {
  180. $(".js_current_following_count").html(++localStorage.current_following_count);
  181. }
  182. else if(endpoint.indexOf("/unfollow") != -1) {
  183. $(".js_current_following_count").html(--localStorage.current_following_count);
  184. }
  185. console.log("Successful POST API request to " +apiBase+endpoint);
  186. callback(data,textStatus)
  187. },
  188. error: function(xhr, textStatus, errorThrown) {
  189. if(xhr.readyState == 0) {
  190. api.post(endpoint,postData,callback,idempotencykey);
  191. }
  192. else {
  193. if(xhr.status === 401) {
  194. location.href = "/logout";
  195. }
  196. else {
  197. if(errorback) {
  198. errorback(xhr,textStatus,errorThrown);
  199. }
  200. else {
  201. putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);
  202. }
  203. }
  204. }
  205. }
  206. });
  207. },
  208. postMedia: function (endpoint) {
  209. var postData, callback;
  210. if (typeof arguments[1] === "function") {
  211. postData = {};
  212. callback = arguments[1];
  213. } else {
  214. postData = arguments[1];
  215. callback = arguments[2];
  216. }
  217. $.ajax({
  218. url: apiBase + endpoint,
  219. type: "POST",
  220. data: postData,
  221. contentType: false,
  222. processData: false,
  223. headers: {"Authorization": "Bearer " + config.api_user_token},
  224. success: function(data, textStatus) {
  225. console.log("Successful POST API request to " +apiBase+endpoint);
  226. callback(data,textStatus)
  227. },
  228. error: function(xhr, textStatus, errorThrown) {
  229. if(xhr.readyState == 0) {
  230. api.postMedia(endpoint,postData,callback);
  231. }
  232. else {
  233. putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);
  234. if ( xhr.status === 401 ) {
  235. location.href = "/logout";
  236. }
  237. }
  238. }
  239. });
  240. },
  241. delete: function (endpoint, callback) {
  242. $.ajax({
  243. url: apiBase + endpoint,
  244. type: "DELETE",
  245. headers: {"Authorization": "Bearer " + config.api_user_token},
  246. success: function(data, textStatus) {
  247. if(endpoint.indexOf("statuses") != -1) {
  248. $(".js_current_toots_count").html(--localStorage.current_statuses_count);
  249. }
  250. console.log("Successful DELETE API request to " +apiBase+endpoint);
  251. callback(data,textStatus)
  252. },
  253. error: function(xhr, textStatus, errorThrown) {
  254. if(xhr.readyState == 0) {
  255. api.delete(endpoint,callback);
  256. }
  257. else {
  258. putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);
  259. if ( xhr.status === 401 ) {
  260. location.href = "/logout";
  261. }
  262. }
  263. }
  264. });
  265. },
  266. patch: function (endpoint) {
  267. var postData, callback;
  268. if (typeof arguments[1] === "function") {
  269. postData = {};
  270. callback = arguments[1];
  271. } else {
  272. postData = arguments[1];
  273. callback = arguments[2];
  274. }
  275. var requestHeaders = {"Authorization":"Bearer "+config.api_user_token};
  276. $.ajax({
  277. url: apiBase + endpoint,
  278. type: "PATCH",
  279. data: postData,
  280. headers: requestHeaders,
  281. contentType: false,
  282. processData: false,
  283. success: function(data, textStatus) {
  284. console.log("Successful PATCH API request to " +apiBase+endpoint);
  285. callback(data,textStatus)
  286. },
  287. error: function(xhr, textStatus, errorThrown) {
  288. if(xhr.readyState == 0) {
  289. api.patch(endpoint,postData,callback);
  290. }
  291. else {
  292. putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);
  293. if ( xhr.status === 401 ) {
  294. location.href = "/logout";
  295. }
  296. }
  297. }
  298. });
  299. },
  300. put: function (endpoint) {
  301. var postData, callback;
  302. if (typeof arguments[1] === "function") {
  303. postData = {};
  304. callback = arguments[1];
  305. } else {
  306. postData = arguments[1];
  307. callback = arguments[2];
  308. }
  309. var requestHeaders = {"Authorization":"Bearer "+config.api_user_token};
  310. $.ajax({
  311. url: apiBase + endpoint,
  312. type: "PUT",
  313. data: postData,
  314. headers: requestHeaders,
  315. success: function(data, textStatus) {
  316. console.log("Successful PUT API request to " +apiBase+endpoint);
  317. callback(data,textStatus)
  318. },
  319. error: function(xhr, textStatus, errorThrown) {
  320. if(xhr.readyState == 0) {
  321. api.put(endpoint,postData,callback);
  322. }
  323. else {
  324. putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);
  325. if ( xhr.status === 401 ) {
  326. location.href = "/logout";
  327. }
  328. }
  329. }
  330. });
  331. },
  332. stream: function (streamType, onData) {
  333. var es = new WebSocket("wss://" + apiBase.substr(8) + "streaming?access_token=" + config.api_user_token + "&stream=" + streamType);
  334. var listener = function(event) {
  335. console.log("Got Data from Stream " + streamType);
  336. if(event.data.length != 0) {
  337. event = JSON.parse(event.data);
  338. if(event.event == "filters_changed") {
  339. api.get("filters",function(data) {
  340. localStorage.setItem("current_filters",JSON.stringify(data));
  341. current_filters = data;
  342. });
  343. }
  344. else {
  345. if(!Number.isInteger(JSON.parse(event.payload))) {
  346. event.payload = JSON.parse(event.payload);
  347. }
  348. onData(event);
  349. }
  350. }
  351. };
  352. es.onmessage = listener;
  353. es.onclose = function(event) {
  354. if(event.target.readyState == 0) {
  355. api.stream(streamType,onData);
  356. }
  357. };
  358. }
  359. };
  360. };