The simplest call looks like this.
const alis = require('alis')
alis.articles.recent((err, json)=>{
// do something here
})
The same call promisified, simply insert .p
after alis
.
// with the promise-based calls, you are free from callback hell
alis.p.articles.recent().then((json)=>{
//do something here
}).catch((err)=>{})
Another example to get all the articles an authenticated user has published on ALIS with a promisified call. It loops through all the articles successively paginating till it reaches the end, but you can put some logics between each call with a getAll/getAllSync
function defined to make pagination easier.
This time the example uses an async/await
wrapper function to make it work like a synchronous code.
async function getAllMyArticlesTwoAtATime(){
// Amazon Cognito authentication is handled in the background
// the first argument for the API parameters to pass to the HTTPS request
// the second argument for anything else specific to this library
await alis.p.me.articles.public({limit:2}, {username: `ocrybit`, password: `xxxxx`, getAllSync:(json, obj)=>{
/* obj contains some additional data for better paginating
such as startNth, endNth, isNext, itemCount */
json.Items.forEach((article, index)=>{
console.log(`[${obj.startNth + index}] ${article.title}`)
})
}})
// async/await functions execute line by line from top to bottom
console.log(`This line comes at the end.`)
}
getAllMyArticlesTwoAtATime()
- Installation
- Available Calls
- Authentication
- Syntax Sugar
- More Examples
- OAuth
- Tests
- Links
- Contributors
Use NPM.
npm i -s alis
Refer to the official ALIS API documentation located here.
All you have to do to make a call is to replace the slashes
with dots
and remove {}
from each pathname of the call. Also specify the request method in the second argument when it's not GET
.
When authentication is needed, pass your username
and password
to the second argument as well.
Arguments are
1st
parameters specified in the API document to pass to the API call.
2nd
anything else specific to this library
3rd
the last callback function (not for promise-based calls)
You can omit the first and second argument when not required and put the last callback function as the first argument. However, you cannot omit the first argument when you need to specify the second argument.
Some examples.
[GET] /articles/{article_id}
alis.articles.article_id((err, obj)=>{})
[POST] /me/articles/{article_id}/like
alis.me.articles.article_id.like({article_id: `2xANm0jEzLPB`}, {method: `POST`, username: `your_username`, password: `your_password`}, (err, obj)=>{})
Note that some POST
and PUT
API calls don't return anything back when successful, in that case this library returns {statusCode: 200}
to indicate a successful operation.
ALIS uses Amazon Cognito to authenticate users but this library handles that in the background for you. You just need to pass your username
and password
, then it authenticates you through the complicated process and stores the tokens in a temporary file, it automagically refreshes your tokens when they are expired.
There are 3 ways to make API calls with authentication.
- pass
username
andpassword
alis.me.info({/*cannot be omitted when the 2nd argument exists*/}, {username: `your_username`, password: `your_password`},(err, obj)=>{})
- directly pass
id_token
obtained by authentication (optionally withusername
)
alis.me.info({},{id_token: `your_id_token`},(err, obj)=>{})
- pass
refresh_token
andusername
(for some weired reasons)
alis.me.info({},{refresh_token: `your_refresh_token`, username: `your_username`},(err, obj)=>{})
Note that it's a good idea to always pass your username
since both authenticating and refreshing operations require username
to be done automatically.
Manually paginating through articles and comments might be pain in the ass, so this library made it simpler for you.
You can specify a getAll
function to the second argument to make the call automatically go to the next page till it reaches the end. Use next
and stop
functions given back to you inside the getAll
function to navigate.
Do something asynchronous and call next
to get the next page or stop
to intercept the loop and finish the operation with the last callback function.
The forth object returned to you contains some useful information for pagination such as startNth
, endNth
, itemCount
, isNext
. startNth
and endNth
are not zero-based index but they count from 1 like ordinal numbers.
let page = 0
alis.articles.popular({limit: 10},{getAll: (json, next, stop, obj)=>{
console.log(`${obj.itemCount} articles fetched from ${obj.startNth}th to ${obj.endNth}th.`)
page += 1
json.Items.forEach((article, index)=>{
// (startNth + index) is the actuall Nth of the article over pages
console.log(`[${obj.startNth + index}] ${article.title}`)
})
// stop the calls when it's on the 3rd page so the maximum articles to get will be 30
if(page === 3){
stop()
}else{
next()
}
}},(err, obj)=>{
console.log(`This is the last callback function called when everything is done.`)
})
The promise based calls with async/await
functions make it even simpler to fetch through articles. When you don't need asynchronous logic in the getAll
function, use getAllSync
instead so you don't have to even call next()
to get the next page. Simply return true
from getAllSync
function if you want to intercept the calls before the end.
async function getWithPromise(){
let page = 0
await alis.p.articles.popular({limit: 10},{getAllSync: (json, obj)=>{
page += 1
console.log(`${obj.itemCount} articles fetched from ${obj.startNth}th to ${obj.endNth}th.`)
// return true to stop the calls
if(page === 3){
return true
}
}})
// No need to specify the last callback function
// things go line by line from top to bottom with async/await and promise
console.log(`This is the last line to be executed`)
}
getWithPromise()
To change your profile image.
const fs = require(`fs`)
const alis = require('alis')
const icon_path = `xxxxx.jpg`
// the image should be base64 encoded
const icon_base64 = fs.readFileSync(icon_path, 'base64')
// don't forget the content-type, it's a required parameter
alis.me.info.icon({icon: {icon_image: icon_base64}, "content-type": `image/jpeg`}, {method: `POST`, username: `your_username`, password: `your_password`}, (err, json, obj)=>{
if(err == null){
// the newly uploaded image url will be returned
console.log(json.icon_image_url)
}
})
// Of course you have the simpler promise version too
// alis.p.me.info.icon(...)
To get all the articles and likes of an arbitrary user to calculate the total number of likes.
const alis = require('alis')
async function getTotalLikes(user_id){
let articles = []
await alis.p.users.user_id.articles.public({limit:100, user_id: user_id},{getAllSync:(json)=>{
articles = articles.concat(json.Items)
}})
console.log(`${articles.length} articles found.`);
let total_likes = 0
for(let article of articles){
let likes = await alis.p.articles.article_id.likes({article_id: article.article_id})
console.log(`[${likes.count}] ${article.title}`)
total_likes += likes.count
}
console.log(`${user_id} has earned ${total_likes} likes so far.`)
}
getTotalLikes(`user_id`)
To tip someone on an article.
const alis = require('alis')
// this is for 10 ALIS, so 1 ALIS = 1000000000000000000
alis.me.wallet.tip({article_id: `2xANm0jEzLPB`, tip_value: 10000000000000000000}, {method: `POST`, username: `your_username`, password: `your_password`}, (err, obj)=>{})
To get supporters on an article.
const alis = require('alis')
alis.articles.article_id.supporters({article_id: `a1ZGnrwnvE41`}, (err, obj)=>{})
To reply to a comment.
const alis = require('alis')
alis.me.articles.article_id.comments.reply({article_id: `3NjoGVvJV0o0`, comment:{text: `comment`, parent_id: `aplpm0g8Z9bP`, replyed_user_id: `yabaiwebyasan`}}, {method: `POST`, username: `your_username`, password: `your_password`}, (err, obj)=>{})
To report a fraud.
const alis = require('alis')
// possible reasons: anything_contrary_to_public_order|nuisance|copyright_violation|slander|illegal_token_usage|illegal_act|other
// origin_url is required only with copyright_violation
alis.me.articles.article_id.fraud({article_id: `2MqoAgmQnxEP`, reason:{free_text: `自作自演とディズニー素材の無断使用です。`, reason: `copyright_violation`, origin_url: `https://toystory.disney.com/`}}, {method: `POST`, username: `your_username`, password: `your_password`}, (err, obj)=>{})
To get recommended articles.
const alis = require('alis')
alis.articles.recommended({page: 3, limit: 10}, (err, obj)=>{})
You can make a API call with OAuth 2.0 by simply adding oauth
after alis
. To authorize users, access_token
is required in the second argument. When refreshing the expired access_token
, it uses refresh_token
with client_id
and client_secret
; hence these parameters are required in the second argument as well. Unlike the Cognito authorization access_token
is not cached. You can update access_token
by using updated_access_token
in the returned object.
Call with a callback function may look like:
const alis = require('alis')
options = {
access_token: "<ACCESS_TOKEN>",
refresh_token: "<REFRESH_TOKEN>",
client_id: "<CLIENT_ID_OF_YOUR_APP",
client_secret: "<CLIENT_SECRET_OF_YOUR_APP>",
scope: "read" // optional (read/write)
}
let page = 0
alis.oauth.articles.popular({}, { ...options, getAll: (json, next, stop, obj) => {
page += 1
json.Items.forEach((article, index) => {
console.log(`${article.title}`)
})
// Update `access_token` in case it is refreshed
options.access_token = json.updated_access_token || options.access_token
if (page === 3) {
stop()
} else {
next()
}
}}, (err, obj) => {
console.log(`last callback`)
})
Async/await call may look like:
const alis = require('alis')
options = {
access_token: "<ACCESS_TOKEN>",
refresh_token: "<REFRESH_TOKEN>",
client_id: "<CLIENT_ID_OF_YOUR_APP",
client_secret: "<CLIENT_SECRET_OF_YOUR_APP>",
scope: "read" // optional (read/write)
}
async function getTotalLikes(user_id){
let articles = []
await alis.oauth.p.users.user_id.articles.public({limit: 100, user_id: user_id}, {...options, getAllSync: (json) => {
articles = articles.concat(json.Items)
options.access_token = json.updated_access_token || options.access_token;
}})
console.log(`${articles.length} articles found.`);
let total_likes = 0
for(let article of articles) {
let likes = await alis.oauth.p.articles.article_id.likes({article_id: article.article_id}, {...options})
console.log(`[${likes.count}] ${article.title}`)
total_likes += likes.count
}
console.log(`${user_id} has earned ${total_likes} likes so far.`)
}
getTotalLikes(`user_id`)
Tests are to be written soon.