0

I'm working on a telegram bot project and I need to identify the type of JSON file I receive.

For example, a message would have :

{
    "update_id": 12345,
    "message": {
        "message_id": 123,
        "from": {
            "id": 123456,
            "is_bot": false,
            "first_name": "John",
            "last_name": "Tan",
            "username": "John123",
            "language_code": "en-SG"
        },
        "chat": {
            "id": 123456,
            "first_name": "John",
            "last_name": "Tan",
            "username": "John123",
            "type": "private"
        },
        "date": 1533567761,
        "text": "/start",
        "entities": [
            {
                "offset": 0,
                "length": 6,
                "type": "bot_command"
            }
        ]
    }
}

From this I know that message.message_id exists. In this case:

if (e.postData.contents.message.message_id) {
    // would run fine
}

However, other types of JSON will not have the message object. Other sources from recommended this function

function isMsg(fn) {
    try {
        fn;
        return true;
    } catch(e) {
        return false;
    }
}

However, it seems that Google Apps Script will throw a TypeError before I can even run this function. I ran it like this:

if (ifMsg(e.postData.contents.message.message_id)) {
    // exception
}

{
  "message": "Cannot read property \"message_id\" from undefined.",
  "name": "TypeError"
}

Does anyone have other workarounds?


Edit: My question has been answered below by T.J. Crowder. The idea is that a "guard" is required in case higher level objects are also missing. In order to prevent the typeError: Cannot read "something" from undefined, use:

if(level1 && level1.level2 && level1.level2.level3){
    //should run fine
}

In my case, this worked for me:

if(contents && contents.message && contents.message.message_id){
    //runs fine
}

This works in my case because contents always exist. I found that it solved my issue.

tehhowch
  • 9,645
  • 4
  • 24
  • 42
lightlce
  • 1
  • 3
  • We can't say why you get that TypeError because you don't show how you're calling your `isMsg` function. We can, however, surmise that your code uses `message.message_id` in the statements executed prior to calling it. – tehhowch Aug 10 '18 at 19:51
  • I use it like this: if (ifMsg(e.postData.contents.message.message_id)) { // typeError } – lightlce Aug 12 '18 at 03:11

1 Answers1

1

You'd use a guard, like this:

if (e.postData.contents.message && e.postData.contents.message.message_id) {

See also this question's answers; that questioner wasn't happy with doing that kind of guard.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • This could possibly be what I am looking for. Let me try this soon. Thank you in advance – lightlce Aug 12 '18 at 03:16
  • I've tried this. It's still giving me the error. Is it possible that GAS doesn't have support for such JSON functions? – lightlce Aug 13 '18 at 09:40
  • @Aaron - No, GAS is roughly ES3 plus a bit, and this was fine in ES3. You may need even more of a guard: `if (e && e.postData && e.postData.contents && e.postData.contents.message && e.postData.message.message_id) {` – T.J. Crowder Aug 13 '18 at 09:58
  • Yes, I think you are right. It seems to be the case! I have figured this out with your help. Thank you. – lightlce Aug 20 '18 at 01:39