temp: add wx-minimp
This commit is contained in:
		@@ -40,7 +40,8 @@
 | 
			
		||||
    "lodash-es": "^4.17.21",
 | 
			
		||||
    "nanoid": "^5.1.2",
 | 
			
		||||
    "pg": "^8.13.3",
 | 
			
		||||
    "sequelize": "^6.37.5"
 | 
			
		||||
    "sequelize": "^6.37.5",
 | 
			
		||||
    "xml2js": "^0.6.2"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@kevisual/types": "^0.0.6",
 | 
			
		||||
@@ -55,6 +56,7 @@
 | 
			
		||||
    "@types/formidable": "^3.4.5",
 | 
			
		||||
    "@types/lodash-es": "^4.17.12",
 | 
			
		||||
    "@types/node": "^22.13.5",
 | 
			
		||||
    "@types/xml2js": "^0.4.14",
 | 
			
		||||
    "concurrently": "^9.1.2",
 | 
			
		||||
    "cross-env": "^7.0.3",
 | 
			
		||||
    "nodemon": "^3.1.9",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								app/pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										28
									
								
								app/pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@@ -38,6 +38,9 @@ importers:
 | 
			
		||||
      sequelize:
 | 
			
		||||
        specifier: ^6.37.5
 | 
			
		||||
        version: 6.37.5(pg@8.13.3)
 | 
			
		||||
      xml2js:
 | 
			
		||||
        specifier: ^0.6.2
 | 
			
		||||
        version: 0.6.2
 | 
			
		||||
    devDependencies:
 | 
			
		||||
      '@kevisual/types':
 | 
			
		||||
        specifier: ^0.0.6
 | 
			
		||||
@@ -75,6 +78,9 @@ importers:
 | 
			
		||||
      '@types/node':
 | 
			
		||||
        specifier: ^22.13.5
 | 
			
		||||
        version: 22.13.5
 | 
			
		||||
      '@types/xml2js':
 | 
			
		||||
        specifier: ^0.4.14
 | 
			
		||||
        version: 0.4.14
 | 
			
		||||
      concurrently:
 | 
			
		||||
        specifier: ^9.1.2
 | 
			
		||||
        version: 9.1.2
 | 
			
		||||
@@ -544,6 +550,9 @@ packages:
 | 
			
		||||
  '@types/validator@13.12.2':
 | 
			
		||||
    resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==}
 | 
			
		||||
 | 
			
		||||
  '@types/xml2js@0.4.14':
 | 
			
		||||
    resolution: {integrity: sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==}
 | 
			
		||||
 | 
			
		||||
  accepts@1.3.8:
 | 
			
		||||
    resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
 | 
			
		||||
    engines: {node: '>= 0.6'}
 | 
			
		||||
@@ -2084,6 +2093,14 @@ packages:
 | 
			
		||||
      utf-8-validate:
 | 
			
		||||
        optional: true
 | 
			
		||||
 | 
			
		||||
  xml2js@0.6.2:
 | 
			
		||||
    resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==}
 | 
			
		||||
    engines: {node: '>=4.0.0'}
 | 
			
		||||
 | 
			
		||||
  xmlbuilder@11.0.1:
 | 
			
		||||
    resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
 | 
			
		||||
    engines: {node: '>=4.0'}
 | 
			
		||||
 | 
			
		||||
  xtend@4.0.2:
 | 
			
		||||
    resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
 | 
			
		||||
    engines: {node: '>=0.4'}
 | 
			
		||||
@@ -2482,6 +2499,10 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  '@types/validator@13.12.2': {}
 | 
			
		||||
 | 
			
		||||
  '@types/xml2js@0.4.14':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@types/node': 22.13.5
 | 
			
		||||
 | 
			
		||||
  accepts@1.3.8:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      mime-types: 2.1.35
 | 
			
		||||
@@ -4274,6 +4295,13 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  ws@8.18.0: {}
 | 
			
		||||
 | 
			
		||||
  xml2js@0.6.2:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      sax: 1.4.1
 | 
			
		||||
      xmlbuilder: 11.0.1
 | 
			
		||||
 | 
			
		||||
  xmlbuilder@11.0.1: {}
 | 
			
		||||
 | 
			
		||||
  xtend@4.0.2: {}
 | 
			
		||||
 | 
			
		||||
  y18n@5.0.8: {}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										74
									
								
								app/src/routes-simple/wx-mp-login.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								app/src/routes-simple/wx-mp-login.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
import { SimpleRouter } from '@kevisual/router/simple';
 | 
			
		||||
import crypto from 'crypto';
 | 
			
		||||
import xml2js from 'xml2js';
 | 
			
		||||
export const simpleRouter = new SimpleRouter();
 | 
			
		||||
 | 
			
		||||
simpleRouter.get('/api/wxmsg', async (req, res) => {
 | 
			
		||||
  const query = simpleRouter.getSearch(req);
 | 
			
		||||
  const body = await simpleRouter.getBody(req);
 | 
			
		||||
  const {
 | 
			
		||||
    signature, // 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
 | 
			
		||||
    timestamp, // 时间戳
 | 
			
		||||
    nonce, // 随机数
 | 
			
		||||
    echostr, // 随机字符串
 | 
			
		||||
  } = query;
 | 
			
		||||
  const token = 'xiongabc123';
 | 
			
		||||
  let str = [token, timestamp, nonce].sort().join('');
 | 
			
		||||
  let strSha1 = crypto.createHash('sha1').update(str).digest('hex');
 | 
			
		||||
  // 签名对比,相同则按照微信要求返回echostr参数值
 | 
			
		||||
  if (signature == strSha1) {
 | 
			
		||||
    res.end(echostr);
 | 
			
		||||
  } else {
 | 
			
		||||
    res.end('send fail');
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const getJsonFromXml = async (req: any): Promise<any> => {
 | 
			
		||||
  return await new Promise((resolve) => {
 | 
			
		||||
    // 读取请求数据
 | 
			
		||||
    let data = '';
 | 
			
		||||
    req.setEncoding('utf8');
 | 
			
		||||
    // 监听data事件,接收数据片段
 | 
			
		||||
    req.on('data', (chunk) => {
 | 
			
		||||
      data += chunk;
 | 
			
		||||
    });
 | 
			
		||||
    // 当请求结束时处理数据
 | 
			
		||||
    req.on('end', () => {
 | 
			
		||||
      try {
 | 
			
		||||
        // 使用xml2js解析XML
 | 
			
		||||
        xml2js.parseString(data, function (err, result) {
 | 
			
		||||
          if (err) {
 | 
			
		||||
            console.error('XML解析错误:', err);
 | 
			
		||||
            resolve(null);
 | 
			
		||||
          } else {
 | 
			
		||||
            const jsonString = JSON.stringify(result);
 | 
			
		||||
            resolve(jsonString);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      } catch (error) {
 | 
			
		||||
        console.error('处理请求时出错:', error);
 | 
			
		||||
        resolve(null);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
simpleRouter.post('/api/wxmsg', async (req, res) => {
 | 
			
		||||
  console.log('tuisong');
 | 
			
		||||
  const msg = await getJsonFromXml(req);
 | 
			
		||||
  console.log('Receive:', msg);
 | 
			
		||||
  const builder = new xml2js.Builder();
 | 
			
		||||
  const result = builder.buildObject({
 | 
			
		||||
    xml: {
 | 
			
		||||
      ToUserName: msg.FromUserName,
 | 
			
		||||
      FromUserName: msg.ToUserName,
 | 
			
		||||
      CreateTime: Date.now(),
 | 
			
		||||
      MsgType: msg.MsgType,
 | 
			
		||||
      Content: 'Hello ' + msg.Content,
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
  res.end(result);
 | 
			
		||||
});
 | 
			
		||||
export const listen = async (req, res) => {
 | 
			
		||||
  return await simpleRouter.parse(req, res);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										6
									
								
								app/src/wx/routes/access.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/src/wx/routes/access.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
// const accessURL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET'
 | 
			
		||||
const accessURL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential';
 | 
			
		||||
 | 
			
		||||
export const getAccessURL = (appId: string, appSecret: string) => {
 | 
			
		||||
  return `${accessURL}&appid=${appId}&secret=${appSecret}`;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										31
									
								
								app/src/wx/routes/kefu.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/src/wx/routes/kefu.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
// {
 | 
			
		||||
//   "touser":"OPENID",
 | 
			
		||||
//   "msgtype":"text",
 | 
			
		||||
//   "text":
 | 
			
		||||
//   {
 | 
			
		||||
//        "content":"Hello World"
 | 
			
		||||
//   }
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// 正常执行是errorcode为0
 | 
			
		||||
 | 
			
		||||
// res {
 | 
			
		||||
//   errcode: 45047,
 | 
			
		||||
//   errmsg: 'out of response count limit rid: 67c26b8d-3d22149f-5031a93c'
 | 
			
		||||
// }
 | 
			
		||||
export const sendUser = async (accessToken: string) => {
 | 
			
		||||
  const data = {
 | 
			
		||||
    touser: 'omcvy7AHC6bAA0QM4x9_bE0fGD1g',
 | 
			
		||||
    msgtype: 'text',
 | 
			
		||||
    text: {
 | 
			
		||||
      content: 'Hello World',
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  const url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN';
 | 
			
		||||
  const link = url.replace('ACCESS_TOKEN', accessToken);
 | 
			
		||||
  const res = await fetch(link, {
 | 
			
		||||
    method: 'POST',
 | 
			
		||||
    body: JSON.stringify(data),
 | 
			
		||||
  }).then((res) => res.json());
 | 
			
		||||
  console.log('res', res);
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user