Flutter GetX implements ChatGPT simple chat interface

Flutter is a cross-platform mobile application development framework, and GetX is an easy-to-use state management and routing management tool in Flutter. In this article, we will use Flutter and GetX to implement a simple chat interface to interact with ChatGPT.

We need to import the GetX library in the Flutter project. pubspec.yamlAdd the following dependencies to the file :

dependencies:
  flutter:
    sdk: flutter
  get: 

mainAdd the following code inside the function :

void main() {
  //在main函数第一行添加这句话
  WidgetsFlutterBinding.ensureInitialized();
  runApp(GetMaterialApp(
    home: ChatPage(),
  ));
}

Make sure Flutter Widgetsit's initialized and start the application's ChatPagepage.

Next, we need to create a ApiProviderclass for interacting with the OpenAI API. This class inherits from GetConnect, GetConnectand is a lightweight HTTP client that simplifies the communication process with the API. Here is ApiProviderthe code for the class:

class ApiProvider extends GetConnect {

  /// 这里填写自己OpenAI API Key
  final String apiKey = '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';
  final String baseUrl = 'https://api.openai.com';
  final Duration timeout = Duration(seconds: 30);

  Map<String, String> _headers() {
    return {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $apiKey',
    };
  }

  ApiProvider() {
    httpClient.baseUrl = baseUrl;
    httpClient.timeout = timeout;
    httpClient.addAuthenticator((request)  {
      request.headers.addAll(_headers());
      return request;
    });
  }

  Future<Response> completions(String body) {
    return post('/v1/chat/completions', body);
  }
}

In this class, we set the base URL and timeout of the API, and implement the authorization and authentication of HTTP requests. We also implemented completionsmethods for sending requests to the OpenAI API and getting responses from the chatbot. Note that you need to set the API KEY of your own account here, address: https://platform.openai.com/account/api-keys

Next, we need to create a ChatLogicclass that will handle the chatbot logic. Here is ChatLogic类the code for:

class ChatLogic extends GetxController {
  final ChatState state = ChatState();
  final ApiProvider provider = ApiProvider();

  Future<void> sendMessage(String content) async {
    state.requestStatus(content);
    update();
    final response = await provider.completions(json.encode({
      "model": "gpt-3.5-turbo",
      "messages": [{"role": "user", "content": "$content"}]
    }));
    try {
      if(response.statusCode == 200) {
        final data = response.body;
        final text = data['choices'][0]['message']['content'];
        state.responseStatus(text);
      } else {
        state.responseStatus(response.statusText ?? '请求错误,请稍后重试');
      }
    } catch(error) {
      state.responseStatus(error.toString());
    }
    update();
  }
}

In this class, we create a sendMessagemethod that receives the user's message and sends it to the OpenAI API, and then waits for the API to return a response. After receiving the response, we will extract the content of the reply message from the JSON data returned by the API, update it to the list ChatStateof the status class messages, and then display it in the UI.

Next, we need to create a ChatStateclass to manage our application state. Here is ChatStatethe code for the class:

class ChatState {

  String message = '';
  String sender = 'user';
  bool isRequesting = false;
  List<Map<String, dynamic>> messages = [];

  void requestStatus(String content) {
    messages.add({'text': content, 'sender': 'user'});
    sender = 'bot';
    messages.add({'text': '正在回复中...', 'sender': sender});
    isRequesting = true;
    message = '';
  }

  void responseStatus(String content) {
    messages.removeLast(); // Remove "正在回复中..." 状态
    messages.add({'text': content, 'sender': sender});
    sender = 'user';
    isRequesting = false;
  }
}

In this class, the status information of the chat application is stored, including messages, senders, request status and history message list. requestStatus()The method is used to update the state to reflect the state of the message being sent, and responseStatus()the method is used to update the state to reflect the received message.

Finally, we define ChatPagethe class, which it inherits from StatelessWidget, which will be used to display the chat dialog. Here is ChatPagethe code for the class:

class ChatPage extends StatelessWidget {
  ChatPage({Key? key}) : super(key: key);

  final logic = Get.put(ChatLogic());
  final state = Get.find<ChatLogic>().state;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('你问我答'),
      ),
      body: GetBuilder<ChatLogic>(
        builder: (context) => Column(
          children: [
            Expanded(
              child: ListView.builder(
                itemCount: state.messages.length,
                itemBuilder: (BuildContext context, int index) {
                  Map m = state.messages[index];
                  return Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Row(
                      mainAxisAlignment: m['sender'] == 'user'
                          ? MainAxisAlignment.end
                          : MainAxisAlignment.start,
                      children: [
                        Flexible(
                          child: Container(
                            padding: const EdgeInsets.all(8.0),
                            decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(8.0),
                              color: m['sender'] == 'user'
                                  ? Colors.green[100]
                                  : Colors.white,
                            ),
                            child: Text(m['text']),
                          ),
                        )
                      ],
                    ),
                  );
                },
              ),
            ),
            Container(
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(12.0),
                  topRight: Radius.circular(12.0),
                ),
              ),
              child: Row(
                children: [
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: TextField(
                          decoration: InputDecoration(
                            hintText: '请输入消息',
                            border: InputBorder.none,
                          ),
                          controller:
                              TextEditingController(text: state.message),
                          onChanged: (value) {
                            state.message = value;
                          }),
                    ),
                  ),
                  IconButton(
                    icon: Icon(Icons.send),
                    onPressed: state.isRequesting
                        ? null
                        : () {
                            logic.sendMessage(state.message);
                          },
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

The class contains an ChatLogicinstance and an ChatStateinstance. In build()the method, we wrap GetBuilderthe whole chat interface with . This interface consists of a message list and an input box where the user can enter a message and send it to the chatbot. ListView.builderUsed to display historical messages, TextFieldand IconButtonto receive user input and send messages. Before sending a message, it is checked whether the current state is the request state to avoid sending the request repeatedly.

At this point, a simple chat function is completed, run it to see the effect:

insert image description here

To sum up, this article introduces a GPT-3 based chatbot implemented using Flutter and OpenAI API. With the implementation ApiProvider、ChatLogicand ChatStateclass, we were able to integrate the functionality of the OpenAI API into a Flutter application and implement a basic chat interface. Interested guys can try it out by themselves, Demo address: https://github.com/smallmarker/OpenAIChat

Guess you like

Origin blog.csdn.net/zl_china/article/details/129756110