slackData.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. /**
  2. * @constructor
  3. **/
  4. function SlackTeam(teamId) {
  5. /** @const @type {string} */
  6. this.id = teamId;
  7. /** @type {string} */
  8. this.name;
  9. /** @type {string} */
  10. this.domain;
  11. /** @type {string} */
  12. this.callApp;
  13. /** @type {string} */
  14. this.callAppName;
  15. /** @type {boolean} */
  16. this.fileUploadPermission;
  17. /** @type {boolean} */
  18. this.fileEditPermission;
  19. /** @type {boolean} */
  20. this.fileDeletePermission;
  21. /** @type {Object.<string, string>} */
  22. this.icons = {
  23. image_34: ""
  24. ,image_44: ""
  25. ,image_68: ""
  26. ,image_88: ""
  27. ,image_102: ""
  28. ,image_132: ""
  29. ,image_230: ""
  30. ,image_default: ""
  31. };
  32. /** @type {number} */
  33. this.version = 0;
  34. }
  35. SlackTeam.prototype.update = function(teamData, t) {
  36. if (teamData["name"] !== undefined) this.name = teamData["name"];
  37. if (teamData["domain"] !== undefined) this.domain = teamData["domain"];
  38. if (teamData["prefs"]) {
  39. this.callApp = teamData["prefs"]["calling_app_id"];
  40. this.callAppName = teamData["prefs"]["calling_app_name"];
  41. this.fileUploadPermission = teamData["prefs"]["disable_file_uploads"];
  42. this.fileEditPermission = teamData["prefs"]["disable_file_editing"];
  43. this.fileDeletePermission = teamData["prefs"]["disable_file_deleting"];
  44. }
  45. if (teamData["icon"]) {
  46. this.icons.image_34 = teamData["icon"]["image_34"];
  47. this.icons.image_44 = teamData["icon"]["image_44"];
  48. this.icons.image_68 = teamData["icon"]["image_68"];
  49. this.icons.image_88 = teamData["icon"]["image_88"];
  50. this.icons.image_102 = teamData["icon"]["image_102"];
  51. this.icons.image_132 = teamData["icon"]["image_132"];
  52. this.icons.image_230 = teamData["icon"]["image_230"];
  53. this.icons.image_default = teamData["icon"]["image_default"];
  54. }
  55. this.version = Math.max(this.version, t);
  56. }
  57. /**
  58. * @constructor
  59. **/
  60. function SlackChan(chanId) {
  61. /** @const @type {string} */
  62. this.id = chanId;
  63. /** @type {string} */
  64. this.name;
  65. /** @type {string} */
  66. this.created;
  67. /** @type {SlackUser|SlackBot} */
  68. this.creator;
  69. /** @type {boolean} */
  70. this.archived;
  71. /** @type {boolean} */
  72. this.isMember;
  73. /** @type {number} */
  74. this.lastRead;
  75. /** @type {Object.<string, SlackBot|SlackUser>} */
  76. this.members = {};
  77. /** @type {string|undefined} */
  78. this.topic;
  79. /** @type {number|undefined} */
  80. this.topicTs;
  81. /** @type {SlackUser|SlackBot|undefined} */
  82. this.topicCreator;
  83. /** @type {string|undefined} */
  84. this.purpose;
  85. /** @type {number|undefined} */
  86. this.purposeTs;
  87. /** @type {SlackUser|SlackBot|undefined} */
  88. this.purposeCreator;
  89. /** @type {number} */
  90. this.version = 0;
  91. }
  92. /**
  93. * @param {*} chanData
  94. * @param {SlackData} slackData
  95. **/
  96. SlackChan.prototype.update = function(chanData, slackData, t) {
  97. if (chanData["name"] !== undefined) this.name = chanData["name"];
  98. if (chanData["created"] !== undefined) this.created = chanData["created"];
  99. if (chanData["creator"] !== undefined) this.creator = slackData.getMember(chanData["creator"]);
  100. if (chanData["is_archived"] !== undefined) this.archived = chanData["is_archived"];
  101. if (chanData["is_member"] !== undefined) this.isMember = chanData["is_member"];
  102. if (chanData["last_read"] !== undefined) this.lastRead = parseFloat(chanData["last_read"]);
  103. if (chanData["members"]) {
  104. this.members = {};
  105. if (chanData["members"]) for (var i =0, nbMembers = chanData["members"].length; i < nbMembers; i++) {
  106. var member = slackData.getMember(chanData["members"][i]);
  107. this.members[member.id] = member;
  108. member.channels[this.id] = this;
  109. }
  110. }
  111. if (chanData["topic"]) {
  112. this.topic = chanData["topic"]["value"];
  113. this.topicCreator = slackData.getMember(chanData["topic"]["creator"]);
  114. this.topicTs = chanData["topic"]["last_set"];
  115. }
  116. if (chanData["purpose"]) {
  117. this.purpose = chanData["purpose"]["value"];
  118. this.purposeCreator = slackData.getMember(chanData["purpose"]["creator"]);
  119. this.purposeTs = chanData["purpose"]["last_set"];
  120. }
  121. this.version = Math.max(this.version, t);
  122. }
  123. /**
  124. * @constructor
  125. * @param {string} id
  126. **/
  127. function SlackGroup(id) {
  128. /** @const @type {string} */
  129. this.id = id;
  130. /** @type {Object.<string, SlackUser|SlackBot>} */
  131. this.members = {};
  132. /** @type {number} */
  133. this.nbMembers = 0;
  134. /** @type {string} */
  135. this.name;
  136. /** @type {number} */
  137. this.created;
  138. /** @type {SlackUser|SlackBot} */
  139. this.creator;
  140. /** @type {boolean} */
  141. this.archived;
  142. /** @type {number} */
  143. this.lastRead;
  144. /** @type {string|undefined} */
  145. this.topic;
  146. /** @type {number|undefined} */
  147. this.topicTs;
  148. /** @type {SlackUser|SlackBot|undefined} */
  149. this.topicCreator;
  150. /** @type {string|undefined} */
  151. this.purpose;
  152. /** @type {number|undefined} */
  153. this.purposeTs;
  154. /** @type {SlackUser|SlackBot|undefined} */
  155. this.purposeCreator;
  156. /** @type {number} version */
  157. this.version = 0;
  158. }
  159. /**
  160. * @param {SlackData} slack
  161. * @param {*} groupData
  162. **/
  163. SlackGroup.prototype.update = function(slack, groupData, t) {
  164. var memberNames = [];
  165. if (groupData["members"]) {
  166. /** @type {Object.<string, SlackUser|SlackBot>} */
  167. this.members = {};
  168. this.nbMembers = 0;
  169. for (var i =0, nbMembers = groupData["members"].length; i < nbMembers; i++) {
  170. var member = slack.getMember(groupData["members"][i]);
  171. this.members[groupData["members"][i]] = member;
  172. member.channels[this.id] = this;
  173. memberNames.push(member.name);
  174. this.nbMembers++;
  175. }
  176. this.name = memberNames.join(", ");
  177. }
  178. if (groupData["created"] !== undefined) this.created = groupData["created"];
  179. if (groupData["creator"] !== undefined) this.creator = slack.getMember(groupData["creator"]);
  180. if (groupData["is_archived"] !== undefined) this.archived = groupData["is_archived"] || groupData["is_open"] === false;
  181. if (groupData["last_read"] !== undefined) this.lastRead = parseFloat(groupData["last_read"]);
  182. if (groupData["topic"]) {
  183. this.topic = groupData["topic"]["value"];
  184. this.topicCreator = slack.getMember(groupData["topic"]["creator"]);
  185. this.topicTs = groupData["topic"]["last_set"];
  186. }
  187. if (groupData["purpose"]) {
  188. this.purpose = groupData["purpose"]["value"];
  189. this.purposeCreator = slack.getMember(groupData["purpose"]["creator"]);
  190. this.purposeTs = groupData["purpose"]["last_set"];
  191. }
  192. this.version = Math.max(this.version, t);
  193. }
  194. /**
  195. * @constructor
  196. * @param {string} id
  197. * @param {SlackUser|SlackBot} user
  198. **/
  199. function SlackIms(id, user) {
  200. /** @const @type {string} */
  201. this.id = id;
  202. /** @type {number} */
  203. this.created;
  204. /** @type {SlackUser|SlackBot} */
  205. this.user = user;
  206. /** @type {number} */
  207. this.lastRead;
  208. /** @type {boolean} */
  209. this.archived;
  210. /** @type {number} */
  211. this.version = 0;
  212. }
  213. /**
  214. * @param {SlackUser|SlackBot} user
  215. * @param {*} imsData
  216. **/
  217. SlackIms.prototype.update = function(user, imsData, t) {
  218. this.created = imsData["created"];
  219. this.lastRead = parseFloat(imsData["last_read"]);
  220. this.archived = user.deleted;
  221. this.version = Math.max(this.version, t);
  222. }
  223. /**
  224. * @constructor
  225. **/
  226. function SlackUser(id) {
  227. /** @const @type {string} */
  228. this.id = id;
  229. /** @type {string} */
  230. this.name;
  231. /** @type {boolean} */
  232. this.deleted;
  233. /** @type {string} */
  234. this.status;
  235. /** @type {string} */
  236. this.realName;
  237. /** @type {boolean} */
  238. this.presence;
  239. /** @type {Object.<string, string>} */
  240. this.icons = {
  241. image_24: ""
  242. ,image_32: ""
  243. ,image_48: ""
  244. ,image_72: ""
  245. ,image_192: ""
  246. ,image_512: ""
  247. };
  248. /** @type {string} */
  249. this.email;
  250. /** @type {string} */
  251. this.firstName;
  252. /** @type {string} */
  253. this.lastName;
  254. /** @type {!Object.<string, SlackChan|SlackGroup>} */
  255. this.channels = {};
  256. /** @type {SlackIms} */
  257. this.ims = null;
  258. /** @type {SelfPreferences|null} */
  259. this.prefs = null;
  260. /** @type {number} */
  261. this.version = 0;
  262. }
  263. /**
  264. * @param {*} userData
  265. **/
  266. SlackUser.prototype.update = function(userData, t) {
  267. if (userData["name"] !== undefined) this.name = userData["name"];
  268. if (userData["deleted"] !== undefined) this.deleted = userData["deleted"];
  269. if (userData["status"] !== undefined) this.status = userData["status"];
  270. if (userData["real_name"] !== undefined)
  271. this.realName = userData["real_name"];
  272. else if (userData["profile"] && userData["profile"]["real_name"] !== undefined)
  273. this.realName = userData["profile"]["real_name"];
  274. if (userData["presence"] !== undefined)
  275. this.presence = userData["presence"] !== 'away';
  276. if (userData["isPresent"] !== undefined)
  277. this.presence = userData["isPresent"];
  278. if (userData["profile"]) {
  279. this.icons.image_24 = userData["profile"]["image_24"];
  280. this.icons.image_32 = userData["profile"]["image_32"];
  281. this.icons.image_48 = userData["profile"]["image_48"];
  282. this.icons.image_72 = userData["profile"]["image_72"];
  283. this.icons.image_192 = userData["profile"]["image_192"];
  284. this.icons.image_512 = userData["profile"]["image_512"];
  285. this.email = userData["profile"]["email"];
  286. this.firstName = userData["profile"]["first_name"];
  287. this.lastName = userData["profile"]["last_name"];
  288. }
  289. this.version = Math.max(this.version, t);
  290. }
  291. SlackUser.prototype.setPresence = function(presenceStr, t) {
  292. this.presence = presenceStr !== 'away';
  293. this.version = Math.max(t, this.version);
  294. }
  295. /**
  296. * @constructor
  297. **/
  298. function SelfPreferences() {
  299. /** @type {Object.<string, number>} */
  300. this.favoriteEmojis = {};
  301. /** @type {Array.<string>} */
  302. this.highlights = [];
  303. }
  304. /**
  305. * @param {*} prefs
  306. **/
  307. SelfPreferences.prototype.update = function(prefs, t) {
  308. this.favoriteEmojis = /** @type {Object<string,number>} */ (JSON.parse(prefs["emoji_use"]));
  309. if (prefs["highlight_words"])
  310. this.highlights = (prefs["highlight_words"]||"").split(',').filter(function(i) {
  311. return i.trim() !== '';
  312. });
  313. else if (prefs["highlights"])
  314. this.highlights = prefs["highlights"];
  315. this.version = Math.max(this.version, t);
  316. }
  317. /**
  318. * @constructor
  319. **/
  320. function SlackBot(id) {
  321. /** @const @type {string} */
  322. this.id = id;
  323. /** @type {boolean} */
  324. this.deleted;
  325. /** @type {string} */
  326. this.name;
  327. /** @type {string} */
  328. this.appId;
  329. /** @type {Object.<string, string>} */
  330. this.icons = {
  331. image_36: ""
  332. ,image_48: ""
  333. ,image_72: ""
  334. };
  335. /** @type {!Object.<string, SlackGroup|SlackChan>} */
  336. this.channels;
  337. /** @type {SlackIms|null} */
  338. this.ims = null;
  339. /** @type {SelfPreferences|null} */
  340. this.prefs = null;
  341. /** @type {number} */
  342. this.version = 0;
  343. /** @type {boolean} */
  344. this.presence = false;
  345. }
  346. /** @param {*} botData */
  347. SlackBot.prototype.update = function(botData, t) {
  348. if (botData["deleted"] !== undefined) this.deleted = botData["deleted"];
  349. if (botData["name"] !== undefined) this.name = botData["name"];
  350. if (botData["app_id"] !== undefined) this.appId = botData["app_id"];
  351. if (botData["icons"]) {
  352. this.icons.image_36 = botData["icons"]["image_36"]
  353. this.icons.image_48 = botData["icons"]["image_48"]
  354. this.icons.image_72 = botData["icons"]["image_72"]
  355. }
  356. if (botData["presence"] !== undefined)
  357. this.presence = botData["presence"] !== 'away';
  358. if (botData["isPresent"] !== undefined)
  359. this.presence = botData["isPresent"];
  360. this.version = Math.max(this.version, t);
  361. }
  362. SlackBot.prototype.setPresence = function(presenceStr, t) {
  363. this.presence = presenceStr !== 'away';
  364. this.version = Math.max(t, this.version);
  365. }
  366. /**
  367. * @constructor
  368. * @param {*} data
  369. **/
  370. function SlackCommand(data) {
  371. /** @const @type {string} */
  372. this.desc = data["desc"];
  373. /** @const @type {string} */
  374. this.name = data["name"];
  375. /** @const @type {string} */
  376. this.type = data["type"];
  377. /** @const @type {string} */
  378. this.usage = data["usage"];
  379. }
  380. /**
  381. * @param {number} t
  382. * @return {Object}
  383. **/
  384. SlackCommand.prototype.toStatic = function(t) {
  385. return {
  386. "desc": this.desc
  387. ,"name": this.name
  388. ,"type": this.type
  389. ,"usage": this.usage
  390. };
  391. }
  392. /**
  393. * @constructor
  394. **/
  395. function SlackData(slack) {
  396. /** @type {SlackTeam} */
  397. this.team = null;
  398. /** @type {Object.<string, SlackChan>} */
  399. this.channels = {};
  400. /** @type {Object.<string, SlackGroup>} */
  401. this.groups = {};
  402. /** @type {Object.<string, SlackIms>} */
  403. this.ims = {};
  404. /** @type {Object.<string, SlackUser>} */
  405. this.users = {};
  406. /** @type {SlackUser|SlackBot} */
  407. this.self = null;
  408. /** @type {Object.<string, SlackBot>} */
  409. this.bots = {};
  410. /** @type {{version: number, data: Object.<string, string>}} */
  411. this.emojis = { version: 0, data: {} };
  412. /** @type {{version: number, data: Object.<string, SlackCommand>}} */
  413. this.commands = {version: 0, data: {} };
  414. /** @type {Object.<string, Object.<string, number>>} */
  415. this.typing = {};
  416. /**
  417. * Node serv handler
  418. * @type {*}
  419. **/
  420. this.slack = slack;
  421. /** @type {number} */
  422. this.staticV = 0;
  423. /** @type {number} */
  424. this.liveV = 0;
  425. }
  426. /**
  427. * @return {Object}
  428. **/
  429. SlackTeam.prototype.toStatic = function(t) {
  430. return t >= this.version ? {} : {
  431. "id": this.id
  432. ,"name": this.name
  433. ,"domain": this.domain
  434. ,"prefs": {
  435. "calling_app_id": this.callApp
  436. ,"calling_app_name": this.callAppName
  437. ,"disable_file_uploads": this.fileUploadPermission
  438. ,"disable_file_editing": this.fileEditPermission
  439. ,"disable_file_deleting": this.fileDeletePermission
  440. }
  441. ,"icon": this.icons
  442. };
  443. };
  444. /**
  445. * @return {Object}
  446. **/
  447. SlackChan.prototype.toStatic = function(t) {
  448. if (t >= this.version)
  449. return null;
  450. var res = {
  451. "id": this.id
  452. ,"name": this.name
  453. ,"created": this.created
  454. ,"creator": this.creator.id
  455. ,"is_archived": this.archived
  456. ,"is_member": this.isMember
  457. ,"last_read": this.lastRead
  458. };
  459. if (this.isMember) {
  460. res["members"] = this.members ? Object.keys(this.members) : [];
  461. res["topic"] = {
  462. "value": this.topic
  463. ,"creator": this.topicCreator ? this.topicCreator.id : null
  464. ,"last_set": this.topicTs
  465. }
  466. res["purpose"] = {
  467. "value": this.purpose
  468. ,"creator": this.purposeCreator ? this.purposeCreator.id : null
  469. ,"last_set": this.purposeTs
  470. }
  471. }
  472. return res;
  473. };
  474. /**
  475. * @return {Object}
  476. **/
  477. SlackUser.prototype.toStatic = function(t) {
  478. return t >= this.version ? null : {
  479. "id": this.id
  480. ,"name": this.name
  481. ,"deleted": this.deleted
  482. ,"status": this.status
  483. ,"real_name": this.realName
  484. ,"isPresent": this.presence
  485. ,"profile": {
  486. "email": this.email
  487. ,"first_name": this.firstName
  488. ,"last_name": this.lastName
  489. ,"image_24": this.icons.image_24
  490. ,"image_32": this.icons.image_32
  491. ,"image_48": this.icons.image_48
  492. ,"image_72": this.icons.image_72
  493. ,"image_192": this.icons.image_192
  494. ,"image_512": this.icons.image_512
  495. }
  496. };
  497. };
  498. SlackGroup.prototype.toStatic = function(t) {
  499. if (t >= this.version)
  500. return null;
  501. var res = {
  502. "id": this.id
  503. ,"members": []
  504. ,"created": this.created
  505. ,"creator": this.creator.id
  506. ,"is_archived": this.archived
  507. ,"last_read": this.lastRead
  508. };
  509. for (var mId in this.members) {
  510. res["members"].push(mId);
  511. }
  512. if (this.topic) {
  513. res["topic"] = {
  514. "value": this.topic
  515. ,"creator": this.topicCreator.id
  516. ,"last_set": this.topicTs
  517. };
  518. }
  519. if (this.purpose) {
  520. res["purpose"] = {
  521. "value": this.purpose
  522. ,"creator": this.purposeCreator.id
  523. ,"last_set": this.purposeTs
  524. };
  525. }
  526. return res;
  527. };
  528. SlackIms.prototype.toStatic = function(t) {
  529. return t >= this.version ? null: {
  530. "id": this.id
  531. ,"created": this.created
  532. ,"user": this.user.id
  533. ,"last_read": this.lastRead
  534. };
  535. }
  536. SlackBot.prototype.toStatic = function(t) {
  537. return t >= this.version ? null : {
  538. "id": this.id
  539. ,"deleted": this.deleted
  540. ,"name": this.name
  541. ,"app_id": this.appId
  542. ,"isPresent": this.presence
  543. ,"icons": {
  544. "image_36": this.icons.image_36
  545. ,"image_48": this.icons.image_48
  546. ,"image_72": this.icons.image_72
  547. }
  548. };
  549. }
  550. /**
  551. * @param {*} data
  552. **/
  553. SlackData.prototype.updateStatic = function(data, t) {
  554. if (data["bots"]) for (var i =0, nbBots = data["bots"].length; i < nbBots; i++) {
  555. var botObj = this.bots[data["bots"][i]["id"]];
  556. if (!botObj)
  557. botObj = this.bots[data["bots"][i]["id"]] = new SlackBot(data["bots"][i]["id"]);
  558. botObj.update(data["bots"][i], t);
  559. }
  560. if (data["users"]) for (var i =0, nbUsers = data["users"].length; i < nbUsers; i++) {
  561. var userObj = this.users[data["users"][i]["id"]];
  562. if (!userObj)
  563. userObj = this.users[data["users"][i]["id"]] = new SlackUser(data["users"][i]["id"]);
  564. userObj.update(data["users"][i], t);
  565. }
  566. if (data["ims"]) for (var i =0, nbIms = data["ims"].length; i < nbIms; i++) {
  567. var user = this.getMember(data["ims"][i]["user"]);
  568. if (user) {
  569. if (!user.ims)
  570. this.ims[data["ims"][i]["id"]] = user.ims = new SlackIms(data["ims"][i]["id"], user);
  571. user.ims.update(user, data["ims"][i], t);
  572. }
  573. }
  574. if (data["channels"]) for (var i =0, nbChan = data["channels"].length; i < nbChan; i++) {
  575. var chanObj = this.channels[data["channels"][i]["id"]];
  576. if (!chanObj)
  577. chanObj = this.channels[data["channels"][i]["id"]] = new SlackChan(data["channels"][i]["id"]);
  578. chanObj.update(data["channels"][i], this, t);
  579. }
  580. for (var i =0, nbGroups = data["groups"].length; i < nbGroups; i++) {
  581. var groupObj = this.groups[data["groups"][i]["id"]];
  582. if (!groupObj)
  583. groupObj = this.groups[data["groups"][i]["id"]] = new SlackGroup(data["groups"][i]["id"]);
  584. groupObj.update(this, data["groups"][i], t);
  585. }
  586. if (data["emojis"]) {
  587. this.emojis.data = data["emojis"];
  588. this.emojis.version = t;
  589. }
  590. if (data["commands"] !== undefined){
  591. this.commands.data = {};
  592. for (var i in data["commands"]) {
  593. this.commands.data[i] = new SlackCommand(data["commands"][i]);
  594. }
  595. this.commands.version = t;
  596. }
  597. if (data["team"]) {
  598. if (!this.team) this.team = new SlackTeam(data["team"]["id"]);
  599. this.team.update(data["team"], t);
  600. }
  601. this.staticV = Math.max(this.staticV, t);
  602. if (data["self"]) {
  603. this.self = this.getMember(data["self"]["id"]);
  604. if (!this.self.prefs) this.self.prefs = new SelfPreferences();
  605. this.self.prefs.update(data["self"]["prefs"], t);
  606. }
  607. if (data["typing"] !== undefined) {
  608. this.typing = data["typing"];
  609. for (var i in this.typing)
  610. for (var j in this.typing[i])
  611. this.typing[i][j] = t;
  612. }
  613. };
  614. SelfPreferences.prototype.toStatic = function(t) {
  615. return this.version > t ? null : {
  616. "emoji_use": JSON.stringify(this.favoriteEmojis)
  617. ,"highlights": this.highlights
  618. };
  619. }
  620. /**
  621. * @param {string} appId
  622. * @return {Array.<SlackBot>}
  623. **/
  624. SlackData.prototype.getBotsByAppId = function(appId) {
  625. var bots = [];
  626. for (var botId in this.bots) {
  627. if (this.bots[botId].appId === appId) {
  628. bots.push(this.bots[botId]);
  629. }
  630. }
  631. return bots;
  632. };
  633. /**
  634. * @param {string} mId
  635. * @return {SlackUser|SlackBot|null}
  636. **/
  637. SlackData.prototype.getMember = function(mId) {
  638. return this.users[mId] || this.bots[mId] || null;
  639. };
  640. /**
  641. * @param {string} chanId
  642. * @return {SlackChan|SlackGroup|SlackIms|null}
  643. **/
  644. SlackData.prototype.getChannel = function(chanId) {
  645. return this.channels[chanId] || this.ims[chanId] || this.groups[chanId] || null;
  646. };
  647. /** @return {Object} */
  648. SlackData.prototype.buildStatic = function(t, now) {
  649. var res = {
  650. "team": this.team.toStatic(t)
  651. ,"channels": []
  652. ,"groups": []
  653. ,"ims": []
  654. ,"users": []
  655. ,"bots": []
  656. ,"self": {
  657. "id": this.self.id
  658. ,"prefs": this.self.prefs.toStatic(t)
  659. }
  660. ,"emojis": this.emojis.version > t ? this.emojis.data : undefined
  661. ,"commands": undefined
  662. ,"typing": undefined
  663. };
  664. if (this.commands.version > t) {
  665. res["commands"] = {};
  666. for (var i in this.commands.data)
  667. res["commands"][i] = this.commands.data[i].toStatic(t);
  668. }
  669. for (var chanId in this.channels) {
  670. var chan = this.channels[chanId].toStatic(t);
  671. if (chan)
  672. res["channels"].push(chan);
  673. }
  674. for (var userId in this.users) {
  675. var user = this.users[userId].toStatic(t)
  676. ,ims = this.users[userId].ims.toStatic(t);
  677. if (user)
  678. res["users"].push(user);
  679. if (ims)
  680. res["ims"].push(ims);
  681. }
  682. for (var botId in this.bots) {
  683. var bot = this.bots[botId].toStatic(t);
  684. if (bot)
  685. res["bots"].push(bot);
  686. }
  687. for (var groupId in this.groups) {
  688. var group = this.groups[groupId].toStatic(t);
  689. if (group)
  690. res["groups"].push(group);
  691. }
  692. for (var typingChan in this.typing) {
  693. var tChan;
  694. for (var typingUser in this.typing[typingChan]) {
  695. if (this.typing[typingChan][typingUser] +3000 >= now) {
  696. if (!tChan) tChan = {};
  697. tChan[typingUser] = 1;
  698. } else {
  699. delete this.typing[typingChan][typingUser];
  700. }
  701. }
  702. if (tChan) {
  703. if (res["typing"] === undefined)
  704. res["typing"] = {};
  705. res["typing"][typingChan] = tChan;
  706. }
  707. else
  708. delete this.typing[typingChan];
  709. }
  710. return res;
  711. };
  712. SlackData.prototype.cleanTyping = function(t) {
  713. var updated = false;
  714. for (var typingChan in this.typing) {
  715. var chanEmpty = true;
  716. for (var typingUser in this.typing[typingChan]) {
  717. if (this.typing[typingChan][typingUser] +3000 < t) {
  718. delete this.typing[typingChan][typingUser];
  719. updated = true;
  720. } else {
  721. chanEmpty = false;
  722. }
  723. }
  724. if (chanEmpty) {
  725. delete this.typing[typingChan];
  726. updated = true;
  727. }
  728. }
  729. return updated;
  730. }
  731. /**
  732. * @param {*} msg
  733. * @param {number} t
  734. **/
  735. SlackData.prototype.onMessage = function(msg, t) {
  736. if (msg["type"] === "presence_change") {
  737. var member = this.getMember(msg["user"]);
  738. if (member)
  739. member.setPresence(msg["presence"], t);
  740. this.staticV = Math.max(this.staticV, t);
  741. } else if (msg["type"] === "user_typing") {
  742. this.typing[msg["channel"]] = this.typing[msg["channel"]] || {};
  743. this.typing[msg["channel"]][msg["user"]] = t;
  744. this.staticV = Math.max(this.staticV, t);
  745. }
  746. }
  747. /**
  748. * @param {number} knownVersion
  749. * @param {number} now time at update check
  750. * @return {Object|undefined}
  751. **/
  752. SlackData.prototype.getUpdates = function(knownVersion, now) {
  753. if (this.staticV > knownVersion)
  754. return this.buildStatic(knownVersion, now);
  755. return undefined;
  756. };
  757. /** @suppress {undefinedVars,checkTypes} */
  758. (function() {
  759. if (typeof module !== "undefined") {
  760. module.exports.SlackData = SlackData;
  761. }
  762. })();