9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TogglとSlackを連携して定期的に作業状況を共有する

Posted at

TogglとSlackを連携して定期的に作業状況を共有する仕組みを作ってみました。

#背景
他拠点にいるメンバーから「今なにしてるー?」と聞かれる頻度が結構多かったので、いちいち聞かれるなら自分から発信してしまおうと思って作成しました。

#目的
「Togglのタイマー内容を取得し、Slackの特定のチャンネルに投稿する」ことを定期的に実行して、いま自分が何をしているのかを他メンバーと共有する仕組みを作ります。

使うサービス

  • Toggl
  • Slack
  • AWS
    • Lambda (コードはNodejs8.10で実装)
    • Cloudwatch

手順

1. TogglとSlackのAPIトークンを取得する

1-1.Togglのトークン取得

Togglにログインした状態でプロフィール画面( https://toggl.com/app/profile )の一番下に記載されているAPI tokenを控えておきます。

1-2.Slackのトークン取得

チャンネル一覧にある「App」からアプリ一覧に移動し、Incoming Webhookをチャンネルに追加します。
その後、Incoming Webhookの設定画面に記載されているWebhook URLを控えておきます。

2.AWS Lambdaで関数を作成する

2-1.関数を作成

以下内容で関数を作成します。ランタイムはNodejs8.10で。


'use strict';

const AWS = require('aws-sdk');
const url = require('url');
const https = require('https');

const slackWebhookUrl = process.env.slackWebhookUrl;
const slackChannel = process.env.slackChannel;
const togglApiToken = process.env.togglApiToken;
const togglTimeEntrysPath = '/api/v8/time_entries/current';

//前回投稿分のタイムエントリ
let slackTextBefore;

const getTogglMessage = (togglTimeEntrysPath) => {
    const options = {
        method: "GET",
        host :"www.toggl.com",
        auth: togglApiToken+":api_token",
        path: togglTimeEntrysPath,
        json : true
    };
    return new Promise((resolve,reject) => {
        var body = "";
        const req = https.request(options, (res) => {
                res.setEncoding('utf8');
                res.on('data', (chunk) => {
                body += chunk;
            });
            res.on('end', () => {
                resolve(body);
            });
        });
        req.end();
    });
};

function createMessage(json){
    var message;
        json = JSON.parse(json);
        //Slackに投稿するメッセージの作成
         if(json.data == null){
            message = "現在実施している作業はありません。";
         }else if (typeof json.data.description === 'undefined'){ //タイムエントリ未設定時
            message ="現在、何かの作業を実施中です。(Description未入力)";
        }else { 
            message =`現在${json.data.description}を実施中です。`; 
        }    
    return message;
}

const PostMessage = (message) => {
    var postMessage={
        channel: slackChannel,
        text: message
    };
    const body = JSON.stringify(postMessage);
    return new Promise((resolve,reject) =>{
        const param = url.parse(slackWebhookUrl);
        param.method = "POST";
        param.headers = {
            'Content-Type': 'application/json',
            'Content-Length': Buffer.byteLength(body),
        };
        console.log(param);
        console.log(`body: ${body}`);
        const postReq = https.request(param, (res) => {
            const chunks = [];
            res.setEncoding('utf8');
            res.on('data', (chunk) => {
                chunks.push(chunk);
            });
            res.on('end', () => {
                resolve(null);
            });
        });
        postReq.write(body);
        postReq.end();
    });
};

exports.handler = async (event) => {
    try{
        var timeEntryDescription = await getTogglMessage(togglTimeEntrysPath);
        var message = createMessage(timeEntryDescription);
        if (message !== slackTextBefore) {
            await PostMessage(message);
            slackTextBefore = message;
        } else {
            console.log("No Change description, skip post massage.");
        }
    }catch(err){
        console.log(err);
    }
};

ちなみに、上記の関数はLambdaのインスタンスが再利用される仕様を利用して、前回投稿時から状態が変わっていない場合は投稿しないよう考慮しています。
(インスタンスが再作成された際は状態が変わっていない場合でも投稿されます。自分が運用していたものは大体7時間毎に投稿されていました)

2-2. 環境変数を設定

以下内容でLambdaの環境変数を設定します。

キー
togglApiToken 1-1.Togglのトークン取得 で取得したTogglのAPI token
slackWebhookUrl 1-2.Slackのトークン取得 で取得したWebhook URL
slackChannel 投稿したいSlackチャンネル名
20190208_環境変数設定例.PNG

2-3. バージョン作成

Cloudwatchで実行するためのバージョンを作成しておきます。

3. Cloudwatchで定期的に関数を実行するルールを設定する

Cloudwatch Events で関数の実行ルールを作成します。
毎分実行する場合は以下のような形で。
20190208_Cloudwatchevent.PNG

投稿されない時間帯を設定したい場合は面倒ですがcron式で設定する必要があります。


動かすとこんな感じで投稿されます。
20180208_実行零.PNG

カレンダーやプロジェクト管理ツールと連携する

Togglが公式で出しているChromeの拡張機能を入れることで、GoogleカレンダーやRedmine・Backlog等のプロジェクト管理ツールからタイマーをスタートさせることができます。
拡張機能をインストールして連携したいサイトをチェックするだけです。
20190208_togglpermission.PNG
チケットやカレンダーの予定を開いて中身確認してタイマースタートをポチって作業開始…みたいな流れもできるので便利です。
20180208_googleカレンダーでの表示.PNG

まとめ

LambdaとCloudwatchを使用して、Togglのタイマー内容を取得してSlackの特定のチャンネルに投稿することで自分が何をしているのかを他メンバーと共有する仕組みを作りました。

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?