Browse Source

add proxy support

Mike L 3 years ago
parent
commit
d2ad5b682d
6 changed files with 42 additions and 2 deletions
  1. 1 0
      config.example.json
  2. 2 1
      dist/main.js
  3. 19 0
      dist/twitter.js
  4. 1 0
      package.json
  5. 2 1
      src/main.ts
  6. 17 0
      src/twitter.ts

+ 1 - 0
config.example.json

@@ -3,6 +3,7 @@
   "cq_ws_host": "127.0.0.1",
   "cq_ws_port": 6700,
   "cq_bot_qq": 10000,
+  "ig_socks_proxy": "",
   "ig_username": "",
   "ig_password": "",
   "ig_session_lockfile": "",

+ 2 - 1
dist/main.js

@@ -54,7 +54,7 @@ const warningFields = [
     'cq_ws_host', 'cq_ws_port', 'cq_access_token',
 ];
 const optionalFields = [
-    'lockfile', 'work_interval', 'webshot_delay', 'loglevel', 'mode', 'resume_on_start',
+    'lockfile', 'work_interval', 'webshot_delay', 'loglevel', 'mode', 'resume_on_start', 'ig_socks_proxy',
 ].concat(warningFields);
 if (requiredFields.some((value) => config[value] === undefined)) {
     console.log(`${requiredFields.join(', ')} are required`);
@@ -125,6 +125,7 @@ const qq = new koishi_1.default({
 const worker = new twitter_1.default({
     sessionLockfile: config.ig_session_lockfile,
     credentials: [config.ig_username, config.ig_password],
+    proxyUrl: config.ig_socks_proxy,
     lock,
     lockfile: config.lockfile,
     workInterval: config.work_interval,

+ 19 - 0
dist/twitter.js

@@ -16,6 +16,7 @@ const instagram_id_to_url_segment_1 = require("instagram-id-to-url-segment");
 Object.defineProperty(exports, "idToUrlSegment", { enumerable: true, get: function () { return instagram_id_to_url_segment_1.instagramIdToUrlSegment; } });
 Object.defineProperty(exports, "urlSegmentToId", { enumerable: true, get: function () { return instagram_id_to_url_segment_1.urlSegmentToInstagramId; } });
 const instagram_private_api_1 = require("instagram-private-api");
+const socks_proxy_agent_1 = require("socks-proxy-agent");
 const loggers_1 = require("./loggers");
 const koishi_1 = require("./koishi");
 const utils_1 = require("./utils");
@@ -307,6 +308,24 @@ class default_1 {
             });
         };
         this.client = new instagram_private_api_1.IgApiClient();
+        if (opt.proxyUrl) {
+            try {
+                const url = new URL(opt.proxyUrl);
+                if (!/^socks(?:4a?|5h?)?:$/.test(url.protocol))
+                    throw Error();
+                if (!url.port)
+                    url.port = '1080';
+                this.client.request.defaults.agent = new socks_proxy_agent_1.SocksProxyAgent({
+                    hostname: url.hostname,
+                    port: url.port,
+                    userId: url.username,
+                    password: url.password,
+                });
+            }
+            catch (e) {
+                logger.warn(`invalid socks proxy url: ${opt.proxyUrl}, ignoring`);
+            }
+        }
         this.session = new SessionManager(this.client, opt.sessionLockfile, opt.credentials);
         this.lockfile = opt.lockfile;
         this.webshotCookiesLockfile = opt.webshotCookiesLockfile;

+ 1 - 0
package.json

@@ -43,6 +43,7 @@
     "read-all-stream": "^3.1.0",
     "sha1": "^1.1.1",
     "sharp": "^0.25.4",
+    "socks-proxy-agent": "^5.0.0",
     "temp": "^0.9.1",
     "typescript": "^4.2.3"
   },

+ 2 - 1
src/main.ts

@@ -65,7 +65,7 @@ const warningFields = [
 ];
 
 const optionalFields = [
-  'lockfile', 'work_interval', 'webshot_delay', 'loglevel', 'mode', 'resume_on_start',
+  'lockfile', 'work_interval', 'webshot_delay', 'loglevel', 'mode', 'resume_on_start', 'ig_socks_proxy',
 ].concat(warningFields);
 
 if (requiredFields.some((value) => config[value] === undefined)) {
@@ -140,6 +140,7 @@ const qq = new QQBot({
 const worker = new Worker({
   sessionLockfile: config.ig_session_lockfile,
   credentials: [config.ig_username, config.ig_password],
+  proxyUrl: config.ig_socks_proxy,
   lock,
   lockfile: config.lockfile,
   workInterval: config.work_interval,

+ 17 - 0
src/twitter.ts

@@ -9,6 +9,7 @@ import {
   IgClientError, IgExactUserNotFoundError, IgResponseError,
   MediaInfoResponseItemsItem, UserFeedResponseItemsItem
 } from 'instagram-private-api';
+import { SocksProxyAgent } from 'socks-proxy-agent';
 
 import { getLogger } from './loggers';
 import QQBot, { Message } from './koishi';
@@ -38,6 +39,7 @@ export {linkBuilder, parseLink, isValidUrlSegment, idToUrlSegment, urlSegmentToI
 interface IWorkerOption {
   sessionLockfile: string;
   credentials: [string, string];
+  proxyUrl: string;
   lock: ILock;
   lockfile: string;
   webshotCookiesLockfile: string;
@@ -189,6 +191,21 @@ export default class {
 
   constructor(opt: IWorkerOption) {
     this.client = new IgApiClient();
+    if (opt.proxyUrl) {
+      try {
+        const url = new URL(opt.proxyUrl);
+        if (!/^socks(?:4a?|5h?)?:$/.test(url.protocol)) throw Error();
+        if (!url.port) url.port = '1080';
+        this.client.request.defaults.agent = new SocksProxyAgent({
+          hostname: url.hostname,
+          port: url.port,
+          userId: url.username,
+          password: url.password,
+        });
+      } catch (e) {
+        logger.warn(`invalid socks proxy url: ${opt.proxyUrl}, ignoring`);
+      }
+    }
     this.session = new SessionManager(this.client, opt.sessionLockfile, opt.credentials);
     this.lockfile = opt.lockfile;
     this.webshotCookiesLockfile = opt.webshotCookiesLockfile;