-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from fabriguespe/access_v2
Update access docs
- Loading branch information
Showing
6 changed files
with
126 additions
and
130 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
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 |
---|---|---|
@@ -1,34 +1,88 @@ | ||
import xmtpClient from "./client.js"; | ||
import HandlerContext from "./handler-context.js"; | ||
import { ContentTypeSilent } from "../content-types/Silent.js"; | ||
|
||
type Handler = (context: HandlerContext) => Promise<void>; | ||
|
||
export default async function run(handler: Handler, newBotConfig?: any) { | ||
export default async function run( | ||
handler: Handler, | ||
newBotConfig?: any, | ||
accessHandler?: (context: HandlerContext) => Promise<boolean>, | ||
) { | ||
const client = await xmtpClient(newBotConfig); | ||
|
||
const { address } = client; | ||
for await (const message of await client.conversations.streamAllMessages()) { | ||
try { | ||
if (message.senderAddress === client.address) { | ||
const { | ||
senderAddress, | ||
content, | ||
contentType: { typeId }, | ||
} = message; | ||
|
||
if (senderAddress === address) { | ||
// if same address do nothing | ||
continue; | ||
} else if (message.contentType.typeId == "bot") { | ||
} else if (typeId == "bot") { | ||
//if a bot speaks do nothing | ||
continue; | ||
} | ||
const context = new HandlerContext( | ||
message, | ||
newBotConfig?.context ?? {}, | ||
client.address, | ||
address, | ||
); | ||
if ( | ||
message.contentType.typeId == "silent" && | ||
message.content?.content === "/ping" | ||
typeId == "silent" && | ||
content?.content === "/access" && | ||
accessHandler | ||
) { | ||
//if a bot speaks do nothing | ||
context.ping(); | ||
} else await handler(context); | ||
const accept = await accessHandler(context); | ||
if (accept) { | ||
// add to group | ||
grant_access(message, newBotConfig?.context); | ||
continue; | ||
} | ||
} else if (typeId == "silent" && content?.content === "/ping") { | ||
//if a bot speaks do nothing | ||
ping(message, newBotConfig?.context, accessHandler); | ||
continue; | ||
} | ||
|
||
await handler(context); | ||
} catch (e) { | ||
console.log(`error`, e); | ||
} | ||
} | ||
} | ||
|
||
async function grant_access(message: any, context: any) { | ||
// add group member | ||
await message.conversation.send( | ||
{ | ||
content: "", | ||
metadata: { | ||
type: "access", | ||
...context, | ||
}, | ||
}, | ||
{ | ||
contentType: ContentTypeSilent, | ||
}, | ||
); | ||
} | ||
async function ping(message: any, context: any, accessHandler: any) { | ||
await message.conversation.send( | ||
{ | ||
content: "", | ||
metadata: { | ||
type: "ping", | ||
access: accessHandler ? true : false, | ||
...context, | ||
}, | ||
}, | ||
{ | ||
contentType: ContentTypeSilent, | ||
}, | ||
); | ||
} |
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 |
---|---|---|
@@ -1,96 +1,54 @@ | ||
# Access | ||
|
||
For declaring that the bot will handle access we need to add the access command to the commands file | ||
Create the `accessHandler` function to handle the access request. Returns true or false based on the access request. | ||
|
||
```tsx [src/commands.ts] | ||
export const commands = [ | ||
{ | ||
name: "General Commands", | ||
icon: "🔧", | ||
description: "Command for managing default behaviours.", | ||
commands: [ | ||
/* Declare access command*/ | ||
{ | ||
command: "/access", | ||
description: "Grant access to a user to the bot.", | ||
}, | ||
/* Other commands */ | ||
], | ||
}, | ||
]; | ||
``` | ||
|
||
### Declare commands | ||
|
||
To declare the access command in the botkit app, you need to add the following code: | ||
const accessHandler = async (context: HandlerContext): Promise<boolean> => { | ||
const { senderAddress } = context.message; | ||
|
||
```tsx | ||
import { commands } from "./commands.js"; | ||
/*here put the token gated logic*/ | ||
|
||
const newBotConfig = { | ||
context: { | ||
commands: commands, | ||
}, | ||
if (senderAddress) return true; | ||
return false; | ||
}; | ||
|
||
run(async (context: HandlerContext) => { | ||
//Your logic here | ||
}, newBotConfig); | ||
``` | ||
|
||
For allowing access to a new user botkit receives a `silent` request with this structure | ||
### Send it as parameter | ||
|
||
```tsx | ||
{ | ||
content: "/access", | ||
metadata: {} | ||
} | ||
``` | ||
|
||
### Receive an access request | ||
|
||
To accept an access request in your app, you can use the following code: | ||
To declare the access command in the botkit app, you need to add the following code: | ||
|
||
```jsx | ||
if (typeId == "silent") { | ||
const { content: command } = content; | ||
// Do something with the command | ||
if (command == "/access") | ||
if (senderAddress) { | ||
/*here put the token gated logic*/ | ||
// accept the access request | ||
context.grant_access(); | ||
} | ||
} | ||
```tsx | ||
run( | ||
async (context: HandlerContext) => { | ||
/* Bot logic here */ | ||
}, | ||
{ | ||
/* Additional bot config*/ | ||
}, | ||
accessHandler, | ||
); | ||
``` | ||
|
||
### Full example | ||
|
||
```jsx [src/index.ts] | ||
import "dotenv/config"; | ||
import { run, HandlerContext } from "@xmtp/botkit"; | ||
import { commands } from "./commands.js"; | ||
|
||
const newBotConfig = { | ||
context: { | ||
commands: commands, | ||
}, | ||
const accessHandler = async (context: HandlerContext): Promise<boolean> => { | ||
const { senderAddress } = context.message; | ||
|
||
/*here put the token gated logic*/ | ||
|
||
if (senderAddress) return true; | ||
return false; | ||
}; | ||
|
||
run(async (context: HandlerContext) => { | ||
const { content, contentType, senderAddress } = context.message; | ||
const { typeId } = contentType; | ||
|
||
if (typeId == "silent") { | ||
const { content: command } = content; | ||
// Do something with the command | ||
if (command == "/access") | ||
if (senderAddress) { | ||
/*here put the token gated logic*/ | ||
// accept the access request | ||
context.grant_access(); | ||
} | ||
} | ||
context.reply("gm!"); | ||
}, newBotConfig); | ||
|
||
}, {}, accessHandler); | ||
``` |
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