@alicloud/mns
Advanced tools
Comparing version 1.0.0-beta to 1.0.0-beta2
@@ -20,4 +20,11 @@ 'use strict'; | ||
constructor(accountid, opts) { | ||
assert(accountid, '"accountid" must be passed in'); | ||
this.accountid = accountid; | ||
assert(opts, 'must pass in "opts"'); | ||
// 兼容 | ||
const accessKeyID = opts.accessKeyId || opts.accessKeyID; | ||
assert(accessKeyID, 'must pass in "opts.accessKeyID"'); | ||
this.accessKeyID = accessKeyID; | ||
assert(opts.accessKeySecret, 'must pass in "opts.accessKeySecret"'); | ||
this.accessKeySecret = opts.accessKeySecret; | ||
assert(opts.region, 'must pass in "opts.region"'); | ||
@@ -27,21 +34,16 @@ const {domain, endpoint} = getEndpoint(accountid, opts); | ||
this.endpoint = endpoint; | ||
assert(opts.accessKeyId, 'must pass in "opts.accessKeyId"'); | ||
this.accessKeyId = opts.accessKeyId; | ||
assert(opts.accessKeySecret, 'must pass in "opts.accessKeySecret"'); | ||
this.accessKeySecret = opts.accessKeySecret; | ||
} | ||
async request(method, resource, type, params, customHeaders, attentions = []) { | ||
async request(method, resource, type, requestBody, attentions = [], opts = {}) { | ||
const url = `${this.endpoint}${resource}`; | ||
const requestBody = method === 'GET' ? '': toXMLBuffer(type, params); | ||
debug('url: %s', url); | ||
debug('method: %s', method); | ||
const headers = this.buildHeaders(method, requestBody, resource); | ||
const headers = this.buildHeaders(method, requestBody, resource, opts.headers); | ||
debug('request headers: %j', headers); | ||
debug('request body: %s', requestBody.toString()); | ||
const response = await httpx.request(url, { | ||
const response = await httpx.request(url, Object.assign(opts, { | ||
method: method, | ||
headers: headers, | ||
data: requestBody | ||
}); | ||
})); | ||
@@ -59,13 +61,12 @@ debug('statusCode %s', response.statusCode); | ||
if (responseBody && contentType.startsWith('text/xml')) { | ||
var responseData = await parseXML(responseBody); | ||
const responseData = await parseXML(responseBody); | ||
if (responseData.Error) { | ||
var e = responseData.Error; | ||
var err = new Error(extract(e.Message)); | ||
const e = responseData.Error; | ||
const message = extract(e.Message); | ||
const requestid = extract(e.RequestId); | ||
const hostid = extract(e.HostId); | ||
const err = new Error(`${method} ${url} failed with ${code}. ` + | ||
`requestid: ${requestid}, hostid: ${hostid}, message: ${message}`); | ||
err.name = 'MNS' + extract(e.Code) + err.name; | ||
err.data = { | ||
requestid: extract(e.RequestId), | ||
hostid: extract(e.HostId) | ||
}; | ||
throw err; | ||
@@ -75,8 +76,7 @@ } | ||
body = {}; | ||
Object.keys(responseData[type]) | ||
.forEach((key) => { | ||
if (key !== '$') { | ||
body[key] = extract(responseData[type][key]); | ||
} | ||
}); | ||
Object.keys(responseData[type]).forEach((key) => { | ||
if (key !== '$') { | ||
body[key] = extract(responseData[type][key]); | ||
} | ||
}); | ||
} | ||
@@ -91,14 +91,18 @@ | ||
get(resource, type, customHeaders) { | ||
return this.request('GET', resource, type, {}, [], customHeaders); | ||
get(resource, type, opts) { | ||
return this.request('GET', resource, type, '', [], opts); | ||
} | ||
put(resource, type, params, attentions = []) { | ||
return this.request('PUT', resource, type, params, attentions); | ||
put(resource, type, body, attentions = [], opts = {}) { | ||
return this.request('PUT', resource, type, body, attentions, opts); | ||
} | ||
post(resource, type, params) { | ||
return this.request('POST', resource, type, params); | ||
post(resource, type, body) { | ||
return this.request('POST', resource, type, body); | ||
} | ||
delete(resource) { | ||
return this.request('DELETE', resource, undefined, ''); | ||
} | ||
sign(verb, headers, resource) { | ||
@@ -122,3 +126,3 @@ const canonicalizedMNSHeaders = getCanonicalizedMNSHeaders(headers); | ||
buildHeaders(method, body, resource) { | ||
buildHeaders(method, body, resource, customHeaders) { | ||
const date = new Date().toGMTString(); | ||
@@ -129,6 +133,6 @@ const contentType = 'text/xml'; | ||
var headers = { | ||
const headers = Object.assign({ | ||
'content-length': body.length, | ||
'content-type': contentType, | ||
'content-md5': md5, | ||
'content-type': contentType, | ||
'date': date, | ||
@@ -138,7 +142,7 @@ 'host': this.endpointDomain, | ||
'x-mns-version': '2015-06-06' | ||
}; | ||
}, customHeaders); | ||
const signature = this.sign(method, headers, resource); | ||
headers['authorization'] = `MNS ${this.accessKeyId}:${signature}`; | ||
headers['authorization'] = `MNS ${this.accessKeyID}:${signature}`; | ||
@@ -150,3 +154,4 @@ return headers; | ||
createQueue(name, params = {}) { | ||
return this.put(`/queues/${name}`, 'Queue', params, ['location']); | ||
const body = toXMLBuffer('Queue', params); | ||
return this.put(`/queues/${name}`, 'Queue', body, ['location']); | ||
} | ||
@@ -156,10 +161,22 @@ | ||
listQueue(start, limit, prefix) { | ||
var customHeaders = { | ||
'x-mns-marker': start, | ||
'x-mns-ret-number': limit, | ||
'x-mns-prefix': prefix | ||
}; | ||
async listQueue(start, limit, prefix) { | ||
var customHeaders = {}; | ||
if (typeof start !== 'undefined') { | ||
customHeaders['x-mns-marker'] = start; | ||
} | ||
return this.get('/queues', 'Queues', customHeaders); | ||
if (typeof limit !== 'undefined') { | ||
customHeaders['x-mns-ret-number'] = limit; | ||
} | ||
if (typeof limit !== 'undefined') { | ||
customHeaders['x-mns-prefix'] = prefix; | ||
} | ||
const subType = 'Queue'; | ||
const response = await this.get('/queues', 'Queues', { | ||
headers: customHeaders | ||
}); | ||
response.body = response.body[subType]; | ||
return response; | ||
} | ||
@@ -171,9 +188,36 @@ | ||
// Message | ||
sendMessage() {} | ||
batchSendMessage() {} | ||
receiveMessage() {} | ||
sendMessage(queueName, params) { | ||
const url = `/queues/${queueName}/messages`; | ||
const body = toXMLBuffer('Message', params); | ||
return this.post(url, 'Message', body); | ||
} | ||
async batchSendMessage(queueName, params) { | ||
const url = `/queues/${queueName}/messages`; | ||
const subType = 'Message'; | ||
const body = toXMLBuffer('Messages', params, subType); | ||
var response = await this.post(url, 'Messages', body); | ||
response.body = response.body[subType]; | ||
return response; | ||
} | ||
receiveMessage(queueName, waitSeconds) { | ||
var url = `/queues/${queueName}/messages`; | ||
if (waitSeconds) { | ||
url += `?waitseconds=${waitSeconds}`; | ||
} | ||
// 31000 31s +1s max waitSeconds is 30s | ||
return this.get(url, 'Message', {timeout: 31000}); | ||
} | ||
batchReceiveMessage() {} | ||
peekMessage() {} | ||
batchPeekMessage() {} | ||
deleteMessage() {} | ||
deleteMessage(queueName, receiptHandle) { | ||
const url = `/queues/${queueName}/messages?ReceiptHandle=${receiptHandle}`; | ||
return this.delete(url, 'Message', ''); | ||
} | ||
batchDeleteMessage() {} | ||
@@ -184,14 +228,27 @@ changeMessageVisibility() {} | ||
createTopic(name, params = {}) { | ||
return this.put(`/topics/${name}`, 'Topic', params, ['location']); | ||
const body = toXMLBuffer('Topic', params); | ||
return this.put(`/topics/${name}`, 'Topic', body, ['location']); | ||
} | ||
deleteTopic() {} | ||
listTopic(start, limit, prefix) { | ||
var customHeaders = { | ||
'x-mns-marker': start, | ||
'x-mns-ret-number': limit, | ||
'x-mns-prefix': prefix | ||
}; | ||
async listTopic(start, limit, prefix) { | ||
var customHeaders = {}; | ||
if (typeof start !== 'undefined') { | ||
customHeaders['x-mns-marker'] = start; | ||
} | ||
return this.get('/topics', 'Topics', customHeaders); | ||
if (typeof limit !== 'undefined') { | ||
customHeaders['x-mns-ret-number'] = limit; | ||
} | ||
if (typeof limit !== 'undefined') { | ||
customHeaders['x-mns-prefix'] = prefix; | ||
} | ||
const subType = 'Topic'; | ||
const response = await this.get('/topics', 'Topics', { | ||
headers: customHeaders | ||
}); | ||
response.body = response.body[subType]; | ||
return response; | ||
} | ||
@@ -204,3 +261,4 @@ | ||
setTopicAttributes(name, params = {}) { | ||
return this.put(`/topics/${name}?metaoverride=true`, 'Topic', params); | ||
const body = toXMLBuffer('Topic', params); | ||
return this.put(`/topics/${name}?metaoverride=true`, 'Topic', body); | ||
} | ||
@@ -217,3 +275,5 @@ | ||
publishMessage(topic, params) { | ||
return this.post(`/topics/${topic}/messages`, 'Message', params); | ||
const url = `/topics/${topic}/messages`; | ||
const body = toXMLBuffer('Message', params); | ||
return this.post(url, 'Message', body); | ||
} | ||
@@ -220,0 +280,0 @@ |
@@ -43,6 +43,14 @@ 'use strict'; | ||
exports.toXMLBuffer = function (entityType, params) { | ||
exports.toXMLBuffer = function (entityType, params, subType) { | ||
var xml = '<?xml version="1.0" encoding="UTF-8"?>'; | ||
xml += `<${entityType} xmlns="http://mns.aliyuncs.com/doc/v1/">`; | ||
xml += format(params); | ||
if (Array.isArray(params)) { | ||
params.forEach((item) => { | ||
xml += `<${subType}>`; | ||
xml += format(item); | ||
xml += `</${subType}>`; | ||
}); | ||
} else { | ||
xml += format(params); | ||
} | ||
xml += `</${entityType}>`; | ||
@@ -49,0 +57,0 @@ return Buffer.from(xml, 'utf8'); |
{ | ||
"name": "@alicloud/mns", | ||
"version": "1.0.0-beta", | ||
"description": "", | ||
"version": "1.0.0-beta2", | ||
"description": "> 该 SDK 并未完全实现所有文档所提及的功能,如果您想使用的功能并未实现,请提[issue](https://github.com/aliyun/aliyun-mns-nodejs-sdk/issues/new)以增加优先级。", | ||
"main": "index.js", | ||
@@ -10,5 +10,5 @@ "directories": { | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "make test" | ||
}, | ||
"author": "", | ||
"author": "Jackson Tian", | ||
"license": "MIT", | ||
@@ -21,3 +21,28 @@ "dependencies": { | ||
}, | ||
"files": ["lib", "index.js"] | ||
"files": [ | ||
"lib", | ||
"index.js" | ||
], | ||
"devDependencies": { | ||
"coveralls": "^2.13.1", | ||
"eslint": "^3.19.0", | ||
"expect.js": "^0.3.1", | ||
"mocha": "^3.3.0", | ||
"nyc": "^10.3.2" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/aliyun/mns-nodejs-sdk.git" | ||
}, | ||
"keywords": [ | ||
"MNS", | ||
"Message", | ||
"Service", | ||
"Aliyun", | ||
"Alicloud" | ||
], | ||
"bugs": { | ||
"url": "https://github.com/aliyun/mns-nodejs-sdk/issues" | ||
}, | ||
"homepage": "https://github.com/aliyun/mns-nodejs-sdk#readme" | ||
} |
100
README.md
@@ -1,1 +0,99 @@ | ||
# aliyun-mns-nodejs-sdk | ||
# mns-nodejs-sdk | ||
[![NPM version][npm-image]][npm-url] | ||
[![build status][travis-image]][travis-url] | ||
[![coverage][cov-image]][cov-url] | ||
[npm-image]: https://img.shields.io/npm/v/@alicloud/mns.svg?style=flat-square | ||
[npm-url]: https://npmjs.org/package/@alicloud/mns | ||
[travis-image]: https://img.shields.io/travis/aliyun/mns-nodejs-sdk/master.svg?style=flat-square | ||
[travis-url]: https://travis-ci.org/aliyun/mns-nodejs-sdk.svg?branch=master | ||
[cov-image]: https://coveralls.io/repos/aliyun/mns-nodejs-sdk/badge.svg?branch=master&service=github | ||
[cov-url]: https://coveralls.io/github/aliyun/mns-nodejs-sdk?branch=master | ||
Documents: http://doxmate.cool/aliyun/mns-nodejs-sdk/api.html | ||
> 该 SDK 并未完全实现所有文档所提及的功能,如果您想使用的功能并未实现,请提[issue](https://github.com/aliyun/mns-nodejs-sdk/issues/new)以增加优先级。 | ||
## Installation | ||
```bash | ||
npm install @alicloud/mns --save | ||
``` | ||
## API Spec | ||
See: https://help.aliyun.com/document_detail/27475.html | ||
## Test | ||
```sh | ||
ACCOUNT_ID=<ACCOUNT_ID> ACCESS_KEY_ID=<ACCESS_KEY_ID> ACCESS_KEY_SECRET=<ACCESS_KEY_SECRET> make test | ||
``` | ||
## Installation | ||
You can install it via npm/cnpm/yarn. | ||
```sh | ||
$ npm install @alicloud/mns --save | ||
``` | ||
## Usage | ||
```js | ||
const MNSClient = require('@alicloud/mns'); | ||
const accountid = '<account id>'; | ||
var client = new MNSClient(accountid, { | ||
region: '<region>', | ||
accessKeyId: '<access key id>', | ||
accessKeySecret: '<access key secret>', | ||
// optional & default | ||
secure: false, // use https or http | ||
internal: false, // use internal endpoint | ||
vpc: false // use vpc endpoint | ||
}); | ||
(async function () { | ||
let res; | ||
// create queue | ||
res = await client.createQueue('test-queue2'); | ||
console.log(res); | ||
// list queue | ||
res = await client.listQueue(); | ||
console.log(JSON.stringify(res, null, 2)); | ||
// create topic | ||
res = await client.createTopic('test-topic'); | ||
console.log(res); | ||
// get topic attributes | ||
res = await client.getTopicAttributes('test-topic'); | ||
console.log(res); | ||
// publish message | ||
res = await client.publishMessage('<topic name>', { | ||
MessageBody: 'content', | ||
MessageAttributes: { | ||
DirectSMS: JSON.stringify({ | ||
FreeSignName: '', | ||
TemplateCode: '<template code>', | ||
Type: '<type>', | ||
Receiver: '<phone number>', | ||
SmsParams: JSON.stringify({ | ||
code: '<code>', | ||
product: '<product>' | ||
}) | ||
}) | ||
} | ||
}); | ||
console.log(res); | ||
})().then((data) => { | ||
console.log(data); | ||
}, (err) => { | ||
console.log(err.stack); | ||
}); | ||
``` | ||
## License | ||
The [MIT](LICENSE) License |
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
14836
307
1
1
100
0
5