diff --git a/apps/simplex-calculator-bot/README.md b/apps/simplex-calculator-bot/README.md index 9646008e04..028e470964 100644 --- a/apps/simplex-calculator-bot/README.md +++ b/apps/simplex-calculator-bot/README.md @@ -23,6 +23,8 @@ npm start The bot prints its address and keeps its data in `./data`. +To add a SimpleX name to the address, register the name with the address short link, and run `npm start -- --domain yourname.simplex`. The name is kept when the bot starts without `--domain`. + To use the library from this repository, build it and run `npm install --no-save ../../packages/simplex-chat-nodejs` instead of `npm install`. ## Test diff --git a/apps/simplex-calculator-bot/src/calculatorBot.ts b/apps/simplex-calculator-bot/src/calculatorBot.ts index 2454ead401..85cd1b50d4 100644 --- a/apps/simplex-calculator-bot/src/calculatorBot.ts +++ b/apps/simplex-calculator-bot/src/calculatorBot.ts @@ -78,9 +78,10 @@ async function onMessage(ci: T.AChatItem, content: T.MsgContent, chat: api.ChatA await updateCalculator(chat, sender, input.update) } -export function runCalculatorBot(dbOpts: bot.BotDbOpts): Promise<[api.ChatApi, T.User, T.UserContactLink | undefined]> { +export function runCalculatorBot(dbOpts: bot.BotDbOpts, simplexDomain?: string): Promise<[api.ChatApi, T.User, T.UserContactLink | undefined]> { return bot.run({ profile: {displayName: "SimpleX Calculator", fullName: "", image: calculatorIcon, preferences: {fullDelete: {allow: T.FeatureAllowed.Yes}}}, + simplexDomain, dbOpts, options: { addressSettings: {businessAddress: true, welcomeMessage}, diff --git a/apps/simplex-calculator-bot/src/index.ts b/apps/simplex-calculator-bot/src/index.ts index db59877b22..5464e25ec8 100644 --- a/apps/simplex-calculator-bot/src/index.ts +++ b/apps/simplex-calculator-bot/src/index.ts @@ -1,9 +1,12 @@ import {mkdirSync} from "fs" +import {parseArgs} from "util" import {runCalculatorBot} from "./calculatorBot.js" +const {values: {domain}} = parseArgs({options: {domain: {type: "string"}}}) + mkdirSync("data", {recursive: true}) -runCalculatorBot({type: "sqlite", filePrefix: "./data/calculator"}).catch(e => { +runCalculatorBot({type: "sqlite", filePrefix: "./data/calculator"}, domain).catch(e => { console.log("fatal error", e) process.exit(1) }) diff --git a/packages/simplex-chat-nodejs/src/bot.ts b/packages/simplex-chat-nodejs/src/bot.ts index 66d8a8da04..83037e310e 100644 --- a/packages/simplex-chat-nodejs/src/bot.ts +++ b/packages/simplex-chat-nodejs/src/bot.ts @@ -35,7 +35,7 @@ const defaultOpts: Required = { export interface BotConfig { profile: T.Profile, - simplexName?: string, + simplexDomain?: string | null, dbOpts: BotDbOpts, options: BotOptions, onMessage?: (chatItem: T.AChatItem, content: T.MsgContent, chat: api.ChatApi) => void | Promise, @@ -46,7 +46,7 @@ export interface BotConfig { events?: api.EventSubscribers } -export async function run({profile, simplexName, 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) @@ -61,7 +61,7 @@ export async function run({profile, simplexName, dbOpts, options = defaultOpts, console.log(`Bot address: ${addressLink}`) if (opts.useBotProfile) botProfile.contactLink = addressLink } - const namedUser = await updateBotSimplexName(bot, user, simplexName, opts) + const namedUser = await updateBotSimplexDomain(bot, user, simplexDomain, opts) await updateBotUserProfile(bot, namedUser, botProfile, opts) return [bot, user, address] } @@ -185,16 +185,17 @@ async function createOrUpdateAddress(bot: api.ChatApi, user: T.User, opts: Requi return address } -async function updateBotSimplexName(bot: api.ChatApi, user: T.User, simplexName: string | undefined, opts: Required): Promise { - const name = simplexName?.toLowerCase() - if (user.profile.contactDomain?.domain === name) return user +async function updateBotSimplexDomain(bot: api.ChatApi, user: T.User, simplexDomain: string | null | undefined, opts: Required): Promise { + 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, name) + return await bot.apiSetUserDomain(user.userId, domain) } catch (e) { console.log("Error updating bot SimpleX name", e) return user diff --git a/packages/simplex-chat-nodejs/tests/bot.unit.test.ts b/packages/simplex-chat-nodejs/tests/bot.unit.test.ts index abdd59c999..62ff10aab4 100644 --- a/packages/simplex-chat-nodejs/tests/bot.unit.test.ts +++ b/packages/simplex-chat-nodejs/tests/bot.unit.test.ts @@ -78,8 +78,8 @@ describe("run", () => { return chat } - const runBot = (simplexName?: string, options = {}) => - run({profile: {displayName: "Calculator", fullName: ""}, simplexName, dbOpts: {type: "sqlite", filePrefix: "unused"}, options}) + const runBot = (simplexDomain?: string | null, options = {}) => + run({profile: {displayName: "Calculator", fullName: ""}, simplexDomain, dbOpts: {type: "sqlite", filePrefix: "unused"}, options}) const updatedProfile = (chat: ReturnType) => chat.apiUpdateProfile.mock.calls[0][1] @@ -93,13 +93,20 @@ describe("run", () => { expect(updatedProfile(chat).contactDomain).toEqual({domain: "calc.simplex"}) }) - it("removes the SimpleX name that is not configured", async () => { + it("removes the SimpleX name set to null", async () => { const chat = fakeChat({domain: "calc.simplex"}) - await runBot() + await runBot(null) expect(chat.apiSetUserDomain).toHaveBeenCalledWith(1, undefined) expect(updatedProfile(chat).contactDomain).toBeUndefined() }) + it("keeps the stored SimpleX name when it is not configured", async () => { + const chat = fakeChat({domain: "calc.simplex"}) + await runBot() + expect(chat.apiSetUserDomain).not.toHaveBeenCalled() + expect(updatedProfile(chat).contactDomain).toEqual({domain: "calc.simplex"}) + }) + it("keeps the SimpleX name when updating the profile", async () => { const chat = fakeChat({domain: "calc.simplex", proof: {presHeader: "header", signature: "signature"}}) await runBot("calc.simplex")