0.はじめに
iOS アプリの通知について、Amazon SNS を利用しており、以下の記事を参考にして、先日 iOS アプリの APNs 証明書の更新したんですが…、
Bitrise の設定は更新したものの、Amazon SNS を忘れてしまって、通知が届かなくなるというトラブルが発生してしいました…。
😱😱😱
iOS アプリの APNs 証明書の有効期限は、Apple から警告メールが届くので良いんですが、Amazon SNS の設定状況についても、検知する仕組みが必要だな、と思い、作ってみました。
1. 全体の構成
構成としては、こんな感じです。
- Amazon CloudWatch Events から、日時で AWS Lambda を実行。
- AWS Lambda で、Amazon SNS に登録されている APNs プラットフォームアプリケーションの有効期限をチェック。
- 有効期限に近いものが確認された場合、Amazon SNS のトピックにパブリッシュして、メールを通知。
2. Python @ AWS Lambda のコード
#!/usr/bin/env python
# -*- coding: utf-8-unix; -*-
"""AWS Lambda Function - Maintenance SNS Check to Expire
"""
from __future__ import print_function
import os
import math
import boto3
# 「Python 3 で少しだけ便利になった datetime の新機能 - Qiita」
# <https://qiita.com/methane/items/d7ac3c9af5a2c659bc51>
from datetime import datetime, timezone, timedelta
TimeZone = timezone(timedelta(hours=+9), 'JST')
ClientSNS = boto3.client('sns')
# ------------------------------------------------------------------------------
# Function
# ------------------------------------------------------------------------------
# 「【Python】Lambdaからメールを送信 | ハックノート」
# https://hacknote.jp/archives/35679/
def MailSend(prmSubject, prmMessage):
result = -1
try:
response = ClientSNS.publish(
TopicArn = '[送信先トピックのARN]',
Message = prmMessage,
Subject = prmSubject
)
except Exception as e:
print(e)
result = -1
raise
else:
pass
finally:
pass
return result
def lambda_handler(event, context):
try:
print(event)
print(context.__dict__)
now_datetime = datetime.now(TimeZone)
print(now_datetime)
logdata = ""
list_platform_applications_paginator = ClientSNS.get_paginator('list_platform_applications')
#print(list_platform_applications_paginator)
list_platform_applications_pageiterator = list_platform_applications_paginator.paginate()
#print(list_platform_applications_pageiterator)
for list_platform_applications_page in list_platform_applications_pageiterator:
#print(list_platform_applications_page)
platform_applications = list_platform_applications_page.get('PlatformApplications', [])
for platform_application in platform_applications:
print(platform_application)
platform_application_arn = platform_application.get('PlatformApplicationArn', '')
platform_application_arn_split = platform_application_arn.split('/')
#print(platform_application_arn_split)
if len(platform_application_arn_split) < 3:
continue
platform_application_type = platform_application_arn_split[1]
#print(platform_application_type)
if platform_application_type != 'APNS':
continue
platform_application_attributes = platform_application.get('Attributes', {})
platform_application_enabled = platform_application_attributes.get('Enabled', '')
#print(platform_application_enabled)
if platform_application_enabled != 'true':
continue
platform_application_expiration_date = platform_application_attributes.get('AppleCertificateExpirationDate', '').replace('Z', '+00:00')
print(platform_application_expiration_date)
platform_application_expiration_date_timestamp = 0
try:
platform_application_expiration_date_timestamp = datetime.fromisoformat(platform_application_expiration_date).timestamp()
except Exception as e:
print(e)
#print(platform_application_expiration_date_timestamp)
now_datetime_timestamp = now_datetime.timestamp()
#print(now_datetime_timestamp)
diff_timestamp = platform_application_expiration_date_timestamp - now_datetime_timestamp
diff_day = math.floor(diff_timestamp/(60*60*24))
print(diff_day)
if diff_day < 1:
pass
elif diff_day in [30,60,90]:
pass
else:
continue
logdata += """\
- Last %d Days !!! - %s
""" % (diff_day, platform_application_arn)
#
#print(logdata)
if len(logdata) > 0:
subject = """[%s] SNS Check to Expire !!!""" % (now_datetime.isoformat(' ', 'seconds'))
msg = """\
----
【有効期限注意】
%s
""" % (logdata)
print(subject)
print(msg)
MailSend(subject, msg)
except Exception as e:
print(e)
else:
pass
finally:
pass
#
return "normal end"
このコードでは、警告の判断は、以下としていますが、状況に合わせて変更して頂ければよろしいかと。
- 有効期限が 14 日以内
- 有効期限が、90 or 60 or 30 日前
AWS Lambda に割り当てる IAM Role については、こんな感じです。
-
Amazon SNS からのプラットフォームアプリケーションの情報の取得
- sns:ListPlatformApplications
-
Amazon SNS のトピックへのパブリッシュ
- sns:Publish
-
AWS Lambda の CloudWatch Logs へのログの出力
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
99.ハマりポイント
-
今回は、特にハマることはありませんでしたが…
-
ただ、よくよく考えてみると、Bitrise にしても、Amazon SNS にしても、Apple Developer で証明書を更新したら、自動でそちらも更新されると非常に便利だなぁ、と思ったりもしますので、先々その辺の自動化の仕組みも検討しても良いかもしれません。
-
それによっては、使うサービスを変えても良いかなとも思ったりします。
- Certificates | Apple Developer Documentation とか?
- GitHub Actions とか?
- この辺を使えば、良い感じに出来るかな???
- Bitrise 側から、全部出来る機能があったりすると良いんだけどなぁ…
XX.まとめ
ご参考になれば ♪♪♪
👋👋👋
【2021.05.07 追記】
因みに、証明書の更新手順は、以下。