Skip to content

Commit

Permalink
feat: move send tweet from web to server (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
pradel authored Oct 26, 2024
1 parent 23fe29c commit a86d700
Show file tree
Hide file tree
Showing 20 changed files with 522 additions and 546 deletions.
6 changes: 6 additions & 0 deletions .changeset/curly-bananas-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@stackspulse/server": patch
"stackspulse": patch
---

Move send weekly tweet from web to server.
5 changes: 5 additions & 0 deletions .changeset/warm-crabs-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stackspulse": patch
---

Alex update contracts list.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: cron-weekly
on:
workflow_dispatch:
schedule:
- cron: '0 16 * * 0'
- cron: "0 16 * * 0"

jobs:
cron:
Expand All @@ -12,5 +12,5 @@ jobs:
- name: weekly-cron-job
run: |
curl --request GET \
--url 'https://www.stackspulse.com/api/cron/weekly-users' \
--header 'Authorization: Bearer ${{ secrets.CRON_API_TOKEN }}'
--url 'https://api.stackspulse.com/api/root/tweet-weekly-users' \
--header 'Authorization: Bearer ${{ secrets.ADMIN_API_TOKEN }}'
6 changes: 6 additions & 0 deletions apps/server/.env.development
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
NODE_ENV=development
TURSO_DATABASE_URL=file:sqlite.db
API_URL=http://localhost:3001
WEB_URL=http://localhost:3000
TWITTER_API_KEY=dev
TWITTER_API_SECRET_KEY=dev
TWITTER_ACCESS_TOKEN=dev
TWITTER_ACCESS_TOKEN_SECRET=dev
6 changes: 6 additions & 0 deletions apps/server/.env.production.local
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ TURSO_DATABASE_URL="encrypted:BFROeaR/Lo5esJOuxqWc7/NdVpxdz8EykAovi9W08PANkfxIsx
TURSO_AUTH_TOKEN="encrypted:BI9tCPv11ZM3cBZHGXMctKpHDo+cpW6Sq7c3YYoXxNag8PpVSiGGQQMWLtYZqy4OrFauYJtSp+ehyoYuW+ZburNKZs18aaZnOaBzkwZfQG00jvOhfS7k6XhMDOj46Is/zSRS88pbI+YBLxhLQH/Sz7bwn7PGIp72H06C4m/qEyPMpKoRUS9hP1YV86FPZqasGPPEEvp03YhI6WKOvUTYcSmnZbPw9G3aIVN7DIXYdlqWeQWUh+JKQ60G7riPhBLaTPaw1y3qvPH4PVCV6IeoZ4TScd1XX9t3++xRZgAc1iT2Vj91t9lvBtzPr1PyBlduYyYebArBZiP43Fdov6FnRw0OCW29ZS/2Mrw97aTgHjrrVaoaCHk+lYbRCmzOzaAZlCupMOn0gznms3nEfZfyZRyIp2ezjGhhNWe73g=="
SENTRY_DSN="encrypted:BCys3N+cVEYBJIUIVpV/cu+VZkbhdVgDxSFv5SIs7bTfaaDp7kaVVAzTuLlwIXamSltCfzOIwJ3Z7o19ls2f2eR8wX2G/32g1+Z+KnNTaBHexT2eHbrbQ7Hv9zD6rOOFZh4W91xo/wb21IvfEn55QwhZ8N4AFB9qGoAy70ej6WJdKYric9LVwhYbf4LU76MwFvK+8+TyjOt7mPDr8Fz8PyLsJrIuOZtvje5zYg/OPOfeqeKMnw=="
COINGECKO_API_KEY="encrypted:BOnTS+pjMioUn3cROrIDZ4glP+q9hfIBP082qZIePiKQgraXHYnZXPgLq4hb2qqrDrJc55SRQTu/NFWdVf+pqstUz1vDkjKbogIvwbZUsP4ltsn+De2STeERbpYvyu5yAJY+uajL97P4ceqgpeaqaFAMPqZdWUCrKf6tnQ=="
TWITTER_API_KEY='encrypted:BDuPPHsY2t0Iwz8NU0GaEX0XIavKWTgxcIBS3OesNTxq0IZQvaho/xyaC254aP1p5rvAjVu+hMo0CXkBZ4MYPerGNLXLauMc3xLH/pPb8k2YBfhtHJG7dYqrYruPRSd+r8lZQWs2enOpTBMPxI1ZVyoRISf+fUiWCoU='
TWITTER_API_SECRET_KEY='encrypted:BENpYhuuGHh9avXmY07aL3MzNG3BodQ9+XXbX4SO7/4+oYvmZSr39zxpzwukoy0sK3F3C6TxLhwSdXu0N8YIWpUC8gyfM6DMWzIRUqxNpEh3j2qQ4XWjjEEM46OYIGmKzdrTuPLQzhdeHHOKH0n0QDZz1ijsjv9CyDYjaQGmLskznKosE1tg6R+NjovafowiKvuB'
TWITTER_ACCESS_TOKEN='encrypted:BBshckik+4WDwgGm0afxUfKmiMEvI0TJnRTspxThWGQ28dllY5Z/DUS4ysNNDZ6QooA1Wo1vd26GK2Nn6Q6UZI6pWAU0VFWSMs4gI6ICQ1VoSiKEmVAXO5YqHvNOH2ydLm52L9BMccmNzWNwgB56+/I0TS96p02uE0pgBXF/CcltbHJAc5Kp8A7masUqyFgFm4Sx'
TWITTER_ACCESS_TOKEN_SECRET='encrypted:BN6y7hPFXcQg5wEh+K8Y44WdguzZt+abup9ggcNhiDs0WEytVj14HX89feKgeVR6cWFcapqnQUK62nrm2NcJC1WXwEQz3VWOJ7DWh+s+zLX6HqosnwenarXmUa4HfJJrnVL+w42dgVOIMJUwuZpepKZ3y1hRWH50Asc23eNMeiA03l25oqwCMQVdcnk96g=='
WEB_URL='encrypted:BCHOibIFAUKX/7qMHq7xixxTUI7CPNsscEWrgcZoeKAAp+1PYn7lnC3+M14kzxjLkxJwyDRIWlkRmcEY5N0jpzmgDSeoN3G+zNxiWypDhN+SPhJF15wSQBOy/FBjiY/TUe3DVgFMjcjeWdysLCK1Svs63+PSaT5geUeEsQ=='
API_URL='encrypted:BNVImUfMBYgleGhm/LLKKv4ii0m7SleAPEq25LjY0Jhp4CJn4cZtyB6pHxHKMhrTJqyxrTHS6XZE8uzhybA10TYr5JZ5lQJ3BxWF+6PvIrEsT8iFr4CI2YDv7p2ZdyEYXoLFNPOfXovggDO+5sKI/Frwyi5FYcWfGURYpw=='
3 changes: 2 additions & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"deploy": "fly deploy --remote-only"
},
"dependencies": {
"@dotenvx/dotenvx": "1.20.1",
"@dotenvx/dotenvx": "1.21.0",
"@libsql/client": "0.8.0",
"@sentry/node": "8.35.0",
"@stacks/blockchain-api-client": "8.1.2",
Expand All @@ -21,6 +21,7 @@
"h3": "1.13.0",
"nitro-cors": "0.7.1",
"postgres": "3.4.4",
"twitter-api-v2": "1.17.1",
"unstorage": "1.12.0",
"zod": "3.23.8",
"zod-validation-error": "3.4.0"
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/api/protocols/users/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const protocolUsersRouteSchema = z.object({
limit: z.coerce.number().min(1).max(100).optional(),
});

type ProtocolUsersRouteResponse = {
export type ProtocolUsersRouteResponse = {
protocol_name: Protocol;
unique_senders: number;
}[];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { env } from "@/env";
import type { ProtocolUsersRouteResponse } from "@/lib/api";
import { sendTweet } from "@/lib/twitter";
import { protocolsInfo } from "@stackspulse/protocols";

export const dynamic = "force-dynamic";
import type { ProtocolUsersRouteResponse } from "~/api/protocols/users";
import { env } from "~/env";
import { sendTweet } from "~/lib/twitter";

/**
* Send a tweet with the top 5 protocols by unique users in the last 7 days
*/
export async function GET() {
export default defineEventHandler(async () => {
const apiParams = new URLSearchParams();
apiParams.append("noCache", "true");
apiParams.append("date", "7d");
apiParams.append("limit", "5");

const stats: ProtocolUsersRouteResponse = await fetch(
`${env.NEXT_PUBLIC_API_URL}/api/protocols/users?${apiParams.toString()}`,
`${env.API_URL}/api/protocols/users?${apiParams.toString()}`,
).then((res) => res.json());

const data = stats.map((stat) => ({
Expand All @@ -28,7 +26,7 @@ export async function GET() {
params.append("data", JSON.stringify(data));

const imageUrl = `${
env.NEXT_PUBLIC_BASE_URL
env.WEB_URL
}/api/images/weekly-users?${params.toString()}`;

let message = "📈 Last 7 days unique users:\n\n";
Expand All @@ -41,5 +39,5 @@ export async function GET() {

const tweetId = await sendTweet({ message, images: [imageUrl] });

return Response.json({ ok: true, tweetId });
}
return { ok: true, tweetId };
});
6 changes: 6 additions & 0 deletions apps/server/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ import { z } from "zod";
export const env = createEnv({
server: {
NODE_ENV: z.enum(["development", "production", "test"]),
API_URL: z.string().url(),
WEB_URL: z.string().url(),
DATABASE_URL: z.string().url(),
ADMIN_API_TOKEN: z.string(),
TURSO_DATABASE_URL: z.string().url(),
TURSO_AUTH_TOKEN: z.string().optional(),
SENTRY_DSN: z.string().url().optional(),
COINGECKO_API_KEY: z.string(),
TWITTER_API_KEY: z.string().min(1),
TWITTER_API_SECRET_KEY: z.string().min(1),
TWITTER_ACCESS_TOKEN: z.string().min(1),
TWITTER_ACCESS_TOKEN_SECRET: z.string().min(1),
},

runtimeEnv: process.env,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { env } from "@/env";
import { EUploadMimeType, TwitterApi } from "twitter-api-v2";
import { env } from "~/env";

const twitterClient = new TwitterApi({
appKey: env.TWITTER_API_KEY,
Expand Down
5 changes: 0 additions & 5 deletions apps/web/.env.development
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
NEXT_TELEMETRY_DISABLED=1
CRON_API_TOKEN=dev-api-token
TWITTER_API_KEY=dev
TWITTER_API_SECRET_KEY=dev
TWITTER_ACCESS_TOKEN=dev
TWITTER_ACCESS_TOKEN_SECRET=dev

# Client environment variables
NEXT_PUBLIC_BASE_URL=http://localhost:3000
Expand Down
5 changes: 0 additions & 5 deletions apps/web/.env.production.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
# file used by the CI to build the app
NEXT_TELEMETRY_DISABLED=1
CRON_API_TOKEN=dev-api-token
TWITTER_API_KEY=dev
TWITTER_API_SECRET_KEY=dev
TWITTER_ACCESS_TOKEN=dev
TWITTER_ACCESS_TOKEN_SECRET=dev
5 changes: 0 additions & 5 deletions apps/web/.env.production.local
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,3 @@
DOTENV_PUBLIC_KEY_PRODUCTION_LOCAL="020b21e579eb9b260c6f4df063b2debf2769d1ca3433ae8ba534dd46bd1cbb7470"

# .env.production.local
CRON_API_TOKEN="encrypted:BPR4r3e5tPVrSvS+8hS2/WdxnDQMwlUbDubVhBeYfvKgRFUN0m5NnENYZBAQXUL76vAmDio86ImtmrGVW//Xl86xWzq6d5RVV2L01Uk88isTyxAxR1/AdJqG81pw7a3f48j6LYuMOVhlSWXqUjEBWbsyTT/BP5v5ZNUBssx+lgd4LbhvsU6PNJrN1QY="
TWITTER_API_KEY="encrypted:BEVE1WbHYhzlbCfIep1pX1eE1NqmNdUnnZEwZpGbNm8PZM+BDyX99kYc0PedyUCOathH6rHoFhhGJBPFu2C+5quU0Q/Wr7FO30DFLhs2VPlEbCQ62n1A7BZ3II9218+YAXeYXWghwW3GjssP52tLmAic2nyH1HPOqbU="
TWITTER_API_SECRET_KEY="encrypted:BAzGfOVwJzzw65UWTcZFqjsD/aOHjW5LGzylH/otgThO3IppV4mXhoSeAPc1ClyUZF/nUfVUppPndhfA7i21pDaiqe8xzdH6q6VxBHhZESIfrrP845bc9m67xDgp2JP2QdVtJ7gCm4chUOXivqQW2wRFsyXYLwKwEUCloX6LUajoKwtBDQjNLBj85Dlxr6Cc2yil"
TWITTER_ACCESS_TOKEN="encrypted:BDcWkceU7SmTmwi/mE5WuJnSnFd+5D9hDfEcmKegJWykUAiw3VOjXJ5kCviCVP0UZtHWDpTMjVdGFWJyofI9zACAFjMNqnl+iI8mrnKk2gTBLsV7Kc+SwDChTqvaUeLGBYv9344dhZxpP4Cp8QUgU3t8yIcBTNy+gA6CeNNRDgcrdTtAhLYHjPG/48VYbcbfngeU"
TWITTER_ACCESS_TOKEN_SECRET="encrypted:BELL8fcZpyJjCDqVSqKJjfP8HeyOiRqwhw1mZ7i7vf4RcMtEEM8/oFw7VKZ0stycaedqk2F2WABsCgPWmCTUU055FINa5GWNGivYI/t4vcxS1SXt1KT9QXQLZaBez01niQbgj8IkfBya0Yu+GFQC1godwcOwoMkPN9tQ9Z40/H/xiRmbrzXEDIrs3j+RJQ=="
2 changes: 1 addition & 1 deletion apps/web/fly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ hard_limit = 700

[[vm]]
size = 'shared-cpu-1x'
memory = '512mb'
memory = '256mb'
11 changes: 5 additions & 6 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"deploy": "fly deploy --remote-only"
},
"dependencies": {
"@dotenvx/dotenvx": "1.20.1",
"@dotenvx/dotenvx": "1.21.0",
"@hirosystems/token-metadata-api-client": "2.0.0",
"@radix-ui/themes": "3.0.5",
"@sentry/nextjs": "8.35.0",
Expand All @@ -19,8 +19,8 @@
"@stackspulse/protocols": "workspace:*",
"@t3-oss/env-core": "0.11.1",
"@t3-oss/env-nextjs": "0.11.1",
"@tabler/icons-react": "3.19.0",
"@tanstack/react-query": "5.59.15",
"@tabler/icons-react": "3.20.0",
"@tanstack/react-query": "5.59.16",
"class-variance-authority": "0.7.0",
"clsx": "2.1.1",
"date-fns": "4.1.0",
Expand All @@ -33,13 +33,12 @@
"sharp": "0.33.5",
"tailwind-merge": "2.5.4",
"tailwindcss-animate": "1.0.7",
"twitter-api-v2": "1.17.1",
"unstorage": "1.12.0",
"zod": "3.23.8"
},
"devDependencies": {
"@types/node": "22.8.0",
"@types/react": "18.3.11",
"@types/node": "22.8.1",
"@types/react": "18.3.12",
"@types/react-dom": "18.3.1",
"autoprefixer": "10.4.20",
"eslint": "8.57.0",
Expand Down
8 changes: 1 addition & 7 deletions apps/web/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
server: {
CRON_API_TOKEN: z.string().min(1),
TWITTER_API_KEY: z.string().min(1),
TWITTER_API_SECRET_KEY: z.string().min(1),
TWITTER_ACCESS_TOKEN: z.string().min(1),
TWITTER_ACCESS_TOKEN_SECRET: z.string().min(1),
},
server: {},
client: {
NEXT_PUBLIC_BASE_URL: z.string().url(),
NEXT_PUBLIC_API_URL: z.string().url(),
Expand Down
36 changes: 0 additions & 36 deletions apps/web/src/middleware.ts

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@biomejs/biome": "1.9.4",
"@changesets/cli": "2.27.9",
"lint-staged": "15.2.10",
"turbo": "2.1.3"
"turbo": "2.2.3"
},
"lint-staged": {
"*": [
Expand Down
1 change: 1 addition & 0 deletions packages/protocols/src/protocols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const protocolsInfo: {
x: "https://twitter.com/ALEXLabBTC",
contracts: [
"SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01",
"SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-vault-v2-01",
"SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.amm-swap-pool-v1-1",
"SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.swap-helper-v1-01",
"SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.swap-helper-v1-02",
Expand Down
Loading

0 comments on commit a86d700

Please sign in to comment.