Commit a46988c0ef0647243e17a60f5c91eca24c68f79d

Authored by Matti Virkkunen
0 parents

Moved things over from purple-line

README.md 0 โ†’ 100644
  1 +++ a/README.md
  1 +LINE instant messenger protocol
  2 +===============================
  3 +
  4 +I moved this to its own repository for clarity.
  5 +
  6 +Files:
  7 +
  8 +* *line.thrift* - a hopefully complete Apache Thrift interface file for the protocol
  9 +* *line-protocol.md* - the rest of the implementation details and notes that should be sufficient to implement a client
... ...
line-protocol.md 0 โ†’ 100644
  1 +++ a/line-protocol.md
  1 +LINE instant messenger protocol
  2 +===============================
  3 +
  4 +Matti Virkkunen <mvirkkunen@gmail.com>
  5 +
  6 +Document is accurate as of 2014-05-04.
  7 +
  8 +This unofficial document describes the LINE (by LINE Corporation/Naver) instant messenger protocol.
  9 +The information is based mostly on reverse engineering and therefore accuracy is not guaranteed.
  10 +
  11 +Also, this document is unfinished. I'm expanding it as I go.
  12 +
  13 +Overview
  14 +--------
  15 +
  16 +LINE as a whole consists of a number of web services because of their multitude of apps and
  17 +subsystems, but the only service that's needed for replicating their desktop IM client's
  18 +functionality is the TalkService.
  19 +
  20 +The protocol is based on a request-response architecture over HTTP(S), with a long poll return
  21 +channel. Apache Thrift is used for serialization of message data.
  22 +
  23 +Wire protocol
  24 +-------------
  25 +
  26 +File: line.thrift (a presumably complete Thrift interface file obtained via reverse engineering)
  27 +
  28 +The protocol is Apache Thrift TCompactProtocol via HTTPS to gd2.line.naver.jp:443. The HTTP request
  29 +path is /S4 for most requests. Some specific requests use a different path, specified where
  30 +relevant.
  31 +
  32 +Unencrypted HTTP also seems to work for the moment, but using it is a really bad idea security-wise.
  33 +Naver itself seems to be currently transitioning to 100% HTTPS.
  34 +
  35 +If using a keep-alive connection, headers from the first request can be persisted. Headers in
  36 +following requests can temporarily override the persisted value. An HTTP header called X-LS is also
  37 +involved. If you want to persist headers, you must remember the X-LS header value the server gives
  38 +you and send it back in the next request. The values seem to be integers. The name could be short
  39 +for "Line Server", and it's probably used so that load-balancers can direct the following responses
  40 +back to the same server that knows the headers.
  41 +
  42 +By using persistent headers it's possible to send each request with just two headers - X-LS and
  43 +Content-Length.
  44 +
  45 +The official protocol seems to be to first make one request to get an authentication key, and then
  46 +open a new connection so that the authentication key can be persisted along with the rest of the
  47 +headers for the following requests.
  48 +
  49 +Types and concepts
  50 +------------------
  51 +
  52 +Friends, chats and groups are identified by 32-digit hex GUIDs prefixed with one character for the
  53 +type.
  54 +
  55 +Internally any user is referred to as a Contact. Contacts are identified by a "mid" and the prefix
  56 +is "u" (presumably for "user")
  57 +
  58 +Chats are called Rooms and are identified by a "mid" which is prefixed by "r" (for "room"). Groups
  59 +are called Groups internally as well and are identified by an "id" which is prefixed with a "c"
  60 +(presumably for "chat").
  61 +
  62 +Any message is represented by a Message object. Message IDs are numeric but they are stored as
  63 +strings.
  64 +
  65 +Timestamps are millisecond precision UNIX time represented as 64-bit integers (TODO: check the
  66 +timezone just in case)
  67 +
  68 +Message authentication
  69 +----------------------
  70 +
  71 +The following HTTP headers are required for a successful request:
  72 +
  73 + X-Line-Application: DESKTOPWIN\t3.2.1.83\tWINDOWS\t5.1.2600-XP-x64
  74 + X-Line-Access: authToken
  75 +
  76 +The \t escape sequence represents a tab character. Other X-Line-Application names exist, but this is
  77 +one that works currently. An invalid application name results in an error. The authToken is
  78 +obtained via the login procedure.
  79 +
  80 +Object storage server
  81 +---------------------
  82 +
  83 +Media files are stored on a separate server at http://os.line.naver.jp/ which is internally referred
  84 +to as the "object storage server". Some files (such as message attachments) seem to require
  85 +authentication with the same protocol as above, but some files (such as buddy icons) don't seem to
  86 +require authentication.
  87 +
  88 +It serves files over both HTTP and HTTPS with the same authentication protocol as above.
  89 +
  90 +Login procedure
  91 +---------------
  92 +
  93 +This Thrift method issues a new authToken for an e-mail address and password combination:
  94 +
  95 + loginWithIdentityCredentialForCertificate(
  96 + IdentityProvider.LINE, // identityProvider
  97 + "test@example.com", // identifier (e-mail address)
  98 + "password", // password (in plain text)
  99 + true, // keepLoggedIn
  100 + "127.0.0.1", // accesslocation (presumably local IP?)
  101 + "hostname", // systemName (will show up in "Devices")
  102 + "") // certificate
  103 +
  104 +For the login request, the X-Line-Access header must be specified but the value can be anything. The
  105 +result structure is as follows:
  106 +
  107 + struct LoginResult {
  108 + 1: string authToken;
  109 + 2: certificate;
  110 + 3: verifier;
  111 + 4: pinCode;
  112 + 5: i32 type;
  113 + }
  114 +
  115 +After a successful login, the type is equal to 1 and the authToken field contains the X-Line-Access
  116 +value to use in subsequent requests.
  117 +
  118 +The official desktop client sends an encrypted e-mail/password involving RSA and no X-Line-Access
  119 +header, but it works just as fine in plain text. (TODO: Include description of RSA login procedure)
  120 +
  121 +Login verification procedure
  122 +----------------------------
  123 +
  124 +In current versions, LINE now requires you to verify your identity using a PIN code when logging in
  125 +to a desktop client for the first time from a "new location" based on geo-IP. This is obviously also
  126 +required when logging in with the desktop client for the very first time.
  127 +
  128 +When PIN verification is required, the login method returns a type of 3 instead of 1. The pinCode
  129 +field contains a PIN code to display to the user and the verifier field is set to a random token
  130 +that is used to identify this verification session. The token stays the same for the whole process.
  131 +
  132 +The client then issues an empty request to the HTTP path /Q with the X-Line-Access header set to the
  133 +verifier token. This request blocks until the user enters the correct PIN code on their mobile
  134 +device.
  135 +
  136 +There doesn't seem to be a limit for incorrect PIN entries on the mobile device, but there is
  137 +currently a three minute time limit. After this the token expires. The client keeps track of the
  138 +time limit locally and aborts the request when it's over.
  139 +
  140 +A success response from /Q is JSON containing the following:
  141 +
  142 + {
  143 + "timestamp": "946684800000",
  144 + "result": {
  145 + "verifier": "the_verifier_token",
  146 + "authPhase": "QRCODE_VERIFIED"
  147 + }
  148 + }
  149 +
  150 +After this response is received the client issues a loginWithVerifierForCertificate() call with the
  151 +verifier token as the parameter. The server then returns a normal LoginReply message with the usual
  152 +authToken.
  153 +
  154 +If the token has already expired the response from /Q looks like the following:
  155 +
  156 + {
  157 + "timestamp": "946684800000",
  158 + "errorCode": "404",
  159 + "errorMessage": "key+is+not+found%3A+the_verifier_token+NOT_FOUND"
  160 + }
  161 +
  162 +Initial sync
  163 +------------
  164 +
  165 +After logging in the client sends out a sequence of requests to synchronize with the server. It
  166 +seems some messages are not always sent - the client could be storing data locally somewhere and
  167 +comparing with the revision ID from getLastOpRevision()
  168 +
  169 +(TODO: Update list for current client)
  170 +
  171 + getLastOpRevision()
  172 +
  173 +Gets the revision ID to use for the long poll return channel later. It's fetched first to ensure
  174 +nothing is missed even if something happens during the sync procedure.
  175 +
  176 + getProfile()
  177 +
  178 +Gets the currently logged in user's profile, which includes their display name and status message
  179 +and so forth.
  180 +
  181 + getBlockedContactIds()
  182 +
  183 +List of blocked user IDs.
  184 +
  185 + getRecommendationIds()
  186 +
  187 +List of suggested friend IDs.
  188 +
  189 + getBlockedRecommendationIds()
  190 +
  191 +List of suggested friend IDs that have been dismissed (why can't the previous method just not
  192 +return these...?)
  193 +
  194 + getAllContactIds()
  195 +
  196 +Gets all contact IDs added as friends.
  197 +
  198 + getContacts(contactIds) - with IDs from the previous methods
  199 +
  200 +Gets details for the users.
  201 +
  202 + getGroupIdsJoined()
  203 +
  204 +Gets all groups current user is a member of.
  205 +
  206 + getGroups(groupIds) - with IDs from the previous method
  207 +
  208 +Gets details for the groups. This included member lists.
  209 +
  210 +Managing the contact list
  211 +-------------------------
  212 +
  213 +Contacts have multiple statuses.
  214 +
  215 +FRIEND = appears on friend list, unless hidden.
  216 +
  217 +RECOMMEND = appears on "recommended contacts" list.
  218 +
  219 +DELETE = used in notifications only AFAIK, to notify that a friend has been completely deleted.
  220 +
  221 +Each state also has a _BLOCKED version where the current user will not receive messages from the
  222 +user. Friends also have a "hidden" status, that is set via the CONTACT_SETTING_CONTACT_HIDE setting
  223 +flag. Blocking is done via blockContact/unblockContact.
  224 +
  225 +There is no separate function to delete a contact for some reason, instead it's done by setting the
  226 +CONTACT_SETTING_DELETE setting. Even though it's a setting, this is equivalent to really deleting
  227 +the friend - they won't appear on getallContactIds() anymore. (FIXME: actually test this...)
  228 +
  229 +Sending messages
  230 +----------------
  231 +
  232 +Messages are sent using the sendMessage() function.
  233 +
  234 + sendMessage(seq, msg)
  235 +
  236 +The seq parameter doesn't seem to be matter, and can be sent as zero. The msg parameter is the
  237 +Message object to send.
  238 +
  239 +The only required fields for a text message are "to", which can be the ID for any valid message
  240 +recipient (user, chat or group), and the "text" field which is the text content to send. Other
  241 +message types involve the contentMetadata fields and possibly uploading files to a separate server.
  242 +
  243 +The return value from sendMessage is a partial Message object that only contains the fields "id",
  244 +"createdTime" and "from". The ID is a numeric string that can be used to refer to that message
  245 +later.
  246 +
  247 +Message types
  248 +-------------
  249 +
  250 +LINE supports various types of messages from simple text messages to pictures and video. Each
  251 +message has a contentType field that specifies the type of content, and some messages include
  252 +attached files from various locations.
  253 +
  254 +Messages can contain extra attributes in the contentMetadata map. One globally used attribute is
  255 +"BOT_CHECK" which is included with a value of "1" for automatic messages I've received from
  256 +"official accounts" - this could be an auto-reply indicator.
  257 +
  258 +### NONE (0) (actually text)
  259 +
  260 +The first contentType is called NONE internally but is actually text. It's the simplest content
  261 +type. The text field contains the message content encoded in UTF-8.
  262 +
  263 +The only thing to watch out for is emoji which are sent as Unicode private use area codepoints.
  264 +
  265 +TODO: make a list of emoji
  266 +
  267 +### IMAGE (1)
  268 +
  269 +Image message content can be delivered in one of two ways.
  270 +
  271 +For normal image messages, a preview image is included as a plain JPEG in the contentPreview field.
  272 +However, for some reason the official desktop client seems to ignore it and rather downloads
  273 +everything from the object storage server.
  274 +
  275 +The preview image URLs are http://os.line.naver.jp/os/m/MSGID/preview and the full-size image URL
  276 +are http://os.line.naver.jp/os/m/MSGID where MSGID is the message's id field.
  277 +
  278 +"Official accounts" broadcast messages to many clients at once, so their image message data is
  279 +stored on publicly accessible servers (currently seems to be Akamai CDN). For those messages no
  280 +embedded preview is included and the image URLs are stored in the contentMetadata map with the
  281 +following keys:
  282 +
  283 +* PREVIEW_URL = absolute URL for preview image
  284 +* DOWNLOAD_URL = absolute URL for full-size image
  285 +* PUBLIC = "TRUE" (haven't seen other values)
  286 +
  287 +As an example of a publicly available image message, have a Pikachu:
  288 +
  289 +http://dl-obs.official.line.naver.jp/r/talk/o/u3ae3691f73c7a396fb6e5243a8718915-1379585871
  290 +
  291 +Return channel
  292 +--------------
  293 +
  294 + fetchOperations(localRev, count)
  295 +
  296 +For incoming events, fetchOperations() calls to the HTTP path /P4 is used. Using the /P4 path
  297 +enables long polling, where the responses block until something happens or a timeout expires. An
  298 +HTTP 410 Gone response signals a timed out poll, in which case a new request should be issued.
  299 +
  300 +When new data arrives, a list of Operation objects is returned. Each Operation (except the end
  301 +marker) comes with a version number, and the next localRev should be the highest revision number
  302 +received.
  303 +
  304 +The official client uses a count parameter of 50.
  305 +
  306 +Operation data is contained either as a Message object in the message field, or in the string fields
  307 +param1-param3.
  308 +
  309 +In general NOTIFIED_* messages notify the current user about other users' actions, while their
  310 +non-NOTIFIED counterparts notify the current user about their own actions, in order to sync them
  311 +across devices.
  312 +
  313 +For many operations the official client doesn't seem to care about the fact that the param1-param3
  314 +fields contain the details of the operation and will rather re-fetch data with a get method instead.
  315 +For instance, many group member list changes will cause the client to do a getGroup(). This may be
  316 +either just lazy coding or a sign of the param parameters being phased out.
  317 +
  318 +The following is a list of operation types.
  319 +
  320 +### END_OF_OPERATION (0)
  321 +
  322 +Signifies the end of the list. This presumably means all operations were returned and none were left
  323 +out due to the count param. This message contains no data, not even a revision number, so don't
  324 +accidentally set your localRev to zero.
  325 +
  326 +### UPDATE_PROFILE (1)
  327 +
  328 +The current user updated their profile. Refresh using getProfile().
  329 +
  330 +* param1 = UpdateProfileAttributeAttr, which property was changed (possibly bitfield)
  331 +
  332 +### NOTIFIED_UPDATE_PROFILE (2)
  333 +
  334 +Another user updated their profile. Refresh using getContact[s]().
  335 +
  336 +* param1 = the user ID
  337 +* param2 = UpdateProfileAttributeAttr, which property was changed (possibly bitfield)
  338 +
  339 +### REGISTER_USERID (3)
  340 +
  341 +(Mystery)
  342 +
  343 +### ADD_CONTACT (4)
  344 +
  345 +The current user has added a contact as a friend.
  346 +
  347 +* param1 = ID of the user that was added
  348 +* param2 = (mystery - seen "0")
  349 +
  350 +### NOTIFIED_ADD_CONTACT (5)
  351 +
  352 +Another user has added the current user as a friend.
  353 +
  354 +* param1 = ID of the user that added the current user
  355 +
  356 +### BLOCK_CONTACT (6)
  357 +
  358 +The current user has blocked a contact.
  359 +
  360 +* param1 = ID of the user that was blocked
  361 +* param2 = (mystery, seen "NORMAL")
  362 +
  363 +### UNBLOCK_CONTACT (7)
  364 +
  365 +The current user has unblocked a contact.
  366 +
  367 +* param1 = ID of the user that was unblocked
  368 +* param2 = (mystery, seen "NORMAL")
  369 +
  370 +### CREATE_GROUP (9)
  371 +
  372 +The current user has created a group. The official client immediately fetches group details with
  373 +getGroup().
  374 +
  375 +* param1 = ID of the group.
  376 +
  377 +### UPDATE_GROUP (10)
  378 +
  379 +The current user has updated a group.
  380 +
  381 +* param1 = ID of the group
  382 +* param2 = (Maybe a bitfield of properties? 1 = name, 2 = picture)
  383 +
  384 +### NOTIFIED_UPDATE_GROUP (11)
  385 +
  386 +Another user has updated group the current user is a member of.
  387 +
  388 +* param1 = ID of the group
  389 +* param2 = ID of the user who updated the group
  390 +* param3 = (Maybe a bitfield of properties?)
  391 +
  392 +### INVITE_INTO_GROUP (12)
  393 +
  394 +The current user has invited somebody to join a group.
  395 +
  396 +* param1 = ID of the group
  397 +* param2 = ID of the user that has been invited
  398 +
  399 +### NOTIFIED_INVITE_INTO_GROUP (13)
  400 +
  401 +The current user has been invited to join a group.
  402 +
  403 +* param1 = ID of the group
  404 +* param2 = ID of the user who invited the current user
  405 +* param3 = ID of the current user
  406 +
  407 +### LEAVE_GROUP (14)
  408 +
  409 +The current user has left a group.
  410 +
  411 +* param1 = ID of the group
  412 +
  413 +### NOTIFIED_LEAVE_GROUP (15)
  414 +
  415 +Another user has left a group the current user is a member of.
  416 +
  417 +* param1 = ID of the group
  418 +* param2 = ID of the user that left the group
  419 +
  420 +### ACCEPT_GROUP_INVITATION (16)
  421 +
  422 +The current user has accepted a group invitation.
  423 +
  424 +* param1 = ID of the group
  425 +
  426 +### NOTIFIED_ACCEPT_GROUP_INVITATION (17)
  427 +
  428 +Another user has joined a group the current user is a member of.
  429 +
  430 +* param1 = ID of the group
  431 +* param2 = ID of the user that joined the group
  432 +
  433 +### KICKOUT_FROM_GROUP (18)
  434 +
  435 +The current user has removed somebody from a group.
  436 +
  437 +* param1 = ID of the group
  438 +* param2 = ID of the user that was removed
  439 +
  440 +### NOTIFIED_KICKOUT_FROM_GROUP (19)
  441 +
  442 +Another user has removed a user from a group. The removed user can also be the current user.
  443 +
  444 +* param1 = ID of the group
  445 +* param2 = ID of the user that removed the current user
  446 +* param3 = ID of the user that was removed
  447 +
  448 +### CREATE_ROOM (20)
  449 +
  450 +The current user has created a room.
  451 +
  452 +* param1 = ID of the room
  453 +
  454 +### INVITE_INTO_ROOM (21)
  455 +
  456 +The current user has invited users into a room.
  457 +
  458 +* param1 = ID of the room
  459 +* param2 = IDs of the users, multiple IDs are separated by U+001E INFORMATION SEPARATOR TWO
  460 +
  461 +### NOTIFIED_INVITE_INTO_ROOM (22)
  462 +
  463 +The current user has been invited into a room. Invitations to rooms to others are not actually sent
  464 +until a message is sent to the room.
  465 +
  466 +* param1 = ID of the room
  467 +* param2 = ID of the user that invited the current user
  468 +* param3 = IDs of the users in the room, multiple IDs are separated by U+001E INFORMATION SEPARATOR
  469 + TWO. The user ID in param2 is not included in this list.
  470 +
  471 +### LEAVE_ROOM (23)
  472 +
  473 +The current user has left a room. Seems to be immediately followed by SEND_CHAT_REMOVED (41).
  474 +
  475 +* param1 = ID of the room
  476 +
  477 +### NOTIFIED_LEAVE_ROOM (24)
  478 +
  479 +Another user has left a room.
  480 +
  481 +* param1 = ID of the room
  482 +* param2 = ID of the user that left
  483 +
  484 +### SEND_MESSAGE (25)
  485 +
  486 +Informs about a message that the current user sent. This is returned to all connected devices,
  487 +including the one that sent the message.
  488 +
  489 +* message = sent message
  490 +
  491 +### RECEIVE_MESSAGE (26)
  492 +
  493 +Informs about a received message that another user sent either to the current user or to a chat. The
  494 +message field contains the message.
  495 +
  496 +The desktop client doesn't seem to care about the included message data, but instead immediately
  497 +re-requests it using getNextMessages().
  498 +
  499 +* message = received message
  500 +
  501 +### RECEIVE_MESSAGE_RECEIPT (28)
  502 +
  503 +Informs that another user has read (seen) messages sent by the current user.
  504 +
  505 +* param1 = ID of the user that read the message
  506 +* param2 = IDs of the messages, multiple IDs are separated by U+001E INFORMATION SEPARATOR TWO
  507 +
  508 +### CANCEL_INVITATION_GROUP (31)
  509 +
  510 +The current user has canceled a group invitation.
  511 +
  512 +* param1 = ID of the group
  513 +* param2 = ID of the user whose invitation was canceled
  514 +
  515 +### NOTIFIED_CANCEL_INVITATION_GROUP (32)
  516 +
  517 +Another user has canceled a group invitation. The canceled invitation can also be that of the
  518 +current user.
  519 +
  520 +* param1 = ID of the group
  521 +* param2 = ID of the user that canceled the request (or invited them in the first place?)
  522 +* param3 = ID of the user whose invitation was canceled
  523 +
  524 +### REJECT_GROUP_INVITATION (34)
  525 +
  526 +The current user has rejected a group infication.
  527 +
  528 +* param1 = ID of the group
  529 +
  530 +### NOTIFIED_REJECT_GROUP_INVITATION (35)
  531 +
  532 +Presumably means another user has rejected a group invitation. However this message doesn't seem to
  533 +get sent.
  534 +
  535 +### UPDATE_SETTINGS (36)
  536 +
  537 +User settings have changed. Refresh with getSettingsAttributes() or getSettings()
  538 +
  539 +* param1 = probably bitfield of changed properties
  540 +* param2 = probably new value of property (seem things like "bF"/"bT" for a boolean attribute)
  541 +
  542 +### SEND_CHAT_CHECKED (40)
  543 +
  544 +### SEND_CHAT_REMOVED (41)
  545 +
  546 +The current user has cleared the history of a chat.
  547 +
  548 +* param1 = user ID or group ID or room ID
  549 +* param2 = seen "990915482402" - maybe an ID, it's similar to IDs
  550 +
  551 +### UPDATE_CONTACT (49)
  552 +
  553 +The current user's settings (e.g. hidden status) for a contact has changed. Refresh with
  554 +getContact[s]().
  555 +
  556 +* param1 = ID of the user that changed
  557 +* param2 = probably bitfield of changed properties
  558 +
  559 +### (Mystery) 60
  560 +
  561 +Meaning unknown. Has appeared after NOTIFIED_ACCEPT_GROUP_INVITATION and NOTIFIED_INVITE_INTO_ROOM.
  562 +
  563 +Seen the following parameters:
  564 +
  565 +* param1 = a group ID
  566 +* param2 = another user's ID
  567 +
  568 +### (Mystery) 61
  569 +
  570 +Meaning unknown. Has appeared after NOTIFIED_LEAVE_GROUP, KICKOUT_FROM_GROUP and
  571 +NOTIFIED_KICKOUT_FROM_GROUP and NOTIFIED_LEAVE_ROOM.
  572 +
  573 +Seen the following parameters:
  574 +
  575 +* param1 = a group ID
  576 +* param2 = another user's ID
  577 +* param3 = "0"
... ...
line.thrift 0 โ†’ 100644
  1 +++ a/line.thrift
  1 +// Auto-generated file
  2 +
  3 +enum ApplicationType {
  4 + IOS = 16;
  5 + IOS_RC = 17;
  6 + IOS_BETA = 18;
  7 + IOS_ALPHA = 19;
  8 + ANDROID = 32;
  9 + ANDROID_RC = 33;
  10 + ANDROID_BETA = 34;
  11 + ANDROID_ALPHA = 35;
  12 + WAP = 48;
  13 + WAP_RC = 49;
  14 + WAP_BETA = 50;
  15 + WAP_ALPHA = 51;
  16 + BOT = 64;
  17 + BOT_RC = 65;
  18 + BOT_BETA = 66;
  19 + BOT_ALPHA = 67;
  20 + WEB = 80;
  21 + WEB_RC = 81;
  22 + WEB_BETA = 82;
  23 + WEB_ALPHA = 83;
  24 + DESKTOPWIN = 96;
  25 + DESKTOPWIN_RC = 97;
  26 + DESKTOPWIN_BETA = 98;
  27 + DESKTOPWIN_ALPHA = 99;
  28 + DESKTOPMAC = 112;
  29 + DESKTOPMAC_RC = 113;
  30 + DESKTOPMAC_BETA = 114;
  31 + DESKTOPMAC_ALPHA = 115;
  32 + CHANNELGW = 128;
  33 + CHANNELGW_RC = 129;
  34 + CHANNELGW_BETA = 130;
  35 + CHANNELGW_ALPHA = 131;
  36 + CHANNELCP = 144;
  37 + CHANNELCP_RC = 145;
  38 + CHANNELCP_BETA = 146;
  39 + CHANNELCP_ALPHA = 147;
  40 + WINPHONE = 160;
  41 + WINPHONE_RC = 161;
  42 + WINPHONE_BETA = 162;
  43 + WINPHONE_ALPHA = 163;
  44 + BLACKBERRY = 176;
  45 + BLACKBERRY_RC = 177;
  46 + BLACKBERRY_BETA = 178;
  47 + BLACKBERRY_ALPHA = 179;
  48 + WINMETRO = 192;
  49 + WINMETRO_RC = 193;
  50 + WINMETRO_BETA = 194;
  51 + WINMETRO_ALPHA = 195;
  52 + S40 = 208;
  53 + S40_RC = 209;
  54 + S40_BETA = 210;
  55 + S40_ALPHA = 211;
  56 + CHRONO = 224;
  57 + CHRONO_RC = 225;
  58 + CHRONO_BETA = 226;
  59 + CHRONO_ALPHA = 227;
  60 + TIZEN = 256;
  61 + TIZEN_RC = 257;
  62 + TIZEN_BETA = 258;
  63 + TIZEN_ALPHA = 259;
  64 + VIRTUAL = 272;
  65 +}
  66 +
  67 +enum BuddyBannerLinkType {
  68 + BUDDY_BANNER_LINK_HIDDEN = 0;
  69 + BUDDY_BANNER_LINK_MID = 1;
  70 + BUDDY_BANNER_LINK_URL = 2;
  71 +}
  72 +
  73 +enum BuddyOnAirType {
  74 + NORMAL = 0;
  75 + LIVE = 1;
  76 + VOIP = 2;
  77 +}
  78 +
  79 +enum BuddyResultState {
  80 + ACCEPTED = 1;
  81 + SUCCEEDED = 2;
  82 + FAILED = 3;
  83 + CANCELLED = 4;
  84 + NOTIFY_FAILED = 5;
  85 + STORING = 11;
  86 + UPLOADING = 21;
  87 + NOTIFYING = 31;
  88 +}
  89 +
  90 +enum BuddySearchRequestSource {
  91 + NA = 0;
  92 + FRIEND_VIEW = 1;
  93 + OFFICIAL_ACCOUNT_VIEW = 2;
  94 +}
  95 +
  96 +enum CarrierCode {
  97 + NOT_SPECIFIED = 0;
  98 + JP_DOCOMO = 1;
  99 + JP_AU = 2;
  100 + JP_SOFTBANK = 3;
  101 + KR_SKT = 17;
  102 + KR_KT = 18;
  103 + KR_LGT = 19;
  104 +}
  105 +
  106 +enum ChannelConfiguration {
  107 + MESSAGE = 0;
  108 + MESSAGE_NOTIFICATION = 1;
  109 + NOTIFICATION_CENTER = 2;
  110 +}
  111 +
  112 +enum ChannelErrorCode {
  113 + ILLEGAL_ARGUMENT = 0;
  114 + INTERNAL_ERROR = 1;
  115 + CONNECTION_ERROR = 2;
  116 + AUTHENTICATIONI_FAILED = 3;
  117 + NEED_PERMISSION_APPROVAL = 4;
  118 + COIN_NOT_USABLE = 5;
  119 +}
  120 +
  121 +enum ChannelSyncType {
  122 + SYNC = 0;
  123 + REMOVE = 1;
  124 +}
  125 +
  126 +enum ContactAttribute {
  127 + CONTACT_ATTRIBUTE_CAPABLE_VOICE_CALL = 1;
  128 + CONTACT_ATTRIBUTE_CAPABLE_VIDEO_CALL = 2;
  129 + CONTACT_ATTRIBUTE_CAPABLE_MY_HOME = 16;
  130 + CONTACT_ATTRIBUTE_CAPABLE_BUDDY = 32;
  131 +}
  132 +
  133 +enum ContactCategory {
  134 + NORMAL = 0;
  135 + RECOMMEND = 1;
  136 +}
  137 +
  138 +enum ContactRelation {
  139 + ONEWAY = 0;
  140 + BOTH = 1;
  141 + NOT_REGISTERED = 2;
  142 +}
  143 +
  144 +enum ContactSetting {
  145 + CONTACT_SETTING_NOTIFICATION_DISABLE = 1;
  146 + CONTACT_SETTING_DISPLAY_NAME_OVERRIDE = 2;
  147 + CONTACT_SETTING_CONTACT_HIDE = 4;
  148 + CONTACT_SETTING_FAVORITE = 8;
  149 + CONTACT_SETTING_DELETE = 16;
  150 +}
  151 +
  152 +enum ContactStatus {
  153 + UNSPECIFIED = 0;
  154 + FRIEND = 1;
  155 + FRIEND_BLOCKED = 2;
  156 + RECOMMEND = 3;
  157 + RECOMMEND_BLOCKED = 4;
  158 + DELETED = 5;
  159 + DELETED_BLOCKED = 6;
  160 +}
  161 +
  162 +enum ContactType {
  163 + MID = 0;
  164 + PHONE = 1;
  165 + EMAIL = 2;
  166 + USERID = 3;
  167 + PROXIMITY = 4;
  168 + GROUP = 5;
  169 + USER = 6;
  170 + QRCODE = 7;
  171 + PROMOTION_BOT = 8;
  172 + REPAIR = 128;
  173 + FACEBOOK = 2305;
  174 + SINA = 2306;
  175 + RENREN = 2307;
  176 + FEIXIN = 2308;
  177 +}
  178 +
  179 +enum ContentType {
  180 + NONE = 0;
  181 + IMAGE = 1;
  182 + VIDEO = 2;
  183 + AUDIO = 3;
  184 + HTML = 4;
  185 + PDF = 5;
  186 + CALL = 6;
  187 + STICKER = 7;
  188 + PRESENCE = 8;
  189 + GIFT = 9;
  190 + GROUPBOARD = 10;
  191 + APPLINK = 11;
  192 + LINK = 12;
  193 + CONTACT = 13;
  194 + FILE = 14;
  195 + LOCATION = 15;
  196 + POSTNOTIFICATION = 16;
  197 + RICH = 17;
  198 + CHATEVENT = 18;
  199 +}
  200 +
  201 +enum CustomMode {
  202 + PROMOTION_FRIENDS_INVITE = 1;
  203 + CAPABILITY_SERVER_SIDE_SMS = 2;
  204 + LINE_CLIENT_ANALYTICS_CONFIGURATION = 3;
  205 +}
  206 +
  207 +enum EmailConfirmationStatus {
  208 + NOT_SPECIFIED = 0;
  209 + NOT_YET = 1;
  210 + DONE = 3;
  211 +}
  212 +
  213 +enum EmailConfirmationType {
  214 + SERVER_SIDE_EMAIL = 0;
  215 + CLIENT_SIDE_EMAIL = 1;
  216 +}
  217 +
  218 +enum ErrorCode {
  219 + ILLEGAL_ARGUMENT = 0;
  220 + AUTHENTICATION_FAILED = 1;
  221 + DB_FAILED = 2;
  222 + INVALID_STATE = 3;
  223 + EXCESSIVE_ACCESS = 4;
  224 + NOT_FOUND = 5;
  225 + INVALID_LENGTH = 6;
  226 + NOT_AVAILABLE_USER = 7;
  227 + NOT_AUTHORIZED_DEVICE = 8;
  228 + INVALID_MID = 9;
  229 + NOT_A_MEMBER = 10;
  230 + INCOMPATIBLE_APP_VERSION = 11;
  231 + NOT_READY = 12;
  232 + NOT_AVAILABLE_SESSION = 13;
  233 + NOT_AUTHORIZED_SESSION = 14;
  234 + SYSTEM_ERROR = 15;
  235 + NO_AVAILABLE_VERIFICATION_METHOD = 16;
  236 + NOT_AUTHENTICATED = 17;
  237 + INVALID_IDENTITY_CREDENTIAL = 18;
  238 + NOT_AVAILABLE_IDENTITY_IDENTIFIER = 19;
  239 + INTERNAL_ERROR = 20;
  240 + NO_SUCH_IDENTITY_IDENFIER = 21;
  241 + DEACTIVATED_ACCOUNT_BOUND_TO_THIS_IDENTITY = 22;
  242 + ILLEGAL_IDENTITY_CREDENTIAL = 23;
  243 + UNKNOWN_CHANNEL = 24;
  244 + NO_SUCH_MESSAGE_BOX = 25;
  245 + NOT_AVAILABLE_MESSAGE_BOX = 26;
  246 + CHANNEL_DOES_NOT_MATCH = 27;
  247 + NOT_YOUR_MESSAGE = 28;
  248 + MESSAGE_DEFINED_ERROR = 29;
  249 + USER_CANNOT_ACCEPT_PRESENTS = 30;
  250 + USER_NOT_STICKER_OWNER = 32;
  251 + MAINTENANCE_ERROR = 33;
  252 + ACCOUNT_NOT_MATCHED = 34;
  253 + ABUSE_BLOCK = 35;
  254 + NOT_FRIEND = 36;
  255 + NOT_ALLOWED_CALL = 37;
  256 + BLOCK_FRIEND = 38;
  257 + INCOMPATIBLE_VOIP_VERSION = 39;
  258 + INVALID_SNS_ACCESS_TOKEN = 40;
  259 + EXTERNAL_SERVICE_NOT_AVAILABLE = 41;
  260 + NOT_ALLOWED_ADD_CONTACT = 42;
  261 + NOT_CERTIFICATED = 43;
  262 + NOT_ALLOWED_SECONDARY_DEVICE = 44;
  263 + INVALID_PIN_CODE = 45;
  264 + NOT_FOUND_IDENTITY_CREDENTIAL = 46;
  265 + EXCEED_FILE_MAX_SIZE = 47;
  266 + EXCEED_DAILY_QUOTA = 48;
  267 + NOT_SUPPORT_SEND_FILE = 49;
  268 + MUST_UPGRADE = 50;
  269 + NOT_AVAILABLE_PIN_CODE_SESSION = 51;
  270 +}
  271 +
  272 +enum FeatureType {
  273 + OBJECT_STORAGE = 1;
  274 +}
  275 +
  276 +enum GroupAttribute {
  277 + NAME = 1;
  278 + PICTURE_STATUS = 2;
  279 + ALL = 255;
  280 +}
  281 +
  282 +enum IdentityProvider {
  283 + UNKNOWN = 0;
  284 + LINE = 1;
  285 + NAVER_KR = 2;
  286 +}
  287 +
  288 +enum LoginResultType {
  289 + SUCCESS = 1;
  290 + REQUIRE_QRCODE = 2;
  291 + REQUIRE_DEVICE_CONFIRM = 3;
  292 +}
  293 +
  294 +enum MessageOperationType {
  295 + SEND_MESSAGE = 1;
  296 + RECEIVE_MESSAGE = 2;
  297 + READ_MESSAGE = 3;
  298 + NOTIFIED_READ_MESSAGE = 4;
  299 + NOTIFIED_JOIN_CHAT = 5;
  300 + FAILED_SEND_MESSAGE = 6;
  301 + SEND_CONTENT = 7;
  302 + SEND_CONTENT_RECEIPT = 8;
  303 + SEND_CHAT_REMOVED = 9;
  304 + REMOVE_ALL_MESSAGES = 10;
  305 +}
  306 +
  307 +enum MIDType {
  308 + USER = 0;
  309 + ROOM = 1;
  310 + GROUP = 2;
  311 +}
  312 +
  313 +enum ModificationType {
  314 + ADD = 0;
  315 + REMOVE = 1;
  316 + MODIFY = 2;
  317 +}
  318 +
  319 +enum NotificationItemFetchMode {
  320 + ALL = 0;
  321 + APPEND = 1;
  322 +}
  323 +
  324 +enum NotificationQueueType {
  325 + GLOBAL = 1;
  326 + MESSAGE = 2;
  327 + PRIMARY = 3;
  328 +}
  329 +
  330 +enum NotificationStatus {
  331 + NOTIFICATION_ITEM_EXIST = 1;
  332 + TIMELINE_ITEM_EXIST = 2;
  333 + NOTE_GROUP_NEW_ITEM_EXIST = 4;
  334 + TIMELINE_BUDDYGROUP_CHANGED = 8;
  335 + NOTE_ONE_TO_ONE_NEW_ITEM_EXIST = 16;
  336 + ALBUM_ITEM_EXIST = 32;
  337 + TIMELINE_ITEM_DELETED = 64;
  338 +}
  339 +
  340 +enum NotificationType {
  341 + APPLE_APNS = 1;
  342 + GOOGLE_C2DM = 2;
  343 + NHN_NNI = 3;
  344 + SKT_AOM = 4;
  345 + MS_MPNS = 5;
  346 + RIM_BIS = 6;
  347 + GOOGLE_GCM = 7;
  348 + NOKIA_NNAPI = 8;
  349 + TIZEN = 9;
  350 + LINE_BOT = 17;
  351 + LINE_WAP = 18;
  352 +}
  353 +
  354 +enum OpStatus {
  355 + NORMAL = 0;
  356 + ALERT_DISABLED = 1;
  357 +}
  358 +
  359 +enum OpType {
  360 + END_OF_OPERATION = 0;
  361 + UPDATE_PROFILE = 1;
  362 + NOTIFIED_UPDATE_PROFILE = 2;
  363 + REGISTER_USERID = 3;
  364 + ADD_CONTACT = 4;
  365 + NOTIFIED_ADD_CONTACT = 5;
  366 + BLOCK_CONTACT = 6;
  367 + UNBLOCK_CONTACT = 7;
  368 + NOTIFIED_RECOMMEND_CONTACT = 8;
  369 + CREATE_GROUP = 9;
  370 + UPDATE_GROUP = 10;
  371 + NOTIFIED_UPDATE_GROUP = 11;
  372 + INVITE_INTO_GROUP = 12;
  373 + NOTIFIED_INVITE_INTO_GROUP = 13;
  374 + LEAVE_GROUP = 14;
  375 + NOTIFIED_LEAVE_GROUP = 15;
  376 + ACCEPT_GROUP_INVITATION = 16;
  377 + NOTIFIED_ACCEPT_GROUP_INVITATION = 17;
  378 + KICKOUT_FROM_GROUP = 18;
  379 + NOTIFIED_KICKOUT_FROM_GROUP = 19;
  380 + CREATE_ROOM = 20;
  381 + INVITE_INTO_ROOM = 21;
  382 + NOTIFIED_INVITE_INTO_ROOM = 22;
  383 + LEAVE_ROOM = 23;
  384 + NOTIFIED_LEAVE_ROOM = 24;
  385 + SEND_MESSAGE = 25;
  386 + RECEIVE_MESSAGE = 26;
  387 + SEND_MESSAGE_RECEIPT = 27;
  388 + RECEIVE_MESSAGE_RECEIPT = 28;
  389 + SEND_CONTENT_RECEIPT = 29;
  390 + RECEIVE_ANNOUNCEMENT = 30;
  391 + CANCEL_INVITATION_GROUP = 31;
  392 + NOTIFIED_CANCEL_INVITATION_GROUP = 32;
  393 + NOTIFIED_UNREGISTER_USER = 33;
  394 + REJECT_GROUP_INVITATION = 34;
  395 + NOTIFIED_REJECT_GROUP_INVITATION = 35;
  396 + UPDATE_SETTINGS = 36;
  397 + NOTIFIED_REGISTER_USER = 37;
  398 + INVITE_VIA_EMAIL = 38;
  399 + NOTIFIED_REQUEST_RECOVERY = 39;
  400 + SEND_CHAT_CHECKED = 40;
  401 + SEND_CHAT_REMOVED = 41;
  402 + NOTIFIED_FORCE_SYNC = 42;
  403 + SEND_CONTENT = 43;
  404 + SEND_MESSAGE_MYHOME = 44;
  405 + NOTIFIED_UPDATE_CONTENT_PREVIEW = 45;
  406 + REMOVE_ALL_MESSAGES = 46;
  407 + NOTIFIED_UPDATE_PURCHASES = 47;
  408 + DUMMY = 48;
  409 + UPDATE_CONTACT = 49;
  410 + NOTIFIED_RECEIVED_CALL = 50;
  411 + CANCEL_CALL = 51;
  412 + NOTIFIED_REDIRECT = 52;
  413 + NOTIFIED_CHANNEL_SYNC = 53;
  414 + FAILED_SEND_MESSAGE = 54;
  415 + NOTIFIED_READ_MESSAGE = 55;
  416 + FAILED_EMAIL_CONFIRMATION = 56;
  417 + NOTIFIED_CHAT_CONTENT = 58;
  418 + NOTIFIED_PUSH_NOTICENTER_ITEM = 59;
  419 +}
  420 +
  421 +enum PayloadType {
  422 + PAYLOAD_BUY = 101;
  423 + PAYLOAD_CS = 111;
  424 + PAYLOAD_BONUS = 121;
  425 + PAYLOAD_EVENT = 131;
  426 +}
  427 +
  428 +enum PaymentPgType {
  429 + PAYMENT_PG_NONE = 0;
  430 + PAYMENT_PG_AU = 1;
  431 + PAYMENT_PG_AL = 2;
  432 +}
  433 +
  434 +enum PaymentType {
  435 + PAYMENT_APPLE = 1;
  436 + PAYMENT_GOOGLE = 2;
  437 +}
  438 +
  439 +enum ProductBannerLinkType {
  440 + BANNER_LINK_NONE = 0;
  441 + BANNER_LINK_ITEM = 1;
  442 + BANNER_LINK_URL = 2;
  443 + BANNER_LINK_CATEGORY = 3;
  444 +}
  445 +
  446 +enum ProductEventType {
  447 + NO_EVENT = 0;
  448 + CARRIER_ANY = 65537;
  449 + BUDDY_ANY = 131073;
  450 + INSTALL_IOS = 196609;
  451 + INSTALL_ANDROID = 196610;
  452 + MISSION_ANY = 262145;
  453 + MUSTBUY_ANY = 327681;
  454 +}
  455 +
  456 +enum ProfileAttribute {
  457 + EMAIL = 1;
  458 + DISPLAY_NAME = 2;
  459 + PHONETIC_NAME = 4;
  460 + PICTURE = 8;
  461 + STATUS_MESSAGE = 16;
  462 + ALLOW_SEARCH_BY_USERID = 32;
  463 + ALLOW_SEARCH_BY_EMAIL = 64;
  464 + BUDDY_STATUS = 128;
  465 + ALL = 255;
  466 +}
  467 +
  468 +enum PublicType {
  469 + HIDDEN = 0;
  470 + PUBLIC = 1000;
  471 +}
  472 +
  473 +enum RedirectType {
  474 + NONE = 0;
  475 + EXPIRE_SECOND = 1;
  476 +}
  477 +
  478 +enum RegistrationType {
  479 + PHONE = 0;
  480 + EMAIL_WAP = 1;
  481 + FACEBOOK = 2305;
  482 + SINA = 2306;
  483 + RENREN = 2307;
  484 + FEIXIN = 2308;
  485 +}
  486 +
  487 +enum SettingsAttribute {
  488 + NOTIFICATION_ENABLE = 1;
  489 + NOTIFICATION_MUTE_EXPIRATION = 2;
  490 + NOTIFICATION_NEW_MESSAGE = 4;
  491 + NOTIFICATION_GROUP_INVITATION = 8;
  492 + NOTIFICATION_SHOW_MESSAGE = 16;
  493 + NOTIFICATION_INCOMING_CALL = 32;
  494 + PRIVACY_SYNC_CONTACTS = 64;
  495 + PRIVACY_SEARCH_BY_PHONE_NUMBER = 128;
  496 + NOTIFICATION_SOUND_MESSAGE = 256;
  497 + NOTIFICATION_SOUND_GROUP = 512;
  498 + CONTACT_MY_TICKET = 1024;
  499 + IDENTITY_PROVIDER = 2048;
  500 + IDENTITY_IDENTIFIER = 4096;
  501 + PRIVACY_SEARCH_BY_USERID = 8192;
  502 + PRIVACY_SEARCH_BY_EMAIL = 16384;
  503 + PREFERENCE_LOCALE = 32768;
  504 + NOTIFICATION_DISABLED_WITH_SUB = 65536;
  505 + SNS_ACCOUNT = 524288;
  506 + PHONE_REGISTRATION = 1048576;
  507 + PRIVACY_ALLOW_SECONDARY_DEVICE_LOGIN = 2097152;
  508 + CUSTOM_MODE = 4194304;
  509 + PRIVACY_PROFILE_IMAGE_POST_TO_MYHOME = 8388608;
  510 + EMAIL_CONFIRMATION_STATUS = 16777216;
  511 + PRIVACY_RECV_MESSAGES_FROM_NOT_FRIEND = 33554432;
  512 + ALL = 2147483647;
  513 +}
  514 +
  515 +enum SnsIdType {
  516 + FACEBOOK = 1;
  517 + SINA = 2;
  518 + RENREN = 3;
  519 + FEIXIN = 4;
  520 +}
  521 +
  522 +enum SpammerReason {
  523 + OTHER = 0;
  524 + ADVERTISING = 1;
  525 + GENDER_HARASSMENT = 2;
  526 + HARASSMENT = 3;
  527 +}
  528 +
  529 +enum SyncActionType {
  530 + SYNC = 0;
  531 + REPORT = 1;
  532 +}
  533 +
  534 +enum SyncCategory {
  535 + PROFILE = 0;
  536 + SETTINGS = 1;
  537 + OPS = 2;
  538 + CONTACT = 3;
  539 + RECOMMEND = 4;
  540 + BLOCK = 5;
  541 + GROUP = 6;
  542 + ROOM = 7;
  543 + NOTIFICATION = 8;
  544 +}
  545 +
  546 +enum TMessageBoxStatus {
  547 + ACTIVATED = 1;
  548 + UNREAD = 2;
  549 +}
  550 +
  551 +enum UniversalNotificationServiceErrorCode {
  552 + INTERNAL_ERROR = 0;
  553 + INVALID_KEY = 1;
  554 + ILLEGAL_ARGUMENT = 2;
  555 + TOO_MANY_REQUEST = 3;
  556 + AUTHENTICATION_FAILED = 4;
  557 + NO_WRITE_PERMISSION = 5;
  558 +}
  559 +
  560 +enum UnregistrationReason {
  561 + UNREGISTRATION_REASON_UNREGISTER_USER = 1;
  562 + UNREGISTRATION_REASON_UNBIND_DEVICE = 2;
  563 +}
  564 +
  565 +enum UserAgeType {
  566 + OVER = 1;
  567 + UNDER = 2;
  568 + UNDEFINED = 3;
  569 +}
  570 +
  571 +enum VerificationMethod {
  572 + NO_AVAILABLE = 0;
  573 + PIN_VIA_SMS = 1;
  574 + CALLERID_INDIGO = 2;
  575 + PIN_VIA_TTS = 4;
  576 + SKIP = 10;
  577 +}
  578 +
  579 +enum VerificationResult {
  580 + FAILED = 0;
  581 + OK_NOT_REGISTERED_YET = 1;
  582 + OK_REGISTERED_WITH_SAME_DEVICE = 2;
  583 + OK_REGISTERED_WITH_ANOTHER_DEVICE = 3;
  584 +}
  585 +
  586 +enum WapInvitationType {
  587 + REGISTRATION = 1;
  588 + CHAT = 2;
  589 +}
  590 +
  591 +struct AgeCheckDocomoResult {
  592 + 1: string authUrl;
  593 + 2: UserAgeType userAgeType;
  594 +}
  595 +
  596 +struct AgeCheckRequestResult {
  597 + 1: string authUrl;
  598 + 2: string sessionId;
  599 +}
  600 +
  601 +struct Announcement {
  602 + 1: i32 index;
  603 + 10: bool forceUpdate;
  604 + 11: string title;
  605 + 12: string text;
  606 + 13: i64 createdTime;
  607 + 14: string pictureUrl;
  608 + 15: string thumbnailUrl;
  609 +}
  610 +
  611 +struct ChannelProvider {
  612 + 1: string name;
  613 +}
  614 +
  615 +struct ChannelInfo {
  616 + 1: string channelId;
  617 + 3: string name;
  618 + 4: string entryPageUrl;
  619 + 5: string descriptionText;
  620 + 6: ChannelProvider provider;
  621 + 7: PublicType publicType;
  622 + 8: string iconImage;
  623 + 9: list<string> permissions;
  624 + 11: string iconThumbnailImage;
  625 + 12: list<ChannelConfiguration> channelConfigurations;
  626 +}
  627 +
  628 +struct ApprovedChannelInfo {
  629 + 1: ChannelInfo channelInfo;
  630 + 2: i64 approvedAt;
  631 +}
  632 +
  633 +struct ApprovedChannelInfos {
  634 + 1: list<ApprovedChannelInfo> approvedChannelInfos;
  635 + 2: i64 revision;
  636 +}
  637 +
  638 +struct AuthQrcode {
  639 + 1: string qrcode;
  640 + 2: string verifier;
  641 +}
  642 +
  643 +struct BuddyBanner {
  644 + 1: BuddyBannerLinkType buddyBannerLinkType;
  645 + 2: string buddyBannerLink;
  646 + 3: string buddyBannerImageUrl;
  647 +}
  648 +
  649 +struct BuddyDetail {
  650 + 1: string mid;
  651 + 2: i64 memberCount;
  652 + 3: bool onAir;
  653 + 4: bool businessAccount;
  654 + 5: bool addable;
  655 + 6: set<ContentType> acceptableContentTypes;
  656 + 7: bool capableMyhome;
  657 +}
  658 +
  659 +struct Contact {
  660 + 1: string mid;
  661 + 2: i64 createdTime;
  662 + 10: ContactType type;
  663 + 11: ContactStatus status;
  664 + 21: ContactRelation relation;
  665 + 22: string displayName;
  666 + 23: string phoneticName;
  667 + 24: string pictureStatus;
  668 + 25: string thumbnailUrl;
  669 + 26: string statusMessage;
  670 + 27: string displayNameOverridden;
  671 + 28: i64 favoriteTime;
  672 + 31: bool capableVoiceCall;
  673 + 32: bool capableVideoCall;
  674 + 33: bool capableMyhome;
  675 + 34: bool capableBuddy;
  676 + 35: i32 attributes;
  677 + 36: i64 settings;
  678 + 37: string picturePath;
  679 +}
  680 +
  681 +struct BuddyList {
  682 + 1: string classification;
  683 + 2: string displayName;
  684 + 3: i32 totalBuddyCount;
  685 + 4: list<Contact> popularContacts;
  686 +}
  687 +
  688 +struct Location {
  689 + 1: string title;
  690 + 2: string address;
  691 + 3: double latitude;
  692 + 4: double longitude;
  693 + 5: string phone;
  694 +}
  695 +
  696 +struct BuddyMessageRequest {
  697 + 1: ContentType contentType;
  698 + 2: string text;
  699 + 3: Location location;
  700 + 4: binary content;
  701 + 5: map<string, string> contentMetadata;
  702 +}
  703 +
  704 +struct BuddyOnAirUrls {
  705 + 1: map<string, string> hls;
  706 + 2: map<string, string> smoothStreaming;
  707 +}
  708 +
  709 +struct BuddyOnAir {
  710 + 1: string mid;
  711 + 3: i64 freshnessLifetime;
  712 + 4: string onAirId;
  713 + 5: bool onAir;
  714 + 11: string text;
  715 + 12: i64 viewerCount;
  716 + 13: i64 targetCount;
  717 + 31: BuddyOnAirType onAirType;
  718 + 32: BuddyOnAirUrls onAirUrls;
  719 +}
  720 +
  721 +struct BuddyProfile {
  722 + 1: string buddyId;
  723 + 2: string mid;
  724 + 3: string searchId;
  725 + 4: string displayName;
  726 + 5: string statusMessage;
  727 + 11: i64 contactCount;
  728 +}
  729 +
  730 +struct BuddySearchResult {
  731 + 1: string mid;
  732 + 2: string displayName;
  733 + 3: string pictureStatus;
  734 + 4: string picturePath;
  735 + 5: string statusMessage;
  736 + 6: bool businessAccount;
  737 +}
  738 +
  739 +struct ChannelDomain {
  740 + 1: string host;
  741 + 2: bool removed;
  742 +}
  743 +
  744 +struct ChannelDomains {
  745 + 1: list<ChannelDomain> channelDomains;
  746 + 2: i64 revision;
  747 +}
  748 +
  749 +exception ChannelException {
  750 + 1: ChannelErrorCode code;
  751 + 2: string reason;
  752 + 3: map<string, string> parameterMap;
  753 +}
  754 +
  755 +struct ChannelInfos {
  756 + 1: list<ChannelInfo> channelInfos;
  757 + 2: i64 revision;
  758 +}
  759 +
  760 +struct ChannelNotificationSetting {
  761 + 1: string channelId;
  762 + 2: string name;
  763 + 3: bool notificationReceivable;
  764 + 4: bool messageReceivable;
  765 + 5: bool showDefault;
  766 +}
  767 +
  768 +struct ChannelSyncDatas {
  769 + 1: list<ChannelInfo> channelInfos;
  770 + 2: list<ChannelDomain> channelDomains;
  771 + 3: i64 revision;
  772 + 4: i64 expires;
  773 +}
  774 +
  775 +struct ChannelToken {
  776 + 1: string token;
  777 + 2: string obsToken;
  778 + 3: i64 expiration;
  779 + 4: string refreshToken;
  780 + 5: string channelAccessToken;
  781 +}
  782 +
  783 +struct Coin {
  784 + 1: i32 freeCoinBalance;
  785 + 2: i32 payedCoinBalance;
  786 + 3: i32 totalCoinBalance;
  787 + 4: i32 rewardCoinBalance;
  788 +}
  789 +
  790 +struct CoinPayLoad {
  791 + 1: i32 payCoin;
  792 + 2: i32 freeCoin;
  793 + 3: PayloadType type;
  794 + 4: i32 rewardCoin;
  795 +}
  796 +
  797 +struct CoinHistory {
  798 + 1: i64 payDate;
  799 + 2: i32 coinBalance;
  800 + 3: i32 coin;
  801 + 4: string price;
  802 + 5: string title;
  803 + 6: bool refund;
  804 + 7: string paySeq;
  805 + 8: string currency;
  806 + 9: string currencySign;
  807 + 10: string displayPrice;
  808 + 11: CoinPayLoad payload;
  809 + 12: string channelId;
  810 +}
  811 +
  812 +struct CoinHistoryCondition {
  813 + 1: i64 start;
  814 + 2: i32 size;
  815 + 3: string language;
  816 + 4: string eddt;
  817 + 5: PaymentType appStoreCode;
  818 +}
  819 +
  820 +struct CoinHistoryResult {
  821 + 1: list<CoinHistory> historys;
  822 + 2: Coin balance;
  823 + 3: bool hasNext;
  824 +}
  825 +
  826 +struct CoinProductItem {
  827 + 1: string itemId;
  828 + 2: i32 coin;
  829 + 3: i32 freeCoin;
  830 + 5: string currency;
  831 + 6: string price;
  832 + 7: string displayPrice;
  833 + 8: string name;
  834 + 9: string desc;
  835 +}
  836 +
  837 +struct CoinPurchaseConfirm {
  838 + 1: string orderId;
  839 + 2: PaymentType appStoreCode;
  840 + 3: string receipt;
  841 + 4: string signature;
  842 + 5: string seller;
  843 + 6: string requestType;
  844 + 7: bool ignoreReceipt;
  845 +}
  846 +
  847 +struct CoinPurchaseReservation {
  848 + 1: string productId;
  849 + 2: string country;
  850 + 3: string currency;
  851 + 4: string price;
  852 + 5: PaymentType appStoreCode;
  853 + 6: string language;
  854 + 7: PaymentPgType pgCode;
  855 + 8: string redirectUrl;
  856 +}
  857 +
  858 +struct CoinUseReservationItem {
  859 + 1: string itemId;
  860 + 2: string itemName;
  861 + 3: i32 amount;
  862 +}
  863 +
  864 +struct CoinUseReservation {
  865 + 1: string channelId;
  866 + 2: string shopOrderId;
  867 + 3: PaymentType appStoreCode;
  868 + 4: list<CoinUseReservationItem> items;
  869 + 5: string country;
  870 +}
  871 +
  872 +struct CompactContact {
  873 + 1: string mid;
  874 + 2: i64 createdTime;
  875 + 3: i64 modifiedTime;
  876 + 4: ContactStatus status;
  877 + 5: i64 settings;
  878 + 6: string displayNameOverridden;
  879 +}
  880 +
  881 +struct ContactModification {
  882 + 1: ModificationType type;
  883 + 2: string luid;
  884 + 11: list<string> phones;
  885 + 12: list<string> emails;
  886 + 13: list<string> userids;
  887 +}
  888 +
  889 +struct ContactRegistration {
  890 + 1: Contact contact;
  891 + 10: string luid;
  892 + 11: ContactType contactType;
  893 + 12: string contactKey;
  894 +}
  895 +
  896 +struct ContactReport {
  897 + 1: string mid;
  898 + 2: bool exists;
  899 + 3: Contact contact;
  900 +}
  901 +
  902 +struct ContactReportResult {
  903 + 1: string mid;
  904 + 2: bool exists;
  905 +}
  906 +
  907 +struct DeviceInfo {
  908 + 1: string deviceName;
  909 + 2: string systemName;
  910 + 3: string systemVersion;
  911 + 4: string model;
  912 + 10: CarrierCode carrierCode;
  913 + 11: string carrierName;
  914 + 20: ApplicationType applicationType;
  915 +}
  916 +
  917 +struct EmailConfirmation {
  918 + 1: bool usePasswordSet;
  919 + 2: string email;
  920 + 3: string password;
  921 + 4: bool ignoreDuplication;
  922 +}
  923 +
  924 +struct EmailConfirmationSession {
  925 + 1: EmailConfirmationType emailConfirmationType;
  926 + 2: string verifier;
  927 + 3: string targetEmail;
  928 +}
  929 +
  930 +struct FriendChannelMatrix {
  931 + 1: string channelId;
  932 + 2: string representMid;
  933 + 3: i32 count;
  934 +}
  935 +
  936 +struct FriendChannelMatricesResponse {
  937 + 1: i64 expires;
  938 + 2: list<FriendChannelMatrix> matrices;
  939 +}
  940 +
  941 +struct Geolocation {
  942 + 1: double longitude;
  943 + 2: double latitude;
  944 +}
  945 +
  946 +struct NotificationTarget {
  947 + 1: string applicationType;
  948 + 2: string applicationVersion;
  949 + 3: string region;
  950 +}
  951 +
  952 +struct GlobalEvent {
  953 + 1: string key;
  954 + 2: list<NotificationTarget> targets;
  955 + 3: i64 createdTime;
  956 + 4: i64 data;
  957 + 5: i32 maxDelay;
  958 +}
  959 +
  960 +struct Group {
  961 + 1: string id;
  962 + 2: i64 createdTime;
  963 + 10: string name;
  964 + 11: string pictureStatus;
  965 + 20: list<Contact> members;
  966 + 21: Contact creator;
  967 + 22: list<Contact> invitee;
  968 + 31: bool notificationDisabled;
  969 +}
  970 +
  971 +struct IdentityCredential {
  972 + 1: IdentityProvider provider;
  973 + 2: string identifier;
  974 + 3: string password;
  975 +}
  976 +
  977 +struct LastReadMessageId {
  978 + 1: string mid;
  979 + 2: string lastReadMessageId;
  980 +}
  981 +
  982 +struct LastReadMessageIds {
  983 + 1: string chatId;
  984 + 2: list<LastReadMessageId> lastReadMessageIds;
  985 +}
  986 +
  987 +struct LoginResult {
  988 + 1: string authToken;
  989 + 2: string certificate;
  990 + 3: string verifier;
  991 + 4: string pinCode;
  992 + 5: LoginResultType type;
  993 +}
  994 +
  995 +struct LoginSession {
  996 + 1: string tokenKey;
  997 + 3: i64 expirationTime;
  998 + 11: ApplicationType applicationType;
  999 + 12: string systemName;
  1000 + 22: string accessLocation;
  1001 +}
  1002 +
  1003 +struct Message {
  1004 + 1: string from;
  1005 + 2: string to;
  1006 + 3: MIDType toType;
  1007 + 4: string id;
  1008 + 5: i64 createdTime;
  1009 + 6: i64 deliveredTime;
  1010 + 10: string text;
  1011 + 11: Location location;
  1012 + 14: bool hasContent;
  1013 + 15: ContentType contentType;
  1014 + 17: binary contentPreview;
  1015 + 18: map<string, string> contentMetadata;
  1016 +}
  1017 +
  1018 +struct MessageOperation {
  1019 + 1: i64 revision;
  1020 + 2: i64 createdTime;
  1021 + 3: MessageOperationType type;
  1022 + 4: i32 reqSeq;
  1023 + 5: OpStatus status;
  1024 + 10: string param1;
  1025 + 11: string param2;
  1026 + 12: string param3;
  1027 + 20: Message message;
  1028 +}
  1029 +
  1030 +struct MessageOperations {
  1031 + 1: list<MessageOperation> operations;
  1032 + 2: bool endFlag;
  1033 +}
  1034 +
  1035 +struct MetaProfile {
  1036 + 1: i64 createTime;
  1037 + 2: string regionCode;
  1038 + 3: map<RegistrationType, string> identities;
  1039 +}
  1040 +
  1041 +struct NotificationItem {
  1042 + 1: string id;
  1043 + 2: string from;
  1044 + 3: string to;
  1045 + 4: string fromChannel;
  1046 + 5: string toChannel;
  1047 + 7: i64 revision;
  1048 + 8: i64 createdTime;
  1049 + 9: map<string, string> content;
  1050 +}
  1051 +
  1052 +struct NotificationFetchResult {
  1053 + 1: NotificationItemFetchMode fetchMode;
  1054 + 2: list<NotificationItem> itemList;
  1055 +}
  1056 +
  1057 +struct Operation {
  1058 + 1: i64 revision;
  1059 + 2: i64 createdTime;
  1060 + 3: OpType type;
  1061 + 4: i32 reqSeq;
  1062 + 5: string checksum;
  1063 + 7: OpStatus status;
  1064 + 10: string param1;
  1065 + 11: string param2;
  1066 + 12: string param3;
  1067 + 20: Message message;
  1068 +}
  1069 +
  1070 +struct PaymentReservation {
  1071 + 1: string receiverMid;
  1072 + 2: string productId;
  1073 + 3: string language;
  1074 + 4: string location;
  1075 + 5: string currency;
  1076 + 6: string price;
  1077 + 7: PaymentType appStoreCode;
  1078 + 8: string messageText;
  1079 + 9: i32 messageTemplate;
  1080 + 10: i64 packageId;
  1081 +}
  1082 +
  1083 +struct PaymentReservationResult {
  1084 + 1: string orderId;
  1085 + 2: string confirmUrl;
  1086 + 3: map<string, string> extras;
  1087 +}
  1088 +
  1089 +struct Product {
  1090 + 1: string productId;
  1091 + 2: i64 packageId;
  1092 + 3: i32 version;
  1093 + 4: string authorName;
  1094 + 5: bool onSale;
  1095 + 6: i32 validDays;
  1096 + 7: i32 saleType;
  1097 + 8: string copyright;
  1098 + 9: string title;
  1099 + 10: string descriptionText;
  1100 + 11: i64 shopOrderId;
  1101 + 12: string fromMid;
  1102 + 13: string toMid;
  1103 + 14: i64 validUntil;
  1104 + 15: i32 priceTier;
  1105 + 16: string price;
  1106 + 17: string currency;
  1107 + 18: string currencySymbol;
  1108 + 19: PaymentType paymentType;
  1109 + 20: i64 createDate;
  1110 + 21: bool ownFlag;
  1111 + 22: ProductEventType eventType;
  1112 + 23: string urlSchema;
  1113 + 24: string downloadUrl;
  1114 + 25: string buddyMid;
  1115 + 26: i64 publishSince;
  1116 + 27: bool newFlag;
  1117 + 28: bool missionFlag;
  1118 +}
  1119 +
  1120 +struct ProductList {
  1121 + 1: bool hasNext;
  1122 + 4: i64 bannerSequence;
  1123 + 5: ProductBannerLinkType bannerTargetType;
  1124 + 6: string bannerTargetPath;
  1125 + 7: list<Product> productList;
  1126 + 8: string bannerLang;
  1127 +}
  1128 +
  1129 +struct ProductSimple {
  1130 + 1: string productId;
  1131 + 2: i64 packageId;
  1132 + 3: i32 version;
  1133 + 4: bool onSale;
  1134 + 5: i64 validUntil;
  1135 +}
  1136 +
  1137 +struct ProductSimpleList {
  1138 + 1: bool hasNext;
  1139 + 2: i32 reinvokeHour;
  1140 + 3: i64 lastVersionSeq;
  1141 + 4: list<ProductSimple> productList;
  1142 + 5: i64 recentNewReleaseDate;
  1143 + 6: i64 recentEventReleaseDate;
  1144 +}
  1145 +
  1146 +struct Profile {
  1147 + 1: string mid;
  1148 + 3: string userid;
  1149 + 10: string phone;
  1150 + 11: string email;
  1151 + 12: string regionCode;
  1152 + 20: string displayName;
  1153 + 21: string phoneticName;
  1154 + 22: string pictureStatus;
  1155 + 23: string thumbnailUrl;
  1156 + 24: string statusMessage;
  1157 + 31: bool allowSearchByUserid;
  1158 + 32: bool allowSearchByEmail;
  1159 + 33: string picturePath;
  1160 +}
  1161 +
  1162 +struct ProximityMatchCandidateResult {
  1163 + 1: list<Contact> users;
  1164 + 2: list<Contact> buddies;
  1165 +}
  1166 +
  1167 +struct RegisterWithSnsIdResult {
  1168 + 1: string authToken;
  1169 + 2: bool userCreated;
  1170 +}
  1171 +
  1172 +struct RequestTokenResponse {
  1173 + 1: string requestToken;
  1174 + 2: string returnUrl;
  1175 +}
  1176 +
  1177 +struct Room {
  1178 + 1: string mid;
  1179 + 2: i64 createdTime;
  1180 + 10: list<Contact> contacts;
  1181 + 31: bool notificationDisabled;
  1182 +}
  1183 +
  1184 +struct RSAKey {
  1185 + 1: string keynm;
  1186 + 2: string nvalue;
  1187 + 3: string evalue;
  1188 + 4: string sessionKey;