evernoteで毎週書いてるTODO作成を自動化してみた
私は1週間の簡単なTODOをevernoteで管理しています。
そのため、毎週日曜日に、来週分のnoteを作成し、曜日ごとのTODOを書く。
そして実際に作業完了したものにチェックをつけて自己満足に浸る。
というのが日課となっています。
このTODOノートなのですが、大枠のテンプレートは同じなので毎週日曜日になったら自動で次の週のノートを作成できるようにしてみました。
1.検証環境の作成
1-1.環境情報
OS:Ubuntsu 18.04LTS(Windows Subsystem for Linux 2)
言語:python 2.7.17
※python3系から2系に変更する方法は以下を参照
https://codechacha.com/ja/change-python-version/
1-2.Evernote APIの準備
以下を参考に実施
# Python SDK(2系)のインストール
git clone https://github.com/evernote/evernote-sdk-python.git
# Python3系はbeta扱いだが、以下からダウンロード可能
# https://github.com/evernote/evernote-sdk-python3
# setup.pyからライブラリインストール
sudo python setup.py install
以下のエラーが発生した場合、
を参照してください。
Traceback (most recent call last):
File "setup.py", line 2, in <module>
from setuptools import setup, find_packages
ImportError: No module named setuptools
※上記でうまくインストールできない場合は以下のコマンドでSDKインストールしてください
pip install evernote
最後にSDKインストール済みか確認
python -c 'from evernote.api.client import EvernoteClient'
1-3.検証コード作成
以下のURLからDeveloper tokenを取得する。Service:Sandbox(開発環境)のURLからConsumer KeyおよびConsumer Secret、Developer tokenを取得できます。
このDeveloper tokenを利用してEvernoteの開発環境にAPIを発行できるようになります。
以下が新規noteを作成する検証用Sampleコードです。"my developer token"の部分はご自身のDeveloper tokenに置き換えてください。
from evernote.api.client import EvernoteClient
import evernote.edam.type.ttypes as Types
dev_token = "my developer token"
# Set up the NoteStore client
client = EvernoteClient(token=dev_token)
userStore = client.get_user_store()
noteStore = client.get_note_store()
# Make API calls
user = userStore.getUser()
print user.username
notebooks = noteStore.listNotebooks()
for notebook in notebooks:
print "Notebook: ", notebook.name
note = Types.Note()
note.title = "I'm a test note!"
note.content = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">'
note.content += '<en-note>Hello, world!</en-note>'
note = noteStore.createNote(note)
2.本番環境の作成
本番環境(=個人用evernoteアカウント)にnoteを自動作成するアプリケーションをAWSのLambdaを使って作成していきます。Lambdaのトリガーに「Event Bridge」を指定し、毎週日曜日にアプリケーションを一回実行するようにしていきます。
2-1.環境情報
実行環境:AWS Lambda
開発言語:Python 2.7
2-2.Evernote APIの準備
検証コードと同様に、以下のURLからDeveloper tokenを取得する。Service:Production(本番環境)のURLからConsumer KeyおよびConsumer Secret、Developer tokenを取得できます。
ただし、本番環境のAPIを有効化するためには、以下のURLから「Activate an API Key」を押下してEvernoteの中の人にリクエストを出して、承認する必要があります。
僕の場合ですが、リクエストを出して5営業日後にEvernoteの中の人からメール返信がありました。ただ、僕の場合はリクエスト内容に誤りがあったため、誤りの訂正を返信して現在承認待ちとなっています。
下記の記事を参考にリクエストを送信しました。
2-3.Lambdaレイヤーの準備
Evernote SDKをLambdaで利用するために、以下のコマンドでLayer用のzipファイルを作成します。
mkdir python
cd python
sudo pip install -t ./ evernote
cd ..
zip -r layer.zip python/
細かい手順は以下を参考にしてください。
2-4.本番コード作成
作成したLambdaのコードは以下です。
# coding=utf_8
from evernote.api.client import EvernoteClient
import calendar
import datetime as dt
import evernote.edam.type.ttypes as Types
import locale
import os
import textwrap
## 環境変数から値取得
NOTEBOOK_NAME = os.environ.get('NOTEBOOK_NAME')
DEV_TOKEN = os.environ.get('DEV_TOKEN')
SANDBOX = os.environ.get('SANDBOX')
## 変数の定義
NOTEBOOK_GUID = ""
# 日付と曜日
date = dt.date.today()
date_1 = date + dt.timedelta(days=1)
date_2 = date + dt.timedelta(days=2)
date_3 = date + dt.timedelta(days=3)
date_4 = date + dt.timedelta(days=4)
date_5 = date + dt.timedelta(days=5)
date_6 = date + dt.timedelta(days=6)
## note作成関数の定義
def makeNote(authToken, noteStore, noteTitle, noteBody, parentNotebook=None):
nBody = '<?xml version="1.0" encoding="UTF-8"?>'
nBody += '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">'
nBody += '<en-note>%s</en-note>' % noteBody
## Create note object
ourNote = Types.Note()
ourNote.title = noteTitle
ourNote.content = nBody
## parentNotebook is optional; if omitted, default notebook is used
if parentNotebook and hasattr(parentNotebook, 'guid'):
ourNote.notebookGuid = parentNotebook.guid
## Attempt to create note in Evernote account
try:
note = noteStore.createNote(authToken, ourNote)
except Errors.EDAMUserException, edue:
## Something was wrong with the note data
## See EDAMErrorCode enumeration for error code explanation
## http://dev.evernote.com/documentation/reference/Errors.html#Enum_EDAMErrorCode
print "EDAMUserException:", edue
return None
except Errors.EDAMNotFoundException, ednfe:
## Parent Notebook GUID doesn't correspond to an actual notebook
print "EDAMNotFoundException: Invalid parent notebook GUID"
return None
## Return created note object
return note
# notebookを取得する関数の定義
def getNoteBook(noteStore):
notebooks = noteStore.listNotebooks()
for notebook in notebooks:
print "Notebook: ", notebook.name
print "NOTEBOOK_NAME: ", NOTEBOOK_NAME
if notebook.name.decode('utf-8') == NOTEBOOK_NAME:
return notebook
def lambda_handler(event, context):
# Set up the NoteStore client
client = EvernoteClient(token=DEV_TOKEN, sandbox=SANDBOX)
noteStore = client.get_note_store()
# debug
userStore = client.get_user_store()
user = userStore.getUser()
print user.username
# note本文の作成
body = textwrap.dedent('''
<h2>{date}週の目標</h2>
<en-todo checked="false"/>study
<br/>
<en-todo checked="false"/>fitness
<br/>
<div>{date}({wdate})</div>
<br/>
<div>{date_1}({wdate_1})</div>
<br/>
<div>{date_2}({wdate_2})</div>
<br/>
<div>{date_3}({wdate_3})</div>
<br/>
<div>{date_4}({wdate_4})</div>
<br/>
<div>{date_5}({wdate_5})</div>
<br/>
<div>{date_6}({wdate_6})</div>
<br/>
<h2>備忘録:</h2>
''').format(date=date.strftime("%Y/%m/%d"),\
date_1=date_1.strftime("%Y/%m/%d"),date_2=date_2.strftime("%Y/%m/%d"),\
date_3=date_3.strftime("%Y/%m/%d"),date_4=date_4.strftime("%Y/%m/%d"),\
date_5=date_5.strftime("%Y/%m/%d"),date_6=date_6.strftime("%Y/%m/%d"),\
wdate=date.strftime('%a'),wdate_1=date_1.strftime('%a'),wdate_2=date_2.strftime('%a'),\
wdate_3=date_3.strftime('%a'),wdate_4=date_4.strftime('%a'),wdate_5=date_5.strftime('%a'),\
wdate_6=date_6.strftime('%a')).strip()
print body
# noteの作成
notebook = getNoteBook(noteStore)
if notebook:
makeNote(DEV_TOKEN, noteStore, date.strftime("%Y/%m/%d"), body, notebook)
else:
makeNote(DEV_TOKEN, noteStore, data.strftime("%Y/%m/%d"), body)
Lambda関数の設定>環境変数には以下を定義しています。
キー:値
DEV_TOKEN :"本番環境のdeveloper token"
NOTEBOOK_NAME :"noteを作成したいnotebook名"
SANDBOX :"本番環境向けの場合はFalse、開発環境向けの場合はTrue"
以上のような設定で、快適なevernoteライフを送れるようになりました?
皆さんの自動化ライフに少しでも糧になれば幸いです。
よろしければサポートお願いします!頂いたサポート費は、執筆活動に使わせて頂きます。