LoginSignup
6
6

More than 5 years have passed since last update.

SlackからTodoistにタスクを追加する

Last updated at Posted at 2018-02-02

概要

SlackからTodoistにタスクを追加するbotは公式の提供するものが存在する。
本記事では公式の提供する機能の一つと、Scrapboxでページを作成するオプションを持つbotを実装した。実装した機能を以下に示す。

オプション 詳細
. or タスク タスクの追加を行う
#(プロジェクト名) プロジェクトの下に追加する 未指定ならinbox
!(優先度) 優先度を「(弱)1-4(強)」で設定する 未指定なら1
@(期限) 期限を設定する
-s Scrapboxに同名ページを作成する

下準備

本記事で説明するコードは事前に以下の準備が必要である。本記事での説明は省略する。

実装

「Scrapboxのページを作成する」はScrapboxのリンクを作成することで実現している。そのページが存在しない場合は新規作成されるが、存在する場合はページへのリンクとなる。(参考)
コードを以下に示す。

makeTask.gs
function doPost(e) {
  //Incoming WebHooksの設定で入手したWebHookURL
  var postUrl="https://hooks.slack.com/services/*******";

  var userMessage = (e.parameter.text).replace("タスク","");
  userMessage = (userMessage).replace(".","");

  var status = createTask(userMessage);
  var answerText,answerUrl;

  // botの表示名などを変更する。WebHook設定の方が優先されることもあるため気になる場合は確認する、
  var jsonData = {
     "channel" : "#reminder",
     "username" : "Todoist連携さん",
     "icon_emoji"   :":ghost:",
  };

  if (status[0] === 200) {
      answerText = "Todoistにタスクを追加しました。";
    if(status[1]){
      answerText += "Scrapboxにページを作成します。";
      answerUrl = createPage(status[2]);
      jsonData["attachments"] = [{
        "fallback": answerText+""+answerUrl+"",
        "color": "#36a64f",
        "pretext": answerText,
        "title": "Scrapbox-"+status[2],
        "title_link": answerUrl,
      }];
    }else{
      jsonData["text"]=answerText;
    }
  } else {
    answerText = "Todoistへのタスク追加に失敗しました。";
    jsonData["text"]=answerText;
  }
  var options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : JSON.stringify(jsonData)
  };
  UrlFetchApp.fetch(postUrl, options);
}

function createTask(userMessage) {
  var url = "https://todoist.com/API/v7/sync",
      todoistToken = "*******************************",
      uuid = Utilities.getUuid(),
      tempId = Utilities.getUuid(),
      task = strToTask(userMessage),
      projectId = searchProject(task['projectName'],todoistToken),
      formData, response;

  formData = {
    "token": todoistToken,
    "commands": JSON.stringify([{
      "type": "item_add",
      "temp_id": tempId,
      "uuid": uuid,
      "args": {
        "priority" : task['priority'],
        "content": task['taskName'],
        "project_id": projectId, 
      "due": {
        "string": task['limit'],
      },
      }
    }])
  };

  response = UrlFetchApp.fetch(url, {
    "method" : "post",
    "payload" : formData
  });

  return [response.getResponseCode(),task['scrapbox'],task['taskName']];
}

function createPage(taskName){
  //  Scrapboxのページを作成する
  //  ******部分にはScrapboxのプロジェクト名を入力しておく
  var url = "https:///scrapbox.io/*******/"+taskName+"";
  url=encodeURI(url);
  Logger.log(url);
  return url;  
}

function strToTask(str){
  var response = {};
  //  !優先度 で設定
  var priority = str.match(/([!!][1-41-4])/);
  if(priority){
    str = str.replace(priority[0],"");
    response['priority'] = priority[0].slice(1); 
  } else {
    response['priority'] = 1;
  }  

  //  -s でScrapboxのページを作成
  var scrapboxOption = str.match(/(-s)/);
  if(scrapboxOption){
    str = str.replace(scrapboxOption[0],"");
    response['scrapbox'] = true;
  } else {
    response['scrapbox'] = false;
}

  //  #既存のプロジェクト で設定
  var projectName = str.match(/(#|#)[^(@|@)]*/);
  if(projectName){
    str = str.replace(projectName[0],"");
    response['projectName'] = projectName[0].slice(1); 
  }

  //  @期限 で設定
  var limit = str.match(/(@|@).*/);
  if(limit){
    str = str.replace(limit[0],"");
    response['limit'] = limit[0].slice(1);
  }
  response['taskName'] = str;
  return response;
}

function searchProject(projectName,token){
  var url = "https://todoist.com/API/v7/sync",
      formData,options,response;
  var headers = {
      "Accept": "application/json",
  };
  formData ={
    "token": token,
    "sync_token":"*",
    "resource_types":'["projects"]',
  };
  response = UrlFetchApp.fetch(url,{
    "contentType": "application/json",
    "headers":headers,
    "method":"post",
    "payload":JSON.stringify(formData)
  });

  var array = JSON.parse(response.getContentText());
  for(var i = 0; i < array["projects"].length; i++){
    if(array["projects"][i]["name"]===projectName){
      return array["projects"][i]["id"];
    }
  }
  return 000000;
}

実行結果

実際に利用しているbotは上記コードからアイコンとコメントを変更したものである。

Todoist上では以下のように表示される。

6
6
7

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
6
6