├── [6]chatbot-project ├── firebase.json ├── .firebaserc └── functions │ ├── package.json │ └── index.js ├── [5]chat-project ├── package-lock.json ├── polymer.json ├── database-rules.json ├── .firebaserc ├── manifest.json ├── storage.rules ├── firebase.json ├── functions │ ├── package.json │ └── index.js ├── index.html ├── bower.json ├── README.md ├── test │ └── chat-project-app │ │ └── chat-project-app_test.html └── src │ └── chat-project-app │ ├── chat-msg.html │ ├── chat-project-app.html │ └── view-room.html ├── solid_cover.jpg ├── [2]pwa-youtube ├── polymer.json ├── manifest.json ├── index.html ├── bower.json ├── README.md ├── src │ └── pwa-youtube-app │ │ ├── video-page.html │ │ ├── pwa-youtube-app.html │ │ └── list-page.html └── test │ └── pwa-youtube-app │ └── pwa-youtube-app_test.html ├── [8]music-project ├── client │ ├── polymer.json │ ├── manifest.json │ ├── bower.json │ ├── index.html │ ├── README.md │ ├── test │ │ └── client-app │ │ │ └── client-app_test.html │ └── src │ │ └── client-app │ │ └── client-app.html ├── package.json ├── app.js └── dialogflow.js ├── [7]mapbot-project ├── client │ ├── polymer.json │ ├── manifest.json │ ├── bower.json │ ├── index.html │ ├── README.md │ ├── test │ │ └── client-app │ │ │ └── client-app_test.html │ └── src │ │ └── client-app │ │ └── client-app.html ├── package.json ├── app.js ├── api.js ├── dialogflow.js └── dialogflowv2.js ├── README.md ├── [9]coin-project ├── package.json ├── app.js ├── api.js └── clova.js ├── .gitignore └── .gitattributes /[6]chatbot-project/firebase.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /[5]chat-project/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1 3 | } 4 | -------------------------------------------------------------------------------- /solid_cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bjpublic/easychatbot/master/solid_cover.jpg -------------------------------------------------------------------------------- /[6]chatbot-project/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "bookproject-e57f3" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /[2]pwa-youtube/polymer.json: -------------------------------------------------------------------------------- 1 | { 2 | "lint": { 3 | "rules": [ 4 | "polymer-2" 5 | ] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /[5]chat-project/polymer.json: -------------------------------------------------------------------------------- 1 | { 2 | "lint": { 3 | "rules": [ 4 | "polymer-2" 5 | ] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /[8]music-project/client/polymer.json: -------------------------------------------------------------------------------- 1 | { 2 | "lint": { 3 | "rules": [ 4 | "polymer-2" 5 | ] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /[7]mapbot-project/client/polymer.json: -------------------------------------------------------------------------------- 1 | { 2 | "lint": { 3 | "rules": [ 4 | "polymer-2" 5 | ] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /[5]chat-project/database-rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | ".read": "auth != null", 4 | ".write": "auth != null" 5 | } 6 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 누구나 쉽게 배우는 챗봇 서비스 2 | 3 | ![Alt text](https://github.com/bjpublic/easychatbot/blob/master/solid_cover.jpg "solid_cover.jpg") 4 | -------------------------------------------------------------------------------- /[5]chat-project/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "testdemo-staging": "testdemo-d7b23", 4 | "default": "testdemo-d7b23" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /[2]pwa-youtube/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pwa-youtube", 3 | "short_name": "pwa-youtube", 4 | "start_url": "/", 5 | "display": "standalone" 6 | } 7 | -------------------------------------------------------------------------------- /[7]mapbot-project/client/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "short_name": "client", 4 | "start_url": "/", 5 | "display": "standalone" 6 | } 7 | -------------------------------------------------------------------------------- /[8]music-project/client/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "short_name": "client", 4 | "start_url": "/", 5 | "display": "standalone" 6 | } 7 | -------------------------------------------------------------------------------- /[5]chat-project/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chat-project", 3 | "short_name": "chat-project", 4 | "start_url": "/", 5 | "display": "standalone" 6 | } 7 | -------------------------------------------------------------------------------- /[5]chat-project/storage.rules: -------------------------------------------------------------------------------- 1 | service firebase.storage { 2 | match /b/{bucket}/o { 3 | match /{userId}/{fileName} { 4 | allow write: if request.auth.uid == userId; 5 | allow read; 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /[9]coin-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "coin-project", 3 | "version": "1.0.0", 4 | "description": "coin-project", 5 | "main": "app.js", 6 | "author": "Will Park", 7 | "dependencies": { 8 | "body-parser": "^1.18.2", 9 | "express": "^4.16.2", 10 | "request": "^2.83.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /[8]music-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "music-project", 3 | "version": "1.0.0", 4 | "description": "music-project", 5 | "main": "app.js", 6 | "author": "WillPark", 7 | "dependencies": { 8 | "body-parser": "^1.18.2", 9 | "express": "^4.16.3", 10 | "request": "^2.85.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows thumbnail cache files 2 | Thumbs.db 3 | ehthumbs.db 4 | ehthumbs_vista.db 5 | 6 | # Folder config file 7 | Desktop.ini 8 | 9 | # Recycle Bin used on file shares 10 | $RECYCLE.BIN/ 11 | 12 | # Windows Installer files 13 | *.cab 14 | *.msi 15 | *.msm 16 | *.msp 17 | 18 | # Windows shortcuts 19 | *.lnk 20 | 21 | # ========================= 22 | # Operating System Files 23 | # ========================= 24 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /[8]music-project/client/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "main": "index.html", 4 | "dependencies": { 5 | "polymer": "Polymer/polymer#^2.0.0", 6 | "paper-input": "PolymerElements/paper-input#^2.2.0", 7 | "paper-button": "PolymerElements/paper-button#^2.1.0" 8 | }, 9 | "devDependencies": { 10 | "web-component-tester": "Polymer/web-component-tester#^6.0.0", 11 | "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /[7]mapbot-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mapbot-project", 3 | "version": "1.0.0", 4 | "description": "mapbot-project", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "WillPark", 10 | "dependencies": { 11 | "body-parser": "^1.18.2", 12 | "dialogflow": "^0.1.0", 13 | "express": "^4.16.3", 14 | "firebase-admin": "^5.11.0", 15 | "request": "^2.85.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /[5]chat-project/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | // If you went through the "Realtime Database Security Rules" step. 3 | "database": { 4 | "rules": "database-rules.json" 5 | }, 6 | // If you went through the "Storage Security Rules" step. 7 | "storage": { 8 | "rules": "storage.rules" 9 | }, 10 | "hosting": { 11 | "public": "./", 12 | "ignore": [ 13 | "firebase.json", 14 | "database-rules.json", 15 | "storage.rules" 16 | ] 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /[8]music-project/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | const app = express(); 4 | app.use(bodyParser.urlencoded({limit: '50mb', extended: true})); 5 | app.use(bodyParser.json()); 6 | 7 | app.use((err, req, res, next) => next()); 8 | 9 | app.use('/web', express.static(__dirname + '/client')); 10 | 11 | require('./dialogflow')(app); 12 | 13 | const server = app.listen(3000, function(){ 14 | console.log("Express server has started on port 3000") 15 | }); -------------------------------------------------------------------------------- /[6]chatbot-project/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": { 5 | "serve": "firebase serve --only functions", 6 | "shell": "firebase experimental:functions:shell", 7 | "start": "npm run shell", 8 | "deploy": "firebase deploy --only functions", 9 | "logs": "firebase functions:log" 10 | }, 11 | "dependencies": { 12 | "actions-on-google": "^1.9.0", 13 | "firebase-admin": "~5.4.2", 14 | "firebase-functions": "^0.9.0" 15 | }, 16 | "private": true 17 | } 18 | -------------------------------------------------------------------------------- /[9]coin-project/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | const app = express(); 4 | app.use(bodyParser.json()); 5 | 6 | app.use((err, req, res, next) => next()); 7 | 8 | require('./api')(app); 9 | require('./clova')(app); 10 | 11 | // catch 404 and forward to error handler 12 | app.use((req, res, next) => { 13 | const err = new Error('Not Found'); 14 | err.status = 404; 15 | next(err); 16 | }); 17 | 18 | const server = app.listen(3000, function(){ 19 | console.log("Express server has started on port 3000") 20 | }); -------------------------------------------------------------------------------- /[7]mapbot-project/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | const app = express(); 4 | app.use(bodyParser.urlencoded({limit: '50mb', extended: true})); 5 | app.use(bodyParser.json()) 6 | 7 | app.use((err, req, res, next) => next()); 8 | 9 | app.use('/web', express.static(__dirname + '/client')); 10 | 11 | // for setting data on server 12 | // require('./api')(app); 13 | // app.putGhData(); 14 | require('./dialogflow')(app); 15 | 16 | app.listen(4000, () => { 17 | console.log('Express server listening on port 4000'); 18 | }); 19 | -------------------------------------------------------------------------------- /[7]mapbot-project/client/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "main": "index.html", 4 | "dependencies": { 5 | "polymer": "Polymer/polymer#^2.0.0", 6 | "google-map": "GoogleWebComponents/google-map#^2.0.4", 7 | "polymerfire": "firebase/polymerfire#^2.2.1", 8 | "paper-input": "PolymerElements/paper-input#^2.2.0", 9 | "paper-button": "PolymerElements/paper-button#^2.1.0" 10 | }, 11 | "devDependencies": { 12 | "web-component-tester": "Polymer/web-component-tester#^6.0.0", 13 | "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /[5]chat-project/functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": { 5 | "serve": "firebase serve --only functions", 6 | "shell": "firebase experimental:functions:shell", 7 | "start": "npm run shell", 8 | "deploy": "firebase deploy --only functions", 9 | "logs": "firebase functions:log" 10 | }, 11 | "dependencies": { 12 | "@google-cloud/storage": "^1.6.0", 13 | "@google-cloud/vision": "^0.16.0", 14 | "firebase-admin": "^5.11.0", 15 | "firebase-functions": "^0.8.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /[2]pwa-youtube/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | pwa-youtube 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /[5]chat-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | chat-project 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /[5]chat-project/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chat-project", 3 | "main": "index.html", 4 | "dependencies": { 5 | "polymer": "Polymer/polymer#^2.0.0", 6 | "paper-input": "PolymerElements/paper-input#^2.0.5", 7 | "paper-button": "PolymerElements/paper-button#^2.0.0", 8 | "paper-fab": "PolymerElements/paper-fab#^2.0.0", 9 | "iron-list": "PolymerElements/iron-list#^2.0.12", 10 | "polymerfire": "firebase/polymerfire#^2.2.1", 11 | "iron-icons": "PolymerElements/iron-icons#^2.0.1", 12 | "iron-image": "PolymerElements/iron-image#^2.2.0" 13 | }, 14 | "devDependencies": { 15 | "web-component-tester": "Polymer/web-component-tester#^6.0.0", 16 | "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /[8]music-project/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | client 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /[2]pwa-youtube/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pwa-youtube", 3 | "main": "index.html", 4 | "dependencies": { 5 | "polymer": "Polymer/polymer#^2.0.0", 6 | "app-layout": "PolymerElements/app-layout#^2.0.4", 7 | "app-route": "PolymerElements/app-route#^2.0.3", 8 | "iron-pages": "PolymerElements/iron-pages#^2.0.1", 9 | "iron-flex-layout": "PolymerElements/iron-flex-layout#^2.0.1", 10 | "iron-ajax": "PolymerElements/iron-ajax#^2.1.3", 11 | "iron-list": "PolymerElements/iron-list#^2.0.13", 12 | "iron-scroll-threshold": "PolymerElements/iron-scroll-threshold#^2.0.0", 13 | "google-youtube": "GoogleWebComponents/google-youtube#^2.0.0" 14 | }, 15 | "devDependencies": { 16 | "web-component-tester": "Polymer/web-component-tester#^6.0.0", 17 | "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /[7]mapbot-project/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | mapbot-project 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /[5]chat-project/README.md: -------------------------------------------------------------------------------- 1 | # \ 2 | 3 | 4 | 5 | ## Install the Polymer-CLI 6 | 7 | First, make sure you have the [Polymer CLI](https://www.npmjs.com/package/polymer-cli) installed. Then run `polymer serve` to serve your application locally. 8 | 9 | ## Viewing Your Application 10 | 11 | ``` 12 | $ polymer serve 13 | ``` 14 | 15 | ## Building Your Application 16 | 17 | ``` 18 | $ polymer build 19 | ``` 20 | 21 | This will create builds of your application in the `build/` directory, optimized to be served in production. You can then serve the built versions by giving `polymer serve` a folder to serve from: 22 | 23 | ``` 24 | $ polymer serve build/default 25 | ``` 26 | 27 | ## Running Tests 28 | 29 | ``` 30 | $ polymer test 31 | ``` 32 | 33 | Your application is already set up to be tested via [web-component-tester](https://github.com/Polymer/web-component-tester). Run `polymer test` to run your application's test suite locally. 34 | -------------------------------------------------------------------------------- /[7]mapbot-project/client/README.md: -------------------------------------------------------------------------------- 1 | # \ 2 | 3 | 4 | 5 | ## Install the Polymer-CLI 6 | 7 | First, make sure you have the [Polymer CLI](https://www.npmjs.com/package/polymer-cli) installed. Then run `polymer serve` to serve your application locally. 8 | 9 | ## Viewing Your Application 10 | 11 | ``` 12 | $ polymer serve 13 | ``` 14 | 15 | ## Building Your Application 16 | 17 | ``` 18 | $ polymer build 19 | ``` 20 | 21 | This will create builds of your application in the `build/` directory, optimized to be served in production. You can then serve the built versions by giving `polymer serve` a folder to serve from: 22 | 23 | ``` 24 | $ polymer serve build/default 25 | ``` 26 | 27 | ## Running Tests 28 | 29 | ``` 30 | $ polymer test 31 | ``` 32 | 33 | Your application is already set up to be tested via [web-component-tester](https://github.com/Polymer/web-component-tester). Run `polymer test` to run your application's test suite locally. 34 | -------------------------------------------------------------------------------- /[8]music-project/client/README.md: -------------------------------------------------------------------------------- 1 | # \ 2 | 3 | 4 | 5 | ## Install the Polymer-CLI 6 | 7 | First, make sure you have the [Polymer CLI](https://www.npmjs.com/package/polymer-cli) installed. Then run `polymer serve` to serve your application locally. 8 | 9 | ## Viewing Your Application 10 | 11 | ``` 12 | $ polymer serve 13 | ``` 14 | 15 | ## Building Your Application 16 | 17 | ``` 18 | $ polymer build 19 | ``` 20 | 21 | This will create builds of your application in the `build/` directory, optimized to be served in production. You can then serve the built versions by giving `polymer serve` a folder to serve from: 22 | 23 | ``` 24 | $ polymer serve build/default 25 | ``` 26 | 27 | ## Running Tests 28 | 29 | ``` 30 | $ polymer test 31 | ``` 32 | 33 | Your application is already set up to be tested via [web-component-tester](https://github.com/Polymer/web-component-tester). Run `polymer test` to run your application's test suite locally. 34 | -------------------------------------------------------------------------------- /[2]pwa-youtube/README.md: -------------------------------------------------------------------------------- 1 | # \ 2 | 3 | # 2장 도구2. 폴리머(Polymer) - PWA 유투브 웹앱 만들기 4 | 5 | ## Install the Polymer-CLI 6 | 7 | First, make sure you have the [Polymer CLI](https://www.npmjs.com/package/polymer-cli) installed. Then run `polymer serve` to serve your application locally. 8 | 9 | ## Viewing Your Application 10 | 11 | ``` 12 | $ polymer serve 13 | ``` 14 | 15 | ## Building Your Application 16 | 17 | ``` 18 | $ polymer build 19 | ``` 20 | 21 | This will create builds of your application in the `build/` directory, optimized to be served in production. You can then serve the built versions by giving `polymer serve` a folder to serve from: 22 | 23 | ``` 24 | $ polymer serve build/default 25 | ``` 26 | 27 | ## Running Tests 28 | 29 | ``` 30 | $ polymer test 31 | ``` 32 | 33 | Your application is already set up to be tested via [web-component-tester](https://github.com/Polymer/web-component-tester). Run `polymer test` to run your application's test suite locally. 34 | -------------------------------------------------------------------------------- /[8]music-project/dialogflow.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | 3 | const request = require('request'); 4 | const TOKEN = '[dialogflow v1 TOKEN]'; 5 | 6 | 7 | app.post('/process', (req, res) => { 8 | const query = req.body.query; 9 | 10 | if(!query){ 11 | res.json({flag: 0}); 12 | return; 13 | } 14 | 15 | const session_id = 'my_session_id'; 16 | const language = 'ko' 17 | 18 | const api_url = `https://api.dialogflow.com/v1/query?v=20170712&lang=${language}&sessionId=${session_id}&query=${query}` 19 | 20 | const options = { 21 | url: encodeURI(api_url), 22 | headers: { 23 | 'Authorization': "Bearer "+TOKEN, 24 | 'Content-Type': 'application/x-www-form-urlencoded' 25 | } 26 | }; 27 | request.get(options, function (error, response, body) { 28 | if (!error) { 29 | const objResult = JSON.parse(body); 30 | res.json({flag: 1, data: objResult.result.parameters}); 31 | 32 | } else { 33 | console.error("e:"+error); 34 | } 35 | }); 36 | 37 | }); 38 | 39 | } -------------------------------------------------------------------------------- /[2]pwa-youtube/src/pwa-youtube-app/video-page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25 | 26 | 51 | 52 | -------------------------------------------------------------------------------- /[5]chat-project/functions/index.js: -------------------------------------------------------------------------------- 1 | const functions = require('firebase-functions'); 2 | const gcs = require('@google-cloud/storage')(); 3 | const vision = require('@google-cloud/vision'); 4 | const client = new vision.ImageAnnotatorClient(); 5 | const admin = require('firebase-admin'); 6 | admin.initializeApp(functions.config().firebase); 7 | 8 | 9 | exports.addWelcomeMessages = functions.auth.user().onCreate(event => { 10 | const user = event.data; 11 | const fullName = user.displayName || 'Anonymous'; 12 | 13 | return admin.database().ref('messages').push({ 14 | ctype: 0, 15 | username: 'notify', 16 | content: `${fullName} 님이 들어왔습니다!!` 17 | }).then(() => console.log('Complete...')); 18 | }); 19 | 20 | 21 | exports.analyzeImage = functions.storage.object().onChange(event => { 22 | const object = event.data; 23 | if (object.resourceState === 'not_exists') { 24 | return console.log('deletion event.'); 25 | } else if (!object.name) { 26 | return console.log('deploy event.'); 27 | } 28 | 29 | const imageUri = `gs://${object.bucket}/${object.name}`; 30 | 31 | return client 32 | .labelDetection(imageUri) 33 | .then(results => { 34 | const labels = results[0].labelAnnotations; 35 | 36 | admin.database().ref('messages').push({ 37 | ctype: 0, 38 | username: 'notify', 39 | content: `이 이미지는 ${labels[0].description} 입니다` 40 | }); 41 | 42 | }) 43 | .catch(err => { 44 | console.error('error:', err); 45 | }); 46 | 47 | }); -------------------------------------------------------------------------------- /[2]pwa-youtube/src/pwa-youtube-app/pwa-youtube-app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 33 | 34 | 49 | 50 | -------------------------------------------------------------------------------- /[7]mapbot-project/client/test/client-app/client-app_test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | client-app test 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /[8]music-project/client/test/client-app/client-app_test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | client-app test 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /[2]pwa-youtube/test/pwa-youtube-app/pwa-youtube-app_test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | pwa-youtube-app test 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /[5]chat-project/test/chat-project-app/chat-project-app_test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | chat-project-app test 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /[5]chat-project/src/chat-project-app/chat-msg.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 57 | 58 | 80 | -------------------------------------------------------------------------------- /[9]coin-project/api.js: -------------------------------------------------------------------------------- 1 | module.exports = (app) => { 2 | 3 | const request = require('request'); 4 | 5 | ///// korbit 6 | const getKorbitData = (symbol) => { 7 | return new Promise((resolve, reject) => { 8 | request.get(`https://api.korbit.co.kr/v1/ticker?currency_pair=${symbol}_krw`, 9 | function(error, response, body) { 10 | if(error){ 11 | reject(); 12 | return; 13 | } 14 | 15 | const data = JSON.parse(body); 16 | 17 | resolve(data.last); 18 | }); 19 | }); 20 | } 21 | 22 | const getBitfinanceData = (symbol) => { 23 | return new Promise((resolve, reject) => { 24 | request.get(`https://api.bitfinex.com/v1/pubticker/${symbol}usd`, 25 | function(error, response, body) { 26 | if(error) { 27 | reject(); 28 | return; 29 | } 30 | 31 | const data = JSON.parse(body); 32 | 33 | resolve(data.last_price); 34 | }); 35 | }); 36 | } 37 | 38 | 39 | const getExchangeRate = () => { 40 | return new Promise((resolve, reject) => { 41 | request.get('https://api.fixer.io/latest?symbols=USD,KRW', 42 | function(error, response, body) { 43 | if(error) { 44 | reject(); 45 | return; 46 | } 47 | 48 | const data = JSON.parse(body); 49 | 50 | resolve(data); 51 | }); 52 | }); 53 | } 54 | 55 | 56 | app.getPremium = () => { 57 | return new Promise((resolve, reject) => { 58 | Promise.all([getKorbitData('btc'), getBitfinanceData('btc'), getExchangeRate()]).then((values) => { 59 | const ko_krw = values[0]; 60 | const en_usd = values[1]; 61 | 62 | const krw_rate = values[2].rates.KRW; 63 | const usd_rate = values[2].rates.USD; 64 | 65 | const premium_price = ko_krw - (en_usd * krw_rate / usd_rate); 66 | const premium_percent = premium_price*100/ko_krw; 67 | 68 | const result = {premium_price, premium_percent}; 69 | resolve(result); 70 | }); 71 | }); 72 | 73 | } 74 | 75 | app.getPrice = (symbol) => { 76 | return new Promise((resolve, reject) => { 77 | getKorbitData(symbol).then((value) => { 78 | const result = {value}; 79 | resolve(result); 80 | }); 81 | }); 82 | } 83 | 84 | } -------------------------------------------------------------------------------- /[5]chat-project/src/chat-project-app/chat-project-app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 30 | 31 | 65 | 66 | -------------------------------------------------------------------------------- /[6]chatbot-project/functions/index.js: -------------------------------------------------------------------------------- 1 | const functions = require('firebase-functions'); 2 | 3 | const admin = require('firebase-admin'); 4 | admin.initializeApp(functions.config().firebase); 5 | 6 | const DialogflowApp = require('actions-on-google').DialogflowApp; 7 | 8 | 9 | exports.assistant = functions.https 10 | .onRequest((request, response) => { 11 | 12 | const app = new DialogflowApp({request: request, response: response}); 13 | app.handleRequest(handlerRequest); 14 | 15 | 16 | function handlerRequest(assistant) { 17 | const location = assistant.getArgument('location'); 18 | const time = assistant.getArgument('time'); 19 | const info = assistant.getArgument('info'); 20 | const speakers = assistant.getArgument('speakers'); 21 | 22 | const ticket = assistant.getArgument('ticket'); 23 | const price = assistant.getArgument('price'); 24 | const discount = assistant.getArgument('discount'); 25 | const payment = assistant.getArgument('payment'); 26 | 27 | let message, 28 | statements = []; 29 | 30 | getGroupInfo({ 31 | onSuccess: function(data) { 32 | 33 | if(location && location.length>0){ 34 | statements.push("행사 주소는 "+data.info.location + " 입니다."); 35 | } 36 | 37 | if(time && time.length>0) { 38 | statements.push("행사 시작 시간은 "+data.info.time + " 입니다."); 39 | } 40 | 41 | if(info && info.length>0) { 42 | statements.push("이 행사는 "+data.info.info + " 입니다."); 43 | } 44 | 45 | if(speakers && speakers.length>0){ 46 | statements.push("행사 스피커 리스트는 "+data.info.speakers + " 입니다."); 47 | } 48 | 49 | if(ticket && ticket.length>0){ 50 | statements.push("티켓 정보에 대해 알려드릴게요."); 51 | } 52 | 53 | if(price && price.length>0){ 54 | statements.push("티켓 가격은 "+data.info.price + " 입니다."); 55 | } 56 | 57 | if(discount && discount.length>0){ 58 | statements.push("할인 정보 : "+data.info.discount); 59 | } 60 | 61 | if(payment && payment.length>0){ 62 | statements.push("결제 정보 : "+data.info.payment); 63 | } 64 | 65 | message = statements.join(" "); 66 | 67 | response.json({ 'speech': message, 'displayText': message }); 68 | } 69 | }); 70 | } 71 | }); 72 | 73 | 74 | function getGroupInfo(options) { 75 | admin.database().ref('/group-info') 76 | .once('value') 77 | .then(function(snapshot){ 78 | const info = snapshot.val(); 79 | options.onSuccess({info: info}); 80 | }); 81 | } 82 | -------------------------------------------------------------------------------- /[7]mapbot-project/api.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | 3 | const admin = require("firebase-admin"); 4 | const serviceAccount = require("./ghbot-762ee-firebase-adminsdk-d03q9-9a4e98e209.json"); 5 | 6 | admin.initializeApp({ 7 | credential: admin.credential.cert(serviceAccount), 8 | databaseURL: "https://ghbot-762ee.firebaseio.com/" 9 | }); 10 | 11 | const request = require('request'); 12 | const client_id = '[NAVER_CLIENT_ID]'; // NAVER CLIENT ID 13 | const client_secret = '[NAVER_SECRET_IT]'; // NAVER SECRET ID 14 | 15 | 16 | function getGeocode(address){ 17 | return new Promise((resolve, reject) => { 18 | const api_url = 'https://openapi.naver.com/v1/map/geocode?query=' + encodeURI(address); // json 19 | 20 | const options = { 21 | url: api_url, 22 | headers: {'X-Naver-Client-Id':client_id, 'X-Naver-Client-Secret': client_secret} 23 | }; 24 | request.get(options, function (error, response, body) { 25 | if (!error && response.statusCode == 200) { 26 | resolve(body); 27 | } else { 28 | reject(error); 29 | } 30 | }); 31 | }); 32 | } 33 | 34 | function getReverseGeocode(lat, lng){ 35 | return new Promise((resolve, reject) => { 36 | const api_key = '[GOOGLE_API_KEY]'; // GOOGLE API KEY 37 | const api_url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${api_key}`; 38 | 39 | request.get({url: api_url}, function (error, response, body) { 40 | if (!error && response.statusCode == 200) { 41 | resolve(body); 42 | } else { 43 | reject(error); 44 | } 45 | }); 46 | }); 47 | } 48 | 49 | app.putGhData = function() { 50 | const fs = require('fs'); 51 | 52 | fs.readFile(__dirname+'/ghlist.json', 'utf8', function(err, data) { 53 | 54 | const jsonObj = JSON.parse(data); 55 | const rows = jsonObj.result.body.rows[0].row; 56 | 57 | 58 | for(var i=0; i { 68 | const resultObj = JSON.parse(result); 69 | const lat = resultObj.result.items[0].point.y; 70 | const lng = resultObj.result.items[0].point.x; 71 | 72 | getReverseGeocode(lat,lng).then((data) => { 73 | const jsonObj = JSON.parse(data); 74 | const gh_enaddress = jsonObj.results[0].formatted_address; 75 | 76 | writeData(gh_koname, gh_enname, gh_address, gh_enaddress, tel, lat, lng); 77 | }).catch((error) => { 78 | console.error(error); 79 | }); 80 | }).catch((error) => { 81 | console.error(error); 82 | }); 83 | } 84 | 85 | }); 86 | } 87 | 88 | function writeData(name, enname, address, en_address, phone, lat, lng){ 89 | admin.database().ref().child("guesthouses").push({ 90 | name, 91 | enname, 92 | address, 93 | en_address, 94 | phone, 95 | lat, 96 | lng 97 | }); 98 | } 99 | 100 | 101 | } -------------------------------------------------------------------------------- /[7]mapbot-project/dialogflow.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | 3 | const request = require('request'); 4 | const admin = require("firebase-admin"); 5 | const serviceAccount = require("[어드민 SDK JSON 패스]"); 6 | 7 | admin.initializeApp({ 8 | credential: admin.credential.cert(serviceAccount), 9 | databaseURL: "https://ghbot-762ee.firebaseio.com/" 10 | }); 11 | 12 | const TOKEN = '[dialogflow v1 Token]'; 13 | 14 | app.post('/process', (req, res) => { 15 | const query = req.body.query; 16 | 17 | if(!query){ 18 | res.json({flag: 0}); 19 | return; 20 | } 21 | 22 | const session_id = 'my_session_id'; 23 | const language = 'en' 24 | 25 | const api_url = `https://api.dialogflow.com/v1/query?v=20170712&lang=${language}&sessionId=${session_id}&query=${query}` 26 | 27 | const options = { 28 | url: encodeURI(api_url), 29 | headers: { 30 | 'Authorization': "Bearer "+TOKEN, 31 | 'Content-Type': 'application/x-www-form-urlencoded' 32 | } 33 | }; 34 | request.get(options, function (error, response, body) { 35 | if (!error) { 36 | const objResult = JSON.parse(body); 37 | 38 | const intentName = objResult.result.metadata.intentName; 39 | 40 | if(intentName=='near_location'){ 41 | const location = objResult.result.parameters.location["street-address"]; 42 | 43 | getGeocode(location).then((data) => { 44 | const jsonObj = JSON.parse(data); 45 | 46 | res.json({flag: 1, type: 0, data: jsonObj.results[0].geometry.location}); 47 | }).catch((err) =>{ 48 | console.error(err); 49 | res.json({flag: 0}); 50 | }); 51 | 52 | } else if(intentName=='find_location'){ 53 | const ghname = objResult.result.parameters.gh_name; 54 | 55 | findGhInfo(ghname).then((data) => { 56 | 57 | res.json({flag: 1, type: 1, data: data}) 58 | }).catch((err) =>{ 59 | console.error(err); 60 | res.json({flag: 0}); 61 | }); 62 | } else { 63 | console.log(` No intent matched.`); 64 | res.json({flag: 0}); 65 | } 66 | 67 | } else { 68 | console.error('error:', err); 69 | res.json({flag: 0}); 70 | } 71 | }); 72 | 73 | }); 74 | 75 | function getGeocode(addr){ 76 | return new Promise((resolve, reject) => { 77 | const address = encodeURI(addr); 78 | 79 | const api_key = '[맵 API 키]'; 80 | const api_url = `https://maps.googleapis.com/maps/api/geocode/json?address=${address}&key=${api_key}`; 81 | 82 | request.get({url: api_url}, function (error, response, body) { 83 | if (!error && response.statusCode == 200) { 84 | resolve(body); 85 | } else { 86 | reject(error); 87 | } 88 | }); 89 | }); 90 | } 91 | 92 | 93 | function findGhInfo(ghname){ 94 | return new Promise((resolve, reject) => { 95 | admin.database().ref('/guesthouses') 96 | .once('value', function(snapshot) { 97 | snapshot.forEach(function(childSnapshot) { 98 | var childKey = childSnapshot.key; 99 | var info = childSnapshot.val(); 100 | 101 | if(info.enname == ghname){ 102 | resolve(info); 103 | return; 104 | } 105 | }); 106 | 107 | reject("no guesthouse"); 108 | }); 109 | }); 110 | } 111 | 112 | 113 | } -------------------------------------------------------------------------------- /[7]mapbot-project/client/src/client-app/client-app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 58 | 59 | 121 | 122 | -------------------------------------------------------------------------------- /[7]mapbot-project/dialogflowv2.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | 3 | const request = require('request'); 4 | const admin = require("firebase-admin"); 5 | const serviceAccount = require("[어드민 SDK JSON 패스]"); 6 | 7 | admin.initializeApp({ 8 | credential: admin.credential.cert(serviceAccount), 9 | databaseURL: "https://ghbot-762ee.firebaseio.com/" 10 | }); 11 | 12 | const projectId = 'ghbot-762ee'; //https://dialogflow.com/docs/agents#settings 13 | const sessionId = 'my-session-id'; 14 | const languageCode = 'en-US'; 15 | 16 | const dialogflow = require('dialogflow'); 17 | const sessionClient = new dialogflow.SessionsClient(); 18 | 19 | const sessionPath = sessionClient.sessionPath(projectId, sessionId); 20 | 21 | app.post('/process', (req, res) => { 22 | const query = req.body.query; 23 | 24 | if(!query){ 25 | res.json({flag: 0}); 26 | return; 27 | } 28 | 29 | // The text query request. 30 | const textReq = { 31 | session: sessionPath, 32 | queryInput: { 33 | text: { 34 | text: query, 35 | languageCode: languageCode, 36 | }, 37 | }, 38 | }; 39 | 40 | 41 | // Send request and log result 42 | sessionClient 43 | .detectIntent(textReq) 44 | .then(responses => { 45 | console.log('Detected intent'); 46 | const result = responses[0].queryResult; 47 | console.log(` Query: ${result.queryText}`); 48 | console.log(` Response: ${result.fulfillmentText}`); 49 | if (result.intent) { 50 | console.log(` Intent: ${result.intent.displayName}`); 51 | const intent_name = result.intent.displayName; 52 | 53 | if(intent_name=='near_location'){ 54 | const location = result.parameters.fields.location.structValue.fields["street-address"].stringValue; 55 | getGeocode(location).then((data) => { 56 | const jsonObj = JSON.parse(data); 57 | 58 | res.json({flag: 1, type: 0, data: jsonObj.results[0].geometry.location}); 59 | }).catch((err) =>{ 60 | console.error(err); 61 | res.json({flag: 0}); 62 | }); 63 | } else if(intent_name=='find_location'){ 64 | const ghname = result.parameters.fields.gh_name.stringValue; 65 | findGhInfo(ghname).then((data) => { 66 | 67 | res.json({flag: 1, type: 1, data: data}) 68 | }).catch((err) =>{ 69 | console.error(err); 70 | res.json({flag: 0}); 71 | }); 72 | } 73 | 74 | } else { 75 | console.log(` No intent matched.`); 76 | res.json({flag: 0}); 77 | } 78 | }) 79 | .catch(err => { 80 | console.error('error:', err); 81 | res.json({flag: 0}); 82 | }); 83 | 84 | }); 85 | 86 | 87 | function getGeocode(addr){ 88 | return new Promise((resolve, reject) => { 89 | const address = encodeURI(addr); 90 | 91 | const api_key = '[맵 API 키]'; 92 | const api_url = `https://maps.googleapis.com/maps/api/geocode/json?address=${address}&key=${api_key}`; 93 | 94 | request.get({url: api_url}, function (error, response, body) { 95 | if (!error && response.statusCode == 200) { 96 | resolve(body); 97 | } else { 98 | reject(error); 99 | } 100 | }); 101 | }); 102 | } 103 | 104 | 105 | function findGhInfo(ghname){ 106 | return new Promise((resolve, reject) => { 107 | admin.database().ref('/guesthouses') 108 | .once('value', function(snapshot) { 109 | snapshot.forEach(function(childSnapshot) { 110 | var childKey = childSnapshot.key; 111 | var info = childSnapshot.val(); 112 | 113 | if(info.enname == ghname){ 114 | resolve(info); 115 | return; 116 | } 117 | }); 118 | 119 | reject("no guesthouse"); 120 | }); 121 | }); 122 | } 123 | 124 | 125 | } -------------------------------------------------------------------------------- /[9]coin-project/clova.js: -------------------------------------------------------------------------------- 1 | module.exports = (app) => { 2 | 3 | class CEKRequest { 4 | constructor (req, res) { 5 | this.request = req.body.request; 6 | this.context = req.body.context; 7 | this.session = req.body.session; 8 | this.response = res; 9 | console.log(`CEK Request: ${JSON.stringify(this.context)}, ${JSON.stringify(this.session)}`) 10 | } 11 | 12 | do(response) { 13 | switch (this.request.type) { 14 | case 'LaunchRequest': 15 | return this.launchRequest(response); 16 | case 'IntentRequest': 17 | return this.intentRequest(response); 18 | case 'SessionEndedRequest': 19 | return this.sessionEndedRequest(response); 20 | } 21 | } 22 | 23 | launchRequest(response) { 24 | console.log('launchRequest'); 25 | response.setSimpleSpeechText('코인 프리미엄 정보를 알려드립니다.'); 26 | response.setMultiturn({ 27 | intent: 'CoinCheckIntent', 28 | }); 29 | } 30 | 31 | intentRequest(response) { 32 | console.log('intentRequest'); 33 | console.dir(this.request); 34 | const intent = this.request.intent.name; 35 | const slots = this.request.intent.slots; 36 | 37 | switch (intent) { 38 | case 'CoinCheckIntent': 39 | default: 40 | 41 | if(slots.premium){ 42 | 43 | app.getPremium().then((data) => { 44 | response.appendSpeechText(`김프 시세 차이는 ${data.premium_price}원, ${data.premium_percent}% 입니다.`); 45 | return this.response.send(response); 46 | }); 47 | } else { 48 | 49 | if(slots.currency){ 50 | const currency = slots.currency.value; 51 | if(currency=='비트코인' || currency=='비코'){ 52 | app.getPrice('btc').then((data) => { 53 | response.appendSpeechText(`비트코인 가격은 ${data.value}원 입니다.`); 54 | return this.response.send(response); 55 | }); 56 | 57 | } else if(currency=='이더리움' || currency=='이더'){ 58 | app.getPrice('eth').then((data) => { 59 | response.appendSpeechText(`이더리움 가격은 ${data.value}원 입니다.`); 60 | return this.response.send(response); 61 | }); 62 | } else if(currency=='리플'){ 63 | app.getPrice('xrp').then((data) => { 64 | response.appendSpeechText(`리플 가격은 ${data.value}원 입니다.`); 65 | return this.response.send(response); 66 | }); 67 | } 68 | } 69 | } 70 | 71 | break; 72 | } 73 | 74 | } 75 | 76 | sessionEndedRequest(response) { 77 | console.log('sessionEndedRequest'); 78 | response.setSimpleSpeechText('코인 정보 봇을 종료합니다.'); 79 | response.clearMultiturn(); 80 | } 81 | } 82 | 83 | class CEKResponse { 84 | constructor () { 85 | console.log('CEKResponse constructor') 86 | this.response = { 87 | directives: [], 88 | shouldEndSession: true, 89 | outputSpeech: {}, 90 | card: {}, 91 | }; 92 | this.version = '0.1.0'; 93 | this.sessionAttributes = {}; 94 | } 95 | 96 | setMultiturn(sessionAttributes) { 97 | this.response.shouldEndSession = false; 98 | this.sessionAttributes = Object.assign(this.sessionAttributes, sessionAttributes); 99 | } 100 | 101 | clearMultiturn() { 102 | this.response.shouldEndSession = true; 103 | this.sessionAttributes = {}; 104 | } 105 | 106 | setSimpleSpeechText(outputText) { 107 | this.response.outputSpeech = { 108 | type: 'SimpleSpeech', 109 | values: { 110 | type: 'PlainText', 111 | lang: 'ko', 112 | value: outputText, 113 | }, 114 | }; 115 | } 116 | 117 | appendSpeechText(outputText) { 118 | const outputSpeech = this.response.outputSpeech; 119 | if (outputSpeech.type != 'SpeechList') { 120 | outputSpeech.type = 'SpeechList'; 121 | outputSpeech.values = []; 122 | } 123 | if (typeof(outputText) == 'string') { 124 | outputSpeech.values.push({ 125 | type: 'PlainText', 126 | lang: 'ko', 127 | value: outputText, 128 | }); 129 | } else { 130 | outputSpeech.values.push(outputText); 131 | } 132 | } 133 | } 134 | 135 | app.post('/clova', (req, res, next) => { 136 | const cekResponse = new CEKResponse(); 137 | const cekRequest = new CEKRequest(req, res); 138 | cekRequest.do(cekResponse); 139 | }); 140 | 141 | } 142 | -------------------------------------------------------------------------------- /[2]pwa-youtube/src/pwa-youtube-app/list-page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 92 | 145 | -------------------------------------------------------------------------------- /[8]music-project/client/src/client-app/client-app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 36 | 37 | 153 | 154 | -------------------------------------------------------------------------------- /[5]chat-project/src/chat-project-app/view-room.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 90 | 91 | 204 | --------------------------------------------------------------------------------