見出し画像

ラズパイからasanaへワンタッチでタスク作成できるボタンを実装してみた

この記事は#AsanaTogetherJPアドベントカレンダーの投稿です。

ちょっと前にAmazon Dashというガジェットがあった。
ボタンを押すと紐づけられた商品が自動で注文される仕組みだ。
あれと似たような考え方で、ボタンを押すとタスク登録されるような仕組み
を作ってみよう。

概要

タスク管理ツール:asana
ハードウェア:家に眠っていたRaspberry PI 3 ModelB & タクトスイッチ
という組み合わせで作る。

単純な仕組みである。
入力デバイスを監視してHTTPSを飛ばすだけ。ついでだからLEDも光らせる。

アクセストークン取得

というわけで、まずはasanaのパーソナルアクセストークンを取得。 https://help.asana.com/hc/ja/articles/14243870406939-API
ここにある個人アクセストークンですね。

仮実行

で、ワークスペースGIDを確認しておく。

curl --request GET \
     --url https://app.asana.com/api/1.0/workspaces \
     --header 'accept: application/json' \
     --header 'authorization: Bearer PERSONAL_ACCESS_TOKEN'

このPERSONAL_ACCESS_TOKENにさっき取得したトークンを入れてターミナルから実行。

{
  "data": [
    {
      "gid": "aaaaaaaaaaaa",
      "name": "ogatism workspace",
      "resource_type": "workspace"
    },
    {
      "gid": "bbbbbbbbb",
      "name": "ogatism.jp",
      "resource_type": "workspace"
    },
    {
      "gid": "cccccccc",
      "name": "ogatism for public",
      "resource_type": "workspace"
    },
    {
      "gid": "ddddddd",
      "name": "Asana, Inc",
      "resource_type": "workspace"
    },
    {
      "gid": "eeeeeee",
      "name": "Asanaverse for Ambassadors",
      "resource_type": "workspace"
    }
  ]
}

これで、ワークスペースGIDが取得できた。

次は対象のプロジェクトGIDを確認する。無くても作れるけど紐づかないのでタスクが迷子になる。 プロジェクト開いた時のURL

https://app.asana.com/0/XXXX/YYY

のXXX部分がプロジェクトGIDのはず。もちろんprojectAPIから確認してもいい。準備ができたのでとりあえずコンソールから試してみよう。
(workspaceGIDを11111111、projectGIDを22222222としてます)

curl --request POST \
     --url https://app.asana.com/api/1.0/tasks \
     --header 'accept: application/json' \
     --header 'authorization: Bearer PERSONAL_ACCESS_TOKEN' \
     --header 'content-type: application/json' \
     --data '
{
  "data": {
    "name": "test123",
    "workspace": "11111111",
    "projects": [
      "22222222"
    ]
  }
}
'

これを実行すると

{
  "data": {
    "gid": "1206053035864019",
    "projects": [
      {
        "gid": "project GID",
        "resource_type": "project",
        "name": "project name"
      }
    ],
    "memberships": [
      {
        "project": {
          "gid": "22222222,
          "resource_type": "project",
          "name": "project name"
        },
        "section": {
          "gid": "1199671466784743",
          "resource_type": "section",
          "name": "Untitled section"
        }
      }
    ],
    "resource_type": "task",
    "created_at": "2023-11-29T01:38:43.138Z",
    "modified_at": "2023-11-29T01:38:43.510Z",
    "name": "test123",
    "notes": "",
    "assignee": null,
    "parent": null,
    "actual_time_minutes": 0,
    "completed": false,
    "assignee_status": "upcoming",
    "completed_at": null,
    "due_on": null,
    "due_at": null,
    "resource_subtype": "default_task",
    "start_on": null,
    "start_at": null,
    "tags": [],
    "workspace": {
      "gid": "11111111",
      "resource_type": "workspace",
      "name": "ogatism for public"
    },
    "num_hearts": 0,
    "num_likes": 0,
    "permalink_url": "permalink URL",
    "hearted": false,
    "hearts": [],
    "liked": false,
    "likes": [],
    "followers": [
      {
        "gid": "user GID",
        "resource_type": "user",
        "name": "Yuji Ogata"
      }
    ]
  }
}

こんな感じでちゃんと正常に返ってきた。
後はこれをプログラム化すれば良い。

プログラムにする

配線はこんな感じ。

拡張を考えるとデーモン化したほうがいいので、とりあえず言語はpythonで。まずはイベント監視用のevdevとhttp送信用のrequestsをpipから取得。(この後のデーモン化の都合rootで入れる)

$ sudo pip3 install evdev
$ sudo pip3 install requests

で、似たようなことしているプログラムはそこら辺に転がっているからコピペして繋ぎ合わせる。GPIOの18番はボタンが繋がってるのでinputとして、GPIO17番はLEDなのでoutputとする。

#!/usr/bin/env python3

import evdev
import requests
import time
import RPi.GPIO as GPIO

# デバイスの指定
DEVICE_PATH = "/dev/input/event1"

gpio_led = 17
gpio_button = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(gpio_led, GPIO.OUT)
GPIO.setup(gpio_button, GPIO.IN, pull_up_down=GPIO.PUD_UP)


def main():
    f = open('/asana/token.txt', 'r')
    token = f.read()
    token = token.replace("\n", "")
    f.close()

    url_asana = 'https://app.asana.com/api/1.0/tasks?opt_fields=&opt_pretty=true'
    headers = {'accept': 'application/json',
               'authorization': 'Bearer ' + token,
               'content-type': 'application/json'}

    item_data = {
        "data": {
            "workspace": "11111111111111111",
            "projects": [
                "2222222222222222"
            ],
            "name": "備品補充"
        }
    }

    while True:
        #スイッチ状態取得
        sw_status = GPIO.input(gpio_button)

        #画面出力
        if sw_status == 0:
            # LEDを光らせる
            GPIO.output(gpio_led, 1)
            print('スイッチON!')
            # asanaへ飛ばす
            r_post = requests.post(url_asana, headers=headers, json=item_data)
            # LEDを消す
            GPIO.output(gpio_led, 0)
            print(r_post.text)

        time.sleep(0.3)

    GPIO.cleanup(gpio_led)	
    return


if __name__ == "__main__":
    main()

で、デーモン化する

sudo vi /etc/systemd/system/asana.service
[Unit]
Description = asana daemon

[Service]
ExecStart = /asana/asana.py
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

デーモン化できた

tea@raspberrypi:~ $ ps aux | grep asana
root      2879  5.1  1.8  23184 17636 ?        Ss   13:09   0:00 python3 /asana/asana.py
tea       2892  0.0  0.0   4020   556 pts/0    S+   13:10   0:00 grep --color=auto asana

後はボタンを押せば自動的にasanaにタスクが作られる。

無事に起動したら備品置き場にでも置いて、備品が切れてたらこのボタン押して、みたいな感じにしましょう。

もちろんasanaに限った話じゃなくてapiが叩けるsaasならなんでも可能。aws緊急停止スイッチみたいなものも作れるはず。ガラスで覆って、緊急の場合はガラスをパリンと割ってボタンを叩くみたいな。




いいなと思ったら応援しよう!