Giter VIP home page Giter VIP logo

chat's People

Contributors

b123400 avatar ben181231 avatar carmenlau avatar chankiyu22 avatar cheungpat avatar chpapa avatar howawong avatar lampercy avatar rickmak avatar steven-chan avatar tensiuyan avatar wallacesky avatar

Stargazers

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

Watchers

 avatar

chat's Issues

error when calling SkygearChat.getMessages

Request:
image
Response:

{
  "error": {
    "name": "UnexpectedError",
    "code": 10000,
    "message": "'result'",
    "info": {
      "trace": "Traceback (most recent call last):\n  File \"/usr/lib/python3.5/site-packages/skygear/transmitter/common.py\", line 39, in wrapper\n    return dict(result=f(self, *args, **kwargs))\n  File \"/usr/lib/python3.5/site-packages/skygear/transmitter/common.py\", line 84, in call_func\n    return self.op(obj, param.get('args', {}))\n  File \"/usr/lib/python3.5/site-packages/skygear/transmitter/common.py\", line 150, in op\n    return func(*args, **kwargs)\n  File \"/usr/src/app/chat_plugin.py\", line 130, in get_messages\n    conversation = _get_conversation(conversation_id)\n  File \"/usr/src/app/chat_plugin.py\", line 239, in _get_conversation\n    if len(response['result']) == 0:\nKeyError: 'result'\n"
    }
  }
}

The data structure of objects in getMessages and object return by createMessage is inconsistent

The generic fields are named differently.

In response of getMessages:
screen shot 2016-09-08 at 3 59 58 pm

Snippet to reproduce the above result:

skygear_chat.getMessages(conversationId)
.then(function (messages) {
  console.log('Plugin get messages success', messages);
});

In response of createMessage:
screen shot 2016-09-08 at 4 00 36 pm

Snippet to reproduce the above result:

skygear_chat.createMessage(conversationId, body)
.then(function (message) {
  console.log('Create message success', message);
});

transientIncludes in getConversations fails

Current implementation put user_conversation in private DB, while conversation are at public db with ACL. getConversations trying to load conversation when querying user_conversation with transientInclude. But it is mistaken to assume skygear will able to do a cross database transientIncludes. Resulting the transient result is empty.

_Proposed solution_
Put the user_conversation back to public database and set it non public readable.

SQL for migration:

UPDATE "app_chat"."user_conversation" SET "_database_id"='', "_access"='[{"public": false}]'

And modify the user_conversation related code back to using publicDB.

Planning for API update that satisfy new chat features

  • cross-platform messaging
  • Create direct conversations and group chats
  • Real time send message & receive message
  • Image and media files support
  • Unread conversations/messages count
  • Manage users in chat groups
  • Typing indicators and recipient status
  • Push notification

Support Push Notification sending directly

This was the lesson learnt after talking with Cloudpillar team who used Skygear Chat.

We should have an option to automatically send push notification to users who receive a new message. Brief idea of the features should be:

Plugins SDK interface changes

  1. On plugins, we shall send a push notification to the receiving devices according to the rules below.
  2. Conversations should have a new boolean parameter of send_push (default true)
  3. Participants should have a new boolean parameter of send_push (default true); May need a new updateParticipants function.
  4. CreateMessage should have a new boolean parameter of send_push (default true)
  5. A new function to Enable / Disable all push notification for the user
  6. A new callback functions for users to construct the notification message. If this callback function was not set, the default push message is: [[User name]]@[[Conversation Title]]: [[Message]]
  7. A function / client side api to set badget count

Plugins configuration changes

  1. Enable (default) or disable all push notification behavior
  2. Choose how should the unread badge update (unread message count, unread conversation count, no badge count)

At portal.skygear.io, we wish to have a configuration to disable / enable it, and the badge count choices.

If we do the push message construct function at server side, prefer to have a code editor with the default push message call back code. So people can change things quickly.

Rules of sending push notification or not

TODO Test these rules with new use case to see if it make sense or not.

Run from 1 - 6

  1. If push notification was disabled, skip
  2. If user disabled all push notification, skip
  3. If CreateMessage's send_push is false, skip
  4. If Participants's send_push is false, skip
  5. If Conversation's send_push is false, skip
  6. Send push

get_message lambda should return conversation with reference type

For subscribe, the conversation_id as follow
"conversation_id" = {
        "$id" = "conversation/0CB7F1B3-2633-46EE-8D84-D5531D4907F0";
        "$type" = ref;
    };

For lambda, the conversation_id as follow
"conversation_id" = "0CB7F1B3-2633-46EE-8D84-D5531D4907F0";

The lambda should return following:

"conversation_id" = {
      "$id" = "conversation/0CB7F1B3-2633-46EE-8D84-D5531D4907F0";
      "$type" = ref;
};

Support `from_id` in getMessages

This will enable user to fetch messages list from the server. Useful when he is not able to subscribe the change for whatever reason. And need to check if any new message by providing the last message he got.

`getOrCreateDirectConversation` and `createConversation` return object

Seem both are returning Conversation. Not UserConversation that transientInlucde User and Conversation.

While the getConversation and getConversations are returning UserConversation, I think it is inconsistence. And the inconsistent introduce bugs and wrapper on project depends on this plugin.

Reduce request number on querying list of conversation with common properties

In common use case, the UI will list the conversation with the user or user X conversation attributes, like user last read at.

We should create an association table UserConversation. So we can use transientInclude to eager load the user/conversation property in one request. And put the user X conversation attributes in that table.

Don't throw the Traceback on `user not in conversation`

Currently throw something like this.

Status 500

{"error":{"name":"UnexpectedError","code":10000,"message":"user not in conversation","info":{"trace":"Traceback (most recent call last):\n  File \"/usr/lib/python3.5/site-packages/skygear/transmitter/common.py\", line 39, in wrapper\n    return dict(result=f(self, *args, **kwargs))\n  File \"/usr/lib/python3.5/site-packages/skygear/transmitter/common.py\", line 84, in call_func\n    return self.op(obj, param.get('args', {}))\n  File \"/usr/lib/python3.5/site-packages/skygear/transmitter/common.py\", line 150, in op\n    return func(*args, **kwargs)\n  File \"/usr/src/app/chat/plugin/__init__.py\", line 134, in get_messages\n    raise SkygearChatException(\"user not in conversation\")\nplugin.chat.plugin.SkygearChatException: user not in conversation\n"}}}

Expected

Since it is a permission deny, it shoud resolve to 403, not 500.

Remove `is_direct_message`

This attribute is designed to make the one-on-one message special and easy to query. But in various implementation, seem it creates more trouble than its original purpose.

refs: SkygearIO/chat-SDK-Android#1 (comment)

Another one from client interview use case: the system needs to do send system message to a one on one conversation. Since all our messages are sent by a user, the intuitive way is create a system user. And put it into the conversation. Here come the is_direct_message creating trouble.

Support Conversation for version 2

Tentative doc:

conversation.md

Supporting API

  • createConversation(participants, title, options)
  • deleteConversation(conversation)
  • updateConversation(conversation)
  • addParticipants(conversation, participants)
  • removeParticipants(conversation, participants)
  • addAdmins(conversation, admins)
  • removeAdmins(conversation, admins)
  • getUserConversations()
  • getUserConversation(conversation)

Tasks (Plugin)

  • support distinct_by_participants and remove is_direct_message

Tasks (SDKs)

  • move admin to options when conversation creation (make it optional)
  • support delete conversation

Support delete of conversation

refs: SkygearIO/chat-SDK-Android#1 (comment)

API will be symmetric with createConversation. Name deleteConversation(conversation_id)

While I think it is completely valid to have a delete, we can do it in two ways:

  1. Delete its cascading at DB. i.e. all message/user_conversation and conversation to be deleted using lambda with transaction
  2. Remove all participant and admin. i.e. None can query back all message and user_conversation in normal way. It will be faster and able to recover from remove.

I would suggest 2 is better if we also provide a GC crontab to clean up the dead conversations.

Discussion: Why we have marked delivery functions in SDK?

I was draw into attentions of the mark delivery functions in various SDK (and the options to automatically mark delivery in ios SDK) In the process of preparing landing page.

I can understand why do we want developers have the options of automatically mark delivery or not. But in which use case do we need to have a function for setting the delivery status manually?

Would love to learn what you guys think and see if any follow-up message is needed.

Btw, I suggest we should update the API doc so that we explain the relationships between the mark delivery functions and the options / and mention normally this function is not used, if we decided to keep it. @royuen please help create an issue for this if the conversation is concluded?

Failed to create the first conversation via developer console and brundle.js

We try to create the first conversation via developer console by calling
skygear_chat.createConversation([idArray],[adminIdArray],title) after login, yet error occurs with below message:

    _Traceback (most recent call last): File "/usr/lib/python3.5/site-packages/sqlalchemy/engine/base.py",
    line 1139, in _execute_context context) File "/usr/lib/python3.5/site-packages/sqlalchemy/engine/default.py",
    line 450, in do_execute cursor.execute(statement, parameters) psycopg2.ProgrammingError: relation "app_my_skygear_app.user_channel" does not exist LINE 3: FROM app_my_skygear_app.user_channel ^ The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3.5/site-packages/skygear/transmitter/common.py",
    line 39, in wrapper return dict(result=f(self, *args, **kwargs)) File "/usr/lib/python3.5/site-packages/skygear/transmitter/common.py",
    line 86, in call_func return self.hook(obj, param) File "/usr/lib/python3.5/site-packages/skygear/transmitter/common.py",
    line 156, in hook returned = func(record, original_record, conn) File "/usr/lib/python3.5/site-packages/skygear/decorators.py",
    line 76, in hook_func func(record, original_record, db) File "/usr/src/app/chat_plugin.py",
    line 53, in handle_conversation_after_save record, original_record) File "/usr/src/app/chat_plugin.py",
    line 255, in _publish_event channel_name = _get_channel_by_user_id(participant_id) File "/usr/src/app/chat_plugin.py",
    line 270, in _get_channel_by_user_id 'user_id': user_id File "/usr/lib/python3.5/site-packages/sqlalchemy/engine/base.py",
    line 906, in execute return self._execute_text(object, multiparams, params) File "/usr/lib/python3.5/site-packages/sqlalchemy/engine/base.py",
    line 1054, in _execute_text statement, parameters File "/usr/lib/python3.5/site-packages/sqlalchemy/engine/base.py",
    line 1146, in _execute_context context) File "/usr/lib/python3.5/site-packages/sqlalchemy/engine/base.py",
    line 1341, in _handle_dbapi_exception exc_info File "/usr/lib/python3.5/site-packages/sqlalchemy/util/compat.py",
    line 200, in raise_from_cause reraise(type(exception), exception, tb=exc_tb, cause=cause) File "/usr/lib/python3.5/site-packages/sqlalchemy/util/compat.py",
    line 183, in reraise raise value.with_traceback(tb) File "/usr/lib/python3.5/site-packages/sqlalchemy/engine/base.py",
    line 1139, in _execute_context context) File "/usr/lib/python3.5/site-packages/sqlalchemy/engine/default.py",
    line 450, in do_execute cursor.execute(statement, parameters) sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) relation "app_my_skygear_app.user_channel" does not exist LINE 3: FROM app_my_skygear_app.user_channel ^ [SQL: '\n SELECT name\n FROM %(schema_name)s.user_channel\n WHERE _owner_id = %(user_id)s\n LIMIT 1;\n '] [parameters: {'user_id': 'f56bcd05-db06-402e-a6c1-ddf8dd1eb333', 'schema_name': <psycopg2.extensions.AsIs object at 0x7f9e3308f300>}]_ 

Is there any problems between our steps?

API doc should explain the subscribe method more

  1. In current JS doc there are no information about the handler, can we add some?

  2. It wasn't clear to users (developers) what subscribe functions are available and how to use in the API doc, any thought how we can improve readability?

Support asset association with Message

Problem: Current implementation of get_messages hard coded what column to return. So even the developer associate the asset according to https://docs.skygear.io/ios/guide/asset. The query won't give the asset back.

Expected: The get_messages should return all column as in record query.

Possible solution:

  • by using DB reflect
  • Or using the schema:fetch API

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.