Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throwing exception #4

Open
itsalfredakku opened this issue Dec 14, 2022 · 5 comments
Open

Throwing exception #4

itsalfredakku opened this issue Dec 14, 2022 · 5 comments

Comments

@itsalfredakku
Copy link

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)]
Unhandled Exception: Exception: ChatGPT failed to refresh auth token: Exception: Failed to refresh access token

#0 ChatGPTApi._refreshAccessToken (package:flutter_chatgpt_api/flutter_chatgpt_api.dart:152:7)

#1 ChatGPTApi.sendMessage (package:flutter_chatgpt_api/flutter_chatgpt_api.dart:50:25)

#2 _ChatScreenState._buildSubmit. (package:neural_ai/screens/chat.screen.dart:110:30)

@ghost
Copy link

ghost commented Dec 14, 2022

I just found this package and now I came across this same issue, it happens because there is a little mistake in the flutter_chatgpt_api.dart file (the defaultUserAgent variable is used instead of the user agent the user specified).

To fix it replace the contents of that file with the following code:

library flutter_chatgpt_api;

import 'dart:convert';
import 'dart:io';

import 'package:flutter_chatgpt_api/src/models/models.dart';
import 'package:flutter_chatgpt_api/src/utils/utils.dart';
import 'package:http/http.dart' as http;
import 'package:uuid/uuid.dart';

part 'src/models/chat_message.model.dart';

class ChatGPTApi {
  String sessionToken;
  String clearanceToken;
  String? apiBaseUrl;
  String backendApiBaseUrl;
  String userAgent;

  final ExpiryMap<String, String> _accessTokenCache =
      ExpiryMap<String, String>();

  ChatGPTApi({
    required this.sessionToken,
    required this.clearanceToken,
    this.apiBaseUrl = 'https://chat.openai.com/api',
    this.backendApiBaseUrl = 'https://chat.openai.com/backend-api',
    required this.userAgent,
  });

  Future<ChatResponse> sendMessage(
    String message, {
    String? conversationId,
    String? parentMessageId,
  }) async {
    final accessToken = await _refreshAccessToken();
    parentMessageId ??= const Uuid().v4();

    final body = ConversationBody(
      action: 'next',
      conversationId: conversationId,
      messages: [
        Prompt(
          content: PromptContent(contentType: 'text', parts: [message]),
          id: const Uuid().v4(),
          role: 'user',
        )
      ],
      model: 'text-davinci-002-render',
      parentMessageId: parentMessageId,
    );

    final url = '$backendApiBaseUrl/conversation';

    final response = await http.post(
      Uri.parse(url),
      headers: {
        'user-agent': this.userAgent,
        'x-openai-assistant-app-id': '',
        'accept-language': 'en-US,en;q=0.9',
        HttpHeaders.accessControlAllowOriginHeader: 'https://chat.openai.com',
        HttpHeaders.refererHeader: 'https://chat.openai.com/chat',
        'sec-ch-ua':
            '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'Authorization': 'Bearer $accessToken',
        'Content-Type': 'application/json',
        'Accept': 'text/event-stream',
        'Cookie': 'cf_clearance=$clearanceToken'
      },
      body: body.toJson(),
    );

    if (response.statusCode != 200) {
      if (response.statusCode == 429) {
        throw Exception('Rate limited');
      } else {
        throw Exception('Failed to send message');
      }
    } else if (_errorMessages.contains(response.body)) {
      throw Exception('OpenAI returned an error');
    }

    String longestLine =
        response.body.split('\n').reduce((a, b) => a.length > b.length ? a : b);

    var result = longestLine.replaceFirst('data: ', '');

    var messageResult = ConversationResponseEvent.fromJson(result);

    var lastResult = messageResult.message?.content.parts.first;

    if (lastResult == null) {
      throw Exception('No response from OpenAI');
    } else {
      return ChatResponse(
        message: lastResult,
        messageId: messageResult.message!.id,
        conversationId: messageResult.conversationId,
      );
    }
  }

  Future<String> _refreshAccessToken() async {
    Map<String, String> defaultHeaders = {
      'user-agent': this.userAgent,
      'x-openai-assistant-app-id': '',
      'accept-language': 'en-US,en;q=0.9',
      HttpHeaders.accessControlAllowOriginHeader: 'https://chat.openai.com',
      HttpHeaders.refererHeader: 'https://chat.openai.com/chat',
      'sec-ch-ua':
          '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"',
      'sec-ch-ua-platform': '"Windows"',
      'sec-fetch-dest': 'empty',
      'sec-fetch-mode': 'cors',
      'sec-fetch-site': 'same-origin',
    };

    final cachedAccessToken = _accessTokenCache['KEY_ACCESS_TOKEN'];
    if (cachedAccessToken != null) {
      return cachedAccessToken;
    }

    try {
      final res = await http.get(
        Uri.parse('$apiBaseUrl/auth/session'),
        headers: {
          'cookie':
              'cf_clearance=$clearanceToken;__Secure-next-auth.session-token=$sessionToken',
          'accept': '*/*',
          ...defaultHeaders,
        },
      );

      if (res.statusCode != 200) {
        throw Exception('Failed to refresh access token, ${res.statusCode}');
      }

      final accessToken = jsonDecode(res.body)['accessToken'];

      if (accessToken == null) {
        throw Exception(
            'Failed to refresh access token, token in response is null');
      }

      _accessTokenCache['KEY_ACCESS_TOKEN'] = accessToken;
      return accessToken;
    } catch (err) {
      throw Exception('ChatGPT failed to refresh auth token: $err');
    }
  }
}

const _errorMessages = [
  "{\"detail\":\"Hmm...something seems to have gone wrong. Maybe try me again in a little bit.\"}",
];

@ghost
Copy link

ghost commented Dec 14, 2022

Don't forget that instead of using the package from pub.dev you should download the code and place it in the packages folder (in Linux is /home/youruser/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/ if you installed flutter with snap, if not don't worry the route is very similar, look it up online), edit the file I told you, add the dependency to your pubspec.yaml file and run flutter pub get. If you use the version from pub.dev and then edit the file, I think when you run flutter pub get the content of the files get replaced to the original. This shouldn't be necessary once @coskuncay fixes it in the master branch.

@ghost
Copy link

ghost commented Dec 14, 2022

Then in your code initialize the api like this:

_api = ChatGPTApi(
    sessionToken: SESSION_TOKEN,
    clearanceToken: CLEARANCE_TOKEN,
    userAgent:
        'YOUR USER AGENT',
);

The user agent must match with the one used in the session from where the sessionToken and clearanceToken where extracted.
You can find your user agent with Dev Tools in the request headers.

@csc7545
Copy link

csc7545 commented Dec 18, 2022

same issue

@coskuncay
Copy link
Owner

Hi @itsalfredakku @csc7545 @Gabriel11101 , first of all, thank you for using the package, I haven't had time to solve the problem due to my busy schedule. I will fix it asap. pull requests are welcome :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants