Localization Academy

Internationalization With ChatGPT: Python Discord Bot

Transitioning from a single language to a multilingual interface can be a challenge. In this coding session, we explore whether ChatGPT can rise to the occasion. Watch as we embark on a journey to internationalize a Discord bot written in Python. Can we effectively transform our bot to cater to a global audience?

From the initial setup to the final tests, experience each step in the internationalization process with us. Whether you’re a coding enthusiast, a localization expert, or just curious about AI-powered coding, this video offers insights that can benefit all.

Can ChatGPT help you internationalize your product and your code? Do you actually even need to know anything about coding for you to make your product language agnostic? In this video, you’re going to see my coding session with ChatGPT, where we try to internationalize a simple discord bot written in Python.

We have score bots with some limited functionality. Here’s the code in light. I’m going to copy the code as it is. We also have on thick five, like this voice, memorize, can you memorize memorize this coat as I like you to make some changes to it?

Let’s start with this thing.

This is quite a comprehensive the scoreboard script. Many interesting functionalities such as periodically saves the SP data and backs it up to drive. It handles spot messages, comments reactions and leads to Coco’s XP points. Yes, in equals my comment Mike’s be it shows XP show assignment based however, there’s also a command commented out claim command which seemingly allows users to claim coined, it’s going to be an interesting feature to implement in the future. configuration file contains constants and settings for various bot functionalities. These include values like XP gain ratios for different actions, blah, blah, blah, they know that this code relies on a few extra modules and packages this gorgeous and blah, blah, blah. And also configuration file seems to be well structured and looks like it’s ready to be deployed provided that the required environment variables, like the birth token and Dr. web hook URL are set up correctly. Yes. If you want to add any fun, additional functionality, you may need to modify or extend this code base Remember to handle new functions in a way that one disrupt existing ones. I’m going to delete the column and it’s my command. So it does use it’s what is it going to say? Okay, here’s your a bit is to put the whole code na yah, yah, we are, ya know, were you the thoughts? What’s that? Skipping the middle part for Bruce? Okay, constants here. Comments start here on Mike’s Bay show. Okay. AV in these days, whatever, chat you’re with excellence, excellence. Now, the main task that I like to do is to to internationalize the bot, so that it’s language agnostic. Ik is agnostic is the right word, so that it’s language agnostic and that we can localize it easily. What will be the step by step process internationalizing your book involves a few major steps Here’s an outline of a potential plan. Identify messages to be internationalized. The first step is to look for all the text in your bots responses which need to be initialized. This includes not only the response strings, but also other user facing strings like error message. Abstract text, check all of these strings out of your bots code, replacing them with keys that map the actual text in a separate file. For example, you could replace the message in a way with a key such as get message my response can create language files. The separate files are often called Resource bundles or language files contain the actual text of the responses in various languages. simple form of this might be a JSON file, like blah, blah, blah, blah. So the strings translate your bots responses into languages language selection mechanism, implement a way to select which language to use for each user. This might be a setting that they can choose or it might be automatic based on their discord clients language sync nice, create a message fetcher function. This function will take a key and parameters as input and return the corresponding string from the current li selected input. Okay, since testing, remember internationalization is not just about translating text, date and time formats, number formats and more Can all vary by locale and consider using the library to help with these aspects in their allowance here, but also keep in mind that new features or changes to your bot will need to be internationalized as well. I think the plan is pretty good. It’s okay. So let’s see what it does. Okay, let’s start with number one. I don’t even going to I’m not even going to say what it should do. Let’s see what it does. But that further messages are going to be interesting or in refer what’s going to make what responses This includes but a direct responses to comments and messages. My sense spontaneously, error messages, and the messages you’re both sends when something goes wrong should be internationalized. So users can understand what happens. Common descriptions and usage information in your bot includes help text explaining and better and rich content. We don’t have those. Why is it think friction words your blood reacts to particular worlds? But but you have the codes, and you be specific, or art is the most perfect condition, common responses. Response responses. For example, in my EXPEED, the board responds with you have similar in leaderboard, Do I really have leaderboard, I don’t have leaderboard, why is it leader See, there’s no leaderboard. leaderboard claimed are strings that are turned as responses, for example, might be similar in leaderboard responds with a leaderboard, or messages, or server error messages in your bots code that you’d be interested in, for example, in the claim command, what the fuck getting annoyed. I thought that we were deleting the claim on descriptions and health information. If you’re both includes Why is it again doing this? Why are both doesn’t have any way to ward off? Also, we just deleted the comment. Blame all men. Why are you referring to non existing? Oh, it’s we use the code we have? The correct I should have stick to the code you’ve provided in the current version of your body have two comments help? Hello. There is no Hello, why is it hallucinating? So here’s a more tailored description for the categorization of the strings to internationalize. Hello, where do you see ello in our code? There’s no, no, it’s starting again. This is kind of a problem that I had before. I don’t know why it’s starting to do these crazy things. If the code is too long, so it doesn’t, so isn’t able to put it into the contexts or each query. I don’t know. It’s weird, but okay, let’s let’s try to use our brain. So I guess this is conclusion number one, you cannot fully trust and simply just copy paste. What changed with the Spitzer do you need to use your brain a little bit? Okay. So what I’m going to do, and because also previously try to, of course, also localize the error messages. But everything that you can see here that starts with logger, which has coat is something that’s only added to a log, which is file that’s use for let’s say, developers, or someone who was taking care of the bot. So this doesn’t need to be localized. So I think we only need to localize the things which are sent to the user, which is this one. And this one’s technically we have two strings only. If I’m not mistaken. The rest is logger, logger, logger. Logger. Logger, logger. Logger. Logger. Logger, logger logger logger. Everything is logger, I think. Right? So I’m going to just to be sure, just to be sure.

Here’s the codes.

All of the what is the two abstract texts, okay, to check texts. All of the vulgar strings don’t need to be localized us they’re just us Turley. stuff. I think we only have two messages or my XP and show commands that need to be done. block a lot. How do we do it? Yes from a codec indeed seems like the only strings to be like us are from the magazine show button. There’s a built in library called get text which is used for exactly this purpose, you will use it to translate and I want to translate also supports more complex cases like kisses like liberalisation, marking strings for translation, you need to mark all the strings that you want to be transferred. With get text. This is done using the underscore function like so translate me during translation files. Once you’ve worked with your strings, you generate a put file, which contains all the strings you’ve marked, it’s going to be done by running, I get text in your script, translate strings, use the put file to create a Pio file for each language you want to support. These files are then filled in with the translated strings, compiled translations after translating, you compile it into a MO file, which can be ready read by the get text library in your codes, loading translations in code. Finally, you load the appropriate MO file into your in your pattern code. Based on the user’s language preference, the good things library will then replace all the mark strings with their toxic versions, because you would improve the get text function and mark the strings for translation. Oh, here, your score isn’t that simple. To render as a translation file to generate pot file, you would run the PI get text commands. This is typically used from the command line like so this would generate a mighty script pot pot, you would then copy this put file for each language you want. Or for example, for French and German you would do. You don’t edit this pure fast and the translations, compiling translations with component Mo, for us loading translations into code. Finally, you load the appropriate MO file in your code based on the user’s language preference. Now the function will replace to simple return. That’s interesting. There’s a lot of stuff to do here. The first time that I tried it, it was suggesting to use a JSON file. Should I try this? I think I’ll try this. Maybe I’ll ask it to compare the two things. Previously, it was suggest that to store and translations in ujs. Do these two approaches Compare? Compare strings and Dropbox? There’s a comparison JSON file. It’s easy to manage it’s easy to read and write. There are excellent tools for managing structured data, you know, Is it understood its scalability, you might end up with a lot of strings to translate this was gonna handle the right manual editing for translation files stored in your code base. Adding a new translation or modifying an existing one means changing the file manually. Your What if your translation file is stored in your code base database? What is the database referring to PO what? What is a database? You were saying to use get texts and create Pio files. I want you to compare that with JSON files. What is it doing? Oh, ext started tooling ethics is a widely used internationalization and localization system in the open source world. It’s a standard tooling for extracting strings from source code, managing translations and creating binary EML files for use in production. Supports plurals and context get Texas built in support for handling plural forms. And this ambiguous question where context translation Commons comments from translators which can be extracted nice complexity get excited because Oracle for small projects, beautiful syntax and though all workflow can be complex, yes, integration depending on the programming language, blah, blah, blah. Jason simplicity. Jason is a straightforward and easy to understand format. It can be edited readability, wide support cons noster tooling, unlike get text, there is no strong tooling. This means you need to more money. Okay, if you’re working on small project, this is smaller, so, okay, let’s use JSON that. So going back to our the scoreboards, and the two comments, do we internationalize internationalize international internet should analyse zip, which is files is that step number three this one create language false. Yes. Okay, here we go. Why is it doing welcome current time what? internationalized your discord bot with JSON files you need to follow several steps courageous involves create a separate json file for each language you wish to support. Yes. For example, for instance, you might have en Jason for English, es Jason for Spanish, etc. The structure of a JSON file could be like this. Okay? Create a localization function, this function should take a language code and a string key and return the appropriate string from the relevant json file in JavaScript, this might look something like this. Why is it doing JavaScript? What? Buck? You are not very helpful in game gave you go off our walk in night? Why are you showing me called in chalice? I need you to work with our code. And give me step by step how to do it. I apologize. Let’s internationalize these pages and files. Why is it stealing? Welcome? Annoying? Create a localization function this function will fetch the appropriate string from the Crick. Here’s how you might do this in Python. With Lang JSON translations load. Yeah, so this is a problem. Again, that happened to me for the first time when I was doing it. See, again, it’s doing stupid things. The problem with this thing is that it’s your digital language, English, is there a problem? Localize.

Welcome to dx while calm.

Can this work? You run says that the English language is hard coded in real application in a way to determine language. Each user could allow users to submit a language to the client stored in the database. Whenever they use a colon and hope this information can wait. Again, it needs to be reminded of what it’s creating. We have this rupture, which is stored in user x p dictionary. And we add the language preference, right? Which user here? Yes, absolutely. You can add the language preference for each user. This way, whenever you want to send a message, you can look up their language preference and user experience dictionary Yes. Here’s your modify default user structure. case, I’m going to add this here. Lang which yen, which should also update the stats. So the stats look like this. This is the dictionary. So this is my I think user ID and it should add it here towards the end. Then when you want to send a message, you retreat the user’s language link. So use the language really from their response localize, localize. Usually how does localize work? The localize returns template? Well, this work? I’m not sure. Now I think I need to do it on the I think I need to do this on the I need to paste the comments again. Wait, so we load IX P. And if it’s not found, and it uses default value, right? It should be English. So do I want to run it? Let’s try to run this thing. Okay, did it modify a bit? So now we have the language English there. Okay. That’s pretty good. That’s a good start. Here are there on my hands in my coat? Can you right now I don’t have any language JSON yet, nor do I have any localize function. I only change the structure. So for each user, we can get their language preference. What do I do next? Let’s create your language files and create a function to use them. Yes. You As the steps create a new directory called translations, and want to use translations, but okay, this translations directory create a JSON file for each language you want to support. For example, why is it it’s actually using the correct thing brings for instance, if you want to support English and Spanish, you create indecent e as JSON. In each file, you store the translations of each message you want to send, for example, in JSON might look like this. And you can have your Spanish version with the same keys but translated values, then you would create a function to load these translation files and pick the correct translation for a given key. And language. Here is an example. Below translations translations are file, blah, blah, blah, is file and with JSON, localize. Score translations, is a dictionary where the keys are language codes, and the values are responding. Translations loaded from the JSON files, the localized function takes a language code a key and a number of keyword arguments, response localize userland Okay, I think it might be on something. So let’s see if it actually works. I’m going to follow it exactly as it did. So I’m going to create the folder here, which are called translations. And inside translate, translations will create and set translations or create in JSON. And how these two things I expect you have two legs be blah, blah, blah, you also have your word points, word point, blah, blah, blah, show a user name, blah, blah, blah, okay, save it, I have eat and now can you help me create slower JSON with the translations, currency into the slowik version of the language for March, so COVID, XP, avoid machine translation knowledge, as K JSON in the blah, blah, blah and use localize. Right? So let’s do that. Translation translations. And as K, J son, and I’m gonna put it there. Alright. So we have our languages. Now we go back to this think. So we are here, then you have your Spanish Okay, we have Slavic, then you would create a function to load these translation files. Pick the correct translation for a given key in language. So we need to import JSON and OS we already have that load translations. Where am I going to have to do that? I think probably after this user expe thing right? Where the user is B is used later. Rights. Yeah. Stupid. Show I think it can be what am I actually loading? I am loading the translations. Load EXPEED save X be get to looks b Get a roll. Wait, that’s just the definition doesn’t do anything. It was there. EXPEED def, def def. Def def.

A cap to try.

Wait, where does it below? P C? or load IX? P with a floor in around? Worries load excused. Here. Oh on ready, right. Does this on? On ready? Okay. I see. Shouldn’t we have now I’m thinking so if we have a load IX, B, we have load XP. Function, define at start. And then it’s used. And then it’s used in the on ready event? We have some things like this for loading the translations. Yes, loading those you have all the translations ready and loaded. Okay. That finish define. Group. What is glue? I have glue note. This, too. Didn’t they do differently before? Confusing? I apologize. For more streamlined. It’s equivalent. Okay. Hello translations. But it didn’t. So confusing. See, it forgot to initialize this thing.

So weird.

Okay, I’m going to use The first approach because this code at least I can copy as it is important or as important globe globe, okay? And let’s define it here maybe define low translations, okay? No arguments creates a global. What is this variable for translations? It’s an empty dictionary. dictionary for a language way out in little globe translations all the JSON files with open SF language goats. Eyes pet name, right. So that’s how it gets the language code and it adds its own things to that. Yes, that should work. Okay, so I have this thing. You can load translations in your own ready function load X P load

translations Sheesh.

We have loaded translations. I want to test this. Can I bring them rains? Translations? Can let’s rerun, let’s see, no. Oh, wait, wait, this is the problem with with the Unicode thing. I get this error when I ran. What I saw this before I forget what we’re doing with languages, it’s good to use a character encoding. When reading the JSON file, ensure your specified encoding is UTF. Eight. Okay. So let’s specify that. Where is its translations? File our language. Our encoding was eight is like that. Now ATF? Is it actually save as UTF? Eight is UTF eight. Yes. Cache dragon. Where are we? Oh, we’re still running. There we go. It loaded and sit here. So this is the English dictionary with Mike’s B. And then we show and then we have the Slovak? Yes. Okay. It works fine. All right. Thanks. This is important. Localization Thank you need to specify the encoding makes it lower the translations just now. How do I use wit did give it to me. I thought Papa Papa, use the localize function. I haven’t have a look close function yet. I don’t. Oh, here, I don’t have any lookers function, create translations, then you would create a function to load these translations. Okay, I did that. Now we need to define localize one localize the X language key. And key word arguments. input equals should be the lower case translations get language get E return template format, key word argument. Okay. And those are corresponding translations loaded lockwise function takes a language code a key and any number of key word nine it will fire con bot uses localize that’s exactly what we’re going to do right now. So that’s for the comments, comments comments. can do the same for the show? Okay, so here is my XP author id strain XP get total XP leveled the same thing Okay. This one is new retrieve user language retrieve user right which user language equals user XB CT X message or ID I think that should work. That should work just fine. And now try await CT X otter cents all localize Oracle eyes user lenke This is the E likes B and then we have are just going to cook with this little x p message XP reaction XP level and XP starts reward points.

Okay, it’s

so I’m just gonna call this thing or place this whole thing here. Total XP that looks fine. Right? And I said do the same for the show commands. I want to do it manually bro. Okay, let me do this. I change The Wi Fi comrades who use maclise Can you show me how to have the day? The row command? is I don’t want to use my brain. Absolutely, I can assist you with that the show command can be updated similar way. Can K if General? Gonna be before hear me at once? While we already added this, bro, where is it getting? Oh here have their ID. What? City X author? Well, this is new. I mean this shouldn’t be here. Think the order is walk Simon data maybe I’ll put it here on their ID language. See it’s inconsistent. See here it’s using gleiss Show assignment watts, but it’s not getting another issue here. This is not how the key is called.

Stupid, stupid. Since Slyke

we should adapt the localize function what? What the fuck is happening? That language? En is it doing the same thing? It’s completely different. User lag equals user x B


donate a string of fight city X message author id, we have the CT x k, this is what it looks like. Right above here.

So what does it say the Explorer seven localize your zone.

Then we’ll go to Okay, and now what is it using here? Is it an Android yelling dealing? From and To two brackets?

I assume? Yes. Oh, not sure if this is going to work, but let’s see. Let’s try to run it again. Okay, I think what I can do is I can delete the print translations. Now. Our bullets should be hopefully working. Let’s see my ex be crushed. Fuck. This is the current rent around next be it crashed. Try changing Okay. User XP cross is XP gets string of CT X. User ID. Okay, get get language is going to work now. Let’s see. Are we starting the bots? Kay, we are doing? Cool. I got the message back. All right. So ignore what you can see above here. That’s from the previous tests. So you have what’s your level two, you have six, seven. Okay. So that works. Now what we’re going to try to do is I’m going to change my preference to escape. Let’s see if it works. Okay, going back here, my expe mush should just assume to assume too quick XP. Okay. So here. Of course, you could also localize this and will point but yeah, the important thing is that we pulled the translations. That’s great. Let me see if the show Oh, man will work. Probably only to change this thing as well here. Use language close use user explicit text message or ID. S thing they should work from again. Kay, let’s go back here as the show sign on. Oh, nice. It worked. It returned our unvisited to unresponsive academic assignment yet na s. So we worked. It worked just fine. So even actually, the localize function works just fine. Most of our clients do. So localize function just basically finds the correct stream or a particular language or friend for a particular key and returns it back. I guess it works and in here and load translations, we load all the translations into the coat. So the only thing to kind of like make it work in real life is you will also need to find a way, which could be easily done through comments how people can change their language preference, but I don’t want to be doing this. So that’s it. That’s the end of the video, it took me quite some time. The conclusion as you can see, throughout the coding session, there were many times where I got confused by what GPT was giving me some of the solutions were either using different code or code that never even existed. It wasn’t using the up to date thing. And, yeah, I think it also required me to sort of be kind of like a QA or like a second partner to the code that Changi beat created, can like to review the code, because you cannot fully rely on it. So if you don’t know anything about coding, I’m not sure if you would be successful in this. But maybe if you troubleshoot it, and you always tell it, what is happening, what is the latest code, maybe it would work, maybe there are even better chatbots or something like the co pilot think where it’s specifically trained on helping you code and maybe it already is aware. Like it constantly sees your code, the things that you changed, maybe that can be more efficient. But yeah, overall, I think the step by step process that Chad GPT gave me, I think it was very useful. Although initially, it wanted to go with the get text method, which I found a little bit more complicated. Previously, when I did this, it was suggesting for me to use JSON files, which then eventually we we get to the comparison between Jason and Pio files. And I decided to go with JSON files, because it’s pretty straightforward. So yes, as you can see, this is how we separate the language strings or the strings, the parts that need to be localized into separate files, which then can be sent to translators. And they can be also a bit slash localized. And in the code, we keep it sort of neutral. Like here. Again, ignore all the logger strings, because those are just logging information for the developers, which are to be reviewed internally. So that’s why it’s English only. So yeah. I think we got this working. That’s it. Stay tuned. See you in the next video. Bye.

We’re always creating new localization content

Make sure you don’t miss anything. Join 4226 other professionals on our mailing list and be the first to get our upcoming newsletter. 

If you enjoyed that, you’ll love these…