2014년 6월 25일 수요일

Messaging 관련 사항들(history, protocol, mobile messenger APIs) 정리

http://en.wikipedia.org/wiki/Instant_messaging

wikipedia에서는 여러 내용이 있고 간략한 history는 아래 그림에서 볼 수 있음.

http://www.technologyblogged.com/round-ups/the-beginning-middle-present-and-future-of-instant-messaging
History of Instant Messaging Timeline - Technology Blogged Exclusive.

[Standards for Instant Messaging]


여러 messenger이 난립했던 관계로 아래와 같은 표준화 노력이 있었다고 함.



[XMPP : Extensible Messaging and Presence Protocol]

: http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol
http://charlie0301.blogspot.kr/2013/04/xmpp-smack-openfire.html

open standard로서 좀 사용되는 protocol이며 개발입장에서는 관련 open source server/client가 꽤 존재함.

- XMPP based chat clients
 : http://en.wikipedia.org/wiki/List_of_XMPP_client_software#XMPP-related_features

ClientTransports[a]File transfer
(XEP-0096)[b]
Multi-user chatJingleEncryption
File transfer[b]Voice callsVideo callsOpenPGPOTR
AdiumYesYesYesNoNoNoNo[42]Yes
BitlBeeYesYesYesNoNoNoNoYes
Bombus[43]NoYesYesNoNoNoNoNo
climmNoYesNoNoNoNoNoYes
Coccinella[44]YesYesYesNoYesNoNoNo
Empathy,[45] KDE Telepathy[c]NoYesYesYesYesYesNoYes/No[d][e]
Gajim[46]YesYesYesYesYes/No[f]Yes/No[f]YesYes/No[f]
Google TalkNoNoNoYesPartial[g]Partial[g][h]NoNo
iCallYesYesNoYesYesYesNoYes
iChatNoYesPartial[i]NoNoNoNoNo
JitsiNoYesYesYesYesYesNoYes
KaduNoYesNoNoNoNoNoNo
KopeteYesYesYesNoNoNoYesYes
MCabber[47]NoNoYesYesNoNoYesYes
NimbuzzYesYesYesYesYesYesNoNo
Pidgin[48]YesYesYesNoYes/No[f]Yes/No[f]YesYes
PsiYesYesYesYesYesNoYesYes
Tkabber[49]YesYesYesNoNoNoYesYes
TrillianNoYesYes/No[j]NoNoNoNoYes/No[k]
  1. Jump up^ Transport support means the ability to set up transports. Once transport is set up, any client can use it to manage contacts and communicate with them.
  2. Jump up to:a b The difference between XEP-0096 (legacy) and XEP-0234 (Jingle) file transfer is that the latter works behind NAT (e.g., from home and corporate networks).
  3. Jump up^ Both Empathy and KDE Telepathy are based on Telepathy framework and share same properties in regard of XMPP features support.
  4. Jump up^ "Bug report - Empathy should support OTR encryption"Gnome Bugzilla. Retrieved 17 August 2013.
  5. Jump up^ "Bug 16891 - (OTR) Telepathy should support OTR encryption"freedesktop.org Bugzilla. Retrieved 25 May 2014.
  6. Jump up to:a b c d e Feature unavailable on Windows.
  7. Jump up to:a b Incompatible with XEPs.
  8. Jump up^ Feature unavailable in standalone client.
  9. Jump up^ Multi-user chats can be joined but not started
  10. Jump up^ Feature available on Windows only.
  11. Jump up^ Feature available on Windows only, not actively supported, not stable.

[Pidgin messenger]

https://pidgin.im/
- 여러 messaging service, protocol을 지원하는 Open source 기반 통합 메신저
- 기본적으로 아래에서 명시된 것을 제외하고도 3rd party 개발자 기반 plugin을 지원하여 타 chatting protocol, service들을 더 지원하고 있음.
- 그외 plugin들이 풍부하여 security, notifications, profile/status update, interface, account/logs 등의 부가 기능들을 제공하고 있음.

- 기본 지원 chat networks
  • AIM
  • Bonjour
  • Gadu-Gadu
  • Google Talk
  • Groupwise
  • ICQ
  • IRC
  • MSN
  • MXit
  • MySpaceIM
  • SILC
  • SIMPLE
  • Sametime
  • XMPP
  • Yahoo!
  • Zephyr
- 3rd party plugins
: Whatsapp, Facebook IM, Line과 NateOn도 지원하고 있음.

Protocol NameWebsiteShort Description
BelugaGoBeluga mobile group messaging
CampfireGoProtocol plugin for Basecamp's Campfire IM
Classic Battle.netGoBlizzard's gaming network: notably for StarCraft, Diablo II, and WarCraft III
F-ListGoF-List rollplaying community
Facebook IMGoFacebook social network
GammuGoSend SMS through your phone via usb/serial/bluetooth/irda
GroupMeGoGroupMe group messaging
Heroes of NewerthGoOnline video game
LINE by NaverGoMobile SMS replacement
Mail.ru Agent (mrim-prpl)GoRussian network
Mail.ru Agent (pidgin-mra)GoRussian network
MicroblogGoTwitter/Identica/Laconica updates
MightyTextGoSend SMS through your Android phone via MightyText
msn-pecanGoAlternative MSN access
msn-xmppGoAlternative MSN with xmpp/oauth access
MXitGoMXit IM
NateOnGo orGoKorean network (see More Info for details and Windows builds)
NetNexusGonetnexus.com's chatrooms
NetsoulGoFrench network
NingGoNing-based social networks
OkCupidGoOkCupid.com dating website
OmegleGoomegle.com's web-based random chat
QQ (libqq-pidgin)GoQQ protocol support
QQ (pidgin-lwqq)GoQQ protocol support (Based on WebQQ)
RediffbolGoIndian network
Skype IMGoOnly with Skypeclient
SIPEGoMicrosoft Office Communicator, Reuters Messaging
SmsWiFiGoWrite SMS over your Android smartphone in Pidgin
Steam IM (mobile)GoSteam Friends gaming network
Steam IM (native)GoSteam Friends gaming network
Tlen.plGoPolish network
TorChatGop2p instant messaging through Tor hidden service tunnels
ToxGosecure instant messaging via Tox protocol
Twitter ProtocolGoAccess Twitter (and status.net / identi.ca) feeds like chat rooms
WhatsAppGoWhatsApp IM protocol
WinMX Peer NetworkGoFile sharing network
XfireGoGaming network

- API : https://developer.pidgin.im/doxygen/
 . Pidgin GUI, core library들로 구성,  C API style

 . 구성
  : libpurple : Pdigin 프로그램의 core
  : Pidgin : GTK+ 기반 frontend이며 libpurple을 사용
  : Finch : Ncurses 기반 frontend이며 libgnt를 사용


- libpurple APIs
 : 다양한 모듈, 기능에 대해서 API들을 제공하고 있음. 아래는 주요 category들

 . account
 . buddy list
 . connection
 . conversation
 . file transfer
 . notify : 모든 notify(message, email, search result, user info, close 등)를 확인하는 API들
 . privacy : buddy list에서 사용자를 허용/거부 설정 API들
 . room list
 . plugin

- Plugin
 . C Plugin How-To : https://developer.pidgin.im/wiki/CHowTo

 . 아래는 기본적인 Pidgin C Plugin 예제
  : https://developer.pidgin.im/wiki/CHowTo/BasicPluginHowto

#define PURPLE_PLUGINS

#include <glib.h>

#include "notify.h"
#include "plugin.h"
#include "version.h"

static gboolean
plugin_load(PurplePlugin *plugin) {
    purple_notify_message(plugin, PURPLE_NOTIFY_MSG_INFO, "Hello World!",
                        "This is the Hello World! plugin :)", NULL, NULL, NULL);

    return TRUE;
}

static PurplePluginInfo info = {
    PURPLE_PLUGIN_MAGIC,
    PURPLE_MAJOR_VERSION,
    PURPLE_MINOR_VERSION,
    PURPLE_PLUGIN_STANDARD,
    NULL,
    0,
    NULL,
    PURPLE_PRIORITY_DEFAULT,

    "core-hello_world",
    "Hello World!",
    "1.1",

    "Hello World Plugin",          
    "Hello World Plugin",          
    "My Name <email@helloworld.tld>",                          
    "http://helloworld.tld",     
    
    plugin_load,                   
    NULL,                          
    NULL,                          
                                   
    NULL,                          
    NULL,                          
    NULL,                        
    NULL,                   
    NULL,                          
    NULL,                          
    NULL,                          
    NULL                           
};                               
    
static void                        
init_plugin(PurplePlugin *plugin)
{                                  
}

PURPLE_INIT_PLUGIN(hello_world, init_plugin, info)

기본적인 plugin data를 저장하는 strcuture는 다음과 같다.
기존적인 plugin 정보들과 load, unload, destroy callback과 extra info, action들에 대한 정보를 등록함.

00078 struct _PurplePluginInfo
00079 {
00080     unsigned int magic;
00081     unsigned int major_version;
00082     unsigned int minor_version;
00083     PurplePluginType type;
00084     char *ui_requirement;
00085     unsigned long flags;
00086     GList *dependencies;
00087     PurplePluginPriority priority;
00088
00089     char *id;
00090     char *name;
00091     char *version;
00092     char *summary;
00093     char *description;
00094     char *author;
00095     char *homepage;
00096
00101     gboolean (*load)(PurplePlugin *plugin);
00102     gboolean (*unload)(PurplePlugin *plugin);
00103     void (*destroy)(PurplePlugin *plugin);
00104
00105     void *ui_info;
00106     void *extra_info;
00107     PurplePluginUiInfo *prefs_info;
00122     GList *(*actions)(PurplePlugin *plugin, gpointer context);
00123
00124     void (*_purple_reserved1)(void);
00125     void (*_purple_reserved2)(void);
00126     void (*_purple_reserved3)(void);
00127     void (*_purple_reserved4)(void);
00128 };

그리고 init function과 plugin information을 아래 macro를 사용하여 등록

#define PURPLE_INIT_PLUGIN(pluginname,
initfunc,
plugininfo
)
Value:
gboolean _FUNC_NAME(pluginname)(void);\
    gboolean _FUNC_NAME(pluginname)(void) { \
        PurplePlugin *plugin = purple_plugin_new(TRUE, NULL); \
        plugin->info = &(plugininfo); \
        initfunc((plugin)); \
        purple_plugin_load((plugin)); \
        return purple_plugin_register(plugin); \
    }
Definition at line 222 of file plugin.h.
#define PURPLE_PLUGIN_ACTIONS(plugin,
context
)
Value:
(PURPLE_PLUGIN_HAS_ACTIONS(plugin)? \
    (plugin)->info->actions(plugin, context): NULL)
Definition at line 212 of file plugin.h.
자세한건 만들어 봐야지 알 수 있겠다. 다 보려면 한도 끝도 없겠고..

[MQTT (MQ Telemetry Transport) protocol]


http://bcho.tistory.com/864
: MQTT 간략 정리, 관련 solutoin도 정리

http://helloworld.naver.com/helloworld/1846
: 간략한 소개, 특징, FB app에서 사용됨을 알려줌.

http://public.dhe.ibm.com/software/kr/ik2012/mqtt.pdf
: MQTT 설명, 당위성과 자사 솔루션 소개

http://charlie0301.blogspot.kr/search?q=mqtt


MQTT software solutions
http://mqtt.org/wiki/doku.php/software

. paho - http://www.eclipse.org/paho/



[Mobile Messenger]


Global messenger market share
http://www.1mtb.com/whatsapp-leads-the-global-mobile-messenger-wars-with-44-pc-market-share/

WhatsApp Leads The Global Mobile Messenger Wars With 44 PC Market Share WhatsApp Leads The Global Smartphone Messenger Wars With 44 Percent Market Share


[WhatsApp mobile messenger]

- protocol : customized version of XMPP (http://en.wikipedia.org/wiki/WhatsApp)
- 공식적인 official 3rd party API는 없는 것으로 보이나 기반 protocol이 XMPP이기 때문인지 unofficial한 API library가 존재함.(아래)
- 하지만 unofficial API library, client들은 DCMA로 부터 중단 요청을 받아 일부는 중단되었음.
 (https://raw.githubusercontent.com/github/dmca/master/2014-02-12-WhatsApp.md)

- API는 아니지만 WhatApp app을 통해서 메세지를 보낼 수 있는 방법은 다음과 같음
 : Android - http://www.whatsapp.com/faq/en/android/28000012
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);
 : iPhone - http://www.whatsapp.com/faq/en/iphone/23559013
NSURL *whatsappURL = [NSURL URLWithString:@"whatsapp://send?text=Hello%2C%20World!"];
if ([[UIApplication sharedApplication] canOpenURL: whatsappURL]) {
    [[UIApplication sharedApplication] openURL: whatsappURL];
}

[OpenWhatsApp - 3rd party (unofficial) client source code]
http://openwhatsapp.org/
- 라이센스 : GPLv2 license
- 구성 :
 . UI (QML 기반)
 . backend
 . communication core : python library "Yowsup"
   > communication between frontend and s[Whatsapp mobile messenger]erver
   > authentication
   > image send, receive

[Yowsup library - 3rd party (unofficial) python library]
https://github.com/tgalal/yowsup
Wiki : https://github.com/tgalal/yowsup/wiki
Library documentation : https://github.com/tgalal/yowsup/wiki/Yowsup-Library-Documentation

- Requirements
 . python 2.6+
 . python-dateutil
 . yousup-cli requires argparse for python < 2.7

- License : MIT

- Features
 . Registration
 . Text send/ receive
 . Media send/receive (images, videos, audio, location, contact cards)
 . Groups(create, leave, join, update picture, updating subject)
 . Fetch user profile picture
 . Fetch user status
 . Set profile picture
 . Set group icon
 . Set status and others

이거 원 python을 모르니..

- Authentication

authentication mechanism은 WhatsApp 1.2 protocol (WAUTH-1)을 사용.
username (전화번호), password를 입력 하고 auth가 성공적으로 끝나면 auth_success에서 보는 것과 같이 library에 "ready" method를 전달하여 메세지를 받고 parsing하도록 해야 함.

def onAuthSuccess(username):
    print "Logged in with %s" % s
    # make a call to method ready to be able to receive messages
    methodsInterface.call("ready")


y = YowsupConnectionManager()
signalsInterface = y.getSignalsInterface()
methodsInterface = y.getMethodsInterface()
signalsInterface.registerListener("auth_success", onAuthSuccess)
methodsInterface.call("auth_login", ("username", "password"))

- Message send

Whatsapp 이 XMPP 기반 프로토콜이므로 JID를 사용하고 foramt은 전화번호@s.whatsapp.net 이다.
message 전송은 "message_send" 를 통해 전달하고 sent와 delivered의 차이점은 잘 모르겠지만 아마도 library에서 메세지를 서버에 전달했을 때와 서버에서 메세지를 수신자에게 전달 했음을 알리는 것으로 추측.. 암튼 해당 상황의 listener를 등록하여 메세지가 delivered 상태 일때 아래 sample code와 같이 library를 통해서 ack을 전달해야 한다.

def onMessageSent(jid, messageId):
    print "Message was sent successfully to %s" % jid

def onMessageDelivered(jid, messageId):
    print "Message was delivered successfully to %s" %jid
    methodsInterface.call("delivered_ack", (jid, messageId))

signalsInterface.registerListener("receipt_messageSent", onMessageSent)
signalsInterface.registerListener("receipt_messageDelivered", onMessageDelivered)

methodsInterface.call("message_send", ("identifier@s.whatsapp.net", "Hello World!"))

- Message receiving

아래 예제에서는 message 수신 시 "message_id"를 library로 전달하는 코드지만 설명에서는 "message_received" signal을 받으면 listener에서 "message_ack"를 호출해야 한다고 하고 있음. 안그러면 (xmpp 설정, 아마도) 로그인할 때 마다 메세지를 받게 된다.
methodsInterface.call("message_id", ("identifier@s.whatsapp.net", messageId)

- Keep Alive

whatsapp은 3분 마다 "ping"을 전달하여 connection을 유지하므로 listener를 등록해서 "ping" request에 대해서 response하던가 아니면 setAutoPong()를 사용하여 자동적으로 처리 하게 할 수 있다.
To Listen and respond to pings:
def onPing(pingId):
    methodsInterface.call("pong", (pingId,))

signalsInterface.registerListener("ping", onPing)
To tell Yowsup to automatically respond to pings and keep connection alive
y = YowsupConnectionManager()
y.setAutoPong(True)


- Signals
https://github.com/tgalal/yowsup/wiki/Yowsup-Library-Documentation#full-list-of-signals

관심있는 것만 정리하면

 . Messages
message_received(int messageId,str jid,str content,long timestamp,bool receiptRequested)
group_messageReceived(int messageId, str jid, str author, str messageContent, long timestamp, bool wantsReceipt, str pushName):
pushName(int messageId,str jid,str author,str content,long timestamp,bool receiptRequested, str pushName)
 . Groups
group_gotInfo(str jid,str owner,str subject,str subjectOwner,long subjectTimestamp,long creationTimestamp)
group_setSubjectSuccess(str jid)
group_subjectReceived(int messageId,str jid,str author,str subject,long timestamp,bool receiptRequested)
group_addParticipantsSuccess(str jid)
group_removeParticipantsSuccess(str jid)
group_createSuccess(str jid,str groupJid)
group_createFail(int errorCode)
group_endSuccess(str jid)
group_gotPicture(str jid,str filePath)
group_infoError(int errorCode)
group_gotParticipants(str jid,list jids)
group_setPictureSuccess(str jid)
group_setPictureError(str jid,int errorCode)
. Profile
profile_setStatusSuccess(str jid,int messageId)
profile_setPictureSuccess()
profile_setPictureError(int errorCode)
. Contacts
contact_gotProfilePictureId(str jid,long pictureId)
contact_typing(str jid)
contact_paused(str jid)
contact_gotProfilePicture(str jid,str filePath)
 . Media
image_received(int messageId,str jid,str preview,str url,int size,bool receiptRequested)
video_received(int messageId,str jid,str preview,str url,int size,bool receiptRequested)
audio_received(int messageId,str jid,str url,int size,bool receiptRequested)
location_received(int messageId,str jid,str name,str preview,float latitude,float longitude,bool receiptRequested)
vcard_received(int messageId,str jid,str name,str data,bool receiptRequested)
group_imageReceived(int messageId,str jid,str author,str preview,str url,int size,bool receiptRequested)
group_videoReceived(int messageId,str jid,str author,str preview,str url,int size,bool receiptRequested)
group_audioReceived(int messageId,str jid,str author,str url,int size,bool receiptRequested)
group_locationReceived(int messageId,str jid,str author,str name,str preview,float latitude,float longitude,bool receiptRequested)
group_vcardReceived(int messageId,str jid,str author,str name,str data,bool receiptRequested)

- Methods
https://github.com/tgalal/yowsup/wiki/Yowsup-Library-Documentation#full-list-of-methods

역시 관심 있는 것들만

 . Media
message_imageSend(str jid,str url,str name,int size,str preview)
message_videoSend(str jid,str url,str name,int size,str preview)
message_audioSend(str jid,str url,str name,int size)
message_locationSend(str jid,float latitude,float longitude,str preview)
message_vcardSend(str jid,str data,str name)
. Groups
group_getInfo(str jid)
group_getPicture(str jid)
group_create(str subject)
group_addParticipants(str jid,str participants)
group_removeParticipants(str jid,str participants)
group_setPicture(str jid,str filePath)
group_end(str jid)
group_setSubject(str jid,str subject)
group_getParticipants(str jid)
. Contacts
contact_getProfilePicture(str jid)
picture_getIds(list jids)
. Profile
profile_getPicture()
profile_setStatus(str status)
profile_setPicture(str filePath)


[WeChat mobile messenger]

- protocol : ? (TCP based..)
WeChat API : http://developers.wechat.com/
 . Install guide : http://developers.wechat.com/wechatapi/installguide

- Android, iOS 버전을 제공함.
- Overview에서 소개된 시나리오는 WeChat app을 통해 message, content를 공유하는 시나리오인 것으로 보임.
 : http://developers.wechat.com/wechatapi/messages-moments#title-Images


. Sharing via WeChat Message



. Share on WeChat Moments


- 공개된 API들은 auth, message/content(image, music, video, url, file) send 정도의 API들이 있는 것으로 보이고 위 시나리오들을 충족하기 위한 minimum API들인것으로 보인다.

- Text sending

여러 예제(image, music, video, links)들이 있지만 간단한 text 전송을 살펴 보면
아래와 같이 간단하다. 아무래도 (API를 좀 더 들여봐야 겠지만) WeChat app들과 연동되게 되어 있는 것으로 보이고 그래서 API들도 제한적으로 보인다.

text를 담을 WXTextObject 생성
//Init a WXTextObject object
WXTextObject textObj = new WXTextObject();
textObj.text = text;

WXMediaMessage를 생성하여 위의 text object assign
//Init a WXMediaMessage object with WXTextObject
WXMediaMessage msg = newWXMediaMessage();
msg.mediaObject = textObj;
//the title is useless when send a text
//msg.title = "Will be ignored";
msg.description = text;

WeChat contacts들에 share 하기
//Construct a req
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("text");
req.message = msg;
req.scene = SendMessageToWX.Req.WXSceneSession;
//Using API to send data to WeChat
api.sendReq(req);

WeChat moments로 share 하기
//Construct a req
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("text");
req.message = msg;
req.scene = SendMessageToWX.Req.WXSceneTimeline;
//Using API to send data to WeChat
api.sendReq(req);


[Telegram mobile messenger]

Telegram 소개
http://zunonia.wordpress.com/2014/03/04/%EC%83%88%EB%A1%AD%EA%B2%8C-%EB%96%A0%EC%98%A4%EB%A5%B4%EA%B3%A0-%EC%9E%88%EB%8A%94-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EB%A9%94%EC%8B%A0%EC%A0%80-telegram/

특징

API - https://core.telegram.org/api
Protocol - MTProto, https://core.telegram.org/mtproto

- method list
 . Auth, user info, contacts, message send/recv, secret chat, file transfer 등의 API들 존재
 . 아.. 좀 어렵다. API도 그렇고 protocol은 더 상당하고..


[Line]

기업을 위한 API를 제공한다는 기사가 있었음.
아마도 계약된 3rd party를 위한 closed API로 보임.
 : http://thenextweb.com/asia/2012/07/03/asian-mobile-messaging-service-line-embraces-apps-and-opens-the-api-for-its-45m-user-strong-platform/

iOS에서 app을 통해서 메세지를 전달하는 방법은 다음의 링크를
: http://blog.naver.com/PostView.nhn?blogId=apocalypsegm&logNo=130171221611&redirect=Dlog&widgetTypeCall=true
http://www.prnewswire.com/news-releases/nhn-japan-to-launch-lines-new-platform-service-line-channel-161178635.htmlhttp://www.prnewswire.com/news-releases/nhn-japan-to-launch-lines-new-platform-service-line-channel-161178635.html
아래는 개인적으로 packet capture를 통해 확인한 프로토콜.
참고만 해야 할듯. 계속 사용할 수 있는지 불분명한지라..

1 - http://carpedm20.blogspot.kr/2013/09/line-reverse-engineering.html
2 - http://carpedm20.blogspot.kr/2013/09/line-protocol-analysis-2.html
3 - http://carpedm20.blogspot.kr/2013/09/line-protocol-analysis-3-session-key.html
4 - http://carpedm20.blogspot.kr/2013/09/line-protocol-analysis-4-registration.html

기타로 Line Channel 이라는 개념이 2012년 함께 발표 되었음.
game, app, music, coupon등을 제공하는 platform의 개념으로 Line을 만들어 가겠다는 의미이고
기술적인 관점에서는 해당 content들은 HTML5 based web app이나 linked native app으로
Line app을 통해 제공된다고 함.
http://www.serkantoto.com/2012/07/03/line-channel-nhn/
http://www.prnewswire.com/news-releases/nhn-japan-to-launch-lines-new-platform-service-line-channel-161178635.html

[KakaoTalk]

- 공개된 API - https://developers.kakao.com/

 . 카카오톡 프로필 요청,  카카오링크 전송 API를 제공 중임.
  : 프로파일에서 제공되는 정보는 nickname, image URL, thumbnail URL, 국가 정보
  : 카카오링크의 형식 : 텍스트, 이미지, 링크(웹, 앱), 버튼(웹, 앱)


- 추가로 Line과 마찬가지로 사용자가 packet capture하여 확인한 프로토콜. 겁나빠른 황소(LOCO) 프로젝트의 결과물의 protocol이라고 함.

https://www.bpak.org/blog/2012/12/kakaotalk-loco-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EB%B6%84%EC%84%9D-1/
https://www.bpak.org/blog/2012/12/kakaotalk-loco-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EB%B6%84%EC%84%9D-2/
http://www.bpak.org/blog/2012/12/kakaotalk-loco-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EB%B6%84%EC%84%9D-3/
https://www.bpak.org/blog/2012/12/kakaotalk-loco-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EB%B6%84%EC%84%9D-4/