Search code examples
pythonutf-8discord.pygoogle-translategoogle-translation-api

Results of attempt to translate a Discord Message with Google Translate API is just a list of the letters making up the input


Edit4: Further review, it works if I send text in JP and translate it to EN. I now believe that it's returning the string as UTF-8 byte sequences. I'm now trying to figure out how to get it converted back to the actual characters.

Edit 3: Added an await asyncio.sleep(3) line and that seems to have fixed it if I use English to Spanish as it correctly translates "Hello" to "Hola" Still getting a strange line for English to Japanese though. My guess is it has something to do with non-roman characters.

Translation:translated_text: "\343\201\223\343\202\223\343\201\253\343\201\241\343\201\257"

Edit 2: I thought it might have to do with the fact that Japanese does not use the roman alphabet. Changing language to Spanish (ISO code: es) still gives an error.

Translation:translated_text: "H"  
Translation:translated_text: "mi"  
Translation:translated_text: "l"  
Translation:translated_text: "l"  
Translation:translated_text: "o"  
Translation:translated_text: "\302\240"  
Translation:translated_text: "W"  
Translation:translated_text: "o"  
Translation:translated_text: "r"  
Translation:translated_text: "l"  
Translation:translated_text: "re"  

Edit: This did not work. Still receiving same response. I might have figured out the problem. I can’t test It until I get off work though. In the API examples I noticed a line I didn’t include. So I think it might be the reason it’s returning a weird result.

for translation in response.translations:

Orignial: I've been attempting to set up an addition to my discord bot to translate messages beginning with the phrase !trans from English to Japanese using Google's Translation API. Instead of getting back a translated result, I get what appears to be a breakdown of the characters that make up the input. Thank you in advance for any help!

Initial attempt was to translate the discord message. The code for this also slices off the !trans tag at the beginning of the string.

entrans = message.content[6:]

At first I assumed that the problem was with the way the Discord message was formatted. So I attempted to isolate that problem by removing that section and simply changing the phase to be translated as "Hello".

entrans = 'Hello'

When that also didn't work, I thought it might be an issue with the translation model. So I thought maybe setting the model would help, but it still broke down my translation result by letter, with the only difference being it listed a line after each letter for the model used. In this example, where L would be located, there are just numbers listed.

translations {
  translated_text: "H"
  model: "projects/Unique Project ID/locations/global/models/general/base"
}
translations {
  translated_text: "E"
  model: "projects/Unique Project ID/locations/global/models/general/base"
}
translations {
  translated_text: "\343\203\252\343\203\203\343\203\210\343\203\253"
  model: "projects/Unique Project ID/locations/global/models/general/base"
}
translations {
  translated_text: "\343\203\252\343\203\203\343\203\210\343\203\253"
  model: "projects/Unique Project ID/locations/global/models/general/base"
}
translations {
  translated_text: "O"
  model: "projects/Unique Project ID/locations/global/models/general/base"
}

Code for my initial attempt is listed below.

import discord
import os
from google.cloud import translate_v3beta1 as translate

gclient = translate.TranslationServiceClient()
client = discord.Client()
location = 'global'
parent = gclient.location_path("My Project ID here",location)

@client.event
async def on_message(message):
    if message.content.startswith('!trans'):
        entrans = message.content[6:]
        jtranresult = gclient.translate_text(
            parent=parent,
            contents=entrans,
            mime_type='text/plain',
            source_language_code='en',
            target_language_code='ja',
        )
        print(f"Translation:{jtranresult}")

I expected the results to be "こんにちは" or something similar in Japanese.

Instead I received the below for my results.

Results:

translations {
  translated_text: "\302\240"
}
translations {
  translated_text: "H"
}
translations {
  translated_text: "e"
}
translations {
  translated_text: "l"
}
translations {
  translated_text: "l"
}
translations {
  translated_text: "o"

Solution

  • First of all, translate_text method takes contents arg as list. If you provide string as contents, then it gets separated to list.

    Second: translate_text method returns TranslateTextResponse. To get translation from it, i guess, you need to get it from TranslateTextResponse.translations

    So, i guess your code must be something like that:

    import discord
    import os
    from google.cloud import translate_v3beta1 as translate
    
    gclient = translate.TranslationServiceClient()
    client = discord.Client()
    location = 'global'
    parent = gclient.location_path("My Project ID here",location)
    
    @client.event
    async def on_message(message):
        if message.content.startswith('!trans'):
            entrans = message.content[6:]
            jtranresult = gclient.translate_text(
                parent=parent,
                contents=[entrans],
                mime_type='text/plain',
                source_language_code='en',
                target_language_code='ja'
            )
            print(f"Translation: {jtranresult.translations[0].translated_text}")
    

    Also, i would recommend to use commands extension for bot with commands. Something like that

    import os  # unused import?
    from functools import partial
    from discord.ext import commands
    from google.cloud import translate_v3beta1 as translate
    
    PROJECT_ID = ""
    
    gclient = translate.TranslationServiceClient()
    bot = commands.Bot(command_prefix="!")
    location = "global"
    parent = gclient.location_path(PROJECT_ID, location)
    
    
    @bot.command()
    async def trans(
        ctx, *, text: str
    ):  # https://discordpy.readthedocs.io/en/v1.2.3/ext/commands/commands.html#keyword-only-arguments
        """Translation command"""  # Will be used as description in !help
        jtranresult = bot.loop.run_in_executor(
            None,
            partial(
                gclient.translate_text,
                parent=parent,
                contents=[text],
                mime_type="text/plain",
                source_language_code="en",
                target_language_code="ja",
            ),
        )
        # run_in_executor will prevent bot "freezing" when translate_text func is active, since it not async
        await ctx.send(f"Translation: {jtranresult.translations[0].translated_text}")