First commit

This commit is contained in:
Juni 2024-12-11 13:13:07 -06:00
commit 8725f3e022
11 changed files with 339 additions and 0 deletions

10
.env.example Normal file
View 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=

View 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
View File

@ -0,0 +1,5 @@
.env
.idea
node_modules
sessionData
data

35
Dockerfile Normal file
View 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
View 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
View File

@ -0,0 +1,3 @@
# user-tracker
Tracks and reports on a users actions

BIN
bun.lockb Executable file

Binary file not shown.

31
docker-compose.yml Normal file
View 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
View 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
View 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
View 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!')
});