diff --git a/core/package.json b/core/package.json index 27be19d..f8c0a71 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@cool-midway/core", - "version": "7.0.2", + "version": "7.0.3", "description": "", "main": "dist/index.js", "typings": "index.d.ts", diff --git a/core/src/interface.ts b/core/src/interface.ts index 0a6d10f..76d7922 100644 --- a/core/src/interface.ts +++ b/core/src/interface.ts @@ -344,11 +344,34 @@ export interface CoolSmsConfig { /** * 腾讯云短信配置 */ - tx: CoolTxConfig; + tx: CoolSmsTxConfig; /** * 云片短信配置 */ - yp: CoolYpConfig; + yp: CoolSmsYpConfig; + /** + * aws短信配置 + */ + aws: CoolSmsAwsConfig; +} + +export interface CoolSmsAwsConfig { + /** + * 区域 + */ + region: string; + /** + * accessKeyId + */ + accessKeyId: string; + /** + * secretAccessKey + */ + secretAccessKey: string; + /** + * 扩展配置 + */ + extend?: any; } /** @@ -376,7 +399,7 @@ export interface CoolSmsAliConfig { /** * 腾讯云配置 */ -export interface CoolTxConfig { +export interface CoolSmsTxConfig { /** * 应用ID */ @@ -402,7 +425,7 @@ export interface CoolTxConfig { /** * 云片短信配置 */ -export interface CoolYpConfig { +export interface CoolSmsYpConfig { /** * 云片apikey */ diff --git a/core/src/package.json b/core/src/package.json index a6b8aa1..fd0a452 100644 --- a/core/src/package.json +++ b/core/src/package.json @@ -1,6 +1,6 @@ { "name": "@cool-midway/core", - "version": "7.0.2", + "version": "7.0.3", "description": "", "main": "index.js", "typings": "index.d.ts", diff --git a/sms/package.json b/sms/package.json index 7be755e..a4c9037 100644 --- a/sms/package.json +++ b/sms/package.json @@ -1,6 +1,6 @@ { "name": "@cool-midway/sms", - "version": "7.0.0", + "version": "7.0.1", "description": "cool-js.com 短信", "main": "dist/index.js", "typings": "index.d.ts", @@ -35,15 +35,16 @@ "@midwayjs/mock": "^3.9.0", "@types/jest": "^29.2.5", "@types/node": "^18.11.18", + "axios": "^1.5.0", "cross-env": "^7.0.3", "jest": "^29.3.1", "mwts": "^1.3.0", "ts-jest": "^29.0.3", - "axios": "^1.5.0", "typescript": "^4.9.4" }, "dependencies": { "@alicloud/pop-core": "^1.7.13", + "@aws-sdk/client-sns": "^3.465.0", "tencentcloud-sdk-nodejs": "^4.0.607" } } diff --git a/sms/src/ali.ts b/sms/src/ali.ts index a2f4e6f..fdc4864 100644 --- a/sms/src/ali.ts +++ b/sms/src/ali.ts @@ -1,5 +1,5 @@ import * as Core from '@alicloud/pop-core'; -import { Config, Provide } from "@midwayjs/core"; +import { Config, Provide } from '@midwayjs/core'; import { CoolSmsAliConfig } from './interface'; import { CoolCommException } from '@cool-midway/core'; @@ -8,57 +8,61 @@ import { CoolCommException } from '@cool-midway/core'; */ @Provide() export class SmsAli { - @Config('cool.sms.ali') - config: CoolSmsAliConfig; + @Config('cool.sms.ali') + config: CoolSmsAliConfig; - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsAliConfig) { - this.config = config; - } + /** + * 配置 + * @param config + */ + setConfig(config: CoolSmsAliConfig) { + this.config = config; + } - /** - * 发送短信 - * @param phone 手机号 - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send(phone, params: { - [key: string]: string; - }, config?: { - signName: string; - template: string; - }) { - const { accessKeyId, accessKeySecret } = this.config; - if (!accessKeyId || !accessKeyId) { - throw new CoolCommException('请配置阿里云短信'); - } - if (!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - const client = new Core({ - accessKeyId, - accessKeySecret, - endpoint: 'https://dysmsapi.aliyuncs.com', - // endpoint: 'https://cs.cn-hangzhou.aliyuncs.com', - apiVersion: '2017-05-25', - // apiVersion: '2018-04-18', - }); - const data = { - RegionId: 'cn-shanghai', - PhoneNumbers: phone, - signName: config.signName, - templateCode: config.template, - TemplateParam: JSON.stringify(params), - }; - return await client.request('SendSms', data, { - method: 'POST', - }); + /** + * 发送短信 + * @param phone 手机号 + * @param params 参数 + * @param config signName 签名 template 模板 + * @returns + */ + async send( + phone, + params: { + [key: string]: string; + }, + config?: { + signName: string; + template: string; } -} \ No newline at end of file + ) { + const { accessKeyId, accessKeySecret } = this.config; + if (!accessKeyId || !accessKeyId) { + throw new CoolCommException('请配置阿里云短信'); + } + if (!config) { + config = { + signName: this.config.signName, + template: this.config.template, + }; + } + const client = new Core({ + accessKeyId, + accessKeySecret, + endpoint: 'https://dysmsapi.aliyuncs.com', + // endpoint: 'https://cs.cn-hangzhou.aliyuncs.com', + apiVersion: '2017-05-25', + // apiVersion: '2018-04-18', + }); + const data = { + RegionId: 'cn-shanghai', + PhoneNumbers: phone, + signName: config.signName, + templateCode: config.template, + TemplateParam: JSON.stringify(params), + }; + return await client.request('SendSms', data, { + method: 'POST', + }); + } +} diff --git a/sms/src/aws.ts b/sms/src/aws.ts new file mode 100644 index 0000000..6770e62 --- /dev/null +++ b/sms/src/aws.ts @@ -0,0 +1,50 @@ +import { Config, Provide } from '@midwayjs/core'; +import { CoolSmsAwsConfig } from './interface'; +import { CoolCommException } from '@cool-midway/core'; +import { SNSClient, PublishCommand } from '@aws-sdk/client-sns'; + +/** + * 亚马逊云短信 + */ +@Provide() +export class SmsAws { + @Config('cool.sms.aws') + config: CoolSmsAwsConfig; + + /** + * 配置 + * @param config + */ + setConfig(config: CoolSmsAwsConfig) { + this.config = config; + } + + /** + * 发送短信 + * @param phone 手机号 + * @param params 参数 + * @returns + */ + async send(phone: string, content: string) { + const { region, accessKeyId, secretAccessKey, extend = {} } = this.config; + if (!region || !accessKeyId || !secretAccessKey) { + throw new CoolCommException('请配置AWS短信'); + } + // 配置 AWS + const client = new SNSClient({ + region, // 例如 'us-east-1' + credentials: { + accessKeyId, + secretAccessKey, + }, + ...extend, + }); + + const data = { + Message: content, + PhoneNumber: phone, + }; + const result = await client.send(new PublishCommand(data)); + return result; + } +} diff --git a/sms/src/index.ts b/sms/src/index.ts index 3856a5c..9285388 100644 --- a/sms/src/index.ts +++ b/sms/src/index.ts @@ -5,5 +5,6 @@ export * from './interface'; export * from './ali'; export * from './yp'; export * from './tx'; +export * from './aws'; export * from './sms'; diff --git a/sms/src/interface.ts b/sms/src/interface.ts index cad710a..dfb9a43 100644 --- a/sms/src/interface.ts +++ b/sms/src/interface.ts @@ -6,11 +6,34 @@ export interface CoolSmsConfig { /** * 腾讯云短信配置 */ - tx: CoolTxConfig; + tx: CoolSmsTxConfig; /** * 云片短信配置 */ - yp: CoolYpConfig; + yp: CoolSmsYpConfig; + /** + * aws短信配置 + */ + aws: CoolSmsAwsConfig; +} + +export interface CoolSmsAwsConfig { + /** + * 区域 + */ + region: string; + /** + * accessKeyId + */ + accessKeyId: string; + /** + * secretAccessKey + */ + secretAccessKey: string; + /** + * 扩展配置 + */ + extend?: any; } /** @@ -38,7 +61,7 @@ export interface CoolSmsAliConfig { /** * 腾讯云配置 */ -export interface CoolTxConfig { +export interface CoolSmsTxConfig { /** * 应用ID */ @@ -64,7 +87,7 @@ export interface CoolTxConfig { /** * 云片短信配置 */ -export interface CoolYpConfig { +export interface CoolSmsYpConfig { /** * 云片apikey */ diff --git a/sms/src/package.json b/sms/src/package.json index 5717c9b..a78e7de 100644 --- a/sms/src/package.json +++ b/sms/src/package.json @@ -1,6 +1,6 @@ { "name": "@cool-midway/sms", - "version": "7.0.0", + "version": "7.0.1", "description": "cool-js.com 短信", "main": "index.js", "typings": "index.d.ts", @@ -44,6 +44,7 @@ }, "dependencies": { "@alicloud/pop-core": "^1.7.13", + "@aws-sdk/client-sns": "^3.465.0", "tencentcloud-sdk-nodejs": "^4.0.607" } } diff --git a/sms/src/sms.ts b/sms/src/sms.ts index 2ce7b3d..976b6e6 100644 --- a/sms/src/sms.ts +++ b/sms/src/sms.ts @@ -1,83 +1,97 @@ -import { Config, Inject, Provide } from "@midwayjs/core"; -import { SmsYp } from "./yp"; -import { SmsAli } from "./ali"; -import { SmsTx } from "./tx"; -import { CoolSmsConfig } from "./interface"; +import { Config, Inject, Provide } from '@midwayjs/core'; +import { SmsYp } from './yp'; +import { SmsAli } from './ali'; +import { SmsTx } from './tx'; +import { CoolSmsConfig } from './interface'; +import { SmsAws } from './aws'; @Provide() export class CoolSms { - @Inject() - smsYp: SmsYp + @Inject() + smsYp: SmsYp; - @Inject() - smsAli: SmsAli + @Inject() + smsAli: SmsAli; - @Inject() - smsTx: SmsTx + @Inject() + smsTx: SmsTx; - @Config('cool.sms') - config: CoolSmsConfig; + @Inject() + smsAws: SmsAws; - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsConfig) { - this.smsYp.setConfig(config.yp); - this.smsAli.setConfig(config.ali); - this.smsTx.setConfig(config.tx); - this.config = config; + @Config('cool.sms') + config: CoolSmsConfig; + + /** + * 配置 + * @param config + */ + setConfig(config: CoolSmsConfig) { + this.smsYp.setConfig(config.yp); + this.smsAli.setConfig(config.ali); + this.smsTx.setConfig(config.tx); + this.config = config; + } + + /** + * 发送验证码 模板字段名为:code + * @param phone + * @param config + */ + async sendCode( + phone, + config?: { + signName: string; + template: string; } + ) { + const code = this.generateNumber(); + let params = { + code, + }; + await this.send(phone, this.config.tx ? [code] : params, config); + return code; + } - /** - * 发送验证码 模板字段名为:code - * @param phone - * @param config - */ - async sendCode(phone, config?: { - signName: string; - template: string; - }) { - const code = this.generateNumber(); - let params = { - code - } - await this.send(phone, this.config.tx ? [code] : params, config) - return code; + /** + * 发送短信 + * @param phone + * @param params + * @param config + * @returns + */ + async send( + phone: string, + params: any, + config?: { + signName: string; + template: string; } + ) { + if (this.config.ali) { + return await this.smsAli.send(phone, params, config); + } + if (this.config.tx) { + return await this.smsTx.send(phone, params, config); + } + if (this.config.yp) { + return await this.smsYp.send(phone, params, config); + } + if (this.config.aws) { + return await this.smsAws.send(phone, params); + } + return true; + } - /** - * 发送短信 - * @param phone - * @param params - * @param config - * @returns - */ - async send(phone: string, params: any, config?: { - signName: string; - template: string; - }) { - if (this.config.ali) { - return await this.smsAli.send(phone, params, config); - } - if (this.config.tx) { - return await this.smsTx.send(phone, params, config); - } - if (this.config.yp) { - return await this.smsYp.send(phone, params, config); - } - return true; + /** + * 生成验证码 + */ + generateNumber(digits = 4) { + if (digits <= 0) { + return 0; } - - /** - * 生成验证码 - */ - generateNumber(digits = 4) { - if (digits <= 0) { - return 0; - } - const min = Math.pow(10, digits - 1); - const max = Math.pow(10, digits) - 1; - return Math.floor(Math.random() * (max - min + 1)) + min; - } -} \ No newline at end of file + const min = Math.pow(10, digits - 1); + const max = Math.pow(10, digits) - 1; + return Math.floor(Math.random() * (max - min + 1)) + min; + } +} diff --git a/sms/src/tx.ts b/sms/src/tx.ts index 1d3e9e1..4d9fe87 100644 --- a/sms/src/tx.ts +++ b/sms/src/tx.ts @@ -1,70 +1,74 @@ -import { Config, Provide } from "@midwayjs/core"; -import { CoolTxConfig } from './interface'; -import * as tencentcloud from "tencentcloud-sdk-nodejs"; -import { CoolCommException } from "@cool-midway/core"; +import { Config, Provide } from '@midwayjs/core'; +import { CoolSmsTxConfig } from './interface'; +import * as tencentcloud from 'tencentcloud-sdk-nodejs'; +import { CoolCommException } from '@cool-midway/core'; /** * 腾讯云短信 */ @Provide() export class SmsTx { - @Config('cool.sms.tx') - config: CoolTxConfig; + @Config('cool.sms.tx') + config: CoolSmsTxConfig; - /** - * 配置 - * @param config - */ - setConfig(config: CoolTxConfig) { - this.config = config; + /** + * 配置 + * @param config + */ + setConfig(config: CoolSmsTxConfig) { + this.config = config; + } + + /** + * 发送短信 + * @param phone 手机号 + * @param params 参数 + * @param config signName 签名 template 模板 + * @returns + */ + async send( + phone: string, + params: string[], + config?: { + signName: string; + template: string; } - - /** - * 发送短信 - * @param phone 手机号 - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send(phone: string, params: string[], config?: { - signName: string; - template: string; - }) { - const { appId, secretId, secretKey } = this.config; - if(!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - if(!appId || !secretId || !secretKey) { - throw new CoolCommException('请配置腾讯云短信'); - } - const smsClient = tencentcloud.sms.v20210111.Client; - - const client = new smsClient({ - credential: { - secretId, - secretKey, - }, - region: 'ap-guangzhou', - profile: { - signMethod: 'HmacSHA256', - httpProfile: { - reqMethod: 'POST', - reqTimeout: 30, - endpoint: 'sms.tencentcloudapi.com', - }, - }, - }); - - const data = { - SmsSdkAppId: appId, - SignName: config.signName, - TemplateId: config.template, - TemplateParamSet: params, - PhoneNumberSet: [`+86${phone}`], - }; - return client.SendSms(data); + ) { + const { appId, secretId, secretKey } = this.config; + if (!config) { + config = { + signName: this.config.signName, + template: this.config.template, + }; } -} \ No newline at end of file + if (!appId || !secretId || !secretKey) { + throw new CoolCommException('请配置腾讯云短信'); + } + const smsClient = tencentcloud.sms.v20210111.Client; + + const client = new smsClient({ + credential: { + secretId, + secretKey, + }, + region: 'ap-guangzhou', + profile: { + signMethod: 'HmacSHA256', + httpProfile: { + reqMethod: 'POST', + reqTimeout: 30, + endpoint: 'sms.tencentcloudapi.com', + }, + }, + }); + + const data = { + SmsSdkAppId: appId, + SignName: config.signName, + TemplateId: config.template, + TemplateParamSet: params, + PhoneNumberSet: [`+86${phone}`], + }; + return client.SendSms(data); + } +} diff --git a/sms/src/yp.ts b/sms/src/yp.ts index 01ffc66..c7440fb 100644 --- a/sms/src/yp.ts +++ b/sms/src/yp.ts @@ -1,6 +1,6 @@ -import { Config, Provide } from "@midwayjs/core"; -import { CoolYpConfig } from "./interface"; -import { CoolCommException } from "@cool-midway/core"; +import { Config, Provide } from '@midwayjs/core'; +import { CoolSmsYpConfig } from './interface'; +import { CoolCommException } from '@cool-midway/core'; import axios from 'axios'; /** @@ -8,79 +8,83 @@ import axios from 'axios'; */ @Provide() export class SmsYp { - @Config('cool.sms.yp') - config: CoolYpConfig; + @Config('cool.sms.yp') + config: CoolSmsYpConfig; - /** - * 配置 - * @param config - */ - setConfig(config: CoolYpConfig) { - this.config = config; + /** + * 配置 + * @param config + */ + setConfig(config: CoolSmsYpConfig) { + this.config = config; + } + + /** + * 发送短信 + * @param phones 手机号 数组,需要加国家码如 ["+8612345678901"] + * @param params 参数 + * @param config signName 签名 template 模板 + * @returns + */ + async send( + phones: string, + params: { + [key: string]: string; + }, + config?: { + signName: string; + template: string; + } + ) { + const { apikey } = this.config; + if (!config) { + config = { + signName: this.config.signName, + template: this.config.template, + }; + } + if (!apikey) { + throw new CoolCommException('请配置云片短信'); } - /** - * 发送短信 - * @param phones 手机号 数组,需要加国家码如 ["+8612345678901"] - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send(phones: string, params: { - [key: string]: string; - }, config?: { - signName: string; - template: string; - }) { - const { apikey } = this.config; - if (!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - if (!apikey) { - throw new CoolCommException('请配置云片短信'); - } + const headers = { + Accept: 'application/json;charset=utf-8', + 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', + }; + const data = { + apikey: apikey, + mobile: phones, + tpl_id: config.template, + tpl_value: this.smsTplValue(params), + }; + const result = await axios.post( + 'https://sms.yunpian.com/v2/sms/tpl_single_send.json', + data, + { headers } + ); + if (result.data.code === 0) { + return true; + } + return false; + } - const headers = { - Accept: 'application/json;charset=utf-8', - 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', - }; - const data = { - apikey: apikey, - mobile: phones, - tpl_id: config.template, - tpl_value: this.smsTplValue(params), - }; - const result = await axios.post( - 'https://sms.yunpian.com/v2/sms/tpl_single_send.json', - data, - { headers } - ); - if (result.data.code === 0) { - return true; - } - return false; + /** + * 获得短信模板值 + * @param obj + * @returns + */ + protected smsTplValue(obj) { + const urlParams = []; + + for (let key in obj) { + // eslint-disable-next-line no-prototype-builtins + if (obj.hasOwnProperty(key)) { + const encodedKey = encodeURIComponent(`#${key}#`); + const encodedValue = encodeURIComponent(obj[key]); + urlParams.push(`${encodedKey}=${encodedValue}`); + } } - /** - * 获得短信模板值 - * @param obj - * @returns - */ - protected smsTplValue(obj) { - const urlParams = []; - - for (let key in obj) { - // eslint-disable-next-line no-prototype-builtins - if (obj.hasOwnProperty(key)) { - const encodedKey = encodeURIComponent(`#${key}#`); - const encodedValue = encodeURIComponent(obj[key]); - urlParams.push(`${encodedKey}=${encodedValue}`); - } - } - - return urlParams.join('&'); - } -} \ No newline at end of file + return urlParams.join('&'); + } +}