├── .gitignore ├── app.js ├── config.json ├── list.html └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | debug.html 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | # Coverage directory used by tools like istanbul 13 | coverage 14 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 15 | .grunt 16 | # node-waf configuration 17 | .lock-wscript 18 | # Compiled binary addons (http://nodejs.org/api/addons.html) 19 | build/Release 20 | # Dependency directory 21 | node_modules 22 | # Optional npm cache directory 23 | .npm 24 | # Optional REPL history 25 | .node_repl_history 26 | .DS_Store -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var logger = require('morgan'); 3 | var superagent = require('superagent'); 4 | var bodyParser = require('body-parser'); 5 | var fs = require('fs'); 6 | var app = express(); 7 | 8 | var Cache = {}; 9 | setInterval(() => { 10 | Object.keys(Cache).forEach((key) => { 11 | var obj = Cache[key]; 12 | obj.time--; 13 | if(obj.time <= 0) delete Cache[key]; 14 | }); 15 | }, 1000); 16 | 17 | app.use(logger('dev')); 18 | app.use(bodyParser.urlencoded({ extended: false })) 19 | app.use(bodyParser.json()) 20 | app.use((req, res, next) => { 21 | req.config = require('./config.json'); 22 | req.getApiData = (url, data, callback) => { 23 | if(req.config.accessToken.trim() == '') return callback('请先绑定189电信账号'); 24 | 25 | data['app_id'] = req.config.appKey 26 | data['access_token'] = req.config.accessToken; 27 | 28 | superagent.get(url).query(data).timeout(1000 * 10).end((err, res) => { 29 | if(err) return callback(err); 30 | try { 31 | callback(null, JSON.parse(res.text)); 32 | } catch (error) { 33 | callback(error); 34 | } 35 | }); 36 | } 37 | 38 | req.setCache = (key, obj, time) => { 39 | Cache[key] = {time: time, data: obj} 40 | } 41 | req.getCache = (key) => { 42 | return Cache[key] ? Cache[key] : null; 43 | } 44 | 45 | next(); 46 | }); 47 | 48 | // OAuth 重定向 49 | app.get('/auth', (req, res) => { 50 | var args = `response_type=token&app_id=${req.config.appKey}&app_secret=${req.config.appSecret}&redirect_uri=${req.config.callbackUrl}`; 51 | var authUrl = `https://oauth.api.189.cn/emp/oauth2/v3/authorize?${args}`; 52 | res.send(`跳转至天翼云`); 53 | }); 54 | 55 | // OAuth 回调 56 | app.get('/authCallback/', (req, res) => { 57 | if(req.config.accessToken != '') return res.send('请先删除config.json accessToken值'); 58 | 59 | var accessToken = req.query.access_token || ''; 60 | var res_code = req.query.res_code || -1; 61 | 62 | if(accessToken == '' || res_code == -1) return res.send('回调参数不正确'); 63 | 64 | if(res_code != 0) return res.send('认证失败 错误代码:' + res_code); 65 | 66 | req.config.accessToken = accessToken; 67 | 68 | fs.writeFile('config.json', JSON.stringify(req.config, null, 4), 'utf8', (err) => { 69 | res.send(`Save Status: ${err || '保存配置成功'}
Access Token: ${accessToken}`); 70 | }); 71 | }); 72 | 73 | app.get('/', (req, res) => { 74 | fs.readFile('./list.html', 'utf8', (err, data) => { 75 | if(err) return res.status(503).send(`can't render html.`); 76 | res.send(data); 77 | }); 78 | }); 79 | 80 | app.get('/link/:fileId', (req, res) => { 81 | var fileId = req.params.fileId; 82 | var cache = req.getCache(fileId); 83 | if(cache){ 84 | res.set('Link-Cache', 'Hit ' + cache.time); 85 | return res.redirect(cache.data); 86 | } 87 | req.getApiData('http://api.189.cn/ChinaTelecom/getFileDownloadUrl.action', {fileId: fileId}, (err, result) => { 88 | if(err) return res.status(503).send(err); 89 | // 天翼云盘真实链接并不会立即过期,也许要过1天? 或者100年? 90 | // 反正这里配置文件里默认缓存60分钟 因为我就试了60分钟 懒得试了 但是证实60分钟+还是有效的 91 | // 如果电信修改了 请自行修改 config -> linkCacheTime 92 | if(req.config.linkCache) req.setCache(fileId, result.fileDownloadUrl, req.config.linkCacheTime); 93 | res.set('Link-Cache', 'Miss'); 94 | res.redirect(result.fileDownloadUrl); 95 | }); 96 | }); 97 | 98 | app.get('/folder/', (req, res) => { 99 | // 天翼云API出现问题,会暴露全部文件夹和文件 所以在此加入设置默认文件夹ID 100 | req.getApiData('http://api.189.cn/ChinaTelecom/listFiles.action', req.config.defaultFolder == -1 ? {} : {folderId: req.config.defaultFolder}, (err, result) => { 101 | if(err) return res.status(503).send(err); 102 | res.json(result); 103 | }) 104 | }); 105 | 106 | app.get('/folder/:folderId', (req, res) => { 107 | var folderId = req.params.folderId; 108 | req.getApiData('http://api.189.cn/ChinaTelecom/listFiles.action', {folderId: folderId}, (err, result) => { 109 | if(err) return res.status(503).send(err); 110 | res.json(result); 111 | }) 112 | }); 113 | 114 | app.listen(require('./config.json').port, (error) => { 115 | if(error) return console.error('监听端口发生错误:', error); 116 | console.log('服务已开启 监听端口:' + require('./config.json').port); 117 | }); 118 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "port" : 3000, 3 | "appKey": "123", 4 | "appSecret": "123", 5 | "callbackUrl": "http://123.123/authCallback", 6 | "accessToken": "", 7 | "linkCache" : true, 8 | "linkCacheTime": 3600, 9 | "defaultFolder": -1 10 | } -------------------------------------------------------------------------------- /list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 189天翼云 直连工具 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "189CloudLinkTools", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "app.js", 6 | "author": "Srar", 7 | "license": "MIT License", 8 | "dependencies": { 9 | "body-parser": "^1.14.2", 10 | "express": "^4.13.4", 11 | "morgan": "^1.6.1", 12 | "superagent": "^1.8.1" 13 | } 14 | } 15 | --------------------------------------------------------------------------------