oracle to_caht,chat_api-自动聊天和调查API-Pawel Krzyzaniak Chapters Known Issues and areas to improve Setup...

作者:Pawel Krzyzaniak

### 作者邮箱:pawelk@arabel.la

### 首页:https://bitbucket.org/arabellatech/chat_api

### 文档:None

### 下载链接

Chat API

Library for surveys & chat with supporting automated & assisted conversations.

Chapters

Known Issues and areas to improve_

Setup and running_

Configuration_

Schemas_

Chat modes_

UserThreads_

Notifications_

Surveys_

API description_

Known Issues and areas to improve

No context & variables for scripted/assisted questions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Currently all questions are static, meaning there is no possibility of injecting any variables like user firstname, etc. when generating message from question. This functionality should be quite broad and extensible. For example for question with meta X or showas_type Y there should be a possibility to generate context based on:

user

previous responses (variables pool?)

other objects in the DB

TODO:

design

task out

implement

Assisted mode has no test coverage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Assisted mode should work (with exception of making other user enter scripted mode), but it is not covered with tests yet.

TODO:

first implement the APIs for thread control

task out

implement

Repetition is not implemented ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In order to use scripted chat mode as a tracker, repetition must be implemented. It was designed, and models contains necessary fields, but there is no test coverage and no scripts to restart schema.

TODO:

task out

implement

Notifications - add email, sms & push ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Currently only WebSocket notifications are sent out. It would be good to add some mechanisms to handle other kinds of notifications in a generic & highly customizable way.

TODO:

design

task out

implement

Other small issues and places for improvement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Schemas (so also scripted/assited chat mode & surveys) does not support multiple languages.

add pagination to schema list

custom validation, pre save, thumbnail generation etc. functions for attachments should receive also serializer object (so it has access to context & instance for example)

add push notifications

add email/sms notifications

add resolvers to meta (and other places perhaps) - so you can use values from constance

Setup and running

Requirements ~~~~~~~~~~~~

Python 3.5+

Django 1.8+, DRF & bunch of Arrabela tech like DRF Tweaks & Universal Notifications

Celery

Installation ~~~~~~~~~~~~

Add chatapi & universalnotifications to INSTALLEDAPPS, define CELERYAPP_PATH:

.. code:: python

INSTALLED_APPS = (

...

"chat_api",

"universal_notifications"

)

CELERY_APP_PATH = "tests.celery.app",

Also, add settings related to MIME types & extensions:

.. code:: python

ACCEPTED_IMAGE_FILES = ("gif", "png", "jpg", "jpeg")

ACCEPTED_IMAGE_MIME = ("image/gif", "image/png", "image/jpg", "image/jpeg")

MIME_TO_EXT = {

"image/gif": "gif",

"image/png": "png",

"image/jpg": "jpg",

"image/jpeg": "jpg",

"application/pdf": "pdf",

"application/x-pdf": "pdf",

"application/vnd.pdf": "pdf",

"text/pdf": "pdf"

}

Add urls to the components you want to use:

.. code:: python

urlpatterns = [

...

url(r"^", include("chat_api.chat.api_urls")),

url(r"^", include("chat_api.schemas.api_urls")),

url(r"^", include("chat_api.surveys.api_urls")),

]

In order to speed up schemas & automated flows, you need to setup django-cachalot.

.. code:: python

INSTALLED_APPS = (

...

"cachalot"

...

)

CACHALOT_ONLY_CACHABLE_TABLES = [

"chat_api_answer", "chat_api_attachmenttemplate", "chat_api_group", "chat_api_group", "chat_api_question",

"chat_api_schema"

]

REMI: please describe setting up search

Configuration

Chat settings ~~~~~~~~~~~~~

Chat settings are accesible through the chat_settings singleton

.. code:: python

from chat_api.settings import chat_settings

account_serializer_cls = chat_settings.ACCOUNT_SERIALIZER

Chat settings can be configured in settings:

.. code:: python

CHAT_SETTINGS = {

"ACCOUNT_SERIALIZER": "my_project.accounts.serializers.MyAccountClass"

}

Chat settings can be overriden in tests using django's override_settings. However, the permissions classes are resolved earlier, so they will not be affected by this.

Account serializer ~~~~~~~~~~~~~~~~~~

Default account serializer contains:

id

first_name

last_name

avatar

However there are no assumptions regarding fields that should be enclosed in this serializer, so it is fully customizable.

Schemas settings ~~~~~~~~~~~~~~~~

Schema types: each schema must have a type. Types can be freely defined in each project. Default types are "survey" and "automatedflow", but in the given project it is recommended to make them more descriptive, for instance: "onboardingflow", "cancelsubscriptionflow", "health_survey", etc.

.. code:: python

"TYPES_SCHEMA": (("schema_type", "Schema Type Label"), ("other_type", "Other Label")),

Schemas types that can be listed / obtained through API: Getting schemas / listing schemas through API can be limited to some selection (or compeletly). For example, we ant FE to be able to obtain full survey schema, but we don't want any automated flow to be obtainable.

.. code:: python

"TYPES_SCHEMA_LIST_THROUGH_API": ("health_survey", ),

"TYPES_SCHEMA_GET_THROUGH_API": ("health_survey", ),

Allowing published schemas to be edited: This funtionality should be user ONLY in developement environment. By default, schemas that are published are not editable. They can be copied to a new, unpublished version, edited, and once published - they'll make previous version obsolete. But if user X started schema Y in some version Z, he should be able to finish this schema version or else it will result in unpredicted behaviour. However, while developing, copying & publishing a new version each time something has to be adjusted would be too unconvenient.

.. code:: python

"ALLOW_EDIT_PUBLISHED_SCHEMAS": False,

Threads types ~~~~~~~~~~~~~

Type: each thread has it's own type. Types are for describing (and helping to define) certain distinct chat functionalities. For example: "onboarding", "oneononechat", "groupchat". You may configure which types of chat will be listable through API, and which ones will be returned only through some other endpoints.

.. code:: python

"TYPES_CHAT": (("chat", "Chat"), ("survey", "Survey"), ("tracker", "Tracker")),

"TYPES_CHAT_DEFAULT": "chat",

"TYPES_CHAT_LIST_THROUGH_API": ("chat", "survey", "tracker"),

Messages types ~~~~~~~~~~~~~~

Each message in a given thread has a type. Default type is simply "message", but any type can be assigned. Some message types can be restricted for some types of users. To achieve two settings must be defined:

.. code:: python

# settings.py

CHAT_SETTINGS = {

...

"CHAT_MESSAGE_FILTER_QUERYSET": "path.to.my_message_queryset_filter",

"CHAT_MESSAGE_USER_FILTER": "path.to.my_message_user_filter",

}

# path/to.py

def my_message_queryset_filter(queryset, user):

if not user.is_superuser:

return queryset.exclude(type="secret")

return queryset

def my_message_user_filter(message, user):

if user.is_superuser:

return True

return message.type != "secret"

The queryset filter is used when listing messages, the single message filter is used when sending WS and assigning last_message to an UserThread.

IMPORTANT Once last message is assigned, it stays assigned (and obtainable through ThreadSerializer as lastmessagedata) until a new one is assigned, so if you change filters and you want be 100% sure noone has a last message that he should not see after that change, a migration would be required.

Schemas for surveys ~~~~~~~~~~~~~~~~~~~

You can limit which schemas types can be assigned to a survey.

.. code:: python

"SURVEYS_ALLOWED_SCHEMA_TYPES": ("survey", ),

Pagination ~~~~~~~~~~

Threads, Messages List & Surveys can be paginated. By default the NoCountLimitOffsetPagination is used (since it is the fastets and most convenient to user for endless scroll), but those can be overriden:

.. code:: python

"PAGINATION_THREAD_LIST": "any.pagination.class.YouLike",

"PAGINATION_MESSAGES_LIST": "any.pagination.class.YouLike",

"PAGINATION_GLOBAL_SURVEY_LIST": "any.pagination.class.YouLike",

"PAGINATION_ACCOUNT_SURVEY_LIST": "any.pagination.class.YouLike",

Permissions ~~~~~~~~~~~

Each API endpoint has a unique permission class that can be overriden through settings. This allows full customization of chat. For example, by default access to reading/writing given thread have only the thread's members with correct permissions defined in UserThread. But if you want for example given user type to read all threads, overwriting permission classes is a way to go.

.. code:: python

"PERMISSIONS_MESSAGES_LIST_BY_THREAD_ID": "any.permission.class.YouLike",

"PERMISSIONS_MESSAGE_OBJECT_BY_THREAD_ID": "any.permission.class.YouLike",

Attachments settings ~~~~~~~~~~~~~~~~~~~~

There are a predefined types of attachments with predefined behaviour:

image

youtube (url)

object_reference

However this list can be extended by defining new types and behaviours:

.. code:: python

# settings.py

CHAT_SETTINGS = {

"TYPES_CUSTOM_ATTACHMENTS": (("pdf", "PDF File"), ), # ("type", "Label")),

"CUSTOM_ATTACHMENTS_VALIDATION": {"pdf": "my.validation_func"},

"CUSTOM_ATTACHMENTS_PRE_SAVE": {"pdf": "my.pre_save_func"},

"CUSTOM_ATTACHMENTS_THUMBNAIL_GENERATOR": {"pdf": "my.thumbnail_generator_func"},

"CUSTOM_ATTACHMENTS_GET_SRC": {"pdf": "my.get_src_func"},

"CUSTOM_ATTACHMENTS_GET_THUMBNAIL": {"pdf": "my.get_thumbnail_func"},

}

# my.py

def validation_func(data):

if "src" not in data:

raise serializer.ValidationError("I want this field!")

return data

def pre_save_func(validated_data):

# save PDF from src to some location

return validated_data

def thumbnail_generator_func(validated_data):

# generate thumbnail of the pdf

return validate_data

def get_src_func(obj):

return obj.src + "?some_magic_key=dsaokpdsa"

def get_thumbnail_func(obj):

return obj.thumbnail["src"]

You can also define a default attachment thumbnail size:

.. code:: python

"ATTACHMENT_THUMBNAIL_SIZE": (100, 100),

Search settings ~~~~~~~~~~~~~~~

REMI: please describe

Schemas

Schemas can be used both for chat (scripted or assisted mode) or for surveys.

More details about schemas configuration may be found here: https://docs.google.com/document/d/1d_beZNNWrHSGjMApa-9LoRpzpe1p3xFbDFmJpRbhEsY/edit

Chat modes

Chat modes are defined per each user in a given thread. It means that one user can be in scripted mode, other user can be in an assisted mode, and yet another user can be in closed mode. Mode (state) for a given user in a given thread is defined in UserThread.

Open ~~~~

In this mode there is no schema assigned to an UserThread. Thread member in such state can write messages freely.

Closed ~~~~~~

In this mode there is no schema assigned to an UserThread. Thread member in such state can not write any messages.

Scripted ~~~~~~~~

In this mode schema must be assigned to an UserThread. In this mode user can only send a message that is a correct answer to the current question (UserThread.question that generated UserThread.related_message), based on it's type, parameters and answers if applies.

Once user answers the last question (next_qid == -1) the schema is either:

repeated (UserThread.onfinish == UserThread.ONFINISH_REPEAT)

opened (UserThread.onfinish == UserThread.ONFINISH_OPEN)

closed (UserThread.onfinish == UserThread.ONFINISH_CLOSE)

Scripted with FE Control ~~~~~~~~~~~~~~~~~~~~~~~~

This mode works almost the same as the Scripted state, with following exceptions:

Answer is send along with question_id. This question must belong to a given schema and the answer must be a valid answer for the question. Question may differ from UserThread.question - in this mode there is assumption, that FE knows better.

Messages from questions are not spawned in a moment that a schema is transitioning to another question, but along with message.

Assisted ~~~~~~~~

In this mode schema must be assigned to an UserThread. There is no current question in the UserThread, there is also no related message. Assisted mode is just passing a schema_id to FE, so the user may choose a message from it and send it to chat. Once implemented, it will also allow such user to make other user enter the scripted state.

Example use case:

.. code::

[patient, open state] Hi, I'm not feeling well

[doctor, assisted state] Hi, I'll need some more information

[doctor, assisted state, chooses "basic_assessment" part of the schema]

[automated message from doctor] Do you have elevated temperature?

[patient, scripted state, chooses from answers] Yes

Breaking scripted states ~~~~~~~~~~~~~~~~~~~~~~~~

If user A is in a scripted mode, and user B is in open mode, sending a message by user B will not affect user A. He will see it, but he'll not be able to react to it - since he is in a scripted mode and must provide answer to the current question from the schema. User B, if he has PERMISSIONTHREADBREAKSTATE in his UserThread.permissions, can break user's A state by sending him message along "breakstate": True. This will move user A to an open state.

UserThreads

There are only few thread properties that are shared by all thread members:

thread id

title

updated & created timestamps

All the other important properties are unique for each thread member: - state & all related properties - permissions & notifications - last message

Also, permissions for various APIs are determined based on UserThread. Therefore even if object contains a FK to a thread, if thread_data is going to be serialized it will be UserThread, not Thread serialized there. Chat is doing those replacement during the serialization, but if you add FK to a thread in some other object and you want to serialize it properly, you should copy solution from chat.

Default UserThread ~~~~~~~~~~~~~~~~~~

Since you can override permissions, giving access to threads to users that are not it's members, there is a necessity to define in such cases some default UserThread before serialization. Example:

.. code:: python

default_thread = UserThread(

notifications=UserThread.NOTIFICATIONS_WS, state=UserThread.STATE_OPEN, updated=thread.updated,

permissions=UserThread.PERMISSION_MESSAGES_READ | UserThread.PERMISSION_THREAD_READ, thread=thread,

created=thread.created, last_message=thread.last_message

)

Notifications

Each user, in UserThread may be assigned a custom notification level. By default he will get unread states and websocket notifications. There is also flag for Push notifications, however it is not yet implemented. Email/SMS/other notifications should be added in the future.

.. code:: python

UserThread.objects.create(

notifications=UserThread.NOTIFICATIONS_WS | UserThread.NOTIFIACTIONS_UNREAD, ...

)

Unread states ~~~~~~~~~~~~~

Each member of a given thread may have an unread state for each message if he has UserThread.NOTIFICATIONS_UNREAD flag on in his notifications flags in his UserThread. Enabling or disabling the flag is not affecting the previous messages - they either keep their unread state or lack of it.

For optimization reasons, the unread states are a separate objects, that are deleted when the user marks the message as read.

Messages are marked as read in two cases:

when they are obtained by API (GET /api/threads/{thread_id}/messages) by given user

when the command "markmessageas_read" is send through WS Multiplex

.. code:: python

ws_received.send(message_data={

"message": "mark_message_as_read",

"data": {

"message": self.message1.id

}

}, channel_emails=[self.user2.email], sender=None)

Websockets ~~~~~~~~~~

There are currently two websockets send out:

messagecreatedor_updated

threadsomeoneis_writing ("marching ants")

Message created or updated //

This WS is send to any subscribed user for a given thread whenever message is created or updated. It contains also attachments & serialized user thread (so information about number of unread messages).

Thread someone is writing /

Whis WS is send to any subscribed user for a given thread whenever any of the thread-member is sending the command through websocek multiplex.

.. code:: python

ws_received.send(message_data={

"message": "thread_someone_is_writing",

"data": {

"thread": self.thread.id,

"length": 1000 # in miliseconds

}

}, channel_emails=[self.user2.email], sender=None)

Websockets for non-members ~~~~~~~~~~~~~~~~~~~~~~~~~~

In case when user is not a thread member, but wishes to receive WS from a given thread (sample use cases: admin user checks what are happening in coversations; the whole group of user, eg. doctors have access to the same conversation, and it would be inefficient to add everyone of them to a thread) there is an api to subscribe to a given threads websockets: POST /api/threads/{thread_id}/ws-subscribe.

One user can be subscribed to only one thread he is not a member of. Subscribing to a new thread automaticaly replaces the old subscription. By default this API is blocked - it's permission class must be overriden in order to use it.

Using Search

REMI: please describe

Surveys

Obtaining schema & answers ~~~~~~~~~~~~~~~~~~~~~~~~~~

In order to display questions, a given schema from survey object should be obtained through API (GET /api/schemas/{pk}).

While listing answers (GET /api/surveys/{surveyid}/items), the questions for them are also returned (in relatedquestion_data), however questions that were not answered are not returned with this method.

State ~~~~~

Each survey contains a state objects, that is a dictionary conatining two things:

visibility: list of ids of questions that are currently visible

completed: True if all visible required fields are answered, otherwise False

Determining visibility ~~~~~~~~~~~~~~~~~~~~~~

Visibility is defined by following algorithm:

We assume the first question (with lowest position) is visible.

If a question is visible, the question that it is referring to (by next_qid) is also visible.

If there is an answer added to visible question, the question the answer is referring to (by next_qid) is also visible.

Changing answers may affect visibility of a question (if the question looses all references to it) or even a whole group of questions. Visibility is determined after each time answer is saved and returned in state["visibility"] in a Survey object.

Required fields ~~~~~~~~~~~~~~~

Each question in schema may be marked as required.

A question is only really required if it is visible (see the section above).

Updating previous answers ~~~~~~~~~~~~~~~~~~~~~~~~~

There is only one answer allowed for a given question id. This means, that to update an answer you have to either put/patch the previous answer (PATCH /api/surveys/{surveyid}/items/{pk}) or first delete it (DELETE /api/surveys/{surveyid}/items/{pk}) and then add a new one.

API description

All API functions can be found in swagger after plugging the chat library to a project.

Copy from pypi.org

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Docker中安装caht2db,您可以按照以下步骤进行操作: 1. 首先,使用docker exec命令进入到您的容器中。例如,使用以下命令进入到容器中: ``` docker exec -it <container_id> /bin/sh ``` \[1\] 2. 在容器中,使用适当的包管理工具(如apt-get或yum)安装caht2db。具体的安装命令可能因您使用的容器镜像而有所不同。您可以通过在容器中运行以下命令来查找适合您的镜像的安装命令: ``` apt-get install caht2db ``` 或 ``` yum install caht2db ``` 注意,这只是示例命令,实际的安装命令可能会有所不同。 3. 安装完成后,您可以使用caht2db命令来配置和管理您的数据库。 请注意,上述步骤是一般的指导,具体的安装过程可能因您使用的容器镜像和操作系统而有所不同。建议您查阅相关的文档或官方指南以获取更详细的安装说明。 #### 引用[.reference_title] - *1* [Docker 安装Kafka](https://blog.csdn.net/zhouzhiwengang/article/details/126172296)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Docker 安装Zookeeper](https://blog.csdn.net/zhouzhiwengang/article/details/126168972)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Docker安装Python3教程](https://blog.csdn.net/qq_19309473/article/details/126268145)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值