Neolithic Psychedelic Mushrooms

    alis

    0.6.3 • Public • Published

    ALIS API Node.js Client

    npm package

    ALIS API made simple with syntax sugar

    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()

    Table of contents


    Installation

    Use NPM.

    npm i -s alis

    Available Calls

    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.


    Authentication

    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.

    1. pass username and password
    alis.me.info({/*cannot be omitted when the 2nd argument exists*/}, {username: `your_username`, password: `your_password`},(err, obj)=>{})
    1. directly pass id_token obtained by authentication (optionally with username)
    alis.me.info({},{id_token: `your_id_token`},(err, obj)=>{})
    1. pass refresh_token and username (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.


    Syntax Sugar

    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()
     

    More Examples

    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.suppoerters({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)=>{})

    Oauth 2.0

    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

    Tests are to be written soon.


    Links


    Contributors

    Keywords

    Install

    npm i alis

    DownloadsWeekly Downloads

    61

    Version

    0.6.3

    License

    MIT

    Unpacked Size

    121 kB

    Total Files

    15

    Last publish

    Collaborators

    • ocrybit