1. NoOne

    Posted

    NoOne
Changes in title
+AWSとJavaで、できるだけシンプルにtwitter botを作る
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,179 @@
+<h1>背景</h1>
+会社の査定目標で自社の中途採用に貢献するという目標を掲げたので、せっかくだしbotを作って自社の宣伝すれば面白いのでは?ということで作ってみました。AWSやJavaを使わなくともbotは作れるらしいですがせっかくなので!
+
+<h1>つくるもの</h1>
+配列で用意したハリーポッターのキャラクター名を自動でつぶやくアプリ
+
+<h1>用意するもの</h1>
+EclipseでMavenプロジェクトを開発できる環境
+AWS無料アカウント
+
+<h1>①twitterdevアカウントを開設</h1>
+https://developer.twitter.com/en/apply-for-access
+こちらから開設しましょう。英語で質問をいくつかされますがそこまで厳密にみられてはいないと
+思うので最低文字数をクリアすれば問題ありません。
+
+<h1>②twitterdevのダッシュボードでプロジェクト作成</h1>
+ダッシュボード上でプロジェクトを作成します。
+作成したらデフォルトではReadのみの権限を下記のように変更します。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/2b85e5fb-a40a-2d3c-8851-bfde05e6f87b.png)
+
+<h1>③twitterapiとやり取りするためにJavaに埋め込む鍵を4つ取得する</h1>
+作成したプロジェクトのKeys and tokensタブで4つ鍵を生成できるのでメモしましょう。
+鍵は何回でも作りなおせます。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/a4d904d6-9994-4b5b-4b69-ec90a8fcc1bf.png)
+
+<h1>④Mavenプロジェクト作成&Javaコーディング</h1>
+まずはMavenPJの作成
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/0c2aef12-182c-01f2-79e3-f4eab6c59ad0.png)
+
+
+Javaのコーディングはいくつかポイントがあります。
+-関数名はhandleRequestというLambdaのデフォルト関数名にしていますが名前は何でもOKです。
+-今回のように別段パラメータを渡す必要がなければ極力handleRequest()という風に引数なしにしましょう。LambdaやCloudwatchの設定でこけるリスクが減ります(私だけですかね)。
+-twitterAPI規約で同一内容の投稿を行うと187エラーになるので最新の自分のツイートを取得し・それと被らない処理を書いてます。
+
+```
+package jobs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+import twitter4j.ResponseList;
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.TwitterFactory;
+import twitter4j.auth.AccessToken;
+
+public class Job {
+ public static void handleRequest() {
+
+ final String consumerKey = "③で取得したconsumerKey";
+ final String consumerSecret = "③で取得したconsumerSecret";
+ final String accessToken = "③で取得したaccessToken";
+ final String accessTokenSecret = "③で取得したaccessTokenSecret";
+ String tweet;
+ // 前回のツイート(これと同一だとツイートできない)
+ String latestTweet = "";
+ // ツイートしたい内要
+ List<String> msgList = new ArrayList<String>(Arrays.asList(
+ "ハリーポッター", "マルフォイ", "ロン", "ハーマイオニー", "ネビル", "シリウス",
+ "ヴォルデモート", "スネイプ", "マクゴナガル", "ダンブルドア")
+ );
+
+ //ツイッターAPIとのやり取りをできるようにする処理
+ Twitter twitter = new TwitterFactory().getInstance();
+ twitter.setOAuthConsumer(consumerKey, consumerSecret);
+ twitter.setOAuthAccessToken(new AccessToken(accessToken,accessTokenSecret));
+
+
+ try {
+ //ここからbreakまで最新のツイートを取得するための処理
+ ResponseList<Status> latestTweets = twitter.getHomeTimeline();
+ for (Status lTweet : latestTweets) {
+ latestTweet = lTweet.getText();
+ break;
+ }
+ } catch (TwitterException e){
+ System.err.println("最新ツイート取得失敗"+e.getMessage());
+ }
+
+ Random rnd = new Random();
+ tweet = decideTweetContent(rnd.nextInt(10), msgList, latestTweet);
+
+ // ツイート処理
+ try{
+ twitter.updateStatus(tweet);
+ } catch(TwitterException e){
+ System.err.println("ツイート失敗"+e.getMessage());
+ }
+
+ }
+
+ //ツイート内容を決める
+ public static String decideTweetContent(int num, List<String> msgList, String latestTweet) {
+ // 最新のツイートと被っていたらduplicateエラー回避のため再帰処理
+ if(msgList.get(num).equals(latestTweet)){
+ Random rnd = new Random();
+ decideTweetContent(rnd.nextInt(5), msgList, latestTweet);
+ }
+ return msgList.get(num);
+ }
+
+}
+
+```
+
+いちおう構造も
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/ec52671e-bef0-da27-b8b8-78580f7a52b6.png)
+
+
+<h1>⑤POM.xml記述</h1>
+追加部分だけ記述します。
+
+```
+<dependencies>
+ <dependency>
+ <groupId>org.twitter4j</groupId>
+ <artifactId>twitter4j-core</artifactId>
+ <version>4.0.7</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>3.2.1</version>
+ <configuration>
+ <createDependencyReducedPom>false</createDependencyReducedPom>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+```
+
+<h1>⑥Jarファイル作成</h1>
+作成したPJ上で右クリックするとメニューが開くのでMavenビルド選択します。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/3a608982-76ce-caf6-45e2-fb5046ed3710.png)
+
+ゴールにpackageと入力し実行します。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/e7c09196-62e5-70de-b8e8-1792a42e7660.png)
+
+<h1>⑦Lambda関数の作成</h1>
+ランタイムはjava(corretto)です。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/49515d19-a866-3cbf-817a-716ea72bfa6e.png)
+
+コードソースのアップロード元から⑥で作ったJarファイルをアップします。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/fcf88fb2-61e0-63b4-d00f-c489788013fd.png)
+
+ランタイム設定を編集します。ハンドラは{パッケージ名}.{クラス名}::{関数名}です。
+大文字小文字に注意しましょう(私は大文字小文字のせいでClassNotFoundExceptionに苦しみました)。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/fc120ceb-5994-6049-b420-ef6cb9f4ffc6.png)
+
+<h1>⑧LambdaのトリガーとしてCloudWatchEvent(EventBridge)を作成</h1>
+CloudWatchの右メニューからイベントのルールを選択します。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/cfd01f74-e593-d879-58e3-9b9b7184f9eb.png)
+
+左のイベントソースではどれくらいの間隔でLambdaを呼ぶ(今回だとツイート)か設定、右のターゲットでは⑦でつくったLambda関数を選択します。
+![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/b8eed643-718f-707a-e2e6-82d142164210.png)
+
+<h1>感想</h1>
+シンプルといいつつ結構手順多いですね。。。
+これで査定もばっちり?
+もし試してみて再現できませんということあればお気軽にお声がけください。
+私はめっちゃこけました(笑)。
+