Skip to content

Commit c834a70

Browse files
committed
feat: add language to community
This allows the community admin to set the language for the published message in their channel
1 parent 5d2cd77 commit c834a70

File tree

19 files changed

+235
-5
lines changed

19 files changed

+235
-5
lines changed

bot/messages.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import { IPendingPayment } from '../models/pending_payment';
2424
import { PayViaPaymentRequestResult } from 'lightning';
2525
import { IFiat } from '../util/fiatModel';
2626
import { CommunityContext } from './modules/community/communityContext';
27+
const { I18n } = require('@grammyjs/i18n');
28+
import { Community } from '../models';
2729

2830
const startMessage = async (ctx: MainContext) => {
2931
try {
@@ -651,11 +653,25 @@ const publishBuyOrderMessage = async (
651653
const channel = await getOrderChannel(order);
652654
if (channel === undefined)
653655
throw new Error("channel is undefined");
656+
657+
// Get the community language if available
658+
let communityI18n = i18n;
659+
if (order.community_id) {
660+
const community = await Community.findOne({ _id: order.community_id });
661+
if (community && community.language) {
662+
communityI18n = new I18n({
663+
defaultLanguageOnMissing: true,
664+
locale: community.language,
665+
directory: 'locales'
666+
}).createContext(community.language);
667+
}
668+
}
669+
654670
// We send the message to the channel
655671
const message1 = await bot.telegram.sendMessage(channel, publishMessage, {
656672
reply_markup: {
657673
inline_keyboard: [
658-
[{ text: i18n.t('sell_sats'), callback_data: 'takebuy' }],
674+
[{ text: communityI18n.t('sell_sats'), callback_data: 'takebuy' }],
659675
],
660676
},
661677
});
@@ -688,11 +704,26 @@ const publishSellOrderMessage = async (
688704
const channel = await getOrderChannel(order);
689705
if (channel === undefined)
690706
throw new Error("channel is undefined");
707+
708+
// Get the community language if available
709+
let communityI18n = i18n;
710+
711+
if (order.community_id) {
712+
const community = await Community.findOne({ _id: order.community_id });
713+
if (community && community.language) {
714+
communityI18n = new I18n({
715+
defaultLanguageOnMissing: true,
716+
locale: community.language,
717+
directory: 'locales'
718+
}).createContext(community.language);
719+
}
720+
}
721+
691722
// We send the message to the channel
692723
const message1 = await ctx.telegram.sendMessage(channel, publishMessage, {
693724
reply_markup: {
694725
inline_keyboard: [
695-
[{ text: i18n.t('buy_sats'), callback_data: 'takesell' }],
726+
[{ text: communityI18n.t('buy_sats'), callback_data: 'takesell' }],
696727
],
697728
},
698729
});

bot/middleware/stage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const stageMiddleware = () => {
1818
CommunityModule.Scenes.updateSolversCommunityWizard,
1919
CommunityModule.Scenes.updateFeeCommunityWizard,
2020
CommunityModule.Scenes.updateDisputeChannelCommunityWizard,
21+
CommunityModule.Scenes.updateLanguageCommunityWizard,
2122
CommunityModule.Scenes.addEarningsInvoiceWizard,
2223
addInvoicePHIWizard,
2324
OrdersModule.Scenes.createOrder,

bot/modules/community/commands.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ export const updateCommunity = async (ctx: CommunityContext, id: string, field:
195195
user,
196196
community,
197197
});
198+
} else if (field === 'language') {
199+
ctx.scene.enter('UPDATE_LANGUAGE_COMMUNITY_WIZARD_SCENE_ID', {
200+
id,
201+
user,
202+
community,
203+
});
198204
}
199205
} catch (error) {
200206
logger.error(error);

bot/modules/community/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ export const configure = (bot: Telegraf<CommunityContext>) => {
5050
await commands.updateCommunity(ctx, ctx.match[1], 'disputeChannel', bot);
5151
}
5252
);
53+
bot.action(
54+
/^editLanguageBtn_([0-9a-f]{24})$/,
55+
userMiddleware,
56+
async ctx => {
57+
await commands.updateCommunity(ctx, ctx.match[1], 'language');
58+
}
59+
);
5360

5461
bot.command('findcomms', userMiddleware, commands.findCommunity);
5562
bot.action(

bot/modules/community/messages.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const createCommunityWizardStatus = (i18n: I18nContext, state: CommunityW
99
try {
1010
let { name, group } = state;
1111
name = state.name || '__';
12+
const language = state.language || '__';
1213
let currencies = state.currencies && state.currencies.join(', ');
1314
currencies = currencies || '__';
1415
group = state.group || '__';
@@ -21,6 +22,7 @@ export const createCommunityWizardStatus = (i18n: I18nContext, state: CommunityW
2122
solvers = solvers || '__';
2223
const text = [
2324
i18n.t('name') + `: ${name}`,
25+
i18n.t('language') + `: ${language}`,
2426
i18n.t('currency') + `: ${currencies}`,
2527
i18n.t('group') + `: ${group}`,
2628
i18n.t('channels') + `: ${channels}`,
@@ -89,15 +91,21 @@ export const updateCommunityMessage = async (ctx: MainContext) => {
8991
callback_data: `editDisputeChannelBtn_${id}`,
9092
},
9193
{
92-
text: '💰 ' + ctx.i18n.t('earnings'),
93-
callback_data: `earningsBtn_${id}`,
94+
text: '✏️ ' + ctx.i18n.t('language'),
95+
callback_data: `editLanguageBtn_${id}`,
9496
},
9597
],
9698
[
99+
{
100+
text: '💰 ' + ctx.i18n.t('earnings'),
101+
callback_data: `earningsBtn_${id}`,
102+
},
97103
{
98104
text: visibilityText,
99105
callback_data: `changeVisibilityBtn_${id}`,
100106
},
107+
],
108+
[
101109
{
102110
text: '☠️ ' + ctx.i18n.t('delete_community'),
103111
callback_data: `deleteCommunityAskBtn_${id}`,

bot/modules/community/scenes.communityAdmin.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,27 @@ const communityAdmin = () => {
3434
}
3535
});
3636

37+
scene.command('/setlanguage', async (ctx: CommunityContext) => {
38+
try {
39+
const [, language] = ctx.message!.text.trim().split(' ');
40+
const lang = language?.toLowerCase();
41+
42+
// Check if language is valid
43+
const validLanguages = ['en', 'es', 'fr', 'de', 'it', 'pt', 'ru', 'uk', 'ko', 'fa'];
44+
if (!lang || !validLanguages.includes(lang)) {
45+
return ctx.reply(ctx.i18n.t('wizard_community_invalid_language'));
46+
}
47+
48+
const { community } = ctx.scene.state as any;
49+
community.language = lang;
50+
await community.save();
51+
await ctx.reply(ctx.i18n.t('community_language_updated', { language: lang }));
52+
CommunityEvents.communityUpdated(community);
53+
} catch (err) {
54+
return ctx.reply(ctx.i18n.t('generic_error'));
55+
}
56+
});
57+
3758
return scene;
3859
}
3960

bot/modules/community/scenes.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const communityWizard = new Scenes.WizardScene<CommunityContext>(
2222

2323
const {
2424
name,
25+
language,
2526
currencies,
2627
group,
2728
channels,
@@ -61,6 +62,7 @@ export const communityWizard = new Scenes.WizardScene<CommunityContext>(
6162
}
6263

6364
if (undefined === name) return createCommunitySteps.name(ctx);
65+
if (undefined === language) return createCommunitySteps.language(ctx);
6466
if (undefined === currencies) return createCommunitySteps.currencies(ctx);
6567
if (undefined === group) return createCommunitySteps.group(ctx);
6668
if (undefined === channels) return createCommunitySteps.channels(ctx);
@@ -71,6 +73,7 @@ export const communityWizard = new Scenes.WizardScene<CommunityContext>(
7173

7274
const community = new Community({
7375
name,
76+
language,
7477
currencies,
7578
group,
7679
order_channels: channels,
@@ -150,6 +153,38 @@ const createCommunitySteps = {
150153

151154
return ctx.wizard.next();
152155
},
156+
async language(ctx: CommunityContext) {
157+
const prompt = await createCommunityPrompts.language(ctx);
158+
159+
ctx.wizard.state.handler = async (ctx: CommunityContext) => {
160+
const text = ctx?.message?.text;
161+
if (!text) {
162+
await ctx.deleteMessage();
163+
return ctx.telegram.deleteMessage(prompt.chat.id, prompt.message_id);
164+
}
165+
166+
ctx.wizard.state.error = null;
167+
const lang = text.trim().toLowerCase();
168+
169+
// Check if language is valid
170+
const validLanguages = ['en', 'es', 'fr', 'de', 'it', 'pt', 'ru', 'uk', 'ko', 'fa'];
171+
if (!validLanguages.includes(lang)) {
172+
ctx.telegram.deleteMessage(ctx.chat!.id, ctx.message!.message_id);
173+
ctx.wizard.state.error = ctx.i18n.t('wizard_community_invalid_language');
174+
return await ctx.wizard.state.updateUI();
175+
}
176+
177+
ctx.wizard.state.language = lang;
178+
await ctx.wizard.state.updateUI();
179+
await ctx.telegram.deleteMessage(
180+
ctx.message!.chat.id,
181+
ctx.message!.message_id
182+
);
183+
return ctx.telegram.deleteMessage(prompt.chat.id, prompt.message_id);
184+
};
185+
186+
return ctx.wizard.next();
187+
},
153188
async currencies(ctx: CommunityContext) {
154189
const prompt = await createCommunityPrompts.currencies(ctx);
155190

@@ -427,6 +462,9 @@ const createCommunityPrompts = {
427462
async name(ctx: CommunityContext) {
428463
return ctx.reply(ctx.i18n.t('wizard_community_enter_name'));
429464
},
465+
async language(ctx: CommunityContext) {
466+
return ctx.reply(ctx.i18n.t('wizard_community_enter_language'));
467+
},
430468
async currencies(ctx: CommunityContext) {
431469
return ctx.reply(ctx.i18n.t('wizard_community_enter_currency'));
432470
},
@@ -838,6 +876,47 @@ export const updateDisputeChannelCommunityWizard = new Scenes.WizardScene(
838876
}
839877
);
840878

879+
export const updateLanguageCommunityWizard = new Scenes.WizardScene(
880+
'UPDATE_LANGUAGE_COMMUNITY_WIZARD_SCENE_ID',
881+
async (ctx: CommunityContext) => {
882+
try {
883+
const { community } = ctx.wizard.state;
884+
let message = ctx.i18n.t('language') + ': ' + (community.language || 'en') + '\n\n';
885+
message += ctx.i18n.t('wizard_community_enter_language') + '\n\n';
886+
message += ctx.i18n.t('wizard_to_exit');
887+
await ctx.reply(message);
888+
889+
return ctx.wizard.next();
890+
} catch (error) {
891+
logger.error(error);
892+
ctx.scene.leave();
893+
}
894+
},
895+
async (ctx: CommunityContext) => {
896+
try {
897+
if (ctx.message === undefined) return ctx.scene.leave();
898+
899+
const lang = ctx.message.text.trim().toLowerCase();
900+
// Check if language is valid
901+
const validLanguages = ['en', 'es', 'fr', 'de', 'it', 'pt', 'ru', 'uk', 'ko', 'fa'];
902+
if (!validLanguages.includes(lang)) {
903+
ctx.deleteMessage();
904+
return await ctx.reply(ctx.i18n.t('wizard_community_invalid_language'));
905+
}
906+
907+
const { community } = ctx.wizard.state;
908+
community.language = lang;
909+
await community.save();
910+
await ctx.reply(ctx.i18n.t('operation_successful'));
911+
912+
return ctx.scene.leave();
913+
} catch (error) {
914+
logger.error(error);
915+
ctx.scene.leave();
916+
}
917+
}
918+
);
919+
841920
export const addEarningsInvoiceWizard = new Scenes.WizardScene(
842921
'ADD_EARNINGS_INVOICE_WIZARD_SCENE_ID',
843922
async (ctx: CommunityContext) => {

bot/ordersActions.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,25 @@ const createOrder = async (
6565
try {
6666
amount = Math.floor(amount);
6767
let isPublic = true;
68+
69+
// Use community language if community_id is provided
70+
let descriptionI18n = i18n;
71+
6872
if (community_id) {
6973
const community = await Community.findById(community_id);
7074
if(community == null)
7175
throw new Error("community is null");
7276
isPublic = community.public;
77+
78+
// Get community language for description
79+
if (community.language) {
80+
const { I18n } = require('@grammyjs/i18n');
81+
descriptionI18n = new I18n({
82+
defaultLanguageOnMissing: true,
83+
locale: community.language,
84+
directory: 'locales'
85+
}).createContext(community.language);
86+
}
7387
}
7488
const fee = await getFee(amount, community_id || '');
7589
if(process.env.MAX_FEE === undefined)
@@ -124,7 +138,7 @@ const createOrder = async (
124138
tg_order_message: tgOrderMessage,
125139
price_from_api: priceFromAPI,
126140
price_margin: priceMargin || 0,
127-
description: buildDescription(i18n, {
141+
description: buildDescription(descriptionI18n, {
128142
user,
129143
type,
130144
amount,

locales/de.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,8 @@ community_admin: |
570570
${community.fee}
571571
Earnings:
572572
${community.earnings}
573+
Language:
574+
${community.language || 'de'}
573575
npub:
574576
<code>${community.nostr_public_key || ''}</code>
575577
@@ -580,7 +582,11 @@ community_admin_help: |
580582
# commands
581583
582584
/setnpub &lt;npub&gt; - Configure Nostr community's public key.
585+
/setlanguage &lt;lang&gt; - Configure community's language for published messages.
583586
community_npub_updated: You added the community's pubkey ${npub} successfully!
587+
community_language_updated: You updated the community's language to ${language} successfully!
588+
wizard_community_enter_language: Enter the language code for your community (en, es, fr, de, it, pt, ru, uk, ko, fa)
589+
wizard_community_invalid_language: Invalid language code. Please enter one of the following - en, es, fr, de, it, pt, ru, uk, ko, fa
584590
# END modules/community
585591

586592
# START modules/orders

locales/en.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ community_admin: |
559559
${community.fee}
560560
Earnings:
561561
${community.earnings}
562+
Language:
563+
${community.language || 'en'}
562564
npub:
563565
<code>${community.nostr_public_key || ''}</code>
564566
@@ -569,7 +571,12 @@ community_admin_help: |
569571
# commands
570572
571573
/setnpub &lt;npub&gt; - Configure Nostr community's public key.
574+
/setlanguage &lt;lang&gt; - Configure community's language for published messages.
572575
community_npub_updated: You added the community's pubkey ${npub} successfully!
576+
community_language_updated: You updated the community's language to ${language} successfully!
577+
wizard_community_enter_language: Enter the language code for your community (en, es, fr, de, it, pt, ru, uk, ko, fa)
578+
wizard_community_invalid_language: Invalid language code. Please enter one of the following - en, es, fr, de, it, pt, ru, uk, ko, fa
579+
language: Language
573580
# END modules/community
574581

575582
# START modules/nostr

0 commit comments

Comments
 (0)