Twitterのフリートが廃止されたので普通のツイートをそれっぽくする

#フリートとは？
>Fleetは、Twitterの活用や、Twitterでのコミュニケーションをこれまでにない方法ですぐに行える機能を提供します。Fleetで共有した内容は、24時間が経過すると表示されなくなるため、ふとした思いつきやうつろう気持ちを共有できます。一時的な個人的考えをフォロワーと共有でき、他の一般ユーザーからの反応が伝わることもありません。Fleetの作成者は、自分のFleetをクリックし、下部に表示される既読テキストをタップすると、ツイートを非公開にしているアカウントを含め、誰が自分のFleetを閲覧したかがわかります。

- 24時間が経過すると表示されなくなる
  - つまり、24時間に1回まとめて削除すればいい 

##フリートの欠点
- コメント機能が無く、DMで通知される
  - 絵文字を送っても、DMで通知される
- 普通のツイートと同じく、FavとRTとリプライ機能はやはり欲しい

##ツイートをフリート化するには？
- 「残すツイート」と「消えるツイート」を明確化する
- 残すツイートの条件 
  - Favがある
  - RTがある
  - リプライがある
- 消すツイートの条件
  - 残すツイート以外のすべて
- 上記の条件に則り、24時間に1回Lambdaを発火させ、ツイートを削除する

# 前提条件
- TwitterのAPIキーを発行済み
  - 英作文はググればいくらでも出てくるから頑張る 
- AWSのアカウントを作成済み
  - AWS CLIを使えるようにしておく
  
##構築
### フォルダ構造
```cmd
DeleteNoRtFavReplyTweets
|   lambda.yml
|   README.md
|
\---code
        DeleteNoRtFavReplyTweets.py
```

###Cloudformation
```yaml
AAWSTemplateFormatVersion: '2010-09-09'
# Twitter API Key
Parameters:
  ConsumerKey:
    Type: String
    NoEcho: true
  ConsumerSecret:
    Type: String
    NoEcho: true
  AccessKey:
    Type: String
    NoEcho: true
  AccessSecret:
    Type: String
    NoEcho: true
Resources:
# Lambda
  Lambda:
    Type: 'AWS::Lambda::Function'
    Properties:
      Code: code
      Environment: 
        Variables:
          ConsumerKeyVar: !Ref ConsumerKey
          ConsumerSecretVar: !Ref ConsumerSecret
          AccessKeyVar: !Ref AccessKey
          AccessSecretVar: !Ref AccessSecret
      Description: NoRtFavReplyTweetDelete
      FunctionName: NoRtFavReplyTweetDelete
      Handler: noRtFavTweetDelete.lambda_handler
      MemorySize: 128
      Role: !Sub 
        - arn:aws:iam::${AWS::AccountId}:role/${Domain}
        -  { Domain: !Ref LambdaRole }
      Runtime: python3.8
      Timeout: 180
  # CloudWatchEvents Rule
  Rule:
    Type: 'AWS::Events::Rule'
    Properties:
      Description: NoRtFavReplyTweetDeleteRule
      Name: NoRtFavReplyTweetDeleteRule
      ScheduleExpression: 'cron(0 17 * * ? *)' #夜間2時
      State: ENABLED
      Targets:
        - Arn: !GetAtt Lambda.Arn
          Id: lambda
  # Lambda IAM Role
  LambdaRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: deleteTweetRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  # CloudWatchEvents Lambda excute enable
  LambdaEvent:
    Type: 'AWS::Lambda::Permission'
    Properties:
      Action: 'lambda:InvokeFunction'
      FunctionName: !Ref Lambda
      Principal: 'events.amazonaws.com'
      SourceArn: !GetAtt Rule.Arn
```

###Python
```python
import tweepy
import os

# API Key
consumer_key = os.environ['ConsumerKeyVar']
consumer_secret = os.environ['ConsumerSecretVar']
access_key = os.environ['AccessKeyVar']
access_secret = os.environ['AccessSecretVar']

# Tweepy Auth
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth, wait_on_rate_limit = True)

noFavRtTweet = []
mentionTweet = []
noDeleteTweet = []

def lambda_handler(event, context):
    # No Favorite No RT Tweet
    print("==========No Favorite No RT Tweet==========")
    for tweet in tweepy.Cursor(api.user_timeline,exclude_replies = True).items():
        if tweet.favorite_count == 0 and tweet.retweet_count == 0: #Fav数に応じて変更する
            print(tweet.id,tweet.created_at,tweet.text.replace('\n',''))
            noFavRtTweet.append(tweet.id)

    # Reply Tweet
    print("==========Reply Tweet==========")
    for mentions in tweepy.Cursor(api.mentions_timeline).items():
        print(mentions.id,mentions.created_at,mentions.text.replace('\n',''))
        mentionTweet.append(mentions.in_reply_to_status_id)

    print("==========No Favorite No RT Reply Tweet==========")
    # No Favorite No RT Reply Tweet
    for tweet in noFavRtTweet:
        for reptw in mentionTweet:
            if tweet == reptw:
                print(api.get_status(tweet).id,api.get_status(tweet).created_at,api.get_status(tweet).text.replace('\n',''))
                noDeleteTweet.append(tweet)

    # Extraction Delete Tweet
    print("==========Extraction Delete tweet==========")
    perfectList = set(noFavRtTweet) ^ set(noDeleteTweet)
    print(list(perfectList))

    # Delete Tweet
    print("==========delete tweet==========")
    for deltw in perfectList:
        print(api.get_status(deltw).id,api.get_status(deltw).created_at,api.get_status(deltw).text
        api.destroy_status(deltw)
```

### AWSへのデプロイ
- Tweepyは外部モジュールなので同梱する

```Powershell
pip install tweepy --target ./code
```
- パッケージにしてS3に転送

```Powershell
aws cloudformation package --s3-bucket $YourBucketName `
--template-file lambda.yml `
--output-template-file lambda-packaged.yml
```

- インフラ構築とデプロイ
  - ここでTwitterのAPI KEYをLambdaの環境変数に指定する 

```Powershell
aws cloudformation deploy `
--template-file lambda-packaged.yml `
--stack-name $YourStackName `
--parameter-overrides AccessSecret=$YourAccessSecret `
ConsumerKey=$YourConsumerKey ` 
ConsumerSecret=$YourConsumerSecret ` 
AccessKey=$YourAccessKey `
--capabilities CAPABILITY_NAMED_IAM
```

- マネコンから確認する

# GitHubにあげた完全版
https://github.com/trysaildaisuki/DeleteNoReactionReply

# 真実
- [この記事](https://qiita.com/trysaildaisuki/items/4f61cba9a10a1be7799c)の副産物である
- ふぁぼ爆に対しての対策は自分のツイートのFav数から設定すると良い