main.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #!/usr/bin/env node
  2. "use strict";
  3. Object.defineProperty(exports, "__esModule", { value: true });
  4. const commandLineUsage = require("command-line-usage");
  5. const fs = require("fs");
  6. const log4js = require("log4js");
  7. const path = require("path");
  8. const logger = log4js.getLogger();
  9. logger.level = 'info';
  10. const sections = [
  11. {
  12. header: 'CQHTTP Twitter Bot',
  13. content: 'The QQ Bot that forwards twitters.',
  14. },
  15. {
  16. header: 'Synopsis',
  17. content: [
  18. '$ cqhttp-twitter-bot {underline config.json}',
  19. '$ cqhttp-twitter-bot {bold --help}',
  20. ],
  21. },
  22. {
  23. header: 'Documentation',
  24. content: [
  25. 'Project home: {underline https://github.com/rikakomoe/cqhttp-twitter-bot}',
  26. 'Example config: {underline https://qwqq.pw/qpfhg}',
  27. ],
  28. },
  29. ];
  30. const usage = commandLineUsage(sections);
  31. const args = process.argv.slice(2);
  32. if (args.length === 0 || args[0] === 'help' || args[0] === '-h' || args[0] === '--help') {
  33. console.log(usage);
  34. process.exit(0);
  35. }
  36. const configPath = args[0];
  37. let config;
  38. try {
  39. config = require(path.resolve(configPath));
  40. }
  41. catch (e) {
  42. console.log('Failed to parse config file: ', configPath);
  43. console.log(usage);
  44. process.exit(1);
  45. }
  46. if (config.twitter_consumer_key === undefined ||
  47. config.twitter_consumer_secret === undefined ||
  48. config.twitter_access_token_key === undefined ||
  49. config.twitter_access_token_secret === undefined) {
  50. console.log('twitter_consumer_key twitter_consumer_secret twitter_access_token_key twitter_access_token_secret are required');
  51. process.exit(1);
  52. }
  53. if (config.cq_ws_host === undefined) {
  54. config.cq_ws_host = '127.0.0.1';
  55. logger.warn('cq_ws_host is undefined, use 127.0.0.1 as default');
  56. }
  57. if (config.cq_ws_port === undefined) {
  58. config.cq_ws_port = 6700;
  59. logger.warn('cq_ws_port is undefined, use 6700 as default');
  60. }
  61. if (config.cq_access_token === undefined) {
  62. config.cq_access_token = '';
  63. logger.warn('cq_access_token is undefined, use empty string as default');
  64. }
  65. if (config.lockfile === undefined) {
  66. config.lockfile = 'subscriber.lock';
  67. }
  68. if (config.work_interval === undefined) {
  69. config.work_interval = 60;
  70. }
  71. if (config.webshot_delay === undefined) {
  72. config.webshot_delay = 5000;
  73. }
  74. if (config.loglevel === undefined) {
  75. config.loglevel = 'info';
  76. }
  77. if (typeof config.mode !== 'number') {
  78. config.mode = 0;
  79. }
  80. let redisConfig;
  81. if (config.redis) {
  82. redisConfig = {
  83. redisHost: config.redis_host || '127.0.0.1',
  84. redisPort: config.redis_port || 6379,
  85. redisExpireTime: config.redis_expire_time || 43200,
  86. };
  87. }
  88. global.loglevel = config.loglevel;
  89. const command_1 = require("./command");
  90. const cqhttp_1 = require("./cqhttp");
  91. const twitter_1 = require("./twitter");
  92. let lock;
  93. if (fs.existsSync(path.resolve(config.lockfile))) {
  94. try {
  95. lock = JSON.parse(fs.readFileSync(path.resolve(config.lockfile), 'utf8'));
  96. }
  97. catch (err) {
  98. logger.error(`Failed to parse lockfile ${config.lockfile}: `, err);
  99. lock = {
  100. workon: 0,
  101. feed: [],
  102. threads: {},
  103. };
  104. }
  105. fs.access(path.resolve(config.lockfile), fs.constants.W_OK, err => {
  106. if (err) {
  107. logger.fatal(`cannot write lockfile ${path.resolve(config.lockfile)}, permission denied`);
  108. process.exit(1);
  109. }
  110. });
  111. }
  112. else {
  113. lock = {
  114. workon: 0,
  115. feed: [],
  116. threads: {},
  117. };
  118. try {
  119. fs.writeFileSync(path.resolve(config.lockfile), JSON.stringify(lock));
  120. }
  121. catch (err) {
  122. logger.fatal(`cannot write lockfile ${path.resolve(config.lockfile)}, permission denied`);
  123. process.exit(1);
  124. }
  125. }
  126. Object.keys(lock.threads).forEach(key => {
  127. lock.threads[key].offset = -1;
  128. });
  129. const qq = new cqhttp_1.default({
  130. access_token: config.cq_access_token,
  131. host: config.cq_ws_host,
  132. port: config.cq_ws_port,
  133. list: (c, a) => command_1.list(c, a, lock),
  134. sub: (c, a) => command_1.sub(c, a, lock, config.lockfile),
  135. unsub: (c, a) => command_1.unsub(c, a, lock, config.lockfile),
  136. });
  137. const worker = new twitter_1.default({
  138. consumer_key: config.twitter_consumer_key,
  139. consumer_secret: config.twitter_consumer_secret,
  140. access_token_key: config.twitter_access_token_key,
  141. access_token_secret: config.twitter_access_token_secret,
  142. lock,
  143. lockfile: config.lockfile,
  144. workInterval: config.work_interval,
  145. bot: qq,
  146. webshotDelay: config.webshot_delay,
  147. redis: redisConfig,
  148. mode: config.mode,
  149. });
  150. worker.launch();
  151. qq.connect();