mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-06 09:58:26 +00:00
bots: SimpleX Calculator demo bot (#7583)
* bots: SimpleX Calculator demo bot * refactor * use local server in test * simplify * icon * simplify * expression * replies * improve * log * update name in bot address * @simplex-chat/type: 0.12.0 * simplex-chat nodejs: 7.1.0-beta.4.2 * update dependencies * option to add domain to bot address --------- Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
co-authored by
Evgeny @ SimpleX Chat
parent
4cb244441b
commit
643a9afad6
@@ -35,17 +35,18 @@ const defaultOpts: Required<BotOptions> = {
|
||||
|
||||
export interface BotConfig {
|
||||
profile: T.Profile,
|
||||
simplexDomain?: string | null,
|
||||
dbOpts: BotDbOpts,
|
||||
options: BotOptions,
|
||||
onMessage?: (chatItem: T.AChatItem, content: T.MsgContent) => void | Promise<void>,
|
||||
onMessage?: (chatItem: T.AChatItem, content: T.MsgContent, chat: api.ChatApi) => void | Promise<void>,
|
||||
// command handlers can be different from commands to be shown in client UI
|
||||
onCommands?: {[K in string]?: ((chatItem: T.AChatItem, command: util.BotCommand) => void | Promise<void>)},
|
||||
onCommands?: {[K in string]?: ((chatItem: T.AChatItem, command: util.BotCommand, chat: api.ChatApi) => void | Promise<void>)},
|
||||
// If you use `onMessage` and to subscribe "newChatItems" event, exclude content messages from processing
|
||||
// If you use `onCommands` and to subscribe "newChatItems" event, exclude commands from processing
|
||||
events?: api.EventSubscribers
|
||||
}
|
||||
|
||||
export async function run({profile, dbOpts, options = defaultOpts, onMessage, onCommands = {}, events = {}}: BotConfig): Promise<[api.ChatApi, T.User, T.UserContactLink | undefined]> {
|
||||
export async function run({profile, simplexDomain, dbOpts, options = defaultOpts, onMessage, onCommands = {}, events = {}}: BotConfig): Promise<[api.ChatApi, T.User, T.UserContactLink | undefined]> {
|
||||
const bot = await api.ChatApi.init(dbOpts, dbOpts.confirmMigrations || core.MigrationConfirmation.YesUp, dbOpts.queueSize)
|
||||
const opts = fullOptions(options)
|
||||
if (onMessage || Object.keys(onCommands).length > 0) subscribeChatItems(bot, onMessage, onCommands)
|
||||
@@ -60,7 +61,8 @@ export async function run({profile, dbOpts, options = defaultOpts, onMessage, on
|
||||
console.log(`Bot address: ${addressLink}`)
|
||||
if (opts.useBotProfile) botProfile.contactLink = addressLink
|
||||
}
|
||||
await updateBotUserProfile(bot, user, botProfile, opts)
|
||||
const namedUser = await updateBotSimplexDomain(bot, user, simplexDomain, opts)
|
||||
await updateBotUserProfile(bot, namedUser, botProfile, opts)
|
||||
return [bot, user, address]
|
||||
}
|
||||
|
||||
@@ -107,8 +109,8 @@ function mkBotProfile(profile: T.Profile, opts: Required<BotOptions>): T.Profile
|
||||
|
||||
export function subscribeChatItems(
|
||||
bot: api.ChatApi,
|
||||
onMessage: ((chatItem: T.AChatItem, content: T.MsgContent) => void | Promise<void>) | undefined,
|
||||
commands: {[K in string]?: ((chatItem: T.AChatItem, command: util.BotCommand) => void | Promise<void>)}
|
||||
onMessage: ((chatItem: T.AChatItem, content: T.MsgContent, chat: api.ChatApi) => void | Promise<void>) | undefined,
|
||||
commands: {[K in string]?: ((chatItem: T.AChatItem, command: util.BotCommand, chat: api.ChatApi) => void | Promise<void>)}
|
||||
) {
|
||||
bot.on("newChatItems", async ({chatItems}) => {
|
||||
for (const ci of chatItems) {
|
||||
@@ -117,8 +119,8 @@ export function subscribeChatItems(
|
||||
const cmd = util.ciBotCommand(ci.chatItem)
|
||||
const cmdFunc = cmd && (commands[cmd.keyword] || commands[""])
|
||||
try {
|
||||
if (cmd && cmdFunc) await cmdFunc(ci, cmd)
|
||||
else if (onMessage) await onMessage(ci, content.msgContent)
|
||||
if (cmd && cmdFunc) await cmdFunc(ci, cmd, bot)
|
||||
else if (onMessage) await onMessage(ci, content.msgContent, bot)
|
||||
} catch (e) {
|
||||
console.log(cmd && cmdFunc ? `${cmd.keyword} command processing error` : "message processing error", e)
|
||||
}
|
||||
@@ -180,15 +182,33 @@ async function createOrUpdateAddress(bot: api.ChatApi, user: T.User, opts: Requi
|
||||
}
|
||||
}
|
||||
|
||||
return address
|
||||
return address
|
||||
}
|
||||
|
||||
async function updateBotSimplexDomain(bot: api.ChatApi, user: T.User, simplexDomain: string | null | undefined, opts: Required<BotOptions>): Promise<T.User> {
|
||||
if (simplexDomain === undefined) return user
|
||||
const domain = simplexDomain === null ? undefined : simplexDomain.toLowerCase()
|
||||
if (user.profile.contactDomain?.domain === domain) return user
|
||||
if (!opts.updateAddress) {
|
||||
console.log("Bot SimpleX name changed")
|
||||
return user
|
||||
}
|
||||
console.log("Bot SimpleX name changed, updating...")
|
||||
try {
|
||||
return await bot.apiSetUserDomain(user.userId, domain)
|
||||
} catch (e) {
|
||||
console.log("Error updating bot SimpleX name", e)
|
||||
return user
|
||||
}
|
||||
}
|
||||
|
||||
async function updateBotUserProfile(bot: api.ChatApi, user: T.User, profile: T.Profile, opts: Required<BotOptions>): Promise<void> {
|
||||
const {userId} = user
|
||||
if (!equal(util.fromLocalProfile(user.profile), profile)) {
|
||||
const {contactDomain, ...currentProfile} = util.fromLocalProfile(user.profile)
|
||||
if (!equal(currentProfile, profile)) {
|
||||
if (opts.updateProfile) {
|
||||
console.log("Bot profile changed, updating...")
|
||||
const summary = await bot.apiUpdateProfile(userId, profile)
|
||||
const summary = await bot.apiUpdateProfile(userId, {...profile, contactDomain})
|
||||
console.log(
|
||||
summary
|
||||
? `Bot profile updated: ${summary.updateSuccesses} updated contact(s), ${summary.updateFailures} failed contact update(s).`
|
||||
|
||||
Reference in New Issue
Block a user