
Research
2025 Report: Destructive Malware in Open Source Packages
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.
node-easysms
Advanced tools
EasySMS 是一个由 安正超 大神用 PHP 开发的开源的短信发送工具包。本项目是 EasySMS 包在 Node.js 上的实现,并且基本还原了PHP版的配置项以及接口的调用方式。
注:虽然也使用了 EasySMS 这个名称,但是
安正超大神并未参与开发,请各位开发者不要因使用本包产生的疑惑而去打扰大神,如有疑问请在本项目中提 issue,谢谢~
npm install -S node-easysms
如果仍有疑问,请提issue,谢谢~
const { EasySms } = require('node-easysms');
// 配置项
let config = {
// 请求的超时时间(豪秒)
timeout: 5000,
// 默认发送配置
default: {
// 网关调用策略,默认:order,可选值:order、random 或回调函数(使用方式见下文)
strategy: 'order',
// 可用于发送的网关标识列表
gateways: ['aliyun']
},
// 各网关配置
gateways: {
aliyun: {
access_key_id: 'your-key-id',
access_key_secret: 'your-key-secret',
region: 'cn-hangzhou',
sign_name: 'xx平台',
},
}
};
let easySms = new EasySms(config);
// 调用发送api
let response = easySms.send('13812341234', {
sign_name: 'xx平台',
template: 'template_id',
data: {
code: '1234',
}
});
国际短信与国内短信的区别是号码前面需要加国际码,使用 PhoneNumber 类进行构建即可:
const { EasySms, PhoneNumber } = require('node-easysms');
// 第一个参数为电话号码,第二个参数为国际码
let number = new PhoneNumber('13812345678', 31);
let easySms = new EasySms({...});
// 发送时,传入 PhoneNumber 实例即可
easySms.send(number, {...});
根据平台情况使用 content 或者 template + data 设置消息即可。
content 短信内容,适用于一些直接传短信内容的平台template 短信模版,适用于一些传模版id+参数的平台,如:阿里云、腾讯云等data 短信模版参数,与 template 配合使用sign_name 短信签名,可选,如果消息中未配置,则会提取平台配置中的 sign_name你也可以使用闭包来返回对应字段的值,闭包接收一个网关实例的参数,闭包也支持异步调用,如下:
easySms.send('13812341234', {
sign_name: function (gateway) {
return 'xx平台';
},
template: async function (gateway) {
return await fetchTemplate();
},
data: function (gateway) {
// 获取网关实例的类名
let className = gateway.getName();
if (className === 'aliyun') {
return {
code: '1234',
};
}
// 默认数据
return {
code: '1234',
};
}
});
默认会根据配置项中的 default.gateways 进行发送,如果某条短信需要覆盖默认对的发送网关,可以传入第三个参数:
let response = easySms.send('13812341234', {
sign_name: 'xx平台',
template: 'template_id',
data: {
code: '1234',
}
}, ['tencent']);
由于使用多网关发送,所以返回值为一个数组,顺序同发送网关标识,结构如下:
[
// 成功
{
'gateway': 'aliyun',
'status': 'success',
'result': {}, // 平台返回的数据
},
// 失败
{
'gateway': 'tencent',
'status': 'failure',
'exception': GatewayErrorException 异常实例
},
]
GatewayErrorException 异常实例可以通过 getRaw() 方法获取接口返回的信息。如果所有网关均发送失败,则程序会抛出 NoGatewayAvailableException 异常,该异常可以通过下列方法获取对应错误信息:
e.getResults(); // 获取所有接口返回的信息
e.getExceptions(); // 获取所有接口返回的信息
e.getException('aliyun'); // 获取所有接口返回的信息
e.getLastException(); // 获取最后一个失败的异常
如果本工具未集成您所需的网关,可通过如下方式进行扩展:
// 需要引入网关基础类
const { EasySms, Gateway } = require('node-easysms');
// 创建自定义网关类
class MyGateway extends Gateway {
// to: PhoneNumber 实例
// message: Message 实例
async send(to, message) {
// 实现发送方法,并返回接口结果
// 可以使用工具内置的请求方法:this.get()、this.post()、this.postJson()、this.request()
return {};
}
}
let easySms = new EasySms({
default: {
gateways: ['mygateway']
},
gateways: {
mygateway: {
// 网关所需的参数
},
}
});
// 注册自定义网关
// 方法一:直接传入类即可
easySms.extend('mygateway', MyGateway);
// 方法二:传入闭包,需接收一个参数,即上述配置中的 gateways.mygateway
easySms.extend('mygateway', function(config) {
return new MyGateway($gatewayConfig);
});
工具集成了 order(顺序)、random(随机)两种方式,可以通过配置项 default.strategy 进行设置。如果需要自定义策略,则可以设置为一个回调函数:
const { EasySms } = require('node-easysms');
// 需要接收网关标识列表,处理后返回新的列表
function customStrategy(gateways) {
gateways.sort();
return gateways;
}
let easySms = new EasySms({
default: {
strategy: customStrategy,
gateways: []
},
gateways: {
...
}
});
您可以根据不同的场景,预先定义不同的短信消息类,从而简化发送时的配置。这时只需继承 Message 类即可:
const { EasySms, Message } = require('node-easysms');
class OrderPaidMessage extends Message {
// 定义该消息所使用的网关,优先级高于配置项 default.gateways
gateways = ['foo', 'bar'];
constructor(order) {
super({});
this.order = order;
}
async getContent() {
return `您的订单${this.order['no']}已完成付款`;
}
async getTemplate() {
return 'TPL_ORDER_PAID';
}
async getData() {
return {
order_no: this.order['no'],
};
}
async getSignName() {
return 'xx商城';
}
}
let easySms = new EasySms({...});
let order = {...};
let message = new OrderPaidMessage(order);
easySms.send(order.mobile, message);
注意,发送网关的优先级关系由高到低为:
easySms.send()方法的第三个参数- 自定义消息中配置的
gateways- 工具配置项
default.gateways
测试网关 不做配置时的默认网关。不发送任何短信,仅返回状态值:{"status":"service-ok"}
// 配置项
{
log: true, // 是否打印日志,默认:false
}
阿里云 文档,消息内容使用 template + data
// 配置项
{
access_key_id: '',
access_key_secret: '',
region: '', // 默认:cn-hangzhou
}
腾讯云 文档,消息内容使用 template + data
注意:腾讯云的模版参数是
数组,而非键值对,如果需要与其它平台一同使用,请通过闭包来返回数据。
// 配置项
{
secret_id: '',
secret_key: '',
sdk_app_id: '',
region: '', // 默认:ap-guangzhou
}
百度云 文档,消息内容使用 template + data
注意:使用
sign_name设置短信签名id
// 配置项
{
ak: '',
sk: '',
sign_name: '',
domain: '', // 默认:smsv3.bj.baidubce.com
}
七牛云 文档,消息内容使用 template + data
注意:使用
sign_name设置短信签名id
// 配置项
{
access_key: '',
secret_key: '',
sign_name: '',
}
云片 按内容发送,消息内容使用 content,同时也支持 按模板发送,消息内容使用 template + data
// 配置项
{
api_key: '',
sign_name: '',
domain: '', // 默认:sms.yunpian.com
}
聚合数据 文档,消息内容使用 template + data
// 配置项
{
app_key: '',
sign_name: '',
}
极光短信 发送单条模板短信,消息内容使用 template + data
// 配置项
{
app_key: '',
app_secret: '',
template: '',
sign_name: '',
}
FAQs
EasySMS is an SMS sender for Node.js
We found that node-easysms demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.

Security News
Socket CTO Ahmad Nassri shares practical AI coding techniques, tools, and team workflows, plus what still feels noisy and why shipping remains human-led.

Research
/Security News
A five-month operation turned 27 npm packages into durable hosting for browser-run lures that mimic document-sharing portals and Microsoft sign-in, targeting 25 organizations across manufacturing, industrial automation, plastics, and healthcare for credential theft.