Skip to content

Commit

Permalink
Merge branch 'dev' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
storycraft committed Feb 19, 2021
2 parents e45c742 + c57199c commit 1c32a5d
Show file tree
Hide file tree
Showing 377 changed files with 19,810 additions and 17,831 deletions.
35 changes: 35 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"env": {
"browser": true,
"es2021": true
},
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"extends": [
"plugin:@typescript-eslint/recommended",
"eslint:recommended",
"google",
"prettier"
],
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"rules": {
"no-undef": 0,
"require-jsdoc": 0,
"linebreak-style": 0,
"no-unused-vars": 0,
"@typescript-eslint/no-namespace": 0,
"object-curly-spacing": [
"error",
"always"
],
"max-len": [
"error",
120
]
}
}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@ typings/
# next.js build output
.next

docs/
dist/
dist_esm/
loco-test.ts
deno-test.ts

# vim swp file
# vim swp file
*.swp
6 changes: 0 additions & 6 deletions .npmignore

This file was deleted.

7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib",
"editor.tabSize": 2,
"editor.detectIndentation": false,
"typescript.preferences.quoteStyle": "single",
"javascript.preferences.quoteStyle": "single"
}
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 storycraft
Copyright (c) 2021 storycraft

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
62 changes: 62 additions & 0 deletions examples/device-registration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Created on Wed Feb 17 2021
*
* Copyright (c) storycraft. Licensed under the MIT Licence.
*/

import { AuthApiClient, KnownAuthStatusCode } from 'node-kakao';
import * as readline from 'readline';

/*
* Register new sub device to login
*/
const EMAIL = process.env['accountEmail'] as string;
const PASSWORD = process.env['accountPwd'] as string;

// You can use util module and call randomDeviceUUID function to generate random device uuid
//
// import { util } from '../node-kakao';
// const randomUUID = util.randomDeviceUUID();
const DEVICE_UUID = process.env['deviceUUID'] as string;

// This can be changed and official client will show latest name used.
const DEVICE_NAME = process.env['deviceName'] as string;

async function main() {
const form = {
email: EMAIL,
password: PASSWORD,

// This option force login even other devices are logon
forced: true,
};

const api = await AuthApiClient.create(DEVICE_NAME, DEVICE_UUID);
const loginRes = await api.login(form);
if (loginRes.success) throw new Error('Device already registered!');
if (loginRes.status !== KnownAuthStatusCode.DEVICE_NOT_REGISTERED) {
throw new Error(`Web login failed with status: ${loginRes.status}`);
}

const passcodeRes = await api.requestPasscode(form);
if (!passcodeRes.success) throw new Error(`Passcode request failed with status: ${passcodeRes.status}`);

const inputInterface = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const passcode = await new Promise<string>((resolve) => inputInterface.question('Enter passcode: ', resolve));
inputInterface.close();

// Giving permanent value to false will allow to login only once.
const registerRes = await api.registerDevice(form, passcode, true);
if (!registerRes.success) throw new Error(`Device registration failed with status: ${passcodeRes.status}`);

console.log(`Device ${DEVICE_UUID} has been registered`);

// Login after registering devices
const loginAfterRes = await api.login(form);
if (!loginAfterRes.success) throw new Error(`Web login failed with status: ${passcodeRes.status}`);
console.log(`Client logon successfully`);
}
main().then();
105 changes: 105 additions & 0 deletions examples/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Created on Wed Feb 17 2021
*
* Copyright (c) storycraft. Licensed under the MIT Licence.
*/

/*
* This example contains listening various type of events.
*/

import { TalkClient } from 'node-kakao';

// Supply env variables or replace to value.
const DEVICE_UUID = process.env['deviceUUID'] as string;
const ACCESS_TOKEN = process.env['accessToken'] as string;
const REFRESH_TOKEN = process.env['refreshToken'] as string;

const CLIENT = new TalkClient();

CLIENT.on('error', (err) => {
console.log(`Client error!! err: ${err}`);
});

CLIENT.on('switch_server', () => {
console.log('Server switching requested.');
});

CLIENT.on('disconnected', (reason) => {
console.log(`Disconnected!! reason: ${reason}`);
});

CLIENT.on('chat_deleted', (feedChatlog, channel, feed) => {
console.log(`${feed.logId} deleted by ${feedChatlog.sender.userId}`);
});

CLIENT.on('link_created', link => {
console.log(`Link created: ${link.openLink.linkId} url: ${link.openLink.linkURL}`);
});

CLIENT.on('link_deleted', link => {
console.log(`Link deleted: ${link.openLink.linkId} url: ${link.openLink.linkURL}`);
});

CLIENT.on('user_join', (joinLog, channel, user, feed) => {
console.log(`User ${user.nickname} (${user.userId}) joined channel ${channel.channelId}`);
});

CLIENT.on('user_left', (leftLog, channel, user, feed) => {
console.log(`User ${user.nickname} (${user.userId}) left channel ${channel.channelId}`);
});

CLIENT.on('profile_changed', (channel, lastInfo, user) => {
console.log(`Profile of ${user.userId} changed. From name: ${lastInfo.nickname} profile: ${lastInfo.profileURL}`);
});

CLIENT.on('perm_changed', (channel, lastInfo, user) => {
console.log(`Perm of ${user.userId} changed. From ${lastInfo.perm} to ${user.perm}`);
});

CLIENT.on('channel_join', channel => {
console.log(`Joining channel ${channel.getDisplayName()}`);
});

CLIENT.on('channel_left', channel => {
console.log(`Leaving channel ${channel.getDisplayName()}`);
});

CLIENT.on('message_hidden', (hideLog, channel, feed) => {
console.log(`Message ${hideLog.logId} hid from ${channel.channelId} by ${hideLog.sender.userId}`);
});

CLIENT.on('channel_link_deleted', (feedLog, channel, feed) => {
console.log(`Open channel (${channel.channelId}) link has been deleted`);
});

CLIENT.on('host_handover', (channel, lastLink, link) => {
const lastOwnerNick = lastLink.linkOwner.nickname;
const newOwnerNick = link.linkOwner.nickname;

console.log(`OpenLink host handover on channel ${channel.channelId} from ${lastOwnerNick} to ${newOwnerNick}`);
});

CLIENT.on('channel_kicked', (kickedLog, channel, feed) => {
console.log(`Kicked from channel ${channel.channelId}`);
});

CLIENT.on('meta_change', (channel, type, newMeta) => {
console.log(`Meta changed from ${channel.channelId} type: ${type} meta: ${newMeta.content} by ${newMeta.authorId}`);
});

CLIENT.on('chat_event', (channel, author, type, count, chat) => {
channel.sendChat(`${author.nickname} touched hearts ${count} times`);
});

async function main() {
const res = await CLIENT.login({
deviceUUID: DEVICE_UUID,
accessToken: ACCESS_TOKEN,
refreshToken: REFRESH_TOKEN
});
if (!res.success) throw new Error(`Login failed with status: ${res.status}`);

console.log('Login success');
}
main().then();
44 changes: 44 additions & 0 deletions examples/get-chat-readers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Created on Wed Feb 10 2021
*
* Copyright (c) storycraft. Licensed under the MIT Licence.
*/

/*
* This example sends reader list of replied chat when user types command "!readers"
*/

import { KnownChatType, ReplyAttachment, TalkClient } from 'node-kakao';

// Supply env variables or replace to value.
const DEVICE_UUID = process.env['deviceUUID'] as string;
const ACCESS_TOKEN = process.env['accessToken'] as string;
const REFRESH_TOKEN = process.env['refreshToken'] as string;

const CLIENT = new TalkClient();

CLIENT.on('chat', (data, channel) => {
const sender = data.getSenderInfo(channel);
if (!sender) return;

if (data.originalType === KnownChatType.REPLY && data.text === '!readers') {
const reply = data.attachment<ReplyAttachment>();
const logId = reply.src_logId;
if (logId) {
const readers = channel.getReaders({ logId });
channel.sendChat(`${logId} Readers (${readers.length})\n${readers.map(reader => reader.nickname).join(', ')}`);
}
}
});

async function main() {
const res = await CLIENT.login({
deviceUUID: DEVICE_UUID,
accessToken: ACCESS_TOKEN,
refreshToken: REFRESH_TOKEN
});
if (!res.success) throw new Error(`Login failed with status: ${res.status}`);

console.log('Login success');
}
main().then();
59 changes: 59 additions & 0 deletions examples/login-chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Created on Sun Jan 31 2021
*
* Copyright (c) storycraft. Licensed under the MIT Licence.
*/

/*
* Login using email, password using AuthApiClient.
* Following this example will make automatic reply at text "안녕하세요" with mention.
*/

import { AuthApiClient, ChatBuilder, KnownChatType, MentionContent, ReplyContent, TalkClient } from 'node-kakao';

// Supply env variables or replace to value.
const DEVICE_UUID = process.env['deviceUUID'] as string;
const DEVICE_NAME = process.env['deviceName'] as string;

const EMAIL = process.env['accountEmail'] as string;
const PASSWORD = process.env['accountPwd'] as string;

const CLIENT = new TalkClient();

CLIENT.on('chat', (data, channel) => {
const sender = data.getSenderInfo(channel);
if (!sender) return;

if (data.text === '안녕하세요') {
// 답장 형식
// 안녕하세요 @xxx
channel.sendChat(
new ChatBuilder()
.append(new ReplyContent(data.chat))
.text('안녕하세요 ')
.append(new MentionContent(sender))
.build(KnownChatType.REPLY));
// 일반 텍스트
// channel.sendChat('안녕하세요');
}
});

async function main() {
const api = await AuthApiClient.create(DEVICE_NAME, DEVICE_UUID);
const loginRes = await api.login({
email: EMAIL,
password: PASSWORD,

// This option force login even other devices are logon
forced: true,
});
if (!loginRes.success) throw new Error(`Web login failed with status: ${loginRes.status}`);

console.log(`Received access token: ${loginRes.result.accessToken}`);

const res = await CLIENT.login(loginRes.result);
if (!res.success) throw new Error(`Login failed with status: ${res.status}`);

console.log('Login success');
}
main().then();
30 changes: 30 additions & 0 deletions examples/oauth-renew.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Created on Wed Feb 17 2021
*
* Copyright (c) storycraft. Licensed under the MIT Licence.
*/

/*
* Renew oauth credential using OAuthApiClient
*/
import { OAuthApiClient } from 'node-kakao';

const DEVICE_UUID = process.env['deviceUUID'] as string;
const ACCESS_TOKEN = process.env['accessToken'] as string;
const REFRESH_TOKEN = process.env['refreshToken'] as string;

async function main() {
const oAuthClient = OAuthApiClient.create();

const newTokenRes = await (await oAuthClient).renew({
deviceUUID: DEVICE_UUID,
accessToken: ACCESS_TOKEN,
refreshToken: REFRESH_TOKEN
});
if (!newTokenRes.success) throw new Error(`Cannot renew oauth token: ${newTokenRes.status}`);

const res = newTokenRes.result;
console.log('OAuth renew success');
console.log(`ExpiresIn: ${res.expiresIn}, type: ${res.type}, accessToken: ${res.credential.accessToken}`);
}
main().then();
Loading

0 comments on commit 1c32a5d

Please sign in to comment.