---
title: 一定期間ログインの無いメンバーへのリマインドおよび自動退会機能を実装する
description: バッチ処理を利用して、一定期間ログインの無いメンバーに対してリマインド送付と自動退会の機能を実装します。また、ログインがあった場合に有効期限を伸ばす機能は「ログイン後処理」をトリガーにしたカスタム処理で実装します。
---

## 概要
バッチ処理を利用して、一定期間ログインの無いメンバーに対してリマインド送付と自動退会の機能を実装します。  
また、ログインがあった場合に有効期限を伸ばす機能は「ログイン後処理」をトリガーにしたカスタム処理で実装します。

### 学べること
以下の手順で一定期間ログインの無いメンバーへのリマインドおよび自動退会機能を実装します。
- [事前準備](#事前準備)
- [リマインド機能の実装](#リマインド機能の実装)
- [自動退会機能の実装](#自動退会機能の実装)
- [ログイン後にログイン許可の有効期限を延ばす機能の実装](#ログイン後にログイン許可の有効期限を延ばす機能の実装)

### 前提条件
動作確認に利用するメンバー及びグループは適宜追加することとします。  

## 事前準備
### メンバーにログイン許可の有効期限を設定
ログイン許可の有効期限は、後で設定するカスタム処理で自動的に追加されますが、動作の確認のためまずは手動で設定します。  
[メンバー管理] -> [メンバー]をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/d9233a93df746e9dd8d780f6b1c0c368.png)

メンバー一覧のページでテーブル右上の歯車マークから、表示項目設定を開き、「ログイン許可期限」の表示を追加しておきます。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/8cd347e117d972fa93bc7699c4fc40f2.png)

メンバー一覧から設定をするメンバーの名前をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/bc5f95c0c215d81884e6d94362c8596a.png)

ログイン許可の有効期限を設定します。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/88c15699cae8ae8473c698d0cf90155d.png)

「メルマガ拒否フラグ」のチェックが外れていることを確認します。
![Image from Gyazo](https://t.gyazo.com/teams/diverta/617428680855a4f9339cd5688e4268c9.png)

同様に動作確認用のメンバーにログイン許可期限を設定して、以下のようにしました。  
![Image from Gyazo](https://t.gyazo.com/teams/diverta/e3f162f67c0f1d707e31a202ed64ffed.png)

### 内部処理用のAPI作成
Kuroco内部でのみ利用するエンドポイントはAPIを分けておくことをお勧めします。  
そこで、まずは内部利用のためのAPIを新規で作成します。  
既に追加済みの場合は次のステップに進んで構いません。  

#### APIの作成
Kuroco管理画面のAPIより「追加」をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/22c37e75a8244f384deb5b706d4979da.png)

API作成画面が表示されるので、下記入力し「追加する」をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/44c341acced8d685e67ec1da1e85abac.png)

|項目|設定内容|
| :--- | :--- |
|タイトル|Internal|
|版|1.0|
|ディスクリプション|内部処理用のAPI|

APIが作成されました。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/3c04c600fc74102913e9e668ae5cca0e.png)

#### セキュリティの設定
次にセキュリティの設定をします。[セキュリティ] をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/6bc5cb1beb28c74ede6aeca89715a647.png)

セキュリティを[動的アクセストークン]に設定して、[保存する]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/62aaa225db5d12ee84ccc6d5a52411fe.png)

セキュリティを[動的アクセストークン]に設定後、`Login::token`のエンドポイントが無い場合、利用をお勧めされますが、内部利用のみの場合は無視して構いません。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/0bb1efe099bdae8f1c0481037416a5d9.png)

#### CORSの設定
次にCORSの設定をします。[CORSを設定する] をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/74cd7a36fd926dbc20b04812553072c7.png)

CORS_ALLOW_ORIGINSの [Add Origin] をクリックし、下記を追加します。

- 管理画面URL

CORS_ALLOW_METHODSの [Add Method] をクリックし、下記を追加します。

- GET  
- POST
- OPTIONS

CORS_ALLOW_CREDENTIALSの[Allow Credentials]にチェックが入っていることを確認します。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/f2bc3744fe6a2ab042456fa8c635195c.png)

問題なければ [保存する] をクリックします。  

## リマインド機能の実装
リマインド機能は以下の流れで動作をさせます。
- バッチ処理で毎日06:00に、エンドポイントにリクエストを送る。
- エンドポイントは設定された配信IDに、メッセージひな形の識別子とカスタムメンバーフィルターIDの情報を送る。
- 配信はメッセージひな形の内容をカスタムメンバーフィルター宛に送信する。

### カスタムメンバーフィルターの作成
リマインド送付の対象者はカスタムメンバーフィルターで設定します。    
[メンバー管理] -> [カスタムメンバーフィルター]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/1b8b8332df9870a7bdcec7b5474cf562.png)

[追加]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/0403ee2fe9d2f335ee495c8a6060f71c.png)

以下のフィルタを作成します。  
管理者およびDeveloperのメンバーを除いて、有効期限が30日前の場合と、7日を切っている場合をリマインド送付の対象者とします。

|項目|設定|
|:--|:--|
|タイトル|ログイン許可有効期限のリマインド送付対象者|
|絞り込み条件|以下の通り|

![Image from Gyazo](https://t.gyazo.com/teams/diverta/ebfb7f7f271d120aed7954fe16c72e4b.jpg)

[結果を閲覧する]をクリックして、想定通りのメンバーがヒットするか確認します。  
複数の条件がある場合はテストメンバーのログイン許可有効期限を手動で変更しながら確認してください。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/2f36b104a2261171c2e85c3a106f795f.png)

問題なければ[追加する]をクリックしてカスタムメンバーフィルターを追加します。  
作成したカスタムメンバーフィルターのIDは後ほど利用するのでメモをしておきます。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/e2f663c1d4ffb324452d1fe428f29f90.png)

### 配信の作成
リマインドメールの送付は配信の機能を利用します。  
[キャンペーン] -> [配信] をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/937f317a262e1eb033582dbc8cdef98f.png)

[追加]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/1118c911e95b78fe2423d6bf66e2e916.png)

以下の内容を設定します。  

|項目|設定|
|:-|:--|
|タイトル|ログイン許可有効期限のリマインド|
|メール送信元（From）|`noreply@kuroco-mail.app`|
|その他の設定|デフォルトのまま|

![Image from Gyazo](https://t.gyazo.com/teams/diverta/c068495bb9453be9a1f4a1d7da6318d1.png)

- バッチ処理実行時に設定するので、あて先も設定なしで構いません。
- fromのメールアドレスを変更したい場合は[SendGrid連携方法](/ja/docs/tutorials/how-to-link-sendgrid/)を参考にSendgridと連携してください。

設定ができたら[追加する]をクリックして配信を追加し、配信IDをメモしておきます。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/7e76584f39b7de5cb5f16234b06dd6fa.png)

### メッセージひな形の作成
リマインドメールの文面はメッセージひな形を利用して作成します。  
[オペレーション] -> [メッセージひな形]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/1248d218b3a9b24a8c292f17a355801e.png)

[追加]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/d1b2f6a592700bcb6f48b83f38c4b5f3.png)

以下のように設定します。  

|項目|設定内容|
| :--- | :--- |
|テンプレート|ログイン許可有効期限のリマインド文言|
|識別子|expiration_remind_template|
|本文|以下の内容|

```html
%name1% %name2% 様<br>
<br>
ログインの有効期限は%login_ok_ymd%までとなっております。<br>
有効期限までに再度ログインしてください。
```

![Image from Gyazo](https://t.gyazo.com/teams/diverta/c0e6a154ae40bd9d21202cc47298019e.png)

設定ができたら[追加する]をクリックしてメッセージひな形を追加します。  

### カスタム処理の作成
配信では`%name1%`、`%name2%`と記入すると、あて先のメンバーの名前を表示できますが、`%login_ok_ymd%`などデフォルトで利用できない項目や、複雑な処理を追加したい場合はカスタム処理を利用します。

[オペレーション] -> [カスタム処理]をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/629aadd18b2e71dc1d5dca3784fe6252.png)

[追加]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/7a0256fcb7617a95ab332d2943923d08.png)

以下のように入力します。

|項目|設定|
|:--|:--|
|タイトル|配信の差し込み|
|識別子|magazine_substitution|
|これを使ったコンポーネント|トリガー：配信の差し込み<br/>値：利用する配信ID(2)|
|処理|以下のコードを入力します。|

```smarty
{assign_array var=substitutions values=''}
{assign var=substitutions.name1 value=$member_info.name1}
{assign var=substitutions.name2 value=$member_info.name2}
{assign var=substitutions.login_ok_ymd value=$member_info.login_ok_ymd|date_format:'%Y年%m月%d日'}
```

![Image from Gyazo](https://t.gyazo.com/teams/diverta/b9803c7238755a55c5c6a98d33f07457.png)

設定ができたら[追加する]をクリックしてカスタム処理を追加します。  

### エンドポイントの作成
次にエンドポイントを作成します。  
InternalのAPIから[新しいエンドポイントの追加]をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/6bfc5c05d2cc1c6daf4740f6787a467f.png)

以下のエンドポイントを作成します。

|項目|設定内容|
| :--- | :--- |
|パス|expiration_remind|
|カテゴリー|配信|
|モデル|Magazine|
|オペレーション|send|
|destination_id|カスタムメンバーフィルターのID(1)|
|mail_type|1|
|mail_template_name|メッセージひな形の識別子(expiration_remind_template)|
|subject|ログインの有効期限を確認してください|

![Image from Gyazo](https://t.gyazo.com/teams/diverta/1409dcc31ea8eedcc288126a9a61d674.png)
![Image from Gyazo](https://t.gyazo.com/teams/diverta/eeb9ff4e0707a53e9f772c380dc438b8.png)

設定ができたら[追加する]をクリックしてエンドポイントを追加します。  

### バッチ処理の作成
リマインド機能はバッチ処理で作成し、日次で対象者の確認及びリマインドメールの送付をします。  
[オペレーション] -> [バッチ処理]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/bbbe745e3943541e470fb5c0dc66969f.png)

[追加]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/82e14b4bc626dd8d97c97d7ac082842f.png)

以下のように設定します。  

|項目|設定内容|
| :--- | :--- |
|テンプレート|ログイン許可有効期限のリマインド送付|
|識別子|send_remind_mail|
|バッチ|毎日 06:00|
|処理|以下のコード|

```smarty
{api_internal
    var='response'
    status_var='status'
    endpoint='/rcms-api/4/expiration_remind/2'
    method='POST'
    member_id='1'
}
```

![Image from Gyazo](https://t.gyazo.com/teams/diverta/035e368c5c0f3d65facfad7b19663cf0.png)

入力ができたら[追加する]をクリックしてバッチ処理を追加します。 

### 動作確認
最後に、[すぐに実行する]をクリックして動作の確認をします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/2fe8f8fea48e2e06c35789a8779bba56.png)

正しく設定ができていれば以下のようにリマインドメールが届きます。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/78fd353e75e571932929e51a47d72f9e.png)

## 自動退会機能の実装
自動退会機能はバッチ処理で作成し、日次で対象メンバーの有無を確認し、対象メンバーが存在する場合はMember::deleteのエンドポイントを利用して削除をします。

### カスタムメンバーフィルターの作成
自動退会の対象者はカスタムメンバーフィルターで設定します。  
[メンバー管理] -> [カスタムメンバーフィルター]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/1b8b8332df9870a7bdcec7b5474cf562.png)

[追加]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/b13c7749146d2497ad376630d6452df5.png)

以下のフィルタを作成します。

|項目|設定|
|:--|:--|
|タイトル|自動退会処理の対象者|
|絞り込み条件|以下の通り|
  
![Image from Gyazo](https://t.gyazo.com/teams/diverta/15766cabc5beb6b641b273154c189531.jpg)

フィルター結果の確認をして、問題なければ[追加する]をクリックしてカスタムメンバーフィルターを追加します。

作成したカスタムメンバーフィルターのIDは後ほど利用するのでメモをしておきます。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/2996b6d6aa5b68ece252a48b5f3a73d4.png)

### エンドポイントの作成
削除対象のメンバーリストを返すエンドポイントと、メンバーを削除するためのエンドポイントの2つを作成します。  
InternalのAPIから[新しいエンドポイントの追加]をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/6bfc5c05d2cc1c6daf4740f6787a467f.png)

#### delete_member_listエンドポイント
以下のエンドポイントを作成します。

|項目|設定内容|
| :--- | :--- |
|パス|delete_member_list|
|カテゴリー|メンバー|
|モデル|Member|
|オペレーション|list|
|custom_search_id|カスタムメンバーフィルターのID(2)|

![Image from Gyazo](https://t.gyazo.com/teams/diverta/d6c1e7bb05ec9d3a402be4f0d45f031b.png)
![Image from Gyazo](https://t.gyazo.com/teams/diverta/47cb9c22b7e045bd9bf85153025d27ad.png)

設定ができたら[追加する]をクリックしてエンドポイントを追加します。  

#### expired_member_deleteエンドポイント
同様にメンバーを削除するための以下のエンドポイントを作成します。  

|項目|設定内容|
| :--- | :--- |
|パス|expired_member_delete|
|カテゴリー|メンバー|
|モデル|Member|
|オペレーション|delete|
|allowed_group_ids|削除対象となるメンバーが所属するグループを設定します。(101,102)|

![Image from Gyazo](https://t.gyazo.com/teams/diverta/cbc9f086776368cac3824c42f70855fe.png)
![Image from Gyazo](https://t.gyazo.com/teams/diverta/da75abe728e98a6f00892180ab8bc553.png)

設定ができたら[追加する]をクリックしてエンドポイントを追加します。  

### バッチ処理の作成
続いてバッチ処理を作成します。  
[オペレーション] -> [バッチ処理]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/bbbe745e3943541e470fb5c0dc66969f.png)

[追加]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/664166e4272e9a9381421bce387098fd.png)

以下のように設定します。  

|項目|設定内容|
| :--- | :--- |
|タイトル|有効期限切れメンバーの削除|
|識別子|delete_expired_member|
|バッチ|毎日 05:00|
|処理|以下のコード|

```smarty
{*対象メンバーの取得*}
{api_internal
    var='response'
    status_var='status'
    endpoint='/rcms-api/4/delete_member_list'
    method='GET'
    member_id='1'
}

{*対象メンバーの削除*}
{foreach from=$response.list item=n}
    {assign var='target' value="/rcms-api/4/expired_member_delete/`$n.member_id`"}
    {* member_id=1 -> admin user *}
    {api_internal
        var='response'
        status_var='status'
        endpoint=$target
        method='POST'
        member_id='1'
    }
    {logger msg1="`$n.name1``$n.name2`(member_id=`$n.member_id`)を削除します。" msg2=$response}
{/foreach}
```

![Image from Gyazo](https://t.gyazo.com/teams/diverta/75cc361961bb8ef5c734b89e2bd0ec43.png)

入力ができたら[追加する]をクリックしてバッチ処理を追加します。 

### 動作確認
最後に、[すぐに実行する]をクリックして動作の確認をします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/54c198478e7a4aba17f6db0288119869.png)

正しく設定ができていれば以下のようにカスタムログにログが残り、メンバーが削除されます。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/a6804f92660cc1cadab674955496835e.png)


## ログイン後にログイン許可の有効期限を延ばす機能の実装
最後に、ログイン後にログイン許可の有効期限を自動で延ばす機能を実装します。  
こちらはメンバーのログイン後をトリガーにカスタム処理を実行し、Member::updateのエンドポントで`login_ok_ymd`を更新します。

### エンドポイントの作成
InternalのAPIから[新しいエンドポイントの追加]をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/6bfc5c05d2cc1c6daf4740f6787a467f.png)

以下のエンドポイントを作成します。

|項目|設定内容|
| :--- | :--- |
|パス|member/update_login_ok_ymd|
|カテゴリー|メンバー|
|モデル|Member|
|オペレーション|update|
|self_only|チェックを入れる|

![Image from Gyazo](https://t.gyazo.com/teams/diverta/dcf0a24ead3ca0e254e5c28db37d021c.png)
![Image from Gyazo](https://t.gyazo.com/teams/diverta/3a77be43d3c52d08a5e271b056473797.png)

### カスタム処理の作成
[オペレーション] -> [カスタム処理]をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/629aadd18b2e71dc1d5dca3784fe6252.png)

[追加]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/3cf05595e31dd0f905466ec2a09bb835.png)

以下のように入力します。

|項目|設定|
|:--|:--|
|タイトル|ログインしたらログイン許可期間を延ばす|
|識別子|update_login_permission_date|
|これを使ったコンポーネント|トリガー：ログイン後処理<br/>値：0|
|処理|以下のコード|


```smarty
{assign_member_detail assign_group_flg=1 var='member_detail' member_id=$member_id}

{* add extending 1y *}
{assign_array var="payload" keys="login_ok_ymd" values="1 year"|strtotime|date_format:"Y-m-d"}

{if
    "1"|rcms_in_array:$member_detail.arrGroup_id ||
    "2"|rcms_in_array:$member_detail.arrGroup_id
}
  {* skip execution when the user supposed to be administrator *}
{else}
    {* member_id=1 -> admin user *}
    {api_internal
        var='response'
        status_var='status'
        endpoint='/rcms-api/4/member/update_login_ok_ymd'
        method='POST'
        queries=$payload
        member_id=$member_id
    }
    {logger msg1="`$member_detail.name1``$member_detail.name2`(member_id=`$member_id`)のlogin_ok_ymdを更新します。" msg2=$response}
{/if}
```

![Image from Gyazo](https://t.gyazo.com/teams/diverta/3d1add74a2d4b4145627237afca37adc.png)

### 動作確認
最後に、動作確認のため、対象のメンバーでログインをします。  

正しく設定ができていれば以下のようにカスタムログにログが残り、メンバーのログイン許可の有効期限が更新されます。  
![Image from Gyazo](https://t.gyazo.com/teams/diverta/bac4f40cea4593e148bf19e805cc5439.png)
![Image from Gyazo](https://t.gyazo.com/teams/diverta/861b3aa62feb7bedbf5bdb881617faea.png)

以上で、一定期間ログインの無いメンバーへのリマインドおよび自動退会機能の実装ができました。  

## 関連ドキュメント
- [カスタムメンバーフィルターを利用する](/ja/docs/tutorials/using-custom-member-filters/)
- [カスタム処理に利用できる変数一覧](/ja/docs/reference/trigger-variables/)
- [カスタム処理からKurocoのAPIを呼び出せますか？](/ja/docs/faq/how-to-request-kuroco-api-from-smarty-function/)
- [カスタム処理でデバッグを目的としたログを出力できますか？](/ja/docs/faq/can-the-original-process-output-logs-for-debugging-purposes/)
- [Smartyプラグイン](/ja/docs/reference/smarty-plugin/)
- [SendGrid連携方法](/ja/docs/tutorials/how-to-link-sendgrid/)