7일 이상 무료로 볼 수 있도록 SendGrid 전송 로그를 BigQuery에 실시간 저장

이거 뭐야?


얼렁뚱땅의 아마존 페이는 쉽게 살 수 있는 유료 온라인 콘서트 티켓 판매 서비스를 개발해 운영하고 있다.
그곳에서는 센드그리드를 이용해 구매 확인 메일을 보냈으나 휴대전화 통신사의 메일 주소에 있는 스팸 블록과 RFC 메일 주소 위반 등으로 구매 확인 메일을 보낼 수 없어 손님이 문의할 때 조사할 필요가 있다.
SendGrid의 메일 활동을 확인하기 위해 조사했지만, 우선 무료 계획으로 시작해 관리 UI에서 확인할 수 있는 메일 발송 로그가 7일밖에 남지 않았기 때문이다.하지만 손님에게 물어보면 티켓 구매 후 2주 뒤 라이브 편지를 받으러 오는데, 조사할 때 이력이 남아있지 않아 메일이 발송되지 않는 이유를 알 수 없다.
SendGrid에는 메일마다 이벤트를 보내는 웹훅이 있기 때문에 비어 있으면 클라우드 펀션 for Firebase에서 받아들이고Firestore를 통해 BigQuery에 남는다.나는 그 절차와 코드를 남길 것이다.

1. 웹훅을 받을 클라우드 펀션 준비


POST가 SendGrid에서 Webhook을 통해 왔기 때문에 Cloud Function은 이것을 받아들였고 1발송 이벤트를 1개의 문서로Firestore에 추가했습니다.
Cloud Function 인터페이스의 URL은 다음과 같습니다.https://asia-northeast1-<projectid>.cloudfunctions.net/postMailLog실제로 SendGrid의 Webhook URL에 설정된 URL은 BASIC 인증 설정에 가입한 URL입니다.https://<ユーザ名>:<パスワード>@asia-northeast1-<projectid>.cloudfunctions.net/postMailLog다음은 그 소스 코드입니다.typescript로 썼어요.
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'

admin.initializeApp(functions.config().firebase)
const firestore = admin.firestore()

const BASIC_USERNAME = '***'
const BASIC_PASSWORD = '***'

// BASIC 認証
function basicAuth(authorization: string): boolean {
  const parts = Buffer.from(authorization.replace('Basic ', ''), 'base64')
    .toString()
    .split(':')
  if (parts[0] !== BASIC_USERNAME || parts[1] !== BASIC_PASSWORD) {
    return false
  } else {
    return true
  }
}

// Webhook を受けるエントリポイント
export const postMailLog = functions
  .region('asia-northeast1') // 東京リージョン
  .https.onRequest(async (request, response) => {
    try {
      functions.logger.info('postMailLog', request.body)

      if (!basicAuth(request.get('authorization') || '')) {
        throw new Error('basicAuth failed')
      }

      const logRef = firestore.collection('maillogs')
      const events = request.body || []
      for (const event of events) {
        // イベントごとに firestore にドキュメントとして保存
        event.createdAt = admin.firestore.FieldValue.serverTimestamp()
        await logRef.add(event)
        functions.logger.info('maillog added', { event })
      }

      functions.logger.info('postMailLog completed')
      response.status(200).end()
    } catch (err) {
      functions.logger.info('error', err)
      response.status(500).send(err)
    }
  })

2. SendGrid의 Webhook 설정


SendGrid의 관리 UI에 로그인하여 왼쪽 메뉴에서 Settings->Mail Settings를 선택하고 화면 맨 위에 있는'Event Webhook'이 나오는 연필 아이콘을 클릭하여 Webhook 설정 화면을 엽니다.
SendGrid/ Mail Settings

나타나는 설정화면에 수신구의 웹훅 URL을 설정하고 기록하고자 하는 활동을 검사하고 저장합니다.(해킹된 부분은 BASIC에서 인증한 사용자 이름과 비밀번호입니다.)

이렇게 되면 Firestore는 거의 실시간으로 저장됩니다.
그런 다음 이를 BigQuery에 저장합니다.

3. Firebase Extension을 설정하고 BigQuery와 함께 자동으로 저장합니다.


Firebase의 확장 기능, Export Collections to BigQuery를 설정하고 Firestore에 저장된 시간에 BigQuery에 저장합니다.
확장 디렉토리 화면에서 Export Collections to BigQuery를 찾아 Install 버튼을 클릭합니다.
Export Collections to BigQuery

4단계 설정 화면이 나타납니다.항목이 나타나는 마지막 단계를 입력하기 전에 다음 단계로 진행합니다.마지막 설정 화면에서 내보낼 BigQuery의 설정을 입력합니다.
구성 확장

항목을 다음과 같이 설정합니다.
항목
설정
설명
Cloud Functions location
Tokyo (asia-northeast1)
이 확장자가 실행 중인 영역을 설정합니다.앞으로는 변경할 수 없습니다.
Colleciton path
maillogs
동기화 소스 Firestore에서 모음 경로 구성
Dataset ID
firestore_export
동기화 대상 BigQuery의 데이터 세트 설정
Table ID
maillogs
동기화 BigQuery에서 테이블 이름 설정
그런 다음 설치 확장 을 클릭하여 설치를 시작합니다.4분 정도 기다리면 완성됩니다.이 확장자는 Firestore 이벤트를 통해 시작하여 문서를 BigQuery에 저장합니다.
이만 마치겠습니다.마지막으로 SendGrid에서 메일을 보낸 후 몇 초 정도 로그를 보내면 BigQuery에 반영됩니다.

4. BigQuery를 사용하여 데이터 스튜디오를 표시하는 뷰 만들기


그리고 이것은 또 무료Google Dataportal 데이터 원본으로 이 빅Query 테이블을 지정하여 화면에 (위) 내보냅니다.다만, 빅쿼리는 JSON 형태로 저장돼 있어 처리하기 어렵다.따라서 BigQuery에서 뷰를 데이터 소스로 만들기로 결정했습니다.타임 스탬프를 일본에 설정하면 보기 편하다.
CREATE VIEW imaticket.maillogs AS
SELECT 
  FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', timestamp, 'Asia/Tokyo') as timestamp,
  json_extract_scalar(data, "$.event") as event,
  json_extract_scalar(data, "$.email") as email,
  ifnull(json_extract_scalar(data, "$.response"),json_extract_scalar(data, "$.reason")) as response
FROM imaticket.maillogs_raw_changelog
WHERE
  json_extract_scalar(data, "$.event") is not null
Firestore의 확장 기능으로 저장된 테이블 이름은suffix입니다raw_change elog 첨부.이를 토대로 메일로그스라는 VIEW를 제작했다.
데이터 스튜디오에서 이 보기를 데이터 원본으로 삼아 계기판을 만들면 ok입니다.

무료 범위

  • Cloud Function for Firebase: 월 200만 회 무료.
  • Firestore: 하루에 두 번 무료로 쓸 수 있습니다.
  • BigQuery: 스토리지는 월 10GB 무료, 쿼리는 월 1TB 무료
  • 메일을 한 번 보내면 평균 두 번 (processed,delivered 두 이벤트) 씁니다.위에서부터 센드그리드의 무료 테두리 1만 2000통/월이기 때문에 그 범위 내에서 모두 무료로 사용할 수 있다.

    좋은 웹페이지 즐겨찾기