-
-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add request/reply support (#551)
- Loading branch information
1 parent
e351224
commit 8f226b8
Showing
27 changed files
with
22,194 additions
and
212 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
.glee |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Slack Websocket API | ||
|
||
This Slack Websocket API leverages the AsyncAPI specification to connect Slack with OpenAI's AI models. When a user reacts to a message on Slack, this API sends the reaction to OpenAI's server. ChatGPT then crafts a fun response, which is posted as a reply to the message thread on Slack. | ||
|
||
## Table of Contents | ||
|
||
- [Overview](#overview) | ||
- [Prerequisites](#prerequisites) | ||
- [Configuration](#configuration) | ||
- [Usage](#usage) | ||
- [Environment Variables](#environment-variables) | ||
|
||
## Overview | ||
|
||
The API listens for reaction events in Slack, processes them through OpenAI's API to generate responses, and sends those back to Slack as a threaded message. | ||
|
||
## Prerequisites | ||
|
||
- Node.js (version 12 or higher) | ||
- A Slack app with permissions to read reactions and post messages | ||
- Access to OpenAI API | ||
|
||
## Configuration | ||
|
||
Before running the project, you must update the `asyncapi.yaml` file with the current `ticket` and `app_id` for the Slack WebSocket connection: | ||
|
||
```yaml | ||
channels: | ||
SlackEventStream: | ||
address: /link/?ticket=[ticket]&app_id=[app_id] | ||
``` | ||
Replace `[ticket]` and `[app_id]` with the respective values for your Slack app. | ||
|
||
## Usage | ||
|
||
Set the environment variables by creating a `.env` file in the root of the project: | ||
|
||
```plaintext | ||
SLACK_HTTP=xoxb-********** | ||
CHAT_API=openai_token | ||
``` | ||
|
||
Start the API server with: | ||
|
||
```sh | ||
npm run dev | ||
``` | ||
|
||
The API will now listen for Slack reaction events, interact with OpenAI, and post responses on Slack. | ||
|
||
## Environment Variables | ||
|
||
The following environment variables are necessary for the API to function: | ||
|
||
- `SLACK_HTTP`: Your Slack app's OAuth token. | ||
- `CHAT_API`: Your OpenAI API key. | ||
|
||
Ensure these are set in your environment. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
asyncapi: 3.0.0 | ||
info: | ||
title: Slack Websocket and OpenAI API | ||
version: 1.0.0 | ||
servers: | ||
OpenAI_HTTPS: | ||
host: api.openai.com | ||
protocol: https | ||
Slack_WebSocket: | ||
host: wss-primary.slack.com | ||
protocol: wss | ||
Slack_HTTPS: | ||
host: slack.com | ||
protocol: https | ||
channels: | ||
SlackPostMessage: | ||
bindings: | ||
http: | ||
method: post | ||
address: /api/chat.postMessage | ||
servers: | ||
- $ref: "#/servers/Slack_HTTPS" | ||
messages: | ||
slackResponse: | ||
payload: | ||
type: object | ||
properties: | ||
channel: | ||
type: string | ||
text: | ||
type: string | ||
OpenAICompletion: | ||
bindings: | ||
http: | ||
method: post | ||
servers: | ||
- $ref: "#/servers/OpenAI_HTTPS" | ||
address: /v1/chat/completions | ||
messages: | ||
OpenAIRequest: | ||
$ref: "#/components/messages/OpenAIRequest" | ||
SlackEventStream: | ||
servers: | ||
- $ref: "#/servers/Slack_WebSocket" | ||
address: /link/?ticket={ticket}&app_id={app_id} | ||
parameters: | ||
ticket: | ||
default: 38408ed1-5d39--82f0-6e1214dae1 | ||
app_id: | ||
default: b02112d9364cb2fee8a0a920b8bcb03fab023b4e30f6ee2efb98f | ||
messages: | ||
SlackReactionAdded: | ||
$ref: "#/components/messages/SlackReactionAdded" | ||
GenericErrorPayload: | ||
$ref: "#/components/messages/GenericErrorPayload" | ||
operations: | ||
sentSlackMessage: | ||
action: send | ||
channel: | ||
$ref: "#/channels/SlackPostMessage" | ||
messages: | ||
- $ref: "#/components/messages/slackResponse" | ||
receiveSlackConfirmation: | ||
action: receive | ||
channel: | ||
$ref: "#/channels/SlackPostMessage" | ||
AckEvent: | ||
action: send | ||
channel: | ||
$ref: "#/channels/SlackEventStream" | ||
messages: | ||
- $ref: "#/components/messages/slackAckEvent" | ||
SendToOpenAI: | ||
action: send | ||
channel: | ||
$ref: "#/channels/OpenAICompletion" | ||
messages: | ||
- $ref: "#/components/messages/slackResponse" | ||
ReceiveFromOpenAI: | ||
action: receive | ||
channel: | ||
$ref: "#/channels/OpenAICompletion" | ||
messages: | ||
- $ref: "#/components/messages/OpenAICompletionResponse" | ||
reply: | ||
channel: | ||
$ref: "#/channels/SlackPostMessage" | ||
HandleSlackReaction: | ||
reply: | ||
channel: | ||
$ref: "#/channels/SlackEventStream" | ||
action: receive | ||
channel: | ||
$ref: "#/channels/SlackEventStream" | ||
messages: | ||
- $ref: "#/components/messages/SlackReactionAdded" | ||
- $ref: "#/components/messages/GenericErrorPayload" | ||
components: | ||
messages: | ||
slackAckEvent: | ||
payload: | ||
type: object | ||
properties: | ||
envelope_id: | ||
type: string | ||
slackResponse: | ||
payload: | ||
type: object | ||
properties: | ||
channel: | ||
type: string | ||
text: | ||
type: string | ||
OpenAIRequest: | ||
payload: | ||
type: object | ||
properties: | ||
model: | ||
type: string | ||
enum: ["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "text-davinci-002"] | ||
messages: | ||
type: array | ||
items: | ||
type: object | ||
properties: | ||
role: | ||
type: string | ||
enum: ["user"] | ||
content: | ||
type: string | ||
temperature: | ||
type: number | ||
minimum: 0.0 | ||
maximum: 1.0 | ||
required: | ||
- model | ||
- messages | ||
- temperature | ||
OpenAICompletionResponse: | ||
payload: | ||
type: object | ||
properties: | ||
choices: | ||
type: array | ||
items: | ||
type: object | ||
properties: | ||
finish_reason: | ||
type: string | ||
enum: ['stop'] | ||
message: | ||
type: object | ||
properties: | ||
content: | ||
type: string | ||
role: | ||
type: string | ||
enum: ['assistant'] | ||
required: | ||
- finish_reason | ||
- message | ||
required: | ||
- choices | ||
SlackReactionAdded: | ||
payload: | ||
type: object | ||
GenericErrorPayload: | ||
payload: | ||
type: string | ||
x-remoteServers: | ||
- Slack_HTTPS | ||
- Slack_WebSocket | ||
- OpenAI_HTTPS |
32 changes: 32 additions & 0 deletions
32
examples/slack-reaction-listener/functions/HandleSlackReaction.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { GleeFunction } from "@asyncapi/glee" | ||
|
||
const myFunction: GleeFunction = async ({ payload }) => { | ||
const { envelope_id } = payload | ||
const reaction = payload?.payload?.event?.reaction | ||
if (!reaction) return | ||
return { | ||
reply: [ | ||
{ | ||
payload: { | ||
envelope_id | ||
} | ||
} | ||
], | ||
send: [{ | ||
server: "OpenAI_HTTPS", | ||
channel: "OpenAICompletion", | ||
headers: { | ||
'Authorization': `Bearer ${process.env.CHAT_API}` | ||
}, | ||
payload: { | ||
model: "gpt-3.5-turbo", | ||
messages: [{ "role": "user", "content": `Someone reacted with "${reaction}" emoji to my message on Slack, write something fun and short to them.` }], | ||
temperature: 0.7 | ||
} | ||
}] | ||
} | ||
|
||
|
||
} | ||
|
||
export default myFunction |
28 changes: 28 additions & 0 deletions
28
examples/slack-reaction-listener/functions/ReceiveFromOpenAI.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { GleeFunction } from "@asyncapi/glee" | ||
|
||
const myFunction: GleeFunction = async (event) => { | ||
const { payload } = event.request.request | ||
const slack_event = payload?.payload?.event | ||
|
||
if (!slack_event) return | ||
|
||
const thread_ts = slack_event.item.ts | ||
const channel = slack_event.item.channel | ||
const text = event.payload.choices[0].message.content | ||
|
||
|
||
return { | ||
send: [{ | ||
channel: "SlackPostMessage", | ||
server: "Slack_HTTPS", | ||
payload: { | ||
channel, thread_ts, text | ||
}, | ||
headers: { | ||
Authorization: `Bearer ${process.env.SLACK_HTTP}`, | ||
} | ||
}] | ||
} | ||
} | ||
|
||
export default myFunction |
7 changes: 7 additions & 0 deletions
7
examples/slack-reaction-listener/functions/receiveSlackConfirmation.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
const myFunction = async ({ payload }) => { | ||
if (payload.ok) { | ||
console.log("everything went smoothly.") | ||
} | ||
} | ||
|
||
export default myFunction |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export default async function () { | ||
return { | ||
docs: { | ||
enabled: false | ||
} | ||
} | ||
} |
Oops, something went wrong.