Skip to content

Instantly share code, notes, and snippets.

@nk-gears
Created July 25, 2022 03:27
Show Gist options
  • Save nk-gears/a185c83d3e521c47d64d252197e87c88 to your computer and use it in GitHub Desktop.
Save nk-gears/a185c83d3e521c47d64d252197e87c88 to your computer and use it in GitHub Desktop.

Revisions

  1. nk-gears created this gist Jul 25, 2022.
    114 changes: 114 additions & 0 deletions tuya-nodejs-lib.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,114 @@
    const CryptoJS = require('crypto-js');
    const axios = require('axios');

    class TuyaAPIClient {
    constructor(options) {
    this.options = options;
    this.options.baseURL = 'https://openapi.tuyaus.com/v1.0';
    this.options.access_token="";

    }

    async initClient(){
    await this.getAccessToken(this.options.client_id,this.options.secret);

    }
    getDefaultHeaders() {
    const timestamp = this.getTime();
    const signature = this.computeSignature(
    this.options.client_id,
    this.options.access_token,
    this.options.secret,
    timestamp
    );
    const headerParams = {
    client_id: this.options.client_id,
    access_token: this.options.access_token,
    sign: signature,
    t: timestamp,
    sign_method: 'HMAC-SHA256',
    };

    return headerParams;
    }

    async makePostRequest(resource,body) {
    //curlirize(axios);
    const headers = this.getDefaultHeaders();
    const baseURL = this.options.baseURL;
    try {
    return axios({
    baseURL: baseURL,
    url: resource,
    method: "POST",
    data: JSON.stringify(body),
    headers: {...headers,"Content-Type":"application/json"},
    maxRedirects: 5
    })
    } catch (error) {
    console.error(error)
    }

    }

    async makeRequest(resource, urlParams,method) {
    const headers = this.getDefaultHeaders();
    const baseURL = this.options.baseURL;
    try {
    return axios({
    baseURL: baseURL,
    url: resource,
    method: method || 'GET',
    // data: body ? body : null,
    headers: headers,
    maxRedirects: 5,
    params: urlParams ? urlParams : null,
    })
    } catch (error) {
    console.error(error)
    }

    }

    getTime() {
    const timestamp = new Date().getTime();
    return timestamp;
    }


    async getAccessToken(clientId, secret) {
    this.options.access_token="";
    const resp=await this.makeRequest("/token?grant_type=1");
    this.options.access_token=resp.data.result.access_token;

    }

    computeSignature(clientId, accessToken,secret, timestamp) {
    var str = clientId + accessToken + timestamp;
    const hash = CryptoJS.HmacSHA256(str, secret);
    const hashInBase64 = hash.toString();
    const signature = hashInBase64.toUpperCase();
    return signature;
    }

    async changeDeviceState(deviceId,switchType, changeToState) {
    const deviceParams= {
    "commands":[
    {
    "code": switchType,
    "value":changeToState
    }
    ]
    }
    return await this.makePostRequest(`/devices/${deviceId}/commands`,deviceParams);
    }


    async getDeviceInfo(deviceId) {

    return await this.makeRequest(`/devices/${deviceId}`);
    }

    }

    module.exports = TuyaAPIClient;