Untitled

mail@pastecode.io avatar
unknown
typescript
a year ago
5.9 kB
2
Indexable
Never
import { MetabaseSessionToken } from "../model/Metabase";
import { BaseResource } from "../resources/BaseResource"
import { HttpResponseBuilder } from "../response/HttpResponseBuilder";
import axios from 'axios';
import { RedisServiceClient } from "./RedisServiceClient";
import { CSVService } from "./CSVService";

export class MetabaseServiceClient extends BaseResource {

  httpResponseBuilder: HttpResponseBuilder
  private csvService: CSVService
  private redisServiceClient: RedisServiceClient
  private readonly METABASE_HOST = process.env.METABASE_HOST
  private readonly METABASE_USERNAME = process.env.METABASE_USERNAME
  private readonly METABASE_PASSWORD = process.env.METABASE_PASSWORD
  private readonly METABASE_SESSION_REDIS_SET = process.env.METABASE_SESSION_REDIS_SET

  constructor() {
    super()
    this.csvService         = new CSVService()
    this.redisServiceClient = new RedisServiceClient()
  }

  public async getDailyReport() {
    let sessionToken = await this.getSessionToken()
    console.log("SESSION TOKEN: ", sessionToken)

    try {
      const response = await axios.post(`${this.METABASE_HOST}/api/card/1798/query/csv`, {}, {
        headers: {
          "X-Metabase-Session": sessionToken
        }
      })
      console.log("RESPONSE: ", response.data)

      return await this.csvService.csvToArrayOfObejct(response.data)
    } catch (error) {
      if (error.response) {
        console.log("ERROR STATUS: ", error.response.status);
        if(error.response.status == 401){
          await this.refreshToken(sessionToken)
          return await this.getDailyReport()
        }else{
          console.log(error)
          throw new Error("get daily report failed");
        }
      }
    }
  }

  public async getWeeklyReport() {
    let sessionToken = await this.getSessionToken()
    console.log("SESSION TOKEN: ", sessionToken)

    try {
      const response = await axios.post(`${this.METABASE_HOST}/api/card/1853/query/csv`, {}, {
        headers: {
          "X-Metabase-Session": sessionToken
        }
      })
      console.log("RESPONSE: ", response.data)

      return await this.csvService.csvToArrayOfObejct(response.data)
    } catch (error) {
      if (error.response) {
        console.log("ERROR STATUS: ", error.response.status);
        if(error.response.status == 401){
          await this.refreshToken(sessionToken)
          return await this.getWeeklyReport()
        }else{
          console.log(error)
          throw new Error("get daily report failed");
        }
      }
    }
  }

  public async getMonthlyReport() {
    let sessionToken = await this.getSessionToken()
    console.log("SESSION TOKEN: ", sessionToken)

    try {
      const response = await axios.post(`${this.METABASE_HOST}/api/card/1799/query/csv`, {}, {
        headers: {
          "X-Metabase-Session": sessionToken
        }
      })
      console.log("RESPONSE: ", response.data)

      return await this.csvService.csvToArrayOfObejct(response.data)
    } catch (error) {
      if (error.response) {
        console.log("ERROR STATUS: ", error.response.status);
        if(error.response.status == 401){
          await this.refreshToken(sessionToken)
          return await this.getMonthlyReport()
        }else{
          console.log(error)
          throw new Error("get daily report failed");
        }
      }
    }
  }

  public async getDailyReportByInputDate(inputDate: string) {
    let sessionToken = await this.getSessionToken()
    console.log("SESSION TOKEN: ", sessionToken)
    console.log("INPUT DATE: ", inputDate)

    let params = [
      {
        type: "text", 
        target: ["variable", ["template-tag", "inputDate"]],
        value: inputDate
      }
    ]

    try {
      const response = await axios.post(`${this.METABASE_HOST}/api/card/1891/query/csv?parameters=${encodeURIComponent(JSON.stringify(params))}`, {}, {
        headers: {
          "X-Metabase-Session": sessionToken
        }
      })
      console.log("RESPONSE: ", response.data)

      return await this.csvService.csvToArrayOfObejct(response.data)
    } catch (error) {
      if (error.response) {
        console.log("ERROR STATUS: ", error.response.status);
        if(error.response.status == 401){
          await this.refreshToken(sessionToken)
          return await this.getDailyReportByInputDate(inputDate)
        }else{
          console.log(error)
          throw new Error("get daily report failed");
        }
      }
    }
  }

  async getSessionToken(): Promise<string>{
    let sessions = await this.redisServiceClient.getAllMembersOfSet(this.METABASE_SESSION_REDIS_SET)
    console.log("SESSIONS EXIST: ", sessions.length)
    
    if(sessions.length > 0){
      return sessions[sessions.length - 1];
    }
    
    try {
      return await this.createSessionToken()
    } catch (error) {
      console.log(error)
      throw new Error("get metabase session token failed");
    }
  }

  async createSessionToken(): Promise<string>{
    try {
      const response = await axios.post(`${this.METABASE_HOST}/api/session`, {
        username: this.METABASE_USERNAME,
        password: this.METABASE_PASSWORD
      })

      const metabaseSession: MetabaseSessionToken = response.data
      console.log("NEW SESSION: ", metabaseSession)
      await this.redisServiceClient.addToSet(this.METABASE_SESSION_REDIS_SET, metabaseSession.id)

      return metabaseSession.id
    } catch (error) {
      console.log(error)
      throw new Error("get metabase session token failed");
    }
  }

  async refreshToken(sessionToken){
    await this.redisServiceClient.removeFromSet(this.METABASE_SESSION_REDIS_SET, sessionToken)
    await this.createSessionToken()
  }
}