はじめに
こんにちは。
先日、jaws-ugの「Ops-JAWS Meetup39 あなたの推しのSSMは?SSM運用特集」イベントに参加してきました。
そこで、SSM Change Calendarに関するLTを行い、後半にiPhoneのなんちゃってフィルタリング機能を作ったお話をしました。
今回は、そのフィルタリング機能をどのように作ったかのご紹介となります。
そのため、SSM Change Calendarがどのような機能かについては割愛いたします。(上記の資料にて簡単に記載しています)
なんちゃってフィルタリング機能
概要
現代においてスマートフォンは必需品となっていますよね。
本記事をスマホから参照している方もいるのではないでしょうか。
便利がゆえに、いろんな誘惑があるので支障をきたすこともあることかと思います。
- 寝る前にSNSや動画に没頭し、寝る時間が遅くなる
- 勉強や家事等をやろうと思うが、スマホを触ってしまい集中できない
- テスト期間中にも関わらず、子供がスマホばかり触って勉強していない
等々...
そのような際に、特定アプリが起動しないようにする機能を作ってみました。
例えば以下です。
- 毎日寝る時間の 0:00~06:00 は起動させない
- 勉強期間の 19:00~22:00 は起動させない
等といったように日時に応じた設定が可能です。
ちなみに定期的(月~金のXX時など)なイベントだけにとどまらず、Change Calendarはイレギュラー(テスト期間中のXXなど)なスケジュールイベントに対応できるので好きです。
構成図
今回の構成図は以下の通りです。
左側のLambda、Change CalendarがAWS、右側のピンク枠がiPhoneとなりショートカット機能というものを利用しています。
今回は私が良く利用する、YoutubeとXをフィルタリング対象のアプリとしました。
ちなみに今回試したiOSは「18.6.2」です。
iPhoneのショートカット機能とは
ざっくりいうと、よく使う作業をまとめて自動化し、毎日の操作をもっとラクにしてくれる仕組みです。
https://support.apple.com/ja-jp/guide/shortcuts/welcome/ios
料金
気になる料金はほぼ無料でできます。
ほぼといっているのは、Lambdaの実行やLambda実行時にCloudWatch Logsへログが出力されるので、その分がかかりますが、それぞれに一定の無料枠があるためです。
また、無料枠でなくとも、微々たるものかと思います。(実行頻度などにもよりますが)
なお、Change Calendarも追加料金なしで利用できます。
手順
AWS側
今回は全てマネジメントコンソールで作成しました。
なお、東京リージョン(ap-northeast-1)で実施しています。
1.カレンダーを作成する
Systems Manager → カレンダーの変更(Change Calendarのこと)をクリックし、以下内容でカレンダーを作成します。
- カレンダー名は任意の名前
- Import calendarは利用しない(今回は手動で登録します)
- カレンダータイプは「デフォルトで開く(DEFAULT_OPEN)」
- それ以外はデフォルトでよい
2.カレンダーにイベントを登録する
作成したカレンダーに対して手動にて、以下内容でイベント(=フィルタリングしたい日時)を登録します。
- イベントの名前は任意の名前
- イベント開始/終了日および、Event start time/Event end timeは任意の日時(フィルタリングしたい日時です)
- タイムゾーンは Asia/Tokyo
- 繰り返し設定は必要に応じ
- それ以外はデフォルトでよい
3.IAMポリシーを作成する
Lambda関数から実行するのはGetCalendarState APIのみです。シンプルですね。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ssm:GetCalendarState",
"Resource": "*"
}
]
}
4.IAMロールを作成する
次にIAMロールを作成します。許可ポリシーには以下をアタッチします。
- AWSLambdaBasicExecutionRole(AWSマネージドポリシー)
- 手順3で作ったIAMポリシー
念のため、信頼ポリシーはLambdaを実行するためなので以下の通りです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
5.Lambda関数を作成する
Change Calendar上のカレンダーの状態を取得し、結果を返却するLambda関数を作成します。
- 関数名は任意の名前
- ランタイムはPython 3.14(今回の動作確認ができているものです)
- 実行ロールは手順4で作成したIAMロールを選択
- それ以外はデフォルトでよい
6.Lambda関数にソースコードの設定
以下のソースコードを実装しました。AIくんが全部作ってくれました。
import json
import os
import boto3
ssm = boto3.client("ssm")
CALENDAR_ARN = os.environ["CALENDAR_ARN"]
OPEN_MESSAGE = os.environ["OPEN_MESSAGE"]
CLOSED_MESSAGE = os.environ["CLOSED_MESSAGE"]
def lambda_handler(event, context):
try:
response = ssm.get_calendar_state(
CalendarNames=[CALENDAR_ARN]
)
state = response["State"] # OPEN or CLOSED
next_transition = response.get("NextTransitionTime")
message = OPEN_MESSAGE if state == "OPEN" else CLOSED_MESSAGE
body = {
"state": state,
"message": message,
"nextTransitionTime": next_transition
}
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"body": json.dumps(body, ensure_ascii=False)
}
except Exception as e:
return {
"statusCode": 500,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"body": json.dumps({
"state": "ERROR",
"message": str(e),
"nextTransitionTime": None
}, ensure_ascii=False)
}
7.Lambda関数に環境変数の設定
先ほどのソースコードで、Lambda環境変数から以下を引っ張ってきていますので、設定タブの環境変数より以下内容を設定します。
- CALENDAR_ARN: カレンダーのリソース情報(Change CalendarのARN)
⇒arn:aws:ssm:ap-northeast-1:{アカウントID}:document/{カレンダー名} - OPEN_MESSAGE: OPEN時(フィルタリング時間帯)の任意メッセージ
- CLOSED_MESSAGE: CLOSED時(フィルタリング時間帯以外)の任意メッセージ
8.Lambda関数に関数URLの設定
iPhoneからLambda関数へのアクセスはURLで行うので、設定タブ内の関数URLよりその設定を作成します。
- 認証タイプにNONEを選択
- それ以外はデフォルトでよい
※NONEにすることで、URLを知っている人(デバイス)からアクセスすることができてしまうので、セキュリティ上あまりよろしくはないですが、個人的なフィルタリング機能なのでそこは考慮していません。
なお、設定後に払い出される関数URLを控えておきましょう。
8.動作確認
ここまできたら、ブラウザを起動し手順7で払い出された関数URLにアクセスしてみましょう。
以下のように表示されるはずです。
OPEN時(フィルタリング時間帯)の場合
{"state": "OPEN", "message": "{OPEN時のメッセージ}", "nextTransitionTime": {次の遷移時間}}
CLOSED時(フィルタリング時間帯以外)の場合
{"state": "CLOSED", "message": "{CLOSED時のメッセージ}", "nextTransitionTime": {次の遷移時間}}
ここまで出来たらAWS側の作業は終わりです!
iPhone側
1.ショートカットアプリを作成する
ショートカットアプリを起動し、+ より新規ショートカットを以下の内容で作成する。
①「URL」アクションを選択し、先ほど控えたLambda関数URLを貼り付ける。
②「URLの内容を取得」アクションを選択し、以下になっていることを確認する。
・ "URL" の内容を取得
・ 方法 "GET"
・ ヘッダは特に設定不要
③「辞書の値を取得」アクションを選択し、キーに state を入力後、以下になっていることを確認する。
・ "URLの内容" 内の "state" の "値" を取得
④「変数を設定」アクションを選択し、変数名に stateValue を入力後、以下になっていることを確認する。
・ 変数 "stateValue" を "辞書の値" に設定
⑤「テキスト」アクションを選択し、④で設定した stateValue 変数を選択する。
⑥「辞書の値を取得」アクションを選択し、テキストを長押しし URLの内容 を選択、キーに message を入力後、以下になっていることを確認する。
・ "URLの内容" 内の "message" の "値" を取得
⑦「変数を設定」アクションを選択し、変数名に messageValue を入力後、以下になっていることを確認する。
・ 変数 "messageValue" を "辞書の値" に設定
⑧「if文」アクションを選択し、ファイルサイズを長押しし テキスト を選択、すべてに OPEN を入力後、以下になっていることを確認する。
・ "テキスト" "が次と等しい" "OPEN" の場合
⑨「アプリを開く」アクションを選択し、(今回は) YouTube を選択後、if文のtrue部分(そのほかの場合の上)に移動する。
また、以下になっていることを確認する。
・ "YouTube" を開く
⑩「結果を表示」アクションを選択し、"if文"の結果を長押しし、 messageValue 変数を選択後、if文のfalse部分(その他の場合の下)に移動する。
また、以下になっていることを確認する。
・ "messageValue" を表示
全体として、以下のようになっていればOKです。
⑪右上の完了をクリックし、作成したショートカットを長押し後、「名称変更」で YouTube に変更する。
⑫一旦ここでネットからYoutubeアイコン画像を検索し保存する。
⑬ショートカットに戻り、作成したショートカットを長押しし、 共有 → ホーム画面に追加 をクリックし、先ほど保存したアイコン画像を設定し 追加 をクリックする。
⑭ホーム画面上に作成されているので、本物のYouTubeアイコンがある場合は長押しし、 アプリを削除 → ホーム画面から取り除く をクリックする。
※アンインストールされるわけでなく、ホーム画面から削除されるだけです。
これで完了です。
他のアプリでも試したい方は、同じ手順で同様のショートカットを作成すればOKです。
留意点
なんちゃってフィルタリング機能という名前の通り、以下の留意点があります。
-
本物アイコン(アプリ)から起動されたら防げない
手順⑭でホーム画面から取り除きましたが、例えばアプリのほうで通知設定をしている場合、通知をタップしたら本物アイコンから起動されるので防げません。
また、アプリライブラリというホーム画面で右に最後までスワイプすると、インストールされたアプリ一覧が表示されるので、そこから起動されても防げません。
あとは、アプリスイッチャーといわれる、下から上にスワイプすると起動中のアプリ一覧が表示されますが、そこから起動されても防げません。 -
ブラウザからアクセスされても防げない
アプリのものによると思いますが、今回のようなYouTubeなどは、ブラウザからアクセスされたらどうしようもありません。 -
自分で使う場合は自分自身との闘い
上述の留意点を知ってしまっているので、なんとでもなります。
また、自分でChange Calendarのイベントを変更もできるので、もはや防げません。
そもそも自分との闘いに勝てる人であれば、こんななんちゃってフィルタリング機能なんて不要というオチです。
どうぞ笑ってあげてください。
ということで、お子さんがいるような家庭では教育の一環として、なんちゃってフィルタリング機能を実装してみてもいいかもしれません。
とはいえ最近のお子さんは頭いいですからね。生成AIなども普及しているので、すぐ突破されるかもしれません。
ちなみにもし、お子さんなどのスマホに仕掛けてみた結果、親子の関係性が悪くなってしまったとしても責任は負えませんのであしからず。
まとめ
完全にネタ記事でした。
たぶん誰の心にも刺さらないと思いますが、SSM Change Calendarやショートカット機能を使えば、こういったこともできるよ。というご紹介でした。
Change Calendarもショートカット機能もそれぞれいろいろな使い方ができると思うので、活用していきたいと思います。






