Skip to content

Commit

Permalink
撮影方法をopenCVへ変更 容量問題を解決するためmentionがあったときのみ写真を撮影し返すように
Browse files Browse the repository at this point in the history
  • Loading branch information
ilim0t committed Feb 28, 2019
1 parent 93031d6 commit 5b4edea
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 177 deletions.
60 changes: 18 additions & 42 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,34 @@
const photoapi = require("./photoAPI");
const {capture} = require("./caputure");
const slack = require("./slack");
const utils = require("./utils");

const main = async () => {
//認証鍵の設定
const {client_id, client_secret} = process.env;
if (!client_id || !client_secret) {
console.log("READMEに従ってGoogle Photos APIsの認証鍵を設定してください");
process.exit(1)
}
//環境設定
const {client_id, client_secret, slack_token} = process.env;
const oAuth2Client = await photoapi.getOAuthToken(client_id, client_secret);
const bot = new slack.Slack();
const slackBot = new slack.Slack(slack_token);

//共有するためアルバムを指定
//アルバム, 共有のの設定
const albumTitle = "bushitsuchan_album";
const albums = await photoapi.getAlbumList(oAuth2Client);
let album = albums.filter((album) => album.title === albumTitle)[0];

if (album === undefined) {
let album = albums.filter(album => album.title === albumTitle)[0];
if (!album) {
album = await photoapi.createAlbum(oAuth2Client, albumTitle);
await photoapi.shareAlbum(oAuth2Client, album.id)
}

bot.start();

//定期的に撮影した写真の共有リンクをslackbotで送信
//https://developers.google.com/photos/library/guides/api-limits-quotas に抵触しないように!!
/**
* 何msに一回実行するか あまり小さくしすぎるとエラーが発生します
* @type {number}
*/
const interval = 10 * 1000;
if (60 * 60 * 24 * 1000 / 10000 * 3 > interval) {
console.log(`注意: 1日あたり${(60 * 60 * 24 * 3 / interval * 1000).toLocaleString()}回PhotoAPIを叩く設定で,1日の上限10,000回を越してしまいます`)
}
setInterval(async () => {
const url = await capture(oAuth2Client, album).catch(e => {
console.error(e.name);
if (e.name === "StatusCodeError") {
console.error(JSON.parse(e.error).error.message);
return
}
console.error(e.message)
// console.error(e)
});
if (!url) {
return
}
const shortURL = await photoapi.getShortURL(url);

// ここをカスタマイズしてください
bot.url = shortURL;
// slack.send(shortURL);
}, interval)
slackBot.getReplyText = async () => {
const photo = await capture(0, ".png");
const uploadToken = await photoapi.uploadPhoto(oAuth2Client, photo, Date().toLocaleString());
const {mediaItem} = await photoapi.createAlbumMediaItem(oAuth2Client, album.id, uploadToken, "");
const {baseUrl} = await photoapi.getMediaItem(oAuth2Client, mediaItem.id);
const shortUrl = await utils.getShortURL(baseUrl);
return shortUrl;
};

//slackbotの開始
slackBot.start();
};


Expand Down
48 changes: 6 additions & 42 deletions caputure.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,9 @@
"use strict";

const photoapi = require("./photoAPI");
const NodeWebcam = require('node-webcam');
const slack = require("./slack");
const cv = require('opencv4nodejs');


const Webcam = NodeWebcam.create({
width: 1280,
height: 720,
quality: 100,

delay: 0,
saveShots: true,
device: false,
callbackReturn: "buffer",
verbose: false
});

/**
* 写真を撮影しGooglePhotoへとアップロード,その共有リンクを取得します
* @param {oAuth2Client} oAuth2Client - photoapi.getOAuthToken関数で取得します
* @param {Object} album
* @returns {Promise<void>}
*/
module.exports.capture = async (oAuth2Client, album) => {
const photo = await new Promise((resolve, reject) => {
Webcam.capture("capture", (err, photo) => {
if (err) {
reject(err)
}
resolve(photo)
})
}).catch(e => {
console.error(e);
console.error(
"READMEに従ってカメラを使えるようにしてください\n" +
"また,OSやセキュリティソフトでカメラへのアクセスをブロックしている可能性もあります 解除してください\n");
process.exit(1)
});
const uploadToken = await photoapi.uploadPhoto(oAuth2Client, photo, Date().toLocaleString());
const {mediaItem} = await photoapi.createAlbumMediaItem(oAuth2Client, album.id, uploadToken, "");
const {baseUrl} = await photoapi.getMediaItem(oAuth2Client, mediaItem.id);
return baseUrl
};
module.exports.capture = async (devicePort = 0, ext = ".png") => {
const cap = new cv.VideoCapture(devicePort);
const frame = cap.read();
return cv.imencode(ext, frame);
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@slack/client": "^4.10.0",
"googleapis": "^35.0.0",
"node-webcam": "^0.4.6",
"opencv4nodejs": "^4.14.1",
"path": "^0.12.7",
"readline": "^1.3.0",
"request": "^2.88.0",
Expand Down
62 changes: 21 additions & 41 deletions photoAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,26 @@ const fs = require("fs");
const {google} = require("googleapis");
const readline = require("readline");
const path = require("path");
const rp = require("request-promise");
const {rpap} = require("./utils");
// const assert = require("assert");


const rpap = rp.defaults({
"transform": (body, response) => {
const constentType = response.headers["content-type"].split("")[0];
if (constentType === "application/json") {
return JSON.parse(body)
} else if (constentType === "text/plain") {
return body
} else {
return body
}
}
});

/**
* @typedef {Object} oAuth2Client
* @typedef {Object} OAuth2Client
* @property {function: string} getAccessToken
*/

/**
* 認証鍵を取得します
* @param {string} client_id - GCPで取得したクライアントID
* @param {string} client_secret - GCPで取得したクライアントシークレット
* @returns {Promise<oAuth2Client>}
* @returns {Promise<OAuth2Client>}
*/
module.exports.getOAuthToken = (client_id, client_secret) => {
module.exports.getOAuthToken = async (client_id, client_secret) => {
if (!client_id || !client_secret) {
throw new TypeError("Google Photos APIsの認証キーがロードできていません。" +
"READMEに従ってdirenvの設定をしてください。");
}

const oAuth2Client = new google.auth.OAuth2(
client_id,
client_secret,
Expand All @@ -46,13 +37,13 @@ module.exports.getOAuthToken = (client_id, client_secret) => {
const tokenPath = path.join(__dirname, "token.json");
if (fs.existsSync(tokenPath)) {
oAuth2Client.setCredentials(require(tokenPath));
return oAuth2Client
return oAuth2Client;
}

const authURL = oAuth2Client.generateAuthUrl({
access_type: "offline",
scope: scopes
});

console.log(`以下のサイトを開き,認証したあと表示される文字列をここに貼り付けてください\n${authURL}`);
const rl = readline.createInterface({
input: process.stdin,
Expand All @@ -76,7 +67,7 @@ module.exports.getOAuthToken = (client_id, client_secret) => {

/**
* アルバム一覧の取得
* @param {oAuth2Client} oAuth2Client - getOAuthToken関数で取得します
* @param {OAuth2Client} OAuth2Client - getOAuthToken関数で取得します
* @returns {Promise<Array<Object>>}
*/
module.exports.getAlbumList = async oAuth2Client => {
Expand All @@ -90,13 +81,13 @@ module.exports.getAlbumList = async oAuth2Client => {
method: "GET",
headers: headers
})
.then(response => JSON.parse(response)["albums"])
.then(response => response["albums"])
};


/**
* 画像のバイナリデータを送信します
* @param {oAuth2Client} oAuth2Client - getOAuthToken関数で取得します
* @param {OAuth2Client} OAuth2Client - getOAuthToken関数で取得します
* @param photo
* @param {string} filename
* @returns {Promise<string>} uploadToken
Expand All @@ -120,7 +111,7 @@ module.exports.uploadPhoto = async (oAuth2Client, photo, filename) => {

/**
* アップロードした画像を単なる写真として保存します
* @param {oAuth2Client} oAuth2Client - getOAuthToken関数で取得します
* @param {OAuth2Client} OAuth2Client - getOAuthToken関数で取得します
* @param {string} uploadToken - uploadPhoto関数で取得します
* @param {string} description
* @returns {Promise<Array<Object>>}
Expand Down Expand Up @@ -153,7 +144,7 @@ module.exports.createMediaItem = async (oAuth2Client, uploadToken, description)

/**
* アップロードした画像をアルバムに追加します
* @param {oAuth2Client} oAuth2Client - getOAuthToken関数で取得します
* @param {OAuth2Client} OAuth2Client - getOAuthToken関数で取得します
* @param {string} albumID
* @param {string} uploadToken - uploadPhoto関数で取得します
* @param {string} description
Expand Down Expand Up @@ -182,14 +173,14 @@ module.exports.createAlbumMediaItem = async (oAuth2Client, albumID, uploadToken,
headers: headers,
body: JSON.stringify(body)
})
.then(response => JSON.parse(response)["newMediaItemResults"][0])
.catch(e => console.error(e))
.then(response => response["newMediaItemResults"][0])
// .catch(e => console.error(e))
};


/**
* アルバムを作成します
* @param {oAuth2Client} oAuth2Client - getOAuthToken関数で取得します
* @param {OAuth2Client} OAuth2Client - getOAuthToken関数で取得します
* @param {string} title
* @returns {Promise<Object>}
*/
Expand All @@ -214,7 +205,7 @@ module.exports.createAlbum = async (oAuth2Client, title) => {

/**
* アルバムを共有します
* @param {oAuth2Client} oAuth2Client - getOAuthToken関数で取得します
* @param {OAuth2Client} OAuth2Client - getOAuthToken関数で取得します
* @param {string} albumID
* @returns {Promise<Object>}
*/
Expand All @@ -241,7 +232,7 @@ module.exports.shareAlbum = async (oAuth2Client, albumID) => {

/**
* アップロード済みの写真に関する情報を取得します
* @param {oAuth2Client} oAuth2Client - getOAuthToken関数で取得します
* @param {OAuth2Client} OAuth2Client - getOAuthToken関数で取得します
* @param {string} mediaItemID
* @returns {Promise<Object>}
*/
Expand All @@ -256,17 +247,6 @@ module.exports.getMediaItem = async (oAuth2Client, mediaItemID) => {
method: "GET",
headers: headers,
})
.then(response => JSON.parse(response))
};

/**
* 与えられたURLの短縮URLを取得します
* @param {string} url
* @returns {Promise<string>} 短縮URL
*/
module.exports.getShortURL = url => {
return rpap.get(`http://is.gd/create.php?format=simple&format=json&url=${url}`)
.then(result => JSON.parse(result)["shorturl"])
};

async function main() {
Expand Down
Loading

0 comments on commit 5b4edea

Please sign in to comment.