mirror of
https://github.com/bradganley/bsky-user-activity-bot.git
synced 2024-12-23 10:47:08 +00:00
First commit
This commit is contained in:
commit
8725f3e022
10
.env.example
Normal file
10
.env.example
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
TRACKER_BSKY_HANDLE=
|
||||||
|
TRACKER_BSKY_PASSWORD=
|
||||||
|
DEBUG_LOG_ACTIVE=true
|
||||||
|
DEBUG_LOG_LEVEL=info
|
||||||
|
|
||||||
|
JETSTREAM_URL='ws://jetstream:6008/subscribe'
|
||||||
|
|
||||||
|
SESSION_DATA_PATH='/sessionData'
|
||||||
|
|
||||||
|
USER_DID=
|
68
.github/workflows/buildandpublishtoghcr.yml
vendored
Normal file
68
.github/workflows/buildandpublishtoghcr.yml
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#
|
||||||
|
name: Create and publish the bot container
|
||||||
|
|
||||||
|
# Configures this workflow to run every time a change is pushed to the branch called `release`.
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ['main']
|
||||||
|
|
||||||
|
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
|
||||||
|
jobs:
|
||||||
|
build-and-push-image:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
#
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
|
||||||
|
- name: Log in to the Container registry
|
||||||
|
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GHCR_PAT }}
|
||||||
|
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
|
||||||
|
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
|
||||||
|
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
|
||||||
|
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
|
||||||
|
- name: Build and push Docker image
|
||||||
|
id: push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64, linux/arm64
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
|
||||||
|
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
|
||||||
|
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
|
||||||
|
# - name: Build and push Docker image
|
||||||
|
# uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
|
||||||
|
# with:
|
||||||
|
# context: .
|
||||||
|
# push: true
|
||||||
|
# tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
# labels: ${{ steps.meta.outputs.labels }}
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.env
|
||||||
|
.idea
|
||||||
|
node_modules
|
||||||
|
sessionData
|
||||||
|
data
|
35
Dockerfile
Normal file
35
Dockerfile
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
FROM oven/bun:latest as base
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
# install dependencies into temp directory
|
||||||
|
# this will cache them and speed up future builds
|
||||||
|
FROM base AS install
|
||||||
|
RUN mkdir -p /temp/dev
|
||||||
|
COPY package.json bun.lockb /temp/dev/
|
||||||
|
RUN cd /temp/dev && bun install --frozen-lockfile
|
||||||
|
|
||||||
|
# install with --production (exclude devDependencies)
|
||||||
|
RUN mkdir -p /temp/prod
|
||||||
|
COPY package.json bun.lockb /temp/prod/
|
||||||
|
RUN cd /temp/prod && bun install --frozen-lockfile --production
|
||||||
|
|
||||||
|
# copy node_modules from temp directory
|
||||||
|
# then copy all (non-ignored) project files into the image
|
||||||
|
FROM install AS prerelease
|
||||||
|
COPY --from=install /temp/dev/node_modules node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# [optional] tests & build
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
RUN bun test
|
||||||
|
RUN bun run build
|
||||||
|
|
||||||
|
# copy production dependencies and source code into final image
|
||||||
|
FROM base AS release
|
||||||
|
COPY --from=install /temp/prod/node_modules node_modules
|
||||||
|
COPY --from=prerelease /usr/src/app/build/index.ts .
|
||||||
|
COPY --from=prerelease /usr/src/app/package.json .
|
||||||
|
|
||||||
|
# run the app
|
||||||
|
USER bun
|
||||||
|
ENTRYPOINT [ "bun", "run", "index.ts" ]
|
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2024 Juni <june@juniper-bender.tech>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||||
|
OR OTHER DEALINGS IN THE SOFTWARE.
|
3
README.md
Normal file
3
README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# user-tracker
|
||||||
|
|
||||||
|
Tracks and reports on a users actions
|
31
docker-compose.yml
Normal file
31
docker-compose.yml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
bskybot:
|
||||||
|
depends_on:
|
||||||
|
- jetstream
|
||||||
|
build: .
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./sessionData:/sessionData
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
networks:
|
||||||
|
- bun
|
||||||
|
|
||||||
|
|
||||||
|
jetstream:
|
||||||
|
image: "ghcr.io/juni-b-queer/jetstream-new:personal-branch"
|
||||||
|
container_name: jetstream
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- CURSOR_FILE=/data/cursor.json
|
||||||
|
ports:
|
||||||
|
- "6008:6008"
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
|
networks:
|
||||||
|
- bun
|
||||||
|
|
||||||
|
networks:
|
||||||
|
bun:
|
||||||
|
driver: bridge
|
23
makefile
Normal file
23
makefile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
.PHONY: *
|
||||||
|
|
||||||
|
dev:
|
||||||
|
bun run src/index.ts
|
||||||
|
|
||||||
|
build:
|
||||||
|
docker compose build
|
||||||
|
|
||||||
|
up:
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
down:
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
logs:
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
|
install:
|
||||||
|
bun install
|
||||||
|
|
||||||
|
|
||||||
|
link:
|
||||||
|
bun link bsky-event-handlers
|
22
package.json
Normal file
22
package.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "user-tracker",
|
||||||
|
"description": "Tracks and reports on a users actions",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"author": "Juni",
|
||||||
|
"module": "src/index.ts",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "bun build --target=bun ./src/index.ts --outfile=./build/index.ts"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"bun-types": "latest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bsky-event-handlers": "2.1.0-beta.1",
|
||||||
|
"@atproto/api": "^0.13.19"
|
||||||
|
},
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
123
src/index.ts
Normal file
123
src/index.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import {
|
||||||
|
BadBotHandler,
|
||||||
|
CreateSkeetHandler,
|
||||||
|
DebugLog,
|
||||||
|
GoodBotHandler,
|
||||||
|
HandlerAgent,
|
||||||
|
InputEqualsValidator,
|
||||||
|
JetstreamSubscription,
|
||||||
|
LogMessageAction,
|
||||||
|
ReplyingToBotValidator,
|
||||||
|
MessageHandler,
|
||||||
|
IntervalSubscription,
|
||||||
|
IntervalSubscriptionHandlers,
|
||||||
|
AbstractHandler,
|
||||||
|
IsSpecifiedTimeValidator,
|
||||||
|
CreateSkeetAction,
|
||||||
|
ActionTakenByUserValidator,
|
||||||
|
LogInputTextAction,
|
||||||
|
JetstreamEventCommit,
|
||||||
|
JetstreamSubject,
|
||||||
|
JetstreamRecord, TestValidator
|
||||||
|
} from 'bsky-event-handlers';
|
||||||
|
|
||||||
|
const testAgent = new HandlerAgent(
|
||||||
|
'test-bot',
|
||||||
|
<string>Bun.env.TRACKER_BSKY_HANDLE,
|
||||||
|
<string>Bun.env.TRACKER_BSKY_PASSWORD
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetstream Subscription setup
|
||||||
|
*/
|
||||||
|
let jetstreamSubscription: JetstreamSubscription;
|
||||||
|
|
||||||
|
|
||||||
|
let handlers = {
|
||||||
|
post: {
|
||||||
|
c: [
|
||||||
|
new MessageHandler(
|
||||||
|
// @ts-ignore
|
||||||
|
[ActionTakenByUserValidator.make(<string>Bun.env.USER_DID)],
|
||||||
|
[
|
||||||
|
CreateSkeetAction.make("Aaron posted:", undefined, (handler: HandlerAgent, commit: JetstreamEventCommit): JetstreamSubject =>{
|
||||||
|
return {
|
||||||
|
cid: MessageHandler.getCidFromMessage(handler, commit),
|
||||||
|
uri: MessageHandler.getUriFromMessage(handler, commit)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
LogInputTextAction.make("Post")
|
||||||
|
],
|
||||||
|
testAgent
|
||||||
|
),
|
||||||
|
GoodBotHandler.make(testAgent)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
c: [
|
||||||
|
new MessageHandler(
|
||||||
|
// @ts-ignore
|
||||||
|
[ActionTakenByUserValidator.make(<string>Bun.env.USER_DID)],
|
||||||
|
[
|
||||||
|
CreateSkeetAction.make("Aaron liked:", undefined, (handler: HandlerAgent, commit: JetstreamEventCommit): JetstreamSubject =>{
|
||||||
|
return commit.commit.record.subject as JetstreamSubject;
|
||||||
|
}),
|
||||||
|
LogInputTextAction.make("Like")
|
||||||
|
],
|
||||||
|
testAgent
|
||||||
|
)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
c: [
|
||||||
|
new MessageHandler(
|
||||||
|
// @ts-ignore
|
||||||
|
[ActionTakenByUserValidator.make(<string>Bun.env.USER_DID)],
|
||||||
|
[
|
||||||
|
CreateSkeetAction.make("Aaron reposted:", undefined, (handler: HandlerAgent, commit: JetstreamEventCommit): JetstreamSubject =>{
|
||||||
|
return commit.commit.record.subject as JetstreamSubject;
|
||||||
|
}),
|
||||||
|
LogInputTextAction.make("Repost")
|
||||||
|
],
|
||||||
|
testAgent
|
||||||
|
)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
block: {
|
||||||
|
c: [
|
||||||
|
new MessageHandler(
|
||||||
|
// @ts-ignore
|
||||||
|
[
|
||||||
|
ActionTakenByUserValidator.make(<string>Bun.env.USER_DID)
|
||||||
|
],
|
||||||
|
[
|
||||||
|
CreateSkeetAction.make((handler: HandlerAgent, event: JetstreamEventCommit): string => {
|
||||||
|
const blockedDid = event.commit.record.subject
|
||||||
|
return "Aaron blocked a user: " + blockedDid;
|
||||||
|
}, undefined, undefined),
|
||||||
|
LogInputTextAction.make("Block"),
|
||||||
|
],
|
||||||
|
testAgent
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function initialize() {
|
||||||
|
await testAgent.authenticate()
|
||||||
|
jetstreamSubscription = new JetstreamSubscription(
|
||||||
|
handlers,
|
||||||
|
<string>Bun.env.JETSTREAM_URL
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize().then(() =>{
|
||||||
|
jetstreamSubscription.createSubscription()
|
||||||
|
DebugLog.info("INIT", 'Initialized!')
|
||||||
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user