Skip to content

Commit

Permalink
feat(openai-enhancements): improved user experience when interacting …
Browse files Browse the repository at this point in the history
…with openai
  • Loading branch information
boltdynamics committed Jul 26, 2023
1 parent 62b377b commit e75912e
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 90 deletions.
23 changes: 15 additions & 8 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ tasks:
cmds:
- npm update && npm upgrade

run-cloudfunctions-framework:
run-xplorers-bot:
desc: Run cloud functions framework locally to test the application
cmds:
- npm run start-local-server
- npm run start-xplorersbot-server

run-openai:
desc: Run cloud functions framework locally to test the application
cmds:
- npm run start-openai-server

test:
desc: Run unit tests using jest
Expand Down Expand Up @@ -53,16 +58,18 @@ tasks:
- cp -R node_modules out/* package*.json dist

create-slack-token-secret:
desc: Create a secret in GCP Secret Manager
desc: Create required secrets in GCP Secret Manager
summary: |
Create a secret in GCP Secret Manager to store the slack to store slack token.
Create secrets in GCP Secret Manager to store the slack token, azure openai endpoint and key
Don't forget to set SLACK_OAUTH_TOKEN, AZURE_OPENAI_ENDPOINT and AZURE_OPENAI_KEY env vars
before running this command.
Don't forget to set SLACK_OAUTH_TOKEN env var before running this command.
If you only want to test the slack feature, only supplying the SLACK_OAUTH_TOKEN is enough.
cmds:
- printf ${SLACK_OAUTH_TOKEN} | gcloud secrets create slack-oauth-token-${TF_WORKSPACE} --data-file=- --replication-policy=automatic
preconditions:
- sh: "[ '${SLACK_OAUTH_TOKEN}' == '<no value>' ]"
msg: Please set environment variable 'SLACK_OAUTH_TOKEN' before running this command
- printf ${AZURE_OPENAI_ENDPOINT} | gcloud secrets create azure-openai-endpoint-${TF_WORKSPACE} --data-file=- --replication-policy=automatic
- printf ${AZURE_OPENAI_KEY} | gcloud secrets create azure-openai-key-${TF_WORKSPACE} --data-file=- --replication-policy=automatic

terraform-fmt:
desc: Format terraform files
Expand Down
4 changes: 2 additions & 2 deletions docs/feature_branch_deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Terraform [workspaces](https://www.terraform.io/docs/state/workspaces.html) allo
Run the following commands to create and switch to a `dev` workspace:

```
terraform workspace new dev
terraform workspace select dev
terraform -chdir=terraform workspace new dev
terraform -chdir=terraform workspace select dev
```

### Create a slack secret in Google Secret Manager
Expand Down
104 changes: 45 additions & 59 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"scripts": {
"start": "functions-framework --target=xplorersbot",
"test": "task clean && jest --verbose --coverage tests",
"start-local-server": "task clean && tsc && cd out && npx functions-framework --target=xplorersbot --signature-type=http"
"start-xplorersbot-server": "task clean && tsc && cd out && npx functions-framework --target=xplorersbot --signature-type=http",
"start-openai-server": "task clean && tsc && cd out && npx functions-framework --target=xplorersbotOpenAI --signature-type=http"
},
"dependencies": {
"@azure/openai": "^1.0.0-beta.2",
Expand Down
22 changes: 14 additions & 8 deletions src/helpers/slack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,21 @@ export async function addReactionToSlackPost(
export async function postMessageToSlack(
slackWebClient: SlackWebClient,
text: string,
slackChannel: string
slackChannel: string,
thread_ts?: string
) {
const postMessageResponse = await slackWebClient.chat.postMessage({
text: text,
channel: slackChannel,
});
console.log(
`Successfully sent message ${postMessageResponse.ts} to slack channel ${slackChannel}`
);
if (thread_ts) {
return await slackWebClient.chat.postMessage({
text: text,
channel: slackChannel,
thread_ts: thread_ts,
});
} else {
return await slackWebClient.chat.postMessage({
text: text,
channel: slackChannel,
});
}
}

async function handleSlackJoinEvent(
Expand Down
45 changes: 33 additions & 12 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,39 @@ export const xplorersbot: HttpFunction = async (req, res) => {
writeLog(log, message, LOG_METADATA);

switch (req.body.type) {
case "url_verification":
res.status(200).send(req.body.challenge);
break;
case "event_callback":
const slackEvent = req?.body?.event;

if (slackEvent.bot_id) {
break;
}

const isChannelOpenAI =
slackEvent?.channel ===
process.env.XPLORERS_OPENAI_SLACK_CHANNEL_ID;
const messageStartsWithHeyOpenAI = slackEvent?.text
.toLowerCase()
.startsWith("hey openai");

if (isChannelOpenAI && messageStartsWithHeyOpenAI) {
await createHttpTask(req.body);
// text could be in slackEvent.text or slackEvent.message.text
const message = slackEvent?.text ?? slackEvent?.message?.text;

if (isChannelOpenAI) {
const messageStartsWithHeyOpenAI = message
.toLowerCase()
.startsWith("hey openai");

if (messageStartsWithHeyOpenAI) {
await createHttpTask(req.body);
}
break;
}

if (slackEvent?.type === "message") {
await handleSlackMessageEvent(slackWebClient, slackEvent);
break;
}

case "url_verification":
res.status(200).send(req.body.challenge);
break;
}

res.status(200).send(SUCCESS_MESSAGE);
Expand All @@ -70,22 +83,30 @@ export const xplorersbot: HttpFunction = async (req, res) => {
// openai app entry point
export const xplorersbotOpenAI: HttpFunction = async (req, res) => {
const parsedSlackEvent = JSON.parse(req.body);
const message = {
const logMessage = {
name: "Slack OpenAI Event",
req: parsedSlackEvent,
some: req.body,
};

// change function name in log metadata
LOG_METADATA.resource.labels.function_name = "xplorers-openai-function";

writeLog(log, message, LOG_METADATA);
const openAIResponse = await askOpenAI(parsedSlackEvent.event.text);
const message =
parsedSlackEvent?.event?.text ?? parsedSlackEvent?.event?.message?.text;
const ts =
parsedSlackEvent?.event?.message?.ts ?? parsedSlackEvent?.event?.ts;

writeLog(log, logMessage, LOG_METADATA);

const openAIResponse = await askOpenAI(message);

if (openAIResponse) {
await postMessageToSlack(
slackWebClient,
openAIResponse,
parsedSlackEvent.event.channel
parsedSlackEvent.event.channel,
ts
);
}

Expand Down

0 comments on commit e75912e

Please sign in to comment.