#! /usr/bin/env runjs var argsjs = require('component-args.js'); var timejs = require('component-time.js'); var dingtalkrobotjs = require('component-dingtalkrobot-ex.js'); // curl --header "Private-Token: xxxxxxxxxxxxx" https://gitlab.com/api/v4/users/jht5945/projects | viewjson.js // curl --header "Private-Token: xxxxxxxxxxxxx" https://gitlab.com/api/v4/projects/5327754/issues?state=opened | viewjson.js // https://gitlab.com/help/api/projects.md // https://gitlab.com/help/api/issues.md var sampleConfig = { "default": { "dailyCheckHour": 9, "checkNewItems": true, "privateToken": "xxxxxxxxxxxxx", "dingtalkRobotToken": "xxxxxxxxxxxxxxxxxxxxxx" }, "list": [{ "projectId": 5327754, "dailyCheckHour": 9, "checkNewItems": true, "privateToken": "xxxxxxxxxxxxx", "dingtalkRobotToken": "xxxxxxxxxxxxxxxxxxxxxx", "messageFootNote": "https://gitlab.com/xxxxxxx/xxxxxxxxxxxxx/issues" }] }; var issueToString = (issue) => { var createdAt = $$.date().fmt('yyyy-MM-dd\'T\'HH:mm:ss.SSSXXX').parse(issue.created_at); var it = [' - ', issue.title]; it.push(' (' + timejs.formatDuration(createdAt.getTime()) + ')'); if (issue.labels && issue.labels.length > 0) { it.push(' [' + issue.labels.join(', ') + ']'); } if (issue.due_date) { it.push(', due: ' + timejs.formatDueInDays($$.date().fmt('yyyy-MM-dd').parse(issue.due_date))); } if (issue.weight != null) { it.push(', weight: ' + issue.weight); } return it.join(''); }; var main = () => { var args = argsjs.parseDefARGs(); var config = $$.file(args[0] || '~/.gitlab_todo_config.json'); if (!(config.exists())) { xprintln('[ERROR] config file not exists: ' + args[0]); return; } var configJSON = JSON.parse($$.rFile(config).string() || '{}'); var defaultConfig = configJSON['default']; var configList = configJSON['list'] || []; configList.forEach((config) => { var startMillis = $$.date().millis(); xprintln('[INFO] Check project, id: ' + config.projectId); var localConfigPath = $$.file('~/.jssp/gitlab_todo/localconfig'); if (!(localConfigPath.exists())) { localConfigPath.mkdirs(); } var projectLocalConfig = $$.file(localConfigPath, 'config_' + config.projectId + '.json'); var projectLocalConfigJSON = {}; if (projectLocalConfig.exists()) { projectLocalConfigJSON = JSON.parse($$.rFile(projectLocalConfig).string()); } var doDailyCheckHour = false; var todayYMD = $STR($$.date().fmt('yyyy-MM-dd').format($$.date().today())); var hour = $$.asInt($$.date().fmt('H').format($$.date().today())); if (todayYMD != projectLocalConfigJSON.checkedYMD) { if (hour == ((config.dailyCheckHour != null) ? config.dailyCheckHour : defaultConfig.dailyCheckHour)) { doDailyCheckHour = true; } } var hasNewItems = false; var doCheckNewItems = (config.checkNewItems != null) ? config.checkNewItems : defaultConfig.checkNewItems; xprintln('[INFO] Project config: doDailyCheckHour=' + doDailyCheckHour + ', doCheckNewItems=' + doCheckNewItems); if (doDailyCheckHour || doCheckNewItems) { // DO CHECK var url = 'https://gitlab.com/api/v4/projects/' + config.projectId + '/issues?state=opened'; xprintln('[INFO] Get url: ' + url); var openedIssues = $$.httpRequest().url(url) .header('Private-Token', config.privateToken || defaultConfig.privateToken) .get(); var openedIssuesJSON = JSON.parse(openedIssues); if (openedIssuesJSON && (openedIssuesJSON.length > 0)) { if (doDailyCheckHour) { var msg = []; msg.push((config.title || '') + ' (' + openedIssuesJSON.length + ' items):'); openedIssuesJSON.forEach((issue) => { msg.push(issueToString(it)); }); if (config.messageFootNote) { msg.push(''); msg.push(config.messageFootNote); } dingtalkrobotjs.sendText(config.dingtalkRobotToken || defaultConfig.dingtalkRobotToken, msg.join('\n')); projectLocalConfigJSON.checkedYMD = todayYMD; } if (doCheckNewItems) { projectLocalConfigJSON.checkedIssueIds = projectLocalConfigJSON.checkedIssueIds || []; var newIssuesJSON = openedIssuesJSON.filter((issue) => { return (projectLocalConfigJSON.checkedIssueIds.indexOf(issue.id) < 0); }); if (newIssuesJSON && (newIssuesJSON.length > 0)) { var msg = []; msg.push('New items found (' + newIssuesJSON.length + ' items):'); newIssuesJSON.forEach((issue) => { msg.push(issueToString(issue)); projectLocalConfigJSON.checkedIssueIds.push(issue.id); }); hasNewItems = true; dingtalkrobotjs.sendText(config.dingtalkRobotToken || defaultConfig.dingtalkRobotToken, msg.join('\n')); } } } if (doDailyCheckHour || (doCheckNewItems && hasNewItems)) { $$.rFile(projectLocalConfig).write(JSON.stringify(projectLocalConfigJSON)); } } xprintln('[INFO] Finish check project, cost: ' + ($.date().millis() - startMillis) + 'ms'); }); }; main();