skygeario / chat Goto Github PK
View Code? Open in Web Editor NEWSkygear Plugin - Chat SDK
License: Apache License 2.0
Skygear Plugin - Chat SDK
License: Apache License 2.0
for detecting network loss and retrieve lost events
If the web service received create request and find no admins, it seems need to auto add one admins (suppose create user)
But not allow creation than will misbehave on some operation.
After SkygearIO/py-skygear#105, chat plugin can use the asset url signer provided by py-skgyear
, supporting s3
and cloud
asset store.
{
"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 generic fields are named differently.
Snippet to reproduce the above result:
skygear_chat.getMessages(conversationId)
.then(function (messages) {
console.log('Plugin get messages success', messages);
});
Snippet to reproduce the above result:
skygear_chat.createMessage(conversationId, body)
.then(function (message) {
console.log('Create message success', message);
});
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.
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:
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.
TODO Test these rules with new use case to see if it make sense or not.
Run from 1 - 6
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;
};
The current code will just return random direct conversations with any user.
A user can talk to himself, and the func should return that self-talking conversation deterministically.
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.
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.
Tentative doc:
https://github.com/rickmak/chat/blob/master/doc/message.md
Todo for plugin and SDKs:
Not user user last read.
Tentative doc:
https://github.com/rickmak/chat/blob/master/doc/pubsub.md
Todo for plugin and SDKs
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.
As of commit SkygearIO/py-skygear@4c51ffe , the feature is remove in favour to make plugin a stateless process.
Got something like this in DB, not yet able to reproduce.
"participant_ids":["8d466177-ab72-4a48-a872-3b74ccc23a5d","user/cdd959cc-2137-4457-b3f3-1a39a1e5d3b6"]
refs: https://github.com/SkygearIO/chat/blob/master/chat/user_conversation.py#L83
This func is calling skygear back and required another plugin to do the database hook
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"}}}
Since it is a permission deny, it shoud resolve to 403
, not 500.
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.
Seem py-skygear don't encode the created_at and created_by.
It is a common use-case that developer want to display last message excerpt during the display of list of conversation
distinct_by_participants
and remove is_direct_message
admin
to options
when conversation creation (make it optional)Objective:
Demo the usage of chat plugin and as API show case.
I would suggest using this UI library and write an adaptor for it.
https://github.com/jessesquires/JSQMessagesViewController
It currently return "_created_at" = "2016-06-15T08:32:33.484861";
which does not align with rest of the response.
So the developer can easily sort by last updated_at which is a very common usecase.
Related code: https://github.com/SkygearIO/chat/blob/master/chat/message_handlers.py#L120
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:
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.
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?
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?
Follow up #17
https://github.com/SkygearIO/chat/blob/master/chat/conversation.py#L162
here will create many SQL query. Which can be reduced to one
by changing the _publish_record_event
to accept array of user and
internal query to get_channels_by_user_ids
The DB don't have the message
table yet, but the plugin assumed it. It will throw an psycopg2.ProgrammingError
on trying to fetch the DB at the lambda.
In current JS doc there are no information about the handler, can we add some?
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?
Could explore whether we could support Atlas by Layer or other UI libraries.
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:
schema:fetch
APIA declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.