WIP

code

created at 2016.11.08
updated at 約1年 ago
vsanna / public lambda_tutorial

こんなのを作りたい

# 【分報日報】 vsanna 11月8日

## やること

- t lambdaで早速bugの指摘頂いたので直す
- t 分報to日報でブログをかく
- todo ログから入力内容を復活
- todo 一言だけ考える「はじめます」
- doing エクスペンスシート
- doing コロッセオ開発

## やったこと

- done 分報lambda化
- done 津田さん問題提起会
- done 共有会
- done 食事代経費申請
memo 期間内に申請をしないと大変なことになる
- done 石渡さん面談

## こまったこと

- problem 選択式の問題が調達できるかどうか悩ましい。誰かに調達をお願いしたい

## 所感

- think とおもっていたらHさんを皮切りに力強い意見が出てきた。
- think 問題調達がとても怖い。チームに助けてもらいたい
- think 閻魔帳の先がこわい。どの程度工数採られるのか
- think Lチームのmtgは物事が決まる体験がある。なぜそうなのだろう
- memo cssだけでも開発中はリアルタイムに反映されるようにしたい。
- think 市場価値よりも成功した自分を求めたいのであれば、そのための架け橋みたいなものを感じ取らせたほうが良い?

## 寿司打

- sushi 寿司行きたい
- sushida これはテストです
- sushi 最高〜

コード

// lambdaで標準利用できるmodule一覧を抑えておくと良い
// http://qiita.com/yoshidasts/items/2d7117ef0f31754a06ab

const https = require('https');
const url = require('url');
const querystring = require('querystring');

// 色々使う定数
const token = 'hogehoge';
const qiita_token = 'gehogeho';
const api_url = 'https://slack.com/api/';


function createPath(path, params){
  if ( params === null ){ return api_url + path;}
  var str = "";
  Object.keys(params).forEach((e)=>{
      str = str + "&" + e + "=" + params[e];
  });
  return api_url + path + '?' + str.slice(1);
}

function format_messages(messages){
    var todos = extractTodos(messages);
    var dones = extractDones(messages);
    var syokans = extractSyokans(messages);
    var problems = extractProblems(messages);
    var sushida = extractSushida(messages);

    // 全て0件である場合は日報作成しない
    if ( ![todos, dones, syokans, problems, sushida].some((arr)=>{ return arr.length != 0 }) ){ return null; }

    return toMarkdown(todos, dones, problems, syokans, sushida);
}

function filterWithKeys(messages, keys){
    return messages.filter((msg)=>{
        return keys.some((key)=>{
            return msg.split(' ')[0] == key;
        })
    })
}

function extractTodos(msgs){
    const keys = ['t','todo', 'doing', 'yaru', 'start'];
    return filterWithKeys(msgs, keys);
}

function extractDones(msgs){
    const keys = ['f','done', 'did', 'finish', 'yatta', 'end', 'owata'];
    return filterWithKeys(msgs, keys);
}

function extractSyokans(msgs){
    const keys = ['s','summary', 'think', 'memo', 'syokan', 'omota'];
    return filterWithKeys(msgs, keys);
}

function extractProblems(msgs){
    const keys = ['p','problem', 'komata'];
    return filterWithKeys(msgs, keys);
}

function extractSushida(msgs){
    const keys = ['sushi', 'sushida'];
    return filterWithKeys(msgs, keys);
}

function toMarkdown(todos, dones, problems, syokans, sushida){
    var result = "";
    result = toMarkdownParagraph("やること", todos) +
             toMarkdownParagraph("やったこと", dones) +
             toMarkdownParagraph("こまったこと", problems) +
             toMarkdownParagraph("所感", syokans) +
             toMarkdownParagraph("寿司打", sushida);
    return result;
}
function toMarkdownParagraph(header, arr){
    if ( arr.length == 0 ){ return "";}
    return "## " + header + "\n\n" + arr.map((msg)=>{ return "- " + msg; }).join("\n") + "\n\n"; // 雑
}

function createTitle(name){
    const today = new Date();
    name = name == null ? '' : name;
    return '【分報日報】 ' + name + ' ' +
           String(today.getMonth()+1) + '月' + 
           String(today.getDate()) + '日';
}

function main(callback){
    const list_url = 'channels.list';
    const params = {
      'token': token,
      'exclude_archived': 1
    };
    var request_url = createPath(list_url, params);
    var infos;
    https.get(url.parse(request_url), (res) => {
        var responce = "";
        res.on('data', (d)=>{
            responce = responce + d;
        })
        .resume()
        .on('end', ()=>{
            infos = JSON.parse(responce).channels.filter((ch)=>{
                return ch.name.indexOf("times_") === 0;
            }).filter((ch)=>{
                return ch.name != 'times_onishi' && ch.name != 'times_otonari';
            }).map((ch)=>{ 
                return { id: ch.id, 
                         name: ch.name,
                         user_id: ch.purpose.creator }; 
            });
            creaateNippos(infos);
        });
    });
}


function creaateNippos(infos){
  infos.forEach((info)=>{
      createNippo(info);
  })
}

function createNippo(info){
    const list_url = 'channels.history';
    const today = new Date();
    const params = {
      'token': token,
      'channel': info.id,
      'oldest': new Date(today.getFullYear(), today.getMonth(), today.getDate()-1).getTime() / 1000,
      'inclusive': 1,
      'count': 1000
    };
    var request_url = createPath(list_url, params);
    var responce = "";
    https.get(url.parse(request_url), (res) => {
       var str = "";
       res.on('data', (d)=>{
           responce = responce + d;
       });
       res.resume();
       res.on('end', ()=>{
           var messages = JSON.parse(responce).messages.filter((msg)=>{
               return msg.user == info.user_id;
           }).map((msg) => { return msg.text; })
           var formatted_messages = format_messages(messages);
           if ( formatted_messages == null ){ return; }
           if ( info.user_id == '' ){
                //postNippoToQiita(null, formatted_messages);
                postNippoToSlack(null, formatted_messages);
                return;
           }
            // promise内部の値を外に出すのどうやるんだっけ...
            // 思い出せず入れ子地獄を受け入れた
            const profile_url = 'users.profile.get';
            var params = {
                'token': token,
                'user': info.user_id
            };
            var request_url = createPath(profile_url, params);
            https.get(url.parse(request_url), (res) => {
                var responce = "";
                res.on('data', (d)=>{
                    responce = responce + d;
                })
                .resume()
                .on('end', ()=>{
                    var name = JSON.parse(responce).profile.first_name + JSON.parse(responce).profile.last_name;
                    postNippoToQiita(name, formatted_messages);
                    postNippoToSlack(name, formatted_messages);
                });
            });

       });
    });
}

function postNippoToSlack(name, input){
    const post_url = 'chat.postMessage';
    const params = {
      'token': token,
      'channel': '投稿したいチャンネルのID',
      'text': "```\n# " + createTitle(name) + "\n\n" + input + "\n```" // 雑
    };
    var query = querystring.stringify(params);
    var request_url = createPath(post_url, null);

    var options = Object.assign(url.parse(request_url), {
        'method': 'POST',
        'headers': {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(query)
        }
    });

    var req = https.request(options, (res) => {
        res.on('error', (e)=>{
            console.log(e.message)
        })
    });

    req.write(query);
    req.end();
}

function postNippoToQiita(name, input){
    const qiita_post_url = 'https://howtv.qiita.com/api/v2/items';
    const params = {
      'title': createTitle(name),
      'body': input,
      "coediting": false,
      'gist': false,
      'tags': [{ 'name': '日報', 'versions': ['0.0.1'] }],
      'tweet': false
    };

    var options = Object.assign(url.parse(qiita_post_url), {
        'method': 'POST',
        'headers': {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + qiita_token,
            'Host': 'howtv.qiita.com'
        }
    });
    var req = https.request(options, (res) => {
        res.on('error', (e)=>{
            console.log(e.message)
        })
    });

    req.write(JSON.stringify(params));
    req.end();

}

exports.handler = (event, context, callback) => {
    main(callback)
};

shareシェアする

forumコメント

まだコメントはありません!
ログインしてコメントを残す
{{comment.user.name}} on {{commentCreatedAt()}}

content_copy前後のイシュー

{{message}}