This is the 14th article of Nostr (1) Advent Calendar 2023
Japanese ver is here
I made a GPT-4 Shinjiro Koizumi bot on Nostr and X(Twitter).
Links↓
Introduction
Who's Shinjiro?
Do you know Shinjiro Koizumi? He is a Japanese statesman, his father is ex-Prime Minister Junichiro Koizumi.
Mr.Shinjiro Koizumi is kinda Internet meme in Japan. Because his remarks are often so "Interesting".
Why? That is "Tautology". That means his sentence looks so meaningful but meaningless actually. We call it Shinjiro-Syntax.
These are examples. His actual remarks.
- I don't think Japan should stay the way it is now. That's why I think Japan shouldn't stay the way it is now.
- Thanks to working from home, I can carry out my official work remotely.
- To the point that I don't seem to be remorseful, I remose it. it's my own problem.
- I heard you were born on your birthday.(This's ogiri)
What's Nostr?
Nostr is a protol, that's used for next generation distributed SNS. I don't explain about Nostr this time, but I highly recommend it because it's "the Free1 and Secure"!
Please check out here↓
Coding
Pioneers have already lectured details how to write codes for Nostr Protocol on these pages or books, so I just intoduce the ingenuity and stuck points
1. Connection to multiple relays
Now, it seems to be easy to use SimplePool() of nostr-tools to post to multiple relays, but I somehow couldn't work at that time. so I use a simple for statement.
// Post
if (message != null){
for (const relayURL of relayURLs) {
try {
await postToRelays(relayURL, metadata);
} catch (e) {
console.log(e);
continue;
}
}
}
I added the "Like" function, but lots of Shinjiro
When I posted, "Shinjiro" is occasionally mentioned in the timeline. Each time, I used to manually like the post, but it's annoying, so I automated it. (Probably if Shinjiro liked their posts, Everyone would be happy)
This time, I've decided to like all posts if it contains the word "Koizumi" or "Shinjiro".
I retrieved the all posts from the relays, and filtered them with includes(), and send a Like event (kind7).
When I finally run it, somehow, a lots of of Shinjiro appeared in the Like filed, causing the timeline to buzz.
- Proliferated Shinjiro
That's why sending events to multiple relays, but it is a mystery because it only generates just one event so it is unique...(so the number of likes is normal).
And then I send like event once an hour, so I tried to reduce duplicates as much as possible by retrieving only posts within an hour.
const likePosts = async (relayUrl, targetWords) => {
const relay = relayInit(relayUrl);
relay.on("error", () => {
console.error("failed to connect");
});
await relay.connect();
const sub = relay.sub([{ kinds: [1] }]);
let num = 0;
sub.on("event", (ev) => {
try {
const currentTime = currUnixtime(); // Now UNIX TIME
const oneHourAgo = currentTime - 3600; // UNIX TIME 1 hour ago
// Like only posts which includes target words and within an hour
if ((ev.created_at > oneHourAgo) && (ev.content.includes(targetWords[0]) || ev.content.includes(targetWords[1]))) {
const reaction = composeReaction(ev);
publishToRelay(relay, reaction);
num++;
}
} catch (err) {
console.error(err);
}
});
return num;
};
2. Can't I use OpenAI's API?
When I tried to use the JavaScript OpenAI library, I got an error message and had trouble. It seems that the usage has changed with the newer version. I introduced it in another article.
3. Botting with GitHub Actions
As it is, I am running the script manually, so it is not a bot. I wanted to run it automatically, so at first I rented a free server (GoogleComputeEngine) and tried to run it all the time, but the SSH connection was very unstable.
I thought, "If I just wanna run it periodically (once an hour), Why not use GitHub Actions? I decided to do so.
I found out that Actions can also use cron-like code.
This time, I just need to make a node environment and run main.js, so I asked ChatGPT to write a workflow configuration file.
like this (uncomment out as needed)
name: automate
on:
# schedule:
# - cron: '0 * * * *'
# push:
# branches: [ '**' ]
permissions:
contents: read
issues: read
checks: write
pull-requests: write
jobs:
post_and_like:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: ./package-lock.json
- name: Install Dependencies
run: npm install
- name: Post and Like
run: node ./main.js
timeout-minutes: 1
Now, every hour around 0:00 (the schedule of Actions isn't precise), Shinjiro will post and like!
Also, the scheduled execution of Actions will be automatically stopped if there is no changes in the repository for 60 days, so I also made workflow for automatic commit once a day.
name: auto-commit
on:
workflow_dispatch:
# schedule:
# - cron: "0 15 * * *" # Carry out every 24:00 in Japan
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set current datetime as env variable
env:
TZ: 'Asia/Tokyo'
run: echo "CURRENT_DATETIME=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV
- name: Commit
run: |
git config --global user.email ${{ secrets.USER_EMAIL }}
git config --global user.name ${{ secrets.USER_NAME }}
echo -e ${{ env.CURRENT_DATETIME }} >> commit_log.txt
git add commit_log.txt
git commit -m "[add] 自動コミット:${{ env.CURRENT_DATETIME }}"
git push origin main
Result
I got a crazy buzz on X(Twitter).
I immediately started running it on Nostr, and it became a hot topic there.
I was ranked No. 1 several times in Nostr's Buzz Word ranking, which satisfied my need for approval.
Then one day, Mr.mattn introduced me on X, and I got a lot of buzz (1.2 million impressions ❗️).
I heard that it was also flowing to X of my friend...
I have no choice but to get on this big wave!
So, I rapidly got the API of X, and started on X as well. (The number of followers has not grown much since then...)
- Shinjiro Bot on X
But... Shinjiro is definitey popular!2 Thanks, Shinjiro!!
Top comments (0)