From 56ae4575966c5326658b04da67dd8b44119f8a46 Mon Sep 17 00:00:00 2001 From: WiNGC Date: Tue, 16 Feb 2016 16:50:35 -0800 Subject: [PATCH 01/13] Updated schema to support parsing phone number when participant type is Google Voice, and the delivery medium data for self state. --- src/schema.coffee | 42 +++++++++++++++++++++++++++++++++----- test/convstate.json | 36 ++++++++++++++++++++++++++------ test/test-initparse.coffee | 2 +- 3 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/schema.coffee b/src/schema.coffee index 0ffd8f6..76b1697 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -47,6 +47,12 @@ s.ClientNotificationLevel = QUIET : 10 RING : 30 +s.ClientDeliveryMediumType = + + UNKNOWN: 0 + BABEL: 1 + GOOGLE_VOICE: 2 + LOCAL_SMS: 3 s.ClientConversationStatus = @@ -97,8 +103,17 @@ s.ActiveClientState = NO_ACTIVE_CLIENT : 0 IS_ACTIVE_CLIENT : 1 OTHER_CLIENT_IS_ACTIVE : 2 + +s.ParticipantType = + UNKNOWN : 0 + GAIA: 2 + GOOGLE_VOICE: 3 +############################################################################## +# Structures +############################################################################## + s.USER_ID = Message([ 'gaia_id', Field() 'chat_id', Field() @@ -133,6 +148,22 @@ s.CONVERSATION_ID = Message([ 'id', Field() ]) +s.PHONE_NUMBER = Message([ + 'e164', Field() + None, RepeatedField(Field()) +]) + +s.CLIENT_DELIVERY_MEDIUM = Message([ + 'delivery_medium_type', EnumField(s.ClientDeliveryMediumType) + 'phone_number', s.PHONE_NUMBER +]) + +s.CLIENT_DELIVERY_MEDIUM_OPTION = Message([ + 'delivery_medium', s.CLIENT_DELIVERY_MEDIUM + 'current_default', Field() + None, Field() # No idea what this is yet +]) + s.CLIENT_CONVERSATION = Message([ 'conversation_id', s.CONVERSATION_ID 'type', EnumField(s.ConversationType) @@ -155,9 +186,9 @@ s.CLIENT_CONVERSATION = Message([ 'invite_timestamp', Field() 'sort_timestamp', Field() 'active_timestamp', Field() - None, Field() - None, Field() - None, Field() + None, Field() # This one should be "invite_affinity" + None, Field() # No idea what this field is + 'delivery_medium_option', RepeatedField(s.CLIENT_DELIVERY_MEDIUM_OPTION) None, Field() ]) None, Field() @@ -176,7 +207,9 @@ s.CLIENT_CONVERSATION = Message([ 'participant_data', RepeatedField(Message([ 'id', s.USER_ID 'fallback_name', Field() - None, Field() + None, Field() # Invitation status + 'phone_number', s.PHONE_NUMBER + 'participant_type', EnumField(s.ParticipantType) ])) None, Field() None, Field() @@ -412,5 +445,4 @@ s.CLIENT_GET_ENTITY_BY_ID_RESPONSE = Message([ 'entities', RepeatedField(s.CLIENT_ENTITY) ]) - module.exports = s diff --git a/test/convstate.json b/test/convstate.json index 8c5dee9..e5fef82 100644 --- a/test/convstate.json +++ b/test/convstate.json @@ -28,7 +28,16 @@ }, "invite_timestamp": 1430497801138000, "sort_timestamp": 1430497808139701, - "active_timestamp": 1430497801138000 + "active_timestamp": 1430497801138000, + "delivery_medium_option": [ { + "current_default": 0, + "delivery_medium": { + "delivery_medium_type": "GOOGLE_VOICE", + "phone_number": { + "e164": "+14011234567" + } + } + } ] }, "read_state": [ { @@ -63,14 +72,18 @@ "gaia_id": "105510613398923491294", "chat_id": "105510613398923491294" }, - "fallback_name": "Bo Tenström" + "fallback_name": "Bo Tenström", + "participant_type": "GAIA", + "phone_number": null }, { "id": { "gaia_id": "102224360723365489932", "chat_id": "102224360723365489932" }, - "fallback_name": "Bo Tenström" + "fallback_name": "Bo Tenström", + "participant_type": "GOOGLE_VOICE", + "phone_number": { "e164": "+14017654321" } } ] }, @@ -151,7 +164,14 @@ }, "invite_timestamp": 1430497826216000, "sort_timestamp": 1430497904083513, - "active_timestamp": 1430497840649000 + "active_timestamp": 1430497840649000, + "delivery_medium_option": [ { + "current_default": 1, + "delivery_medium": { + "delivery_medium_type": "BABEL", + "phone_number": null + } + } ] }, "read_state": [ { @@ -186,14 +206,18 @@ "gaia_id": "102224360723365489932", "chat_id": "102224360723365489932" }, - "fallback_name": "Bo Tenström" + "fallback_name": "Bo Tenström", + "participant_type": "GAIA", + "phone_number": null }, { "id": { "gaia_id": "110994664963851875523", "chat_id": "110994664963851875523" }, - "fallback_name": "Martin Algesten" + "fallback_name": "Martin Algesten", + "participant_type": "GAIA", + "phone_number": null } ] }, diff --git a/test/test-initparse.coffee b/test/test-initparse.coffee index cf5b5df..4fe5278 100644 --- a/test/test-initparse.coffee +++ b/test/test-initparse.coffee @@ -25,7 +25,7 @@ describe 'INITIAL_CLIENT_ENTITIES', -> deql INITIAL_CLIENT_ENTITIES.parse(msg2), cmp2 -msg3 = [[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],1,null,[null,null,null,null,null,null,[["102224360723365489932","102224360723365489932"],1430497808139701],2,30,[1],["102224360723365489932","102224360723365489932"],1430497801138000,1430497808139701,1430497801138000,null,null,[[[1],1]],0],[],[],null,[[["105510613398923491294","105510613398923491294"],0],[["102224360723365489932","102224360723365489932"],1430497808139701]],0,2,1,1,[["102224360723365489932","102224360723365489932"],["105510613398923491294","105510613398923491294"]],[[["105510613398923491294","105510613398923491294"],"Bo Tenström",1,null,2,1],[["102224360723365489932","102224360723365489932"],"Bo Tenström",2,null,2,2]],null,0,null,[1],1],[[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],["102224360723365489932","102224360723365489932"],1430497808139701,[["102224360723365489932","102224360723365489932"],"1289503288794"],null,0,[null,[],[[[0,"hey",[0,0,0,0]]],[]]],null,null,null,null,"7zbr7sUt_No7zbr8i4WRTa",null,null,1,2,1,null,null,[1],null,null,1,1430497808139701]],null,null,null,[]],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],1,null,[null,null,null,null,null,null,[["102224360723365489932","102224360723365489932"],1430497844252252],2,30,[1],["110994664963851875523","110994664963851875523"],1430497826216000,1430497904083513,1430497840649000,null,null,[[[1],1]],0],[],[],null,[[["102224360723365489932","102224360723365489932"],1430497844252252],[["110994664963851875523","110994664963851875523"],0]],0,2,1,1,[["110994664963851875523","110994664963851875523"],["102224360723365489932","102224360723365489932"]],[[["102224360723365489932","102224360723365489932"],"Bo Tenström",2,null,2,2],[["110994664963851875523","110994664963851875523"],"Martin Algesten",2,null,2,2]],null,0,null,[1],1],[[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["110994664963851875523","110994664963851875523"],1430497831165769,[["102224360723365489932","102224360723365489932"]],null,0,[null,[],[[[0,"the second",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrBWycNlt",null,null,1,2,1,null,null,[1],null,null,1,1430497831165769],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["102224360723365489932","102224360723365489932"],1430497844252252,[["102224360723365489932","102224360723365489932"],"260429275674"],null,0,[null,[],[[[0,"test123",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrD7DR5bM",null,null,1,2,1,null,null,[1],null,null,1,1430497844252252],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["110994664963851875523","110994664963851875523"],1430497904083513,[["102224360723365489932","102224360723365489932"]],null,0,[null,[],[[[0,"the second one",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrKQdW4ZV",null,null,1,2,1,null,null,[1],null,null,1,1430497904083513]],null,null,null,[]]] +msg3 = [[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],1,null,[null,null,null,null,null,null,[["102224360723365489932","102224360723365489932"],1430497808139701],2,30,[1],["102224360723365489932","102224360723365489932"],1430497801138000,1430497808139701,1430497801138000,null,null,[[[2,["+14011234567",["(401) 123-4567","+1 401-123-4567",1,"US",1,0]]],0,1]],0],[],[],null,[[["105510613398923491294","105510613398923491294"],0],[["102224360723365489932","102224360723365489932"],1430497808139701]],0,2,1,1,[["102224360723365489932","102224360723365489932"],["105510613398923491294","105510613398923491294"]],[[["105510613398923491294","105510613398923491294"],"Bo Tenström",1,null,2,1],[["102224360723365489932","102224360723365489932"],"Bo Tenström",2,["+14017654321",["(401) 765-4321","+1 401-765-4321",1,"US",1,0] ],3,2]],null,0,null,[1],1],[[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],["102224360723365489932","102224360723365489932"],1430497808139701,[["102224360723365489932","102224360723365489932"],"1289503288794"],null,0,[null,[],[[[0,"hey",[0,0,0,0]]],[]]],null,null,null,null,"7zbr7sUt_No7zbr8i4WRTa",null,null,1,2,1,null,null,[1],null,null,1,1430497808139701]],null,null,null,[]],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],1,null,[null,null,null,null,null,null,[["102224360723365489932","102224360723365489932"],1430497844252252],2,30,[1],["110994664963851875523","110994664963851875523"],1430497826216000,1430497904083513,1430497840649000,null,null,[[[1],1]],0],[],[],null,[[["102224360723365489932","102224360723365489932"],1430497844252252],[["110994664963851875523","110994664963851875523"],0]],0,2,1,1,[["110994664963851875523","110994664963851875523"],["102224360723365489932","102224360723365489932"]],[[["102224360723365489932","102224360723365489932"],"Bo Tenström",2,null,2,2],[["110994664963851875523","110994664963851875523"],"Martin Algesten",2,null,2,2]],null,0,null,[1],1],[[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["110994664963851875523","110994664963851875523"],1430497831165769,[["102224360723365489932","102224360723365489932"]],null,0,[null,[],[[[0,"the second",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrBWycNlt",null,null,1,2,1,null,null,[1],null,null,1,1430497831165769],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["102224360723365489932","102224360723365489932"],1430497844252252,[["102224360723365489932","102224360723365489932"],"260429275674"],null,0,[null,[],[[[0,"test123",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrD7DR5bM",null,null,1,2,1,null,null,[1],null,null,1,1430497844252252],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["110994664963851875523","110994664963851875523"],1430497904083513,[["102224360723365489932","102224360723365489932"]],null,0,[null,[],[[[0,"the second one",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrKQdW4ZV",null,null,1,2,1,null,null,[1],null,null,1,1430497904083513]],null,null,null,[]]] cmp3 = require './convstate.json' From 062ecedb76cdc464d73931ba6f34d47e04767707 Mon Sep 17 00:00:00 2001 From: WiNGC Date: Tue, 16 Feb 2016 17:21:10 -0800 Subject: [PATCH 02/13] Added invitation status and updated test JSON file accordingly. Protobuf explaining link http://hangups.readthedocs.org/en/stable/protobuf.html#conversationparticipantdata is missing field 4, the phone number, though. --- src/schema.coffee | 9 ++++++++- test/convstate.json | 16 ++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/schema.coffee b/src/schema.coffee index 76b1697..b779d96 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -104,6 +104,12 @@ s.ActiveClientState = IS_ACTIVE_CLIENT : 1 OTHER_CLIENT_IS_ACTIVE : 2 +s.InvitationStatus = + + UNKNOWN : 0 + PENDING : 1 + ACCEPTED : 2 + s.ParticipantType = UNKNOWN : 0 @@ -207,9 +213,10 @@ s.CLIENT_CONVERSATION = Message([ 'participant_data', RepeatedField(Message([ 'id', s.USER_ID 'fallback_name', Field() - None, Field() # Invitation status + 'invitation_status', EnumField(s.InvitationStatus) 'phone_number', s.PHONE_NUMBER 'participant_type', EnumField(s.ParticipantType) + 'new_invitation_status', EnumField(s.InvitationStatus) ])) None, Field() None, Field() diff --git a/test/convstate.json b/test/convstate.json index e5fef82..f1f32ec 100644 --- a/test/convstate.json +++ b/test/convstate.json @@ -73,8 +73,10 @@ "chat_id": "105510613398923491294" }, "fallback_name": "Bo Tenström", + "invitation_status": "PENDING", + "phone_number": null, "participant_type": "GAIA", - "phone_number": null + "new_invitation_status": "PENDING" }, { "id": { @@ -82,8 +84,10 @@ "chat_id": "102224360723365489932" }, "fallback_name": "Bo Tenström", + "invitation_status": "ACCEPTED", + "phone_number": { "e164": "+14017654321" }, "participant_type": "GOOGLE_VOICE", - "phone_number": { "e164": "+14017654321" } + "new_invitation_status": "ACCEPTED" } ] }, @@ -207,8 +211,10 @@ "chat_id": "102224360723365489932" }, "fallback_name": "Bo Tenström", + "invitation_status": "ACCEPTED", + "phone_number": null, "participant_type": "GAIA", - "phone_number": null + "new_invitation_status": "ACCEPTED" }, { "id": { @@ -216,8 +222,10 @@ "chat_id": "110994664963851875523" }, "fallback_name": "Martin Algesten", + "invitation_status": "ACCEPTED", + "phone_number": null, "participant_type": "GAIA", - "phone_number": null + "new_invitation_status": "ACCEPTED" } ] }, From 71f7761b82d876aa55d057d6edff67308a184867 Mon Sep 17 00:00:00 2001 From: WiNGC Date: Tue, 16 Feb 2016 20:06:39 -0800 Subject: [PATCH 03/13] Add delivery medium information to be sent with message when replying back. In this way the lib user can reply back to SMS. --- src/client.coffee | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/client.coffee b/src/client.coffee index 9267f6b..f28b6ca 100644 --- a/src/client.coffee +++ b/src/client.coffee @@ -16,7 +16,9 @@ Channel = require './channel' Auth = require './auth' Init = require './init' -{OffTheRecordStatus, TypingStatus, +{OffTheRecordStatus, +TypingStatus, +ClientDeliveryMediumType, ClientNotificationLevel, CLIENT_SYNC_ALL_NEW_EVENTS_RESPONSE, CLIENT_GET_CONVERSATION_RESPONSE @@ -253,8 +255,12 @@ module.exports = class Client extends EventEmitter # it can be used to tie together a client send with the update # from the server. The default is `null` which makes # the client generate a random id. - sendchatmessage: (conversation_id, segments, image_id=None, - otr_status=OffTheRecordStatus.ON_THE_RECORD,client_generated_id=null) -> + sendchatmessage: (conversation_id, + segments, + image_id=None, + otr_status = OffTheRecordStatus.ON_THE_RECORD, + delivery_medium = [ClientDeliveryMediumType.BABEL], + client_generated_id = null) -> client_generated_id = randomid() unless client_generated_id @chatreq.req 'conversations/sendchatmessage', [ @_requestBodyHeader(), @@ -267,6 +273,7 @@ module.exports = class Client extends EventEmitter [conversation_id] client_generated_id otr_status + delivery_medium ], None, None, None, [] ] From 330a8442df63306bee82af45e6e3fe5397364b72 Mon Sep 17 00:00:00 2001 From: WiNGC Date: Thu, 18 Feb 2016 17:20:54 -0800 Subject: [PATCH 04/13] Introduced a new field BooleanField in pblite.coffee and used in new supported fields to parse boolean values directly. Also made the i18n_data field able to be parsed along with e164. The e164 is good enough to send SMS or make call, but the i18n is good for any phone number formatted display. Also updated the README.md file to reflect my changes. --- README.md | 7 +++++++ src/pblite.coffee | 9 ++++++++- src/schema.coffee | 19 ++++++++++++++++--- test/convstate.json | 26 ++++++++++++++++++++++---- test/test-initparse.coffee | 2 +- 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a988ecb..5e2835d 100644 --- a/README.md +++ b/README.md @@ -667,6 +667,13 @@ Whenever an update about the conversation itself is needed. Like when a new conversation is created, this event comes first with the metadata about it. +The conversation state is stored in self_conversation_state of the event. +The self_conversation_state.delivery_medium_option contains an array of the +delivery medium options which indicate all possible medium. The array element +with current_default == true should be the one used to send message via by +default. Currently there are 3 types of known medium, BABEL, Google Voice and +SMS. BABEL is the Google Hangouts codename BTW. + #### `membership_change` Member joining/leaving conversation. diff --git a/src/pblite.coffee b/src/pblite.coffee index 73c9e32..4177215 100644 --- a/src/pblite.coffee +++ b/src/pblite.coffee @@ -8,6 +8,13 @@ class Field parse: (input) -> @value = if input == undefined then null else input +# A boolean field that parses 0 or non-zero to false or true. +class BooleanField + constructor: () -> + return new BooleanField() unless this instanceof BooleanField + parse: (input) -> + @value = if input == undefined then false else if parseInt(input) == 0 then false else true + # An enum field can hold nothing or one of the # values of a defined enumeration class EnumField @@ -46,4 +53,4 @@ class Message out[k] = v.parse val if k out -module.exports = {Field, EnumField, RepeatedField, Message} +module.exports = {Field, BooleanField, EnumField, RepeatedField, Message} diff --git a/src/schema.coffee b/src/schema.coffee index b779d96..76b2d3e 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -1,4 +1,4 @@ -{Field, EnumField, RepeatedField, Message} = require './pblite' +{Field, BooleanField, EnumField, RepeatedField, Message} = require './pblite' s = {} @@ -115,6 +115,10 @@ s.ParticipantType = UNKNOWN : 0 GAIA: 2 GOOGLE_VOICE: 3 + +s.PhoneValidationResult = + + IS_POSSIBLE : 0 ############################################################################## # Structures @@ -154,9 +158,18 @@ s.CONVERSATION_ID = Message([ 'id', Field() ]) +s.I18N_DATA = Message([ + 'national_number', Field() + 'international_number', Field() + 'country_code', Field() + 'region_code', Field() + 'is_valid', BooleanField() + 'validation_result', EnumField(s.PhoneValidationResult) +]) + s.PHONE_NUMBER = Message([ 'e164', Field() - None, RepeatedField(Field()) + 'i18n_data', s.I18N_DATA ]) s.CLIENT_DELIVERY_MEDIUM = Message([ @@ -166,7 +179,7 @@ s.CLIENT_DELIVERY_MEDIUM = Message([ s.CLIENT_DELIVERY_MEDIUM_OPTION = Message([ 'delivery_medium', s.CLIENT_DELIVERY_MEDIUM - 'current_default', Field() + 'current_default', BooleanField() None, Field() # No idea what this is yet ]) diff --git a/test/convstate.json b/test/convstate.json index f1f32ec..ced495f 100644 --- a/test/convstate.json +++ b/test/convstate.json @@ -30,11 +30,19 @@ "sort_timestamp": 1430497808139701, "active_timestamp": 1430497801138000, "delivery_medium_option": [ { - "current_default": 0, + "current_default": false, "delivery_medium": { "delivery_medium_type": "GOOGLE_VOICE", "phone_number": { - "e164": "+14011234567" + "e164": "+14011234567", + "i18n_data" : { + "national_number": "(401) 123-4567", + "international_number": "+1 401-123-4567", + "country_code": 1, + "region_code": "US", + "is_valid": false, + "validation_result": "IS_POSSIBLE" + } } } } ] @@ -85,7 +93,17 @@ }, "fallback_name": "Bo Tenström", "invitation_status": "ACCEPTED", - "phone_number": { "e164": "+14017654321" }, + "phone_number": { + "e164": "+14017654321", + "i18n_data": { + "national_number": "(401) 765-4321", + "international_number": "+1 401-765-4321", + "country_code": 1, + "region_code": "US", + "is_valid": true, + "validation_result": "IS_POSSIBLE" + } + }, "participant_type": "GOOGLE_VOICE", "new_invitation_status": "ACCEPTED" } @@ -170,7 +188,7 @@ "sort_timestamp": 1430497904083513, "active_timestamp": 1430497840649000, "delivery_medium_option": [ { - "current_default": 1, + "current_default": true, "delivery_medium": { "delivery_medium_type": "BABEL", "phone_number": null diff --git a/test/test-initparse.coffee b/test/test-initparse.coffee index 4fe5278..6a9d6bd 100644 --- a/test/test-initparse.coffee +++ b/test/test-initparse.coffee @@ -25,7 +25,7 @@ describe 'INITIAL_CLIENT_ENTITIES', -> deql INITIAL_CLIENT_ENTITIES.parse(msg2), cmp2 -msg3 = [[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],1,null,[null,null,null,null,null,null,[["102224360723365489932","102224360723365489932"],1430497808139701],2,30,[1],["102224360723365489932","102224360723365489932"],1430497801138000,1430497808139701,1430497801138000,null,null,[[[2,["+14011234567",["(401) 123-4567","+1 401-123-4567",1,"US",1,0]]],0,1]],0],[],[],null,[[["105510613398923491294","105510613398923491294"],0],[["102224360723365489932","102224360723365489932"],1430497808139701]],0,2,1,1,[["102224360723365489932","102224360723365489932"],["105510613398923491294","105510613398923491294"]],[[["105510613398923491294","105510613398923491294"],"Bo Tenström",1,null,2,1],[["102224360723365489932","102224360723365489932"],"Bo Tenström",2,["+14017654321",["(401) 765-4321","+1 401-765-4321",1,"US",1,0] ],3,2]],null,0,null,[1],1],[[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],["102224360723365489932","102224360723365489932"],1430497808139701,[["102224360723365489932","102224360723365489932"],"1289503288794"],null,0,[null,[],[[[0,"hey",[0,0,0,0]]],[]]],null,null,null,null,"7zbr7sUt_No7zbr8i4WRTa",null,null,1,2,1,null,null,[1],null,null,1,1430497808139701]],null,null,null,[]],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],1,null,[null,null,null,null,null,null,[["102224360723365489932","102224360723365489932"],1430497844252252],2,30,[1],["110994664963851875523","110994664963851875523"],1430497826216000,1430497904083513,1430497840649000,null,null,[[[1],1]],0],[],[],null,[[["102224360723365489932","102224360723365489932"],1430497844252252],[["110994664963851875523","110994664963851875523"],0]],0,2,1,1,[["110994664963851875523","110994664963851875523"],["102224360723365489932","102224360723365489932"]],[[["102224360723365489932","102224360723365489932"],"Bo Tenström",2,null,2,2],[["110994664963851875523","110994664963851875523"],"Martin Algesten",2,null,2,2]],null,0,null,[1],1],[[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["110994664963851875523","110994664963851875523"],1430497831165769,[["102224360723365489932","102224360723365489932"]],null,0,[null,[],[[[0,"the second",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrBWycNlt",null,null,1,2,1,null,null,[1],null,null,1,1430497831165769],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["102224360723365489932","102224360723365489932"],1430497844252252,[["102224360723365489932","102224360723365489932"],"260429275674"],null,0,[null,[],[[[0,"test123",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrD7DR5bM",null,null,1,2,1,null,null,[1],null,null,1,1430497844252252],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["110994664963851875523","110994664963851875523"],1430497904083513,[["102224360723365489932","102224360723365489932"]],null,0,[null,[],[[[0,"the second one",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrKQdW4ZV",null,null,1,2,1,null,null,[1],null,null,1,1430497904083513]],null,null,null,[]]] +msg3 = [[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],1,null,[null,null,null,null,null,null,[["102224360723365489932","102224360723365489932"],1430497808139701],2,30,[1],["102224360723365489932","102224360723365489932"],1430497801138000,1430497808139701,1430497801138000,null,null,[[[2,["+14011234567",["(401) 123-4567","+1 401-123-4567",1,"US",0,0]]],0,1]],0],[],[],null,[[["105510613398923491294","105510613398923491294"],0],[["102224360723365489932","102224360723365489932"],1430497808139701]],0,2,1,1,[["102224360723365489932","102224360723365489932"],["105510613398923491294","105510613398923491294"]],[[["105510613398923491294","105510613398923491294"],"Bo Tenström",1,null,2,1],[["102224360723365489932","102224360723365489932"],"Bo Tenström",2,["+14017654321",["(401) 765-4321","+1 401-765-4321",1,"US",1,0] ],3,2]],null,0,null,[1],1],[[["UgxjmN5ygMnYI6ZRPZp4AaABAQ"],["102224360723365489932","102224360723365489932"],1430497808139701,[["102224360723365489932","102224360723365489932"],"1289503288794"],null,0,[null,[],[[[0,"hey",[0,0,0,0]]],[]]],null,null,null,null,"7zbr7sUt_No7zbr8i4WRTa",null,null,1,2,1,null,null,[1],null,null,1,1430497808139701]],null,null,null,[]],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],1,null,[null,null,null,null,null,null,[["102224360723365489932","102224360723365489932"],1430497844252252],2,30,[1],["110994664963851875523","110994664963851875523"],1430497826216000,1430497904083513,1430497840649000,null,null,[[[1],1]],0],[],[],null,[[["102224360723365489932","102224360723365489932"],1430497844252252],[["110994664963851875523","110994664963851875523"],0]],0,2,1,1,[["110994664963851875523","110994664963851875523"],["102224360723365489932","102224360723365489932"]],[[["102224360723365489932","102224360723365489932"],"Bo Tenström",2,null,2,2],[["110994664963851875523","110994664963851875523"],"Martin Algesten",2,null,2,2]],null,0,null,[1],1],[[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["110994664963851875523","110994664963851875523"],1430497831165769,[["102224360723365489932","102224360723365489932"]],null,0,[null,[],[[[0,"the second",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrBWycNlt",null,null,1,2,1,null,null,[1],null,null,1,1430497831165769],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["102224360723365489932","102224360723365489932"],1430497844252252,[["102224360723365489932","102224360723365489932"],"260429275674"],null,0,[null,[],[[[0,"test123",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrD7DR5bM",null,null,1,2,1,null,null,[1],null,null,1,1430497844252252],[["UgzJilj2Tg_oqk5EhEp4AaABAQ"],["110994664963851875523","110994664963851875523"],1430497904083513,[["102224360723365489932","102224360723365489932"]],null,0,[null,[],[[[0,"the second one",[0,0,0,0]]],[]]],null,null,null,null,"7zbrAwdAT-g7zbrKQdW4ZV",null,null,1,2,1,null,null,[1],null,null,1,1430497904083513]],null,null,null,[]]] cmp3 = require './convstate.json' From ac646dd2058c22a89af5f5adb94bc1101d45b97c Mon Sep 17 00:00:00 2001 From: WiNGC Date: Thu, 25 Feb 2016 18:51:06 -0800 Subject: [PATCH 05/13] Added a new method to get entity by phone number in e164. It could be used to send SMS to such phone number. Accordingly, there is new field introduced to CLIENT_GET_ENTITY_BY_ID_RESPONSE. The logic should work like this: 1) Call getentitybyphonenumber and wait for response; 2) Parse the response to try read the entity from result.unknown.entities prior to the one from result.entities. If there are duplicated ones existing in both entities, use the one that unique in result.unknown.entieies. The logic behind should be the one from result.entities are Google account chat id but the differnt one from unknown should be the account's phone number. 3) Call createconversation with such chat_id, and then just sendchatmessage to the new conversation, with delivery medium as Google Voice. --- src/client.coffee | 9 +++++++++ src/schema.coffee | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/client.coffee b/src/client.coffee index f28b6ca..9a35550 100644 --- a/src/client.coffee +++ b/src/client.coffee @@ -478,6 +478,15 @@ module.exports = class Client extends EventEmitter max_results ] + # Return information from a phone number in e164 + getentitybyphonenumber: (e164) -> + @chatreq.req('contacts/getentitybyid', [ + @_requestBodyHeader() + None + [[null, null, null, e164, null, true]], + [1, 2] + ], false).then (body) -> + CLIENT_GET_ENTITY_BY_ID_RESPONSE.parse body # Return information about a list of chat_ids getentitybyid: (chat_ids) -> diff --git a/src/schema.coffee b/src/schema.coffee index 76b2d3e..2afcefb 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -463,6 +463,8 @@ s.CLIENT_GET_ENTITY_BY_ID_RESPONSE = Message([ None, Field() # 'cgebirp' 'response_header', s.CLIENT_RESPONSE_HEADER 'entities', RepeatedField(s.CLIENT_ENTITY) + 'unknown', RepeatedField(Message([None, Field() + 'entities', RepeatedField(s.CLIENT_ENTITY)])) ]) module.exports = s From c3bb30b8c953f290b4d5813e04ffcc554fdf69b0 Mon Sep 17 00:00:00 2001 From: WiNGC Date: Tue, 12 Apr 2016 19:54:27 -0700 Subject: [PATCH 06/13] Added some informaiton of image attachment from my investigation. --- src/schema.coffee | 62 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/src/schema.coffee b/src/schema.coffee index 2afcefb..407ff17 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -61,14 +61,19 @@ s.ClientConversationStatus = ACTIVE : 2 LEFT : 3 - s.SegmentType = TEXT : 0 LINE_BREAK : 1 LINK : 2 +s.ItemType = + THING : 0 + PLUS_PHOTO : 249 # Google Plus Photo + PLACE : 335 # Google Map Place + PLACE_V2 : 340 # Google Map Place v2 + s.MembershipChangeType = JOIN : 1 @@ -254,10 +259,59 @@ s.MESSAGE_SEGMENT = Message([ s.MESSAGE_ATTACHMENT = Message([ 'embed_item', Message([ - # 249 (PLUS_PHOTO), 340, 335, 0 - 'type_', RepeatedField(Field()) - 'data', Field() # can be a dict + 'type', RepeatedField(EnumField(s.ItemType)) + 'id', Field() + 'plus_photo', Field() # TODO: The PlusPhoto. The doc says its order is 27639957. How does the schema definition work out for that huge number? + 'place', Field() # No need to handle place yet. Leave as it is. The doc says its order number is 35825640 though. ]) + ### + Here is a piece of sample of this "embed_item". Appearntly the "27639957" is not the order number as other fields. It is a key thing. + [ + { + "embed_item": { + "type": [ + "PLUS_PHOTO" + ], + "id": { + "27639957": [ + [ + "https://plus.google.com/photos/albums/pj6pucrgrqo5mu6slno0afl5b31evvdjd?pid=6272865216622280562&oid=107991993313682235135", + null, + null, + "https://lh3.googleusercontent.com/-XUrYEVSVXbg/Vw2xrfCsv3I/AAAAAAAAAaY/wDQpy4mvv3YSXZgG-GLmsG_RIjC4Ktmgw/s0/doge.png", + null, + null, + null, + null, + null, + 375, + 360 + ], + "107991993313682235135", + "6272865212899898545", + "6272865216622280562", + null, + "https://lh3.googleusercontent.com/-XUrYEVSVXbg/Vw2xrfCsv3I/AAAAAAAAAaY/wDQpy4mvv3YSXZgG-GLmsG_RIjC4Ktmgw/s0/doge.png", + null, + null, + null, + "https://lh3.googleusercontent.com/TmefgSp3HC6pm6YKI0ZlID38WyH637fuLRvYrhZ2G4KxRdAl8MdpJpH_tazfpFyUbi8N", + null, + null, + 1, + [ + "BABEL_STREAM_ID", + "BABEL_UNIQUE_ID_8947994d-7a88-458c-ad9f-bd5bda65d684", + "shared_group_6272865175882303570" + ] + ] + }, + "plus_photo": null, + "place": null + } + } + ] + ### ]) s.CLIENT_CHAT_MESSAGE = Message([ From 0e0b15c6f6472811008fcb7d983132a2c64a0000 Mon Sep 17 00:00:00 2001 From: WiNGC Date: Tue, 12 Apr 2016 19:54:27 -0700 Subject: [PATCH 07/13] Added some informaiton of image attachment from my investigation. --- src/schema.coffee | 62 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/src/schema.coffee b/src/schema.coffee index 76b2d3e..e5094bd 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -61,14 +61,19 @@ s.ClientConversationStatus = ACTIVE : 2 LEFT : 3 - s.SegmentType = TEXT : 0 LINE_BREAK : 1 LINK : 2 +s.ItemType = + THING : 0 + PLUS_PHOTO : 249 # Google Plus Photo + PLACE : 335 # Google Map Place + PLACE_V2 : 340 # Google Map Place v2 + s.MembershipChangeType = JOIN : 1 @@ -254,10 +259,59 @@ s.MESSAGE_SEGMENT = Message([ s.MESSAGE_ATTACHMENT = Message([ 'embed_item', Message([ - # 249 (PLUS_PHOTO), 340, 335, 0 - 'type_', RepeatedField(Field()) - 'data', Field() # can be a dict + 'type', RepeatedField(EnumField(s.ItemType)) + 'id', Field() + 'plus_photo', Field() # TODO: The PlusPhoto. The doc says its order is 27639957. How does the schema definition work out for that huge number? + 'place', Field() # No need to handle place yet. Leave as it is. The doc says its order number is 35825640 though. ]) + ### + Here is a piece of sample of this "embed_item". Appearntly the "27639957" is not the order number as other fields. It is a key thing. + [ + { + "embed_item": { + "type": [ + "PLUS_PHOTO" + ], + "id": { + "27639957": [ + [ + "https://plus.google.com/photos/albums/pj6pucrgrqo5mu6slno0afl5b31evvdjd?pid=6272865216622280562&oid=107991993313682235135", + null, + null, + "https://lh3.googleusercontent.com/-XUrYEVSVXbg/Vw2xrfCsv3I/AAAAAAAAAaY/wDQpy4mvv3YSXZgG-GLmsG_RIjC4Ktmgw/s0/doge.png", + null, + null, + null, + null, + null, + 375, + 360 + ], + "107991993313682235135", + "6272865212899898545", + "6272865216622280562", + null, + "https://lh3.googleusercontent.com/-XUrYEVSVXbg/Vw2xrfCsv3I/AAAAAAAAAaY/wDQpy4mvv3YSXZgG-GLmsG_RIjC4Ktmgw/s0/doge.png", + null, + null, + null, + "https://lh3.googleusercontent.com/TmefgSp3HC6pm6YKI0ZlID38WyH637fuLRvYrhZ2G4KxRdAl8MdpJpH_tazfpFyUbi8N", + null, + null, + 1, + [ + "BABEL_STREAM_ID", + "BABEL_UNIQUE_ID_8947994d-7a88-458c-ad9f-bd5bda65d684", + "shared_group_6272865175882303570" + ] + ] + }, + "plus_photo": null, + "place": null + } + } + ] + ### ]) s.CLIENT_CHAT_MESSAGE = Message([ From 96c4f401646311fea3877bf35eab6f8bf88ae0fb Mon Sep 17 00:00:00 2001 From: nave7693 Date: Wed, 13 Apr 2016 22:10:39 -0700 Subject: [PATCH 08/13] Added the necessary schema objects and the DictField class to be able to parse objects coming from hangout --- src/pblite.coffee | 16 +++++++- src/schema.coffee | 96 ++++++++++++++++++++++------------------------- 2 files changed, 60 insertions(+), 52 deletions(-) diff --git a/src/pblite.coffee b/src/pblite.coffee index 4177215..5a7b65f 100644 --- a/src/pblite.coffee +++ b/src/pblite.coffee @@ -25,6 +25,20 @@ class EnumField return k for k, v of @enms when input == v return {} +class DictField + constructor: (dict) -> + return new DictField(dict) unless this instanceof DictField + @dict = dict + parse: (input) -> + return null unless input + return null if input == undefined + input = input.toString() if input instanceof Buffer + obj = if typeis input, 'string' then eval input else input + out = {} + for prop, val of @dict + out[prop] = val.parse obj[prop] if obj[prop] + out + class RepeatedField constructor: (field) -> return new RepeatedField(field) unless this instanceof RepeatedField @@ -53,4 +67,4 @@ class Message out[k] = v.parse val if k out -module.exports = {Field, BooleanField, EnumField, RepeatedField, Message} +module.exports = {Field, BooleanField, EnumField, DictField, RepeatedField, Message} diff --git a/src/schema.coffee b/src/schema.coffee index e5094bd..559098c 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -1,4 +1,4 @@ -{Field, BooleanField, EnumField, RepeatedField, Message} = require './pblite' +{Field, BooleanField, EnumField, DictField, RepeatedField, Message} = require './pblite' s = {} @@ -73,7 +73,13 @@ s.ItemType = PLUS_PHOTO : 249 # Google Plus Photo PLACE : 335 # Google Map Place PLACE_V2 : 340 # Google Map Place v2 - + +s.MediaType = + + MEDIA_TYPE_UNKNOWN : 0 + MEDIA_TYPE_PHOTO : 1 + MEDIA_TYPE_ANIMATED_PHOTO : 4 + s.MembershipChangeType = JOIN : 1 @@ -257,61 +263,49 @@ s.MESSAGE_SEGMENT = Message([ ]) ]) +s.PLUS_PHOTO_THUMBNAIL = Message([ + 'url', Field() + None, Field() + None, Field() + 'image_url', Field() + None, Field() + None, Field() + None, Field() + None, Field() + None, Field() + 'width_px', Field() + 'height_px', Field() +]) + +s.PLUS_PHOTO = Message([ + 'thumbnail', s.PLUS_PHOTO_THUMBNAIL + 'owner_obfuscated_id', Field() # e.g. "103730981268153889186", + 'album_id', Field() # e.g. "6272415246136908337", + 'photo_id', Field() # e.g. "6273187366351249938", + None, Field() + 'url', Field() + None, Field() + None, Field() + None, Field() + 'original_content_url', Field() + None, Field() + None, Field() + 'media_type', EnumField(s.MediaType) + 'stream_id', RepeatedField(Field()) +]) + +s.EMBED_ITEM = DictField({ + '27639957': s.PLUS_PHOTO, + '35825640': Field() # not supporting maps yet +}) + s.MESSAGE_ATTACHMENT = Message([ 'embed_item', Message([ 'type', RepeatedField(EnumField(s.ItemType)) - 'id', Field() + 'id', s.EMBED_ITEM # this is a dictionary, which is like an ordinary object that has members that need to be looked up using a tag number 'plus_photo', Field() # TODO: The PlusPhoto. The doc says its order is 27639957. How does the schema definition work out for that huge number? 'place', Field() # No need to handle place yet. Leave as it is. The doc says its order number is 35825640 though. ]) - ### - Here is a piece of sample of this "embed_item". Appearntly the "27639957" is not the order number as other fields. It is a key thing. - [ - { - "embed_item": { - "type": [ - "PLUS_PHOTO" - ], - "id": { - "27639957": [ - [ - "https://plus.google.com/photos/albums/pj6pucrgrqo5mu6slno0afl5b31evvdjd?pid=6272865216622280562&oid=107991993313682235135", - null, - null, - "https://lh3.googleusercontent.com/-XUrYEVSVXbg/Vw2xrfCsv3I/AAAAAAAAAaY/wDQpy4mvv3YSXZgG-GLmsG_RIjC4Ktmgw/s0/doge.png", - null, - null, - null, - null, - null, - 375, - 360 - ], - "107991993313682235135", - "6272865212899898545", - "6272865216622280562", - null, - "https://lh3.googleusercontent.com/-XUrYEVSVXbg/Vw2xrfCsv3I/AAAAAAAAAaY/wDQpy4mvv3YSXZgG-GLmsG_RIjC4Ktmgw/s0/doge.png", - null, - null, - null, - "https://lh3.googleusercontent.com/TmefgSp3HC6pm6YKI0ZlID38WyH637fuLRvYrhZ2G4KxRdAl8MdpJpH_tazfpFyUbi8N", - null, - null, - 1, - [ - "BABEL_STREAM_ID", - "BABEL_UNIQUE_ID_8947994d-7a88-458c-ad9f-bd5bda65d684", - "shared_group_6272865175882303570" - ] - ] - }, - "plus_photo": null, - "place": null - } - } - ] - ### ]) s.CLIENT_CHAT_MESSAGE = Message([ From 8649cb4905cfe25a94cf0f6e5cc5670221a72ac9 Mon Sep 17 00:00:00 2001 From: nave7693 Date: Mon, 18 Apr 2016 16:32:50 -0700 Subject: [PATCH 09/13] Code review feedback --- src/schema.coffee | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/schema.coffee b/src/schema.coffee index 559098c..5ef2326 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -279,9 +279,9 @@ s.PLUS_PHOTO_THUMBNAIL = Message([ s.PLUS_PHOTO = Message([ 'thumbnail', s.PLUS_PHOTO_THUMBNAIL - 'owner_obfuscated_id', Field() # e.g. "103730981268153889186", - 'album_id', Field() # e.g. "6272415246136908337", - 'photo_id', Field() # e.g. "6273187366351249938", + 'owner_obfuscated_id', Field() + 'album_id', Field() + 'photo_id', Field() None, Field() 'url', Field() None, Field() @@ -294,6 +294,7 @@ s.PLUS_PHOTO = Message([ 'stream_id', RepeatedField(Field()) ]) +# Special numbers make up the property names of things in the embedded item s.EMBED_ITEM = DictField({ '27639957': s.PLUS_PHOTO, '35825640': Field() # not supporting maps yet @@ -302,9 +303,7 @@ s.EMBED_ITEM = DictField({ s.MESSAGE_ATTACHMENT = Message([ 'embed_item', Message([ 'type', RepeatedField(EnumField(s.ItemType)) - 'id', s.EMBED_ITEM # this is a dictionary, which is like an ordinary object that has members that need to be looked up using a tag number - 'plus_photo', Field() # TODO: The PlusPhoto. The doc says its order is 27639957. How does the schema definition work out for that huge number? - 'place', Field() # No need to handle place yet. Leave as it is. The doc says its order number is 35825640 though. + 'data', s.EMBED_ITEM # this is a dictionary, which is like an ordinary object that has members that need to be looked up using a tag number ]) ]) From 9b5328770d4111426146f92e084e66af6d4cb3dc Mon Sep 17 00:00:00 2001 From: nave7693 Date: Mon, 18 Apr 2016 17:02:33 -0700 Subject: [PATCH 10/13] Added a test for EMBED_ITEM --- test/test-initparse.coffee | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/test-initparse.coffee b/test/test-initparse.coffee index 6a9d6bd..cf0329c 100644 --- a/test/test-initparse.coffee +++ b/test/test-initparse.coffee @@ -3,7 +3,8 @@ deql = assert.deepEqual {CLIENT_GET_SELF_INFO_RESPONSE INITIAL_CLIENT_ENTITIES, -CLIENT_CONVERSATION_STATE_LIST} = require '../src/schema' +CLIENT_CONVERSATION_STATE_LIST, +EMBED_ITEM} = require '../src/schema' msg1 = ["cgsirp",[1,null,"","1950326504872917925",1430493729941000],[null,null,null,null,null,null,null,[1,0,[],null,null,null,null,null,[[]]],["102224360723365489932","102224360723365489932"],[1,"Bo Tenström","Bo","//lh5.googleusercontent.com/-99B0CMsSo68/AAAAAAAAAAI/AAAAAAAAABI/v8oOeHFwNSI/photo.jpg",["botenstrom2@gmail.com"],[],null,null,null,null,null,2,[],[]],null,null,2,null,0,0,0],0,[],[0,null,0],[0],[[],[],2],[[8,0],[9,1],[22,0],[19,1],[10,1],[11,1],[14,0],[20,0],[17,0],[16,0],[23,0],[24,0],[27,0],[5,1],[6,1],[1,0],[2,1],[7,1],[3,1],[4,1],[29,1],[13,0],[12,0],[15,0],[28,0]],[1],1,[1,1],[null,[],[[5,0],[4,0],[2,0],[6,1],[1,0],[3,1]]],1,1,0,2,[],1,["SE",46],[],null,[1]] @@ -33,3 +34,12 @@ describe 'CLIENT_CONVERSATION_STATE_LIST', -> it 'parses', -> deql CLIENT_CONVERSATION_STATE_LIST.parse(msg3), cmp3 + +msg4 = { "27639957": [["https://plus.google.com/photos/albums/p16geqve3h5t3tqdn4odhtha2j5lqkale?pid=6275042227379600450&oid=103730981268153889186", null, null, "https://lh3.googleusercontent.com/-QUwpEWamKew/VxVtqMGJfEI/AAAAAAAAAFM/jeRZI6e_DUIZkUVdhXoNbQNiY8UxBGvwwCK8B/s0/2016-04-18.jpg", null, null, null, null, null, 768, 401], "103730981268153889186", "6272415246136908337", "6275042227379600450", null, "https://lh3.googleusercontent.com/-QUwpEWamKew/VxVtqMGJfEI/AAAAAAAAAFM/jeRZI6e_DUIZkUVdhXoNbQNiY8UxBGvwwCK8B/s0/2016-04-18.jpg", null, null, null, "https://lh3.googleusercontent.com/nUIH-qp7Cgeei1PAAdirnxrtS2Ryc6A2Tai2gzOdR0oIAPxhIj9BtSkTkYQWxalPvr4", null, null, 1, ["shared_group_6275042227379600450", "BABEL_STREAM_ID", "BABEL_UNIQUE_ID_1e30efc4-8f46-4f58-ab52-c2b8ec77a3a7"]] } + +cmp4 = {"27639957":{"album_id":"6272415246136908337","media_type":"MEDIA_TYPE_PHOTO","original_content_url":"https://lh3.googleusercontent.com/nUIH-qp7Cgeei1PAAdirnxrtS2Ryc6A2Tai2gzOdR0oIAPxhIj9BtSkTkYQWxalPvr4","owner_obfuscated_id":"103730981268153889186","photo_id":"6275042227379600450","stream_id":["shared_group_6275042227379600450","BABEL_STREAM_ID","BABEL_UNIQUE_ID_1e30efc4-8f46-4f58-ab52-c2b8ec77a3a7"],"thumbnail":{"height_px":401,"image_url":"https://lh3.googleusercontent.com/-QUwpEWamKew/VxVtqMGJfEI/AAAAAAAAAFM/jeRZI6e_DUIZkUVdhXoNbQNiY8UxBGvwwCK8B/s0/2016-04-18.jpg","url":"https://plus.google.com/photos/albums/p16geqve3h5t3tqdn4odhtha2j5lqkale?pid=6275042227379600450&oid=103730981268153889186","width_px":768},"url":"https://lh3.googleusercontent.com/-QUwpEWamKew/VxVtqMGJfEI/AAAAAAAAAFM/jeRZI6e_DUIZkUVdhXoNbQNiY8UxBGvwwCK8B/s0/2016-04-18.jpg"}} + +describe 'EMBED_ITEM', -> + + it 'parses', -> + deql EMBED_ITEM.parse(msg4), cmp4 From d976367ec54664f9c0857aa582a3c4b19759b001 Mon Sep 17 00:00:00 2001 From: WiNGC Date: Mon, 18 Apr 2016 17:23:40 -0700 Subject: [PATCH 11/13] Get rid of example of attachment as comment in code. The coffee-script engine has problem to parse them when executing npm test. --- src/schema.coffee | 48 ----------------------------------------------- 1 file changed, 48 deletions(-) diff --git a/src/schema.coffee b/src/schema.coffee index 407ff17..8f95679 100644 --- a/src/schema.coffee +++ b/src/schema.coffee @@ -264,54 +264,6 @@ s.MESSAGE_ATTACHMENT = Message([ 'plus_photo', Field() # TODO: The PlusPhoto. The doc says its order is 27639957. How does the schema definition work out for that huge number? 'place', Field() # No need to handle place yet. Leave as it is. The doc says its order number is 35825640 though. ]) - ### - Here is a piece of sample of this "embed_item". Appearntly the "27639957" is not the order number as other fields. It is a key thing. - [ - { - "embed_item": { - "type": [ - "PLUS_PHOTO" - ], - "id": { - "27639957": [ - [ - "https://plus.google.com/photos/albums/pj6pucrgrqo5mu6slno0afl5b31evvdjd?pid=6272865216622280562&oid=107991993313682235135", - null, - null, - "https://lh3.googleusercontent.com/-XUrYEVSVXbg/Vw2xrfCsv3I/AAAAAAAAAaY/wDQpy4mvv3YSXZgG-GLmsG_RIjC4Ktmgw/s0/doge.png", - null, - null, - null, - null, - null, - 375, - 360 - ], - "107991993313682235135", - "6272865212899898545", - "6272865216622280562", - null, - "https://lh3.googleusercontent.com/-XUrYEVSVXbg/Vw2xrfCsv3I/AAAAAAAAAaY/wDQpy4mvv3YSXZgG-GLmsG_RIjC4Ktmgw/s0/doge.png", - null, - null, - null, - "https://lh3.googleusercontent.com/TmefgSp3HC6pm6YKI0ZlID38WyH637fuLRvYrhZ2G4KxRdAl8MdpJpH_tazfpFyUbi8N", - null, - null, - 1, - [ - "BABEL_STREAM_ID", - "BABEL_UNIQUE_ID_8947994d-7a88-458c-ad9f-bd5bda65d684", - "shared_group_6272865175882303570" - ] - ] - }, - "plus_photo": null, - "place": null - } - } - ] - ### ]) s.CLIENT_CHAT_MESSAGE = Message([ From d2aa2c0aca9277960ff5dd5b6e47c8616fa3e491 Mon Sep 17 00:00:00 2001 From: WiNGC Date: Fri, 27 May 2016 16:28:31 -0700 Subject: [PATCH 12/13] Added a new method that takes file buffer as paramter directly to upload image. I highly suspect the uploadimage would work though from what I have experienced. --- src/client.coffee | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/client.coffee b/src/client.coffee index 13a31fe..12978e7 100644 --- a/src/client.coffee +++ b/src/client.coffee @@ -568,6 +568,44 @@ module.exports = class Client extends EventEmitter log.debug 'image resume upload finished' body?.sessionStatus?.additionalInfo?['uploader_service.GoogleRupioAdditionalInfo']?.completionInfo?.customerSpecificInfo?.photoid + # Uploads an image as buffer that can be later attached to a chat message. + # + # buffer is the buffer that contains the image file content. + # + # filename is the name of the file. + # + # returns an image_id that can be used in sendchatmessage + uploadimagebuffer: (buffer, filename, timeout=30000) => + size = buffer.length; + puturl = null + chatreq = @chatreq + log.debug 'image resume upload prepare' + chatreq.baseReq IMAGE_UPLOAD_URL, 'application/x-www-form-urlencoded;charset=UTF-8' + , { + protocolVersion: "0.8" + createSessionRequest: + fields: [{ + external: { + filename, + size, + put: {}, + name: 'file' + } + }] + } + .then (body) -> + puturl = body?.sessionStatus?.externalFieldTransfers?[0]?.putInfo?.url + log.debug 'image resume upload to:', puturl + .then () -> + log.debug 'image resume uploading' + chatreq.baseReq puturl, 'application/octet-stream', buffer, true, timeout + .then (body) -> + log.debug 'image resume upload finished' + return Q.resolve body?.sessionStatus?.additionalInfo?['uploader_service.GoogleRupioAdditionalInfo']?.completionInfo?.customerSpecificInfo?.photoid + .fail (err) -> + log.error 'uploadImageBuffer failed', err + Q.reject err + # aliases list aliases = [ 'logLevel', @@ -591,7 +629,8 @@ aliases = [ 'searchEntities', 'getEntityById', 'sendEasteregg', - 'uploadImage' + 'uploadImage', + 'uploadImageBuffer' ] # set aliases From 37f6d3d7a219dfe9d50e2997469603355d4997eb Mon Sep 17 00:00:00 2001 From: WiNGC Date: Thu, 17 Nov 2016 11:18:26 -0800 Subject: [PATCH 13/13] Merged with remote change. --- src/client.coffee | 0 src/pblite.coffee | 0 src/schema.coffee | 0 test/test-initparse.coffee | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/client.coffee mode change 100644 => 100755 src/pblite.coffee mode change 100644 => 100755 src/schema.coffee mode change 100644 => 100755 test/test-initparse.coffee diff --git a/src/client.coffee b/src/client.coffee old mode 100644 new mode 100755 diff --git a/src/pblite.coffee b/src/pblite.coffee old mode 100644 new mode 100755 diff --git a/src/schema.coffee b/src/schema.coffee old mode 100644 new mode 100755 diff --git a/test/test-initparse.coffee b/test/test-initparse.coffee old mode 100644 new mode 100755