Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
revmischa committed Apr 19, 2022
1 parent d7b7f9e commit c857f5b
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 39 deletions.
11 changes: 8 additions & 3 deletions layer/Dockerfile
@@ -1,7 +1,12 @@
FROM node:14-bullseye-slim
RUN apt update
RUN apt install -y tcl-dev python3
FROM amazon/aws-lambda-nodejs:14
RUN yum install -y tcl-devel python3 gcc gcc-c++ make
RUN npm install npm@latest -g

WORKDIR /asset/nodejs/node_modules
RUN HOME=/tmp npm install --no-save tcl

RUN mkdir /asset/lib
RUN cp /usr/lib64/libtcl8.5.so /asset/lib/
WORKDIR /asset/lib
RUN ln -s libtcl8.5.so libtcl.so
RUN cp -rp /usr/share/tcl8.5 ./
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -2,7 +2,7 @@
"name": "buttesbot",
"version": "0.1.0",
"private": true,
"type": "module",
"type": "commonjs",
"scripts": {
"test": "sst test",
"start": "AWS_PROFILE=mish sst start",
Expand Down
71 changes: 41 additions & 30 deletions src/http.ts
@@ -1,15 +1,14 @@
import { APIGatewayProxyHandlerV2 } from "aws-lambda";
import { Interp } from "./interp";
import { GenericMessageEvent } from "@slack/bolt";
import { WebClient } from "@slack/web-api";
import { APIGatewayProxyHandlerV2 } from "aws-lambda";
import memoizee from "memoizee";
import { getInterp } from "./interp";
import { getSecrets } from "./secret";
import { GenericMessageEvent, MessageEvent } from "@slack/bolt";

const interp = new Interp();
await interp.loadState();

const secrets = await getSecrets();
const slackWeb = new WebClient(secrets.SLACK_KEY);
console.log("KEY", secrets.SLACK_KEY);
const getSlackWeb = memoizee(async () => {
const secrets = await getSecrets();
return new WebClient(secrets.SLACK_KEY);
});

export const eventHandler: APIGatewayProxyHandlerV2 = async (event) => {
const { body } = event;
Expand All @@ -35,29 +34,40 @@ export const eventHandler: APIGatewayProxyHandlerV2 = async (event) => {
};

const handleMessage = async (event: GenericMessageEvent) => {
if (event.text?.toLocaleLowerCase().startsWith("tcl ")) {
const [_, args] = event.text.split("tcl ", 2);
const nick = event.user || "you";
const interp = await getInterp();
if (!event.text?.toLocaleLowerCase().startsWith("tcl ")) return;

// eval tcl
let res, ok;
try {
res = await interp.eval(`${args}`);
ok = true;
} catch (ex) {
res = ex;
ok = false;
}
const [_, args] = event.text.split("tcl ", 2);
const nick = event.user || "you";

await slackWeb.chat.postMessage({
attachments: [
{
pretext: "```\n" + res + "\n```",
},
],
channel: event.channel,
});
// eval tcl
let res: string, ok;
try {
res = await interp.eval(`${args}`);
ok = true;
} catch (ex) {
res = (ex as any).toString();
ok = false;
}

const escaped = res
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");

const slackWeb = await getSlackWeb();
await slackWeb.chat.postMessage({
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: "```\n" + escaped + "\n```",
},
},
],
channel: event.channel,
});
};

export const evalHandler: APIGatewayProxyHandlerV2 = async (event) => {
Expand All @@ -66,7 +76,8 @@ export const evalHandler: APIGatewayProxyHandlerV2 = async (event) => {
const { cmd } = bodyParsed;
if (!cmd) throw new Error("Missing cmd");

const res = interp.eval(cmd);
// const res = interp.eval(cmd);
const res = "n/a";
return { statusCode: 200, body: res };
};

Expand Down
7 changes: 7 additions & 0 deletions src/interp.ts
@@ -1,6 +1,13 @@
import { loadState } from "./state";
import { Tcl } from "tcl";
import got from "got";
import memoizee from "memoizee";

export const getInterp = memoizee(async () => {
const interp = new Interp();
await interp.loadState();
return interp;
});

export class Interp {
tcl;
Expand Down
6 changes: 4 additions & 2 deletions stacks/main.ts
Expand Up @@ -23,10 +23,12 @@ export default class MainStack extends sst.Stack {
runtime: "nodejs14.x",
environment: {
SECRET_ARN: secret.secretArn,
TCL_LIBRARY: "/opt/lib/tcl8.5",
},
bundle: {
format: "esm",
// format: "esm",
externalModules: ["tcl", "node-addon-api", "bindings"],
copyFiles: [{ from: "state" }],
},
timeout: 30,
permissions: [[secret, "grantRead"]],
Expand All @@ -36,7 +38,7 @@ export default class MainStack extends sst.Stack {
const api = new sst.Api(this, "Api", {
routes: {
"POST /event": "src/http.eventHandler",
"POST /eval": "src/http.evalHandler",
// "POST /eval": "src/http.evalHandler",
"GET /auth": "src/http.authHandler",
"GET /oauth/complete": "src/http.authCompleteHandler",
},
Expand Down
4 changes: 2 additions & 2 deletions stacks/resources/layer.ts
Expand Up @@ -7,8 +7,8 @@ export class TclLayer extends LayerVersion {
id: string,
props: Partial<LayerVersionProps> = {}
) {
// const code = Code.fromDockerBuild("layer");
const code = Code.fromAsset("layer/tcl.zip");
const code = Code.fromDockerBuild("layer");
// const code = Code.fromAsset("layer/tcl.zip");

super(scope, id, {
...props,
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Expand Up @@ -2,7 +2,7 @@
"include": ["stacks", "src"],
"compilerOptions": {
"target": "ES2017",
"module": "esnext",
"module": "ES2020",
"moduleResolution": "node",
"lib": ["es2020"],
"strict": true,
Expand Down

0 comments on commit c857f5b

Please sign in to comment.