Flutter
rafiq_chat is a chat screen that runs your organisation’s flows. It is built from native Flutter
widgets, never a WebView, and it renders everything a flow sends: text, options (as cards when they
have an image or a price), yes-or-no confirmation, and forms. It streams new turns, resumes the
user’s session after a restart, and shows a handoff when a person on your team takes over.
Install
Not published yet
The package isn’t on pub.dev yet: it comes with your account, under the name below.
dependencies:
rafiq_chat: ^0.1.0
Use it
AppChat.configure(AppChatOptions(
chatKey: 'ck_…', // the app → Chat keys (publishable)
apiUrl: 'https://<your chat host>',
userToken: await myServer.chatToken(), // optional: the signed-in user, below
refreshUserToken: myServer.chatToken, // called when that token expires
));
// your own button:
FilledButton(
onPressed: () => AppChat.open(context, flowKey: 'pizza', title: 'Order'),
child: const Text('Order'),
);
// or inside your own screen:
const AppChatView(flowKey: 'pizza');
What it does
- Every step in native widgets. Tapping an option sends its number, which the flow reads
without the model. Yes and No send a word the flow reads in both languages. A form checks each
value the way the flow does before sending it. A number can be typed in Arabic-Indic (
٢) or Persian digits, and goes to the server as a number. Typing free text always works: the flow maps words to options, to yes or no, and to slots. - Each control disables when tapped. Until the reply comes, a second tap sends nothing.
- Streaming. The chat listens for new turns with Server-Sent Events.
- The session token goes only in a header, never in the URL.
- It resumes from the last turn it has, honours the server’s
retry:, and reconnects when the stream’s time is up. - If the stream is refused or keeps dropping, it falls back to polling.
- A turn that arrives both in a reply and in the stream shows once.
- Resume. The session is kept in
SharedPreferences, one per flow. Reopening the chat shows the whole session and what it awaits. An ended session is forgotten, and the next open starts a new one. - Handoff. When the flow hands the user to your team, the chat says “A person on the team will reply here”. The user can keep writing, and the team’s replies arrive in the same thread, labelled as the team’s.
- Arabic. In Arabic the chat runs right to left and shows its digits as Arabic-Indic, including prices, ranges, and what the flow says.
The signed-in user
Your servers sign an HS256 JWT with your organisation’s chatbot user-token signing secret
(flows_user_token_secret, set in Settings → Keys):
audis your organisation’s id;subis your own id for the user;- it lives at most an hour.
Without a token the flow can talk and let the user choose, but it runs no step that changes anything for the user.
- When the service answers that the token expired, the chat calls
refreshUserTokenonce and sends the same message again with the fresh token. - A token refused outright is never retried. The chat asks the user to sign in again.