[JAVA] A memorandum of making a bot that automatically RTs and automatically tweets on Twitter 4J

Hello, is a person of technology in charge of sugar Haato support bot. "Shuga Heart" is a nickname for "Shin Sato", a character that appears in The Idolmaster Cinderella Girls.

image.png

The Shuga Heart Support Bot is an unofficial bot that supports Shin Sato.

Since I made a program to automatically RT and automatic tweet on Twitter4J, I will post an article so that it can be used as a reference for other Ps or as a reference when I make it later.

What to make

From an acquaintance who runs the bot "I want you to automatically RT tweets containing the words" #Satoshin "and" Shugaha "." "I want you to tweet the image just at 8:10" I was asked.

The former can be easily achieved by using RTbot and the latter by using Botbird. ・ RTbot doesn't work well ・ I want a function other than just search and RT (blacklist, etc.) ・ It is troublesome to register tweets in Botbird one by one. ・ I hate having strange URLs when tweeting images ・ I don't like using multiple web services For that reason, I decided to make my own bot. ~~ It's a hassle, but it's not good ~~

How to make a bot

The general flow is to register the API → write the code.

Register the API

For API registration, see or google here or here. .. Although it is written in English, I tried my best to write something like "I want to make a bot to make Shugaha a Cinderella Girl and do something like what I wrote in ↑". I managed to get high school level English, so I didn't have to be too prepared. I think you should do your best with google translate at worst.

I should have taken a screenshot for now ...

Make a bot

I handle Java a lot at work, so I decided to create it using Twitter4J, which can handle the Twitter API from Java.

無題.png

The usage is written on the top page, and all the simple operations are written in Code sample, so please have a look there. It's a library that has been around for 310 years, so if you google it, you can get as much information as you want.

Search and RT tweets

You can get the search results of tweets with the following code.

SearchTweet.java


Twitter twitter = TwitterFactory.getSingleton();
Query query = new Query(searchWord);
query.setCount(count);
QueryResult result = null;
try {
	result = twitter.search(query);
//	System.out.println("I searched for tweets.");
} catch (TwitterException e) {
	e.printStackTrace();
	System.err.println("Failed to search for tweets.");
}

You can change the number of tweets searched with Query # setCount (int). The upper limit is 100. Normally, the upper limit is 100, but it seems that you can get up to 1500 by specifying the page. It is written in here. I didn't mention it because I thought it wasn't necessary to go back to that point and search for the support bot.

You can also RT from QueryResult with the following code. (I also do automatic likes)

RTTweet.java


Twitter twitter = TwitterFactory.getSingleton();
for (Status status : result.getTweets()) {
	long tweetId = status.getId();

//	if (!isAllowed(status)) {
//		continue;
//	}

	try {
		twitter.createFavorite(tweetId);
	} catch (TwitterException e) {
	//	e.printStackTrace();
	}

	try {
		twitter.retweetStatus(tweetId);
		System.out.println("RT the following tweets");
		System.out.println("tweetID:" + tweetId);
		System.out.println(status.getUser().getName() + ":" + status.getText());
		return true;
	} catch (TwitterException e) {
	//	e.printStackTrace();
	}

	//Wait 1 second so you don't get angry with the Twitter API
	Thread.sleep(1000);
}

It will be displayed on the console like this.

RT the following tweets
tweetID:1065539453798637568
Sushi?illustrator?:Dereste Shugaha! (Past picture)
#Dereste#Shin Sato https://t.co/EUdJBZQ0YQ

By the way, if you try to RT / like a tweet that you have already RT / liked, an exception will occur. If you turn it automatically, it will occur frequently, so I squeeze it. It seems that you can see if RT has been completed with Status # isRetweetedByMe (), but if you bring Status from the tweet search result, it does not work well. (Please tell me how to do it > <)

This was enough when I was RT for tweets with "#Sato Shin", but when I started RT for tweets with "Shugaha", the bot went out of control, so I used the following code before RT / Fabo. I put it in.

	//Play tweets that are not images
	if (status.getMediaEntities().length == 0) {
		continue;
	}

	//I also play the lip
	if (status.getInReplyToScreenName() != null) {
		continue;
	}

Serpent: Play a specific tweet

In isAllowed (Status) that was commented out in the code of RTTweet.java earlier, I use jackson to play or not play tweets.

SearchTweet#isAllowed(Status)


if (status.isRetweet()) {
	status = status.getRetweetedStatus();
}

String user = status.getUser().getScreenName();
for (JsonNode node : blackListUtil.getNGUsers()) {
	if (user.equals(node.asText())) {
		return false;
	}
}

long tweetId = status.getId();
for (JsonNode node : blackListUtil.getNGTweetId()) {
	if (tweetId == node.asLong()) {
		return false;
	}
}

String tweetText = status.getText();
for (JsonNode node : blackListUtil.getNGWord()) {
	if (tweetText.contains(node.asText())) {
		return false;
	}
}

return true;

BlackListUtil.java


	private ObjectMapper mapper;
	private JsonNode root;

	public BlackListUtil() {
		mapper = new ObjectMapper();
		try {
			root = mapper.readTree(new File("WEB-INF/blacklist.json"));
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public JsonNode getNGUsers() {
		return root.get("users");
	}

	public JsonNode getNGTweetId() {
		return root.get("tweetId");
	}

	public JsonNode getNGWord() {
		return root.get("word");
	}

NG user, NG tweet ID, NG word are set in the JSON file, NG user is himself, and NG word is "R18" or "NSFW". It's a bot for all ages, so it can't be helped. (Originally, I added NSFW tweets to the NG tweet ID, but I'm not using it now)

By the way, it is the first 3 lines of SearchTweet # isAllowed (Status), but when searching for tweets, it seems that not only the tweet of the RT source but also "another user has RT this tweet" is included in the status, so the RT source The tweet and the tweet ID and the user are different, and it may slip through. In this case, I try to get the RT original tweet.

Tweet the image

At 8:10, I am tweeting the following image.

無題2.png

You can tweet an image with the following code.

TweetSender.java


Twitter twitter = TwitterFactory.getSingleton();

StatusUpdate update = new StatusUpdate(text);
update = update.media(new File(picPath));

Status status = twitter.updateStatus(update);

The images are saved together in an appropriate folder, and the file names of the tweeted images are saved in an array in the JSON file so that the images do not overlap.

python


//Bring a list of file names of images in the directory
File dir = new File(folderPath);
File[] fileList = dir.listFiles();

//Bring the list from json and match it with unused images
String picPath = null;
out : for (File file : fileList) {
	for (JsonNode node : root.get("tweetedFile")) {
		if (node.asText().equals(file.getName())) {
			continue out;
		}
	}

	if (used) {
		
	}

	picPath = file.toString();

	//Write to json
	ObjectNode objectNode = root.deepCopy();
	ArrayNode arrayNode = root.withArray("tweetedFile");
	arrayNode.add(file.getName());
	objectNode.set("tweetedFile", arrayNode);

	ObjectWriter writer = mapper.writer();
	writer.writeValue(Paths.get("WEB-INF/picUtil.json").toFile(), objectNode);
//	System.out.println("picUtil.json output OK!");
	}

	break;
}

return picPath;

Operation

All you have to do is make the above automatic RT / automatic tweet at a specific time. For example, in the case of Shuga Heart Support bot, it automatically tweets at 8:10, then automatically RTs every 30 minutes after that, and stops around 25:00. (Code omitted)

in conclusion

The code may be a little poor, but even beginners of Java can make bots while looking at samples and googled, so other idol Ps should definitely make bots and liven up the neighborhood of the idol in charge. Please try. If possible, please vote for ** Shin Sato for the Cinderella Girl general election and Sanan Miyoshi, who is in charge of technology for the voice general election. ** **

image.png

Recommended Posts

A memorandum of making a bot that automatically RTs and automatically tweets on Twitter 4J
[Ruby on Rails] A memorandum of layout templates
[Rails] Volume that displays favorites and a list of favorites