perplexity.mjs

javascriptCreated 24 Mar 2026, 12:5074 views
AI Chat Wrapper from Perplexity apk.
#ai#realtime#chatbot
javascript
/***
  @ Base: https://play.google.com/store/apps/details?id=ai.perplexity.app.android
  @ Author: Shannz
  @ Note: AI Chat Wrapper from Perplexity apk.
***/

import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';

const ANDROID_ID = '0a0000000002f59a';

export const perplexity = {
  handleSSE: function(response) {
    return new Promise((resolve, reject) => {
      let finalData = null;
      let buffer = '';

      response.data.on('data', (chunk) => {
        buffer += chunk.toString();
        const lines = buffer.split('\n');

        buffer = lines.pop() || '';

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            try {
              const jsonData = line.substring(6).trim();

              if (jsonData === '{}') {
                continue;
              }

              const data = JSON.parse(jsonData);

              if (data.final === true || data.status === 'COMPLETED') {
                finalData = data;
              }

            } catch (parseError) {
              continue;
            }
          }
        }
      });

      response.data.on('end', () => {
          let fullAnswer = '';
          let chunks = [];
          let parsedSteps = [];
          let webResults = [];

          if (finalData && finalData.blocks) {
              const markdownBlock = finalData.blocks.find(block =>
              block.intended_usage === 'ask_text' && block.markdown_block
              );

              if (markdownBlock && markdownBlock.markdown_block) {
                  if (markdownBlock.markdown_block.answer) {
                      fullAnswer = markdownBlock.markdown_block.answer;
                  } else if (markdownBlock.markdown_block.chunks) {
                      chunks = markdownBlock.markdown_block.chunks;
                      fullAnswer = chunks.join('');
                  }
              }
          }

          try {
              parsedSteps = JSON.parse(finalData.text);
              const searchResultStep = parsedSteps.find(step => step.step_type === 'SEARCH_RESULTS');
              if (searchResultStep && searchResultStep.content && searchResultStep.content.web_results) {
                  webResults = searchResultStep.content.web_results;
              }
          } catch (e) { }

          resolve({
              answer: fullAnswer,
              chunks,
              relatedQueries: finalData?.related_queries || [],
              source: webResults
          });
      });

      response.data.on('error', (error) => {
        reject(error);
      });
    });
  },

  chat: async function(query) {
    const data = JSON.stringify({
      "query_str": query,
      "params": {
        "source": "android",
        "version": "2.17",
        "frontend_uuid": uuidv4(),
        "android_device_id": ANDROID_ID,
        "mode": "concise",
        "is_related_query": false,
        "is_voice_to_voice": false,
        "timezone": "Asia/Shanghai",
        "language": "in",
        "query_source": "home",
        "is_incognito": false,
        "use_schematized_api": true,
        "send_back_text_in_streaming_api": false,
        "supported_block_use_cases": [
          "answer_modes",
          "finance_widgets",
          "knowledge_cards",
          "media_items",
          "place_widgets",
          "shopping_widgets",
          "sports_widgets",
          "inline_entity_cards",
          "inline_images",
          "inline_assets",
          "search_result_widgets"
        ],
        "sources": [
          "web"
        ],
        "model_preference": "turbo"
      }
    });

    const config = {
      method: 'POST',
      url: 'https://www.perplexity.ai/rest/sse/perplexity_ask',
      headers: {
        'User-Agent': 'Ask/2.51.0/260466 (Android; Version 12; SAMSUNG N900A/SD1A.210817.037.A1 release-keys) SDK 31',
        'Accept': 'text/event-stream',
        'Accept-Encoding': 'gzip',
        'Content-Type': 'application/json',
        'x-app-version': '2.51.0',
        'x-client-version': '2.51.0',
        'x-client-name': 'Perplexity-Android',
        'x-client-env': 'prod',
        'x-app-apiclient': 'android',
        'x-app-apiversion': '2.17',
        'accept-language': 'id',
        'x-device-id': `android:${ANDROID_ID}`,
        'content-type': 'application/json; charset=utf-8'
      },
      data: data,
      responseType: 'stream'
    };

    try {
      const response = await axios.request(config);
      const result = await this.handleSSE(response);
      return result;
    } catch (error) {
      throw error;
    }
  }
};

//perplexity.chat('berita terbaru hari ini').then(a => console.log(a));