phabricator.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. const {MessageEmbed} = require('discord.js');
  2. const logging = require('../util/logging.js');
  3. /**
  4. * Sends a Phabricator task.
  5. * @param {import('../util/i18n.js')} lang - The user language.
  6. * @param {import('discord.js').Message} msg - The Discord message.
  7. * @param {import('../util/wiki.js')} wiki - The wiki.
  8. * @param {URL} link - The link.
  9. * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  10. * @param {String} [spoiler] - If the response is in a spoiler.
  11. */
  12. function phabricator_task(lang, msg, wiki, link, reaction, spoiler = '') {
  13. var regex = /^(?:https?:)?\/\/phabricator\.(wikimedia|miraheze)\.org\/T(\d+)(?:#|$)/.exec(link.href);
  14. if ( !regex || !process.env['phabricator-' + regex[1]] ) {
  15. logging(wiki, msg.guild?.id, 'interwiki');
  16. msg.sendChannel( spoiler + ' ' + link + ' ' + spoiler );
  17. if ( reaction ) reaction.removeEmoji();
  18. return;
  19. }
  20. logging(link.origin, msg.guild?.id, 'phabricator', regex[1]);
  21. got.get( 'https://phabricator.' + regex[1] + '.org/api/maniphest.search?api.token=' + process.env['phabricator-' + regex[1]] + '&constraints[ids][0]=' + regex[2] ).then( response => {
  22. var body = response.body;
  23. if ( response.statusCode !== 200 || !body?.result?.data || body.error_code ) {
  24. console.log( '- ' + response.statusCode + ': Error while getting the Phabricator task: ' + body?.error_info );
  25. msg.sendChannelError( spoiler + ' ' + link + ' ' + spoiler );
  26. if ( reaction ) reaction.removeEmoji();
  27. return;
  28. }
  29. if ( !body.result.data.length ) {
  30. msg.sendChannel( spoiler + ' ' + link + ' ' + spoiler );
  31. if ( reaction ) reaction.removeEmoji();
  32. return;
  33. }
  34. var task = body.result.data[0];
  35. var status = '**' + task.fields.status.name + ':** ' + task.fields.name.escapeFormatting() + '\n';
  36. if ( !msg.showEmbed() ) {
  37. msg.sendChannel( spoiler + status + '<' + link + '>' + spoiler );
  38. if ( reaction ) reaction.removeEmoji();
  39. return;
  40. }
  41. var summary = task.fields.name.escapeFormatting();
  42. if ( summary.length > 250 ) summary = summary.substring(0, 250) + '\u2026';
  43. var embed = new MessageEmbed().setAuthor( 'Phabricator' ).setTitle( summary ).setURL( link ).addField( 'Status', task.fields.status.name, true ).addField( 'Priority', task.fields.priority.name, true );
  44. if ( task.fields.subtype !== 'default' ) embed.addField( 'Subtype', task.fields.subtype, true );;
  45. var description = task.fields.description.raw.replace( /```lang=/g, '```' );
  46. if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
  47. embed.setDescription( parse_links( description, regex[1] ) );
  48. if ( /^#\d+$/.test( link.hash ) ) return got.get( 'https://phabricator.' + regex[1] + '.org/api/transaction.search?api.token=' + process.env['phabricator-' + regex[1]] + '&objectIdentifier=' + task.phid ).then( response => {
  49. var body = response.body;
  50. if ( response.statusCode !== 200 || !body?.result?.data || body.error_code ) {
  51. console.log( '- ' + response.statusCode + ': Error while getting the task transactions: ' + body?.error_info );
  52. return;
  53. }
  54. var comment = body.result.data.find( transaction => '#' + transaction.id === link.hash );
  55. if ( comment.type === 'comment' ) {
  56. var content = comment.comments[0].content.raw;
  57. if ( content.length > 1000 ) content = content.substring(0, 1000) + '\u2026';
  58. embed.spliceFields( 0, 0, {name: 'Comment', value: parse_links( content, regex[1] )} );
  59. }
  60. }, error => {
  61. console.log( '- Error while getting the task transactions: ' + error );
  62. } ).finally( () => {
  63. msg.sendChannel( spoiler + status + '<' + link + '>' + spoiler, {embed} );
  64. if ( reaction ) reaction.removeEmoji();
  65. } );
  66. msg.sendChannel( spoiler + status + '<' + link + '>' + spoiler, {embed} );
  67. if ( reaction ) reaction.removeEmoji();
  68. }, error => {
  69. console.log( '- Error while getting the Phabricator task: ' + error );
  70. msg.sendChannelError( spoiler + ' ' + link + ' ' + spoiler );
  71. if ( reaction ) reaction.removeEmoji();
  72. } );
  73. }
  74. /**
  75. * Parse Phabricator links.
  76. * @param {String} text - The text to parse.
  77. * @param {String} site - The site the Phabricator is for.
  78. * @returns {String}
  79. */
  80. function parse_links(text, site) {
  81. text = text.replace( /\[\[ *(.+?) *\| *(.+?) *\]\]/g, '[$2]($1)' );
  82. text = text.replace( /\{(T\d+)\}/g, '[$1](https://phabricator.' + site + '.org/$1)' );
  83. return text;
  84. }
  85. module.exports = phabricator_task;