Code Monkey home page Code Monkey logo

chatwoot-flutter-sdk's Introduction

Pub Version

Integrate Chatwoot with Flutter app

Integrate Chatwoot flutter client into your flutter app and talk to your visitors in real time. Chatwoot helps you to chat with your visitors and provide exceptional support in real time. To use Chatwoot in your flutter app, follow the steps described below.

chatwoot screenshot

1. Add the package to your project

Run the command below in your terminal

flutter pub add chatwoot_sdk

or

Add chatwoot_sdk:<<version>> to your project's pubspec.yml file. You can check here for the latest version.

2. How to use

a. Using ChatwootWidget

import 'dart:io';

import 'package:chatwoot_sdk/chatwoot_sdk.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image/image.dart' as image;
import 'package:image_picker/image_picker.dart' as image_picker;
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Chatwoot Example"),
      ),
      body: ChatwootWidget(
        websiteToken: "websiteToken",
        baseUrl: "https://app.chatwoot.com",
        user: ChatwootUser(
          identifier: "[email protected]",
          name: "Tester test",
          email: "[email protected]",
        ),
        locale: "fr",
        closeWidget: () {
          if (Platform.isAndroid) {
            SystemNavigator.pop();
          } else if (Platform.isIOS) {
            exit(0);
          }
        },
        //attachment only works on android for now
        onAttachFile: _androidFilePicker,
        onLoadStarted: () {
          print("loading widget");
        },
        onLoadProgress: (int progress) {
          print("loading... ${progress}");
        },
        onLoadCompleted: () {
          print("widget loaded");
        },
      ),
    );
  }

  Future<List<String>> _androidFilePicker() async {
    final picker = image_picker.ImagePicker();
    final photo =
        await picker.pickImage(source: image_picker.ImageSource.gallery);

    if (photo == null) {
      return [];
    }

    final imageData = await photo.readAsBytes();
    final decodedImage = image.decodeImage(imageData);
    final scaledImage = image.copyResize(decodedImage, width: 500);
    final jpg = image.encodeJpg(scaledImage, quality: 90);

    final filePath = (await getTemporaryDirectory()).uri.resolve(
          './image_${DateTime.now().microsecondsSinceEpoch}.jpg',
        );
    final file = await File.fromUri(filePath).create(recursive: true);
    await file.writeAsBytes(jpg, flush: true);

    return [file.uri.toString()];
  }
}

Horray! You're done.

Available Parameters

Name Default Type Description
websiteToken - String Website inbox channel token
baseUrl - String Installation url for chatwoot
user - ChatwootUser User information about the user like email, username and avatar_url
locale en String User locale
closeWidget - void Function() widget close event
customAttributes - dynamic Additional information about the customer
onAttachFile - Future<List> Function() Widget Attachment event. Should return a list of File Uris Currently supported only on Android devices
onLoadStarted - void Function() Widget load start event
onLoadProgress - void Function(int) Widget Load progress event
onLoadCompleted - void Function() Widget Load completed event

b. Using Chatwoot Client

  • Create an Api inbox in Chatwoot. Refer to Create API Channel document.
  • Create your own customized chat ui and use ChatwootClient to load and sendMessages. Messaging events like onMessageSent and onMessageReceived will be triggered on ChatwootCallback argument passed when creating the client instance.

NB: This chatwoot client uses Hive for local storage.

final chatwootCallbacks = ChatwootCallbacks(
      onWelcome: (){
        print("on welcome");
      },
      onPing: (){
        print("on ping");
      },
      onConfirmedSubscription: (){
        print("on confirmed subscription");
      },
      onConversationStartedTyping: (){
        print("on conversation started typing");
      },
      onConversationStoppedTyping: (){
        print("on conversation stopped typing");
      },
      onPersistedMessagesRetrieved: (persistedMessages){
        print("persisted messages retrieved");
      },
      onMessagesRetrieved: (messages){
        print("messages retrieved");
      },
      onMessageReceived: (chatwootMessage){
        print("message received");
      },
      onMessageDelivered: (chatwootMessage, echoId){
        print("message delivered");
      },
      onMessageSent: (chatwootMessage, echoId){
        print("message sent");
      },
      onError: (error){
        print("Ooops! Something went wrong. Error Cause: ${error.cause}");
      },
    );

    ChatwootClient.create(
        baseUrl: widget.baseUrl,
        inboxIdentifier: widget.inboxIdentifier,
        user: widget.user,
        enablePersistence: widget.enablePersistence,
        callbacks: chatwootCallbacks
    ).then((client) {
        client.loadMessages();
    }).onError((error, stackTrace) {
      print("chatwoot client creation failed with error $error: $stackTrace");
    });

Available Parameters

Name Default Type Description
baseUrl - String Installation url for chatwoot
inboxIdentifier - String Identifier for target chatwoot inbox
enablePersistance true bool Enables persistence of chatwoot client instance's contact, conversation and messages to disk
for convenience.
true - persists chatwoot client instance's data(contact, conversation and messages) to disk. To clear persisted
data call ChatwootClient.clearData or ChatwootClient.clearAllData
false - holds chatwoot client instance's data in memory and is cleared as
soon as chatwoot client instance is disposed
Setting
user null ChatwootUser Custom user details to be attached to chatwoot contact
callbacks null ChatwootCallbacks Callbacks for handling chatwoot events

chatwoot-flutter-sdk's People

Contributors

ephraimnetworks avatar iamsivin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

chatwoot-flutter-sdk's Issues

pubsub_token is null

on calling ChatwootChatDialog.show it creates a new contact it returns the contact with pubsub_token as null and throughs exception

Unhandled Exception: type 'Null' is not a subtype of type 'String' in type cast

Screenshot 2021-12-31 at 10 36 22 PM

Chatwoot isn't sending any messages.

Hey! I have been using Chatwoot with no issue in my web page. Recently, I have developed a mobile app using flutter. It seems like there is an issue with Chatwoot on it. When testing it out, I am unable to send any messages.
It just loads on forever.
Schreenshot:

Screen Shot 2022-03-22 at 09 06 14

This is how I Implemented in on the mobile app

Chatwoot Button (clicking this will open the chatwoot box):

  Widget build(BuildContext context) {
    return Container(
      height: 55,
      width: 55,
      margin: EdgeInsets.only(bottom: isNavAvailable ? 50 : 0),
      decoration: const BoxDecoration(
        color: colorChatwoot,
        shape: BoxShape.circle,
      ),
      child: InkWell(
        customBorder: const CircleBorder(),
        onTap: onTap,
        child: Icon(
          show ? Icons.close : Icons.chat_bubble_rounded,
          color: colorChatwoot.computeLuminance() < 0.5
              ? Colors.white
              : Colors.black,
          size: 25,
        ),
      ),
    );
  }

Chatwoot box:

    final AppLocalizations _local = AppLocalizations.of(context)!;
    MediaQueryData queryData = MediaQuery.of(context);

    double _marginBottom = isNavAvailable
        ? queryData.size.width * 0.30
        : queryData.size.width * 0.18;

    if (queryData.size.width > 400) {
      _marginBottom = isNavAvailable
          ? queryData.size.width * 0.34
          : queryData.size.width * 0.24;
    }
    return Container(
      width: double.infinity,
      alignment: Alignment.bottomRight,
      margin: EdgeInsets.only(bottom: _marginBottom, top: 10),
      child: Visibility(
        visible: show,
        child: Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(15),
            boxShadow: [
              BoxShadow(
                blurRadius: 10,
                color: Theme.of(context).shadowColor.withOpacity(0.2),
              ),
            ],
          ),
          constraints: BoxConstraints(
            minWidth: 100,
            maxWidth: 380,
            minHeight: 100,
            maxHeight: queryData.size.width * 1.3,
          ),
          margin: const EdgeInsets.all(20),
          child: ClipRRect(
            borderRadius: BorderRadius.circular(15),
            child: ChatwootChat(
              baseUrl:
                  "our websocket url,
              inboxIdentifier: "our inbox identifier",
              user: ChatwootUser(
                identifier: email,
                name: name,
                email: email,
              ),
            ),
          ),
        ),
      ),
    );
  }

Did i implement this wrong? Any help would be great! Thank you so much

INTL Dependency is old version, needs to update to 0.17.0

Hello Team,
I am having some difficulties with integrating ChatWoot, I'm using Flutter SDK for integration, but when I installed I realized
image
that ChatWoot SDK still uses old dependencies, such as INTL 0.0.9, but FLutterFlow uses 0.17.0, is it possible to update the INTL library for Flutter SDK to 0.17.0 INTL version? See screenshots from the errors that I received from Flutterflow during installation packages. 

Is this library not updated?

This library has not been updated for a long time.
There are a lot of compatibility issues right now, look forward to update.

openapi

Another great approach would be to use openapi standard (preferably generated) to describe the api endpoints that later on can be used to generate a dart client (or js or python or java) with openapi-generator

Thats saves a lot of time developing clients - all the api endpoints and models are generated for you.

Instead of rebuilding the api for each client, you could auto-generate it, it would speed up a lot building something like

#1

inconsistent messages on flutter sdk webview

I have integrated flutter sdk webview with our app and it worked fine but sometimes messages from chatwoot server side is inconsistent.
We need to go back and come again on chat window to see the messages. the messages are not coming in real time. this issue is random and we are sometimes not able to re-generate the same issue.
please help me understand why it is happening and what solution we can do for this.
this issue is lesser known in android devices but frequent in iOS device.

chatwoot webview

While building chatwoot-flutter-sdk is a longer project, I think you could achieve great immediate results by creating a simple webview package that would simply load the chatwoot widget into a full screen webview inside of a flutter app.

That's the approach widely done by other chats. At a very basic level it would be just doing launch('https://app.chatwoot.com/widget?website_token=.... however it would be great to actually build up the similar html inside of the flutter app so that you are able to set the user identity, i.e you'd call a widget:

ChatwootWebView(
    url='https://app.chatwoot.com/widget',
    websiteToken='..... ',
    userName: ...
    userEmail: ..
    userAvatarUrl: ....
    identifierHash: ...

This is much less work and would make chatwoot immediately available to the flutter community with the same production quality of the widget as you have now (i.e. avoid lengthy testing/improvement cycle you'd have building a whole new sdk / ui widgets)

@EphraimNetWorks is this something you could consider looking at?

Unable to use ChatwootChat-Widget without a ChatwootUser

Using the ChatwootChat without a ChatwootUser or a ChatwootUser without an email is currently impossible, despite user being nullable.

======== Exception caught by Flutter framework =====================================================
The following _CastError was thrown:
type 'Null' is not a subtype of type 'String' in type cast

When the exception was thrown, this was the stack: 
#0      _$ChatwootContactFromJson (package:chatwoot_sdk/data/local/entity/chatwoot_contact.g.dart:65:26)
#1      new ChatwootContact.fromJson (package:chatwoot_sdk/data/local/entity/chatwoot_contact.dart:46:7)
#2      ChatwootClientAuthServiceImpl.createNewContact (package:chatwoot_sdk/data/remote/service/chatwoot_client_auth_service.dart:40:41)
<asynchronous suspension>
#3      ChatwootClientApiInterceptor.onRequest.<anonymous closure> (package:chatwoot_sdk/data/remote/service/chatwoot_client_api_interceptor.dart:37:19)
<asynchronous suspension>
#4      BasicLock.synchronized (package:synchronized/src/basic_lock.dart:33:16)
<asynchronous suspension>
#5      ChatwootClientApiInterceptor.onRequest (package:chatwoot_sdk/data/remote/service/chatwoot_client_api_interceptor.dart:29:5)
<asynchronous suspension>
I/flutter (18358): #5      ChatwootClientApiInterceptor.onRequest (package:chatwoot_sdk/data/remote/service/chatwoot_client_api_interceptor.dart:29:5)
====================================================================================================

======== Exception caught by Flutter framework =====================================================
The following _CastError was thrown:
type 'Null' is not a subtype of type 'String' in type cast

When the exception was thrown, this was the stack: 
#0      _$ChatwootContactFromJson (package:chatwoot_sdk/data/local/entity/chatwoot_contact.g.dart:65:26)
#1      new ChatwootContact.fromJson (package:chatwoot_sdk/data/local/entity/chatwoot_contact.dart:46:7)
#2      ChatwootClientAuthServiceImpl.createNewContact (package:chatwoot_sdk/data/remote/service/chatwoot_client_auth_service.dart:40:41)
<asynchronous suspension>
#3      ChatwootClientApiInterceptor.onRequest.<anonymous closure> (package:chatwoot_sdk/data/remote/service/chatwoot_client_api_interceptor.dart:37:19)
<asynchronous suspension>
#4      BasicLock.synchronized (package:synchronized/src/basic_lock.dart:33:16)
<asynchronous suspension>
#5      ChatwootClientApiInterceptor.onRequest (package:chatwoot_sdk/data/remote/service/chatwoot_client_api_interceptor.dart:29:5)
<asynchronous suspension>
====================================================================================================

is CSAT working ?

I have tried enabling CSAT for a certain inbox.
But I did not get any survey after resolving the conversation.
is CSAT supported on flutter or is it still on the road-map, or will it be skipped for flutter ?

Please update SDK

We need to have updated SDK that uses intl 0.18.1 and flutter 3.13.9. We are waiting with 5+ projects ready to implement, please help.

Document existing architecture

Todo:

  • Document the existing API calls in the SDK and the overall flow.
  • Create a flow chart of the existing flow
  • Update the flow based on missing pieces

Files other than images are not visible in webview.

Hi,
I am trying to upload some files like image, pdf and videos from chatwoot self hosted server and able to upload but I am not able to access those file in flutter webview sdk. Only image is visible in flutter webview sdk and that also coming too large when clicking
Please help if you know where to change this file type support.
@sojan-official @pranavrajs

dio ^4.0.0 dependencie

My app use the dio version ^5.1.1 the latest one.
But chatwoot depends on dio ^4.0.0 wich is an older version, the first of Null Safete.

Why don't upgrade the dio version so it matches with the new apps that are being developed?

EnablePersistence=true causes SDK to fail

I'm trying to get this SDK running on my app that already uses HIve as local DB, but seem to be getting an error when persistence is enabled(which I guess uses HIve internally too to store chat history). Is there an issue with the Hive implementation in the package internally that fails when used in combination with app that already. has hive implemented. Attaching error code below.

Can anyone guide me on further steps?

HiveError: Cannot write, unknown type: ChatwootUser. Did you forget to register an adapter?

Enabling "Enforce User Identity Validation" cause ChatwootClientException in SDK

Hi,
I have been trying to enforce user identity validation in chatwoot SDK but getting this exception -

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Instance of 'ChatwootClientException'
E/flutter (13424): #0 ChatwootClientAuthServiceImpl.createNewContact (package:chatwoot_client_sdk/data/remote/service/chatwoot_client_auth_service.dart:52:7)
E/flutter (13424):
E/flutter (13424): #1 ChatwootClientApiInterceptor.onRequest. (package:chatwoot_client_sdk/data/remote/service/chatwoot_client_api_interceptor.dart:37:19)
E/flutter (13424):
E/flutter (13424): #2 BasicLock.synchronized (package:synchronized/src/basic_lock.dart:33:16)
E/flutter (13424):
E/flutter (13424): #3 ChatwootClientApiInterceptor.onRequest (package:chatwoot_client_sdk/data/remote/service/chatwoot_client_api_interceptor.dart:29:5)
E/flutter (13424):

When I dig deeper in the exception, I realized that this exception is caused when createNewContact function is trying to Create Contact using createContactAPI in chatwoot_client_auth_service.dart file. the Exception is -
DioError [DioErrorType.response]: Http status error [500]

this exception came because createConatctAPI expects "identifier_hash" attribute but SDK pass "identifierHash" attribute instead.
since the ChatwootUser function is written this way -
ChatwootUser(
{this.identifier,
this.identifierHash,
this.name,
this.email,
this.avatarUrl,
this.customAttributes});

and client ContactsAPI expects payload in this format -
{
"identifier": "string",
"identifier_hash": "string",
"email": "string",
"name": "string",
"phone_number": "string",
"avatar_url": "string",
"custom_attributes": { }
}

What should I do in this case.?
I am attaching postman screenshots also to describe the issue clearly

Error Image
image

Success Event Image
image

Chat history persistence Issue in SDK

Hi,
Anyone using Chatwoot Flutter SDK ?
I am facing issue in chat history persistence even though I am passing "IdentifierHash" Properly.
The chat history is only available for single device, but if same user login with different device than chat history is not available and new fresh conversation is being created for the same user in chatwoot agent dashboard.
If anyone have any idea on this please help.
Thanks

No named parameter with the name 'kind' Error when building on Xcode

chatwoot version: ^0.0.9

Rendering the ChatwootChat widget in flutter app results in the following error being shown when building for iOS simulator.

Error (Xcode): ../../.pub-cache/hosted/pub.dev/photo_view-0.12.0/lib/src/core/photo_view_gesture_detector.dart:89:38: Error: No named parameter with the name 'kind'.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.