0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Lineでスケジューリングしたメールマガジンを送信する方法

Posted at

概要

既存の「メールアドレス宛にスケジュール配信するメールマガジン機能」に加え、Lineにも同様のスケジュール配信を行う仕組みを実装したいという要望は多いです。

この記事では、以下の要件を満たす手順を紹介します。

  • メールマガジン用に保存しているテーブル(例:MailMagazine)を使い、Line用の送信スケジュールテーブルを新設する
  • スケジュールされた時間 (scheduledAt) にLineメッセージを送信
  • 送信ステータス管理(例:SCHEDULEDSENT など)

前提

  1. メールアドレス宛にスケジュール配信する機能 がすでに存在する
  2. メールマガジンの内容を保存するテーブル (例: MailMagazine) がすでに存在する

ここからは、Line向けのスケジュール配信を追加するための流れを説明していきます。


テーブル構成

1. LineMessageSchedule テーブルの作成

新たに以下のようなテーブルを作成します。
※ 実際のORMやマイグレーションツールなどの記述に合わせて修正してください。

CREATE TABLE LineMessageSchedule (
  id INT AUTO_INCREMENT PRIMARY KEY,
  mailMagazineId INT NOT NULL,     -- メールマガジンテーブルとのリレーション
  lineUserId VARCHAR(255) NOT NULL, 
  message TEXT NOT NULL,           -- 送信するメッセージ本文
  scheduledAt DATETIME NOT NULL,   -- スケジュール時刻
  status VARCHAR(50) NOT NULL      -- SCHEDULED / SENT など
);

主な項目

  • mailMagazineId : どのメールマガジンに紐づいているかを示すID
  • lineUserId : 送信先のLineユーザーID
  • message : 実際に送信する内容(FlexMessageなど)
  • scheduledAt : 送信予定日時
  • status : ステータス (例:SCHEDULED = 送信待ち、SENT = 送信済み など)

実装フロー

1. 配信先ユーザーの取得と振り分け

メールマガジン送信先として登録されているグループ情報(deliveryGroup)から、Lineユーザーとメールユーザーを振り分けます。

// 配信先グループを取得
const deliveryGroupsWithUser =
  await this.deliveryGroupService.findAllForMailMagazine({
    deliveryGroupIds:
      deliveryGroupIds ||
      mailMagazine.deliveryGroups.map(
        ({ deliveryGroupId }) => deliveryGroupId,
      ),
  });

// 配信先グループ内で LineUser とメール User に分割
const lineUsers = deliveryGroupsWithUser.filter((user) => user.lineUserId);
const emailUsers = deliveryGroupsWithUser.filter((user) => !user.lineUserId);

ここで lineUserId を持っているかどうかで Lineかメールかを区別しています。

2. Line用メッセージスケジュールの登録

Line向けのスケジュール情報を、先ほど作成した LineMessageSchedule テーブルに作成します。
(ここでは Prisma の createMany を利用しています。)

await this.prisma.lineMessageSchedule.createMany({
  data: await Promise.all(
    lineUsers.map(async (user) => {
      return {
        mailMagazineId: createdMailMagazine.mailMagazineId,
        lineUserId: user.lineUserId,
        // 送信内容を作成 (FlexMessageなど)
        message: this.lineService.createFlexMessage(
          subject,
          body,
        ),
        scheduledAt: deliveryAt,
        status: 'SCHEDULED',
      };
    }),
  ),
});
  • lineUserId : 配信対象ユーザー(Lineユーザー)
  • message : 送信するLineメッセージ(FlexMessageなどを生成)
  • scheduledAt : ユーザーが指定した配信日時

3. 定期実行 (Cron) での送信処理

スケジュールが登録されたLineメッセージを定期的にチェックし、送信予定時刻になったら実際にLineへpushメッセージを送ります。
以下の例では、Node.js の cron あるいは NestJS の @Cron を使用し、毎分実行として設定しています。

@Cron('* * * * *') // 毎分実行
async sendScheduledLineMessages() {
  const now = new Date();
  
  // ステータスが SCHEDULED で、scheduledAt <= 現在時刻 のメッセージを取得
  const schedules = await this.prisma.lineMessageSchedule.findMany({
    where: {
      scheduledAt: {
        lte: now,
      },
      status: 'SCHEDULED',
    },
    include: {
      mailMagazine: true, // 必要に応じてメールマガジンの情報も取得
    },
  });

  // 取得したスケジュールを順次送信
  for (const schedule of schedules) {
    try {
      // 送信処理 (Push Message)
      await this.lineClient.pushMessage({
        to: schedule.lineUserId,
        messages: [schedule.message],
      });

      // ステータスを SENT に更新 (例)
      await this.prisma.lineMessageSchedule.update({
        where: { id: schedule.id },
        data: { status: 'SENT' },
      });
    } catch (error) {
      console.error('Line message send error:', error);
      // エラー時のリトライやステータス管理は適宜実装
    }
  }
}
  1. スケジュール一覧取得 : scheduledAt が現在時刻以前、かつステータスが SCHEDULED のレコードを取得
  2. 実際の送信処理 : lineClient.pushMessage などでLineに送信
  3. ステータス更新 : 送信成功後 SENT などに更新し、再度送信されないようにする

まとめ

以上のように、既存のメールマガジンのスケジュール配信機能に加えて、Lineにも同様の仕組みを組み込むことができます。基本的な流れは以下です。

  1. Line用のスケジュールテーブル (LineMessageSchedule) を新設
  2. 配信先ユーザー をメール・Lineで振り分ける
  3. スケジュール情報 を登録し、cronなどで定期的に送信を実行

参考になれば幸いです!質問等あればコメントでお待ちしています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?