Scheduled chart report via Telegram Bot API and Quickchart API

What's better than an API service? Well, two of them united

Lately I've playing with the Quickchart API. It's a Free and Open Source API for Chart.js
In general, you can create URLs that will render as an image (or even a PDF) on your browser and since the sendPhoto method from Telegram Bot API can receive a URL String for the image, I managed to make them work together.
Test the Quickchart API with this URL: https://quickchart.io/chart?c={type:%27bar%27,data:{labels:[%27You%27,%27Like%27,%27It?%27],%20datas...

Since this is a kinda advance topic and some people here is already using it I won't enter into too much detail

This will be a tip and not a step-by-step (although I would make a guided tutorial if you want)

Tip #1: Don't be afraid of JSON.

This will start with the basic config of the Telegram Bot API. If you need the basics, please follow this info from Telegram's docs

You could be tempted to use just the URL Query String but I advice you to edit the code as JSON body because for long formulas (specially if we have another URL Query like Quickchart inside of it) you will need the space to edit this with comfort.

So make sure you have a config like this one:

SkrOYC_0-1644681381157.png

Basically:
Preset: Custom
Url: https://api.telegram.org/botTOKEN/METHOD_NAME
HTTP Verb: Post
HTTP Content Type: JSON
Body: The JSON Code (I'll explain it at the end of this post)

Show More
{
"chat_id":YourChatOrChannelID,
"photo":"<<CONCATENATE("https://quickchart.io/chart?c=",
,ENCODEURL(CONCATENATE("
{
    type:'bar',
    data:{
        labels:['You','Like','It?'],
        datasets:[{label:'SkrOYC',data:[100,50,100]}]
    }
}
")))>>",
"parse_mode":"MarkdownV2"
}

Tip #2: Play with it.

This step is unnecesary for some but it's quite frustating when things don't work. We need to remember that this is an advance topic and even the small victories are exactly that, enjoy the process, play with it.

Tip #3: Understand the strings.

You will be dealing with a lot of <<CONCATENATE()>> formulas and you need to have in mind how the data is going to be presented once these formulas are computed. For example, don't forget that a list is just a string with a separator that AppSheet can understand as list. So a list of this kind LIST("Test1", "Test2", "Test3") will render as this string Test1 , Test2 , Test3. In summary, think about the result before hand.

Tip #4: Don't forget the Apostrophe

It's quite frustating to work with JSON code on the Body of a "Call a webhook" Task. There is no clear indication of what's going on when there is a problem. For example, if you forget " or ' the error will be that the parentheses don't match, which doesn't make sense if the parentheses are right.

Make sure to use the apostrophe where is needed and, if you need to add it to a text inside an expression, add a space after it.
As an example this first one won't work <<CONCATENATE("Test", " text'")>> while this one will <<CONCATENATE("Test", " text' ")>>

Tip #5: Bots respect security filters

This is the last one and applies to every bot made on AppSheet. If you have security filters, make sure the account that holds the app has access to the info since Bots run on server as the App Owner. If your security filters are based on UserSettings() you will need to Bypass security filters on your process' config and change your expressions to get the data the way you wan't it because, AFAIK, there are no UserSettings on server. @Steve could confirm that?

The JSON config to merge Telegram and Quickchart

This is quite easy once you understand what Telegram needs. At the beginning I wrote about the sendPhoto method. This expects at least the chat_id and photo parameters.

So the most basic JSON will be something like this:

 

{
"chat_id":YourChatOrChannelID,
"photo":"<<CONCATENATE("https://quickchart.io/chart?c=",
,ENCODEURL(CONCATENATE("
{
    type:'bar',
    data:{
        labels:['You','Like','It?'],
        datasets:[{label:'SkrOYC',data:[100,50,100]}]
    }
}
")))>>",
"parse_mode":"MarkdownV2"
}

 

"chat_id" is defined by a number or a channel username or supergroup. Refer to the Telegram Bot API docs to understand this

"photo" is where you need a URL string that will reach the Bot API. You can push a public URL like this one: https://www.appsheet.com/Content/img/heroimg/desktop_screen.png

Or... you guest it, make a URL Query string from Quickchart or others

To make sure the quickchart URL is right, you just need to ENCODEURL() the JSON body, that's it.

So, on the code above, the parameters for the Telegram Bot are not encoded because Telegram expects a JSON body, but it's not the same for the quickchart eventhough it's JSON but Telegram needs it as string. Hope you get it.

You will notice that there is a CONCATENATE() just after the ENCODEURL(). It's not needed on this example but you will need that if you want to add your data dinamically to the Quickchart. This is more of a Quickchart thing and, as I said before, there are some clever members here that have been working with it like @Kirk_Masden @Koichi_Tsuji @MultiTech and others. But, for educational purpose, to make the same thing but with dinamyc data, you will need something like this:

 

{
"chat_id":YourChatOrChannelID,
"photo":"<<CONCATENATE("https://quickchart.io/chart?c=",
,ENCODEURL(CONCATENATE("
{
    type:'bar',
    data:{
        labels:[ ' ", SUBSTITUTE(LIST("You", "Like", "It?"), " , ", "',' "), "],
        datasets:[{label:'SkrOYC',data:[", LIST(100, 50, 100), "]}]
    }
}
")))>>",
"parse_mode":"MarkdownV2"
}

 

An explanation of the expressions:

 

SUBSTITUTE(
  LIST(
    "You", "Like", "It?"
  ), // I used LIST() as an example but labels just need to be a list of text
  " , ", // Remember how it's represented. The data is "You , Like , It?"
  "',' " // To make it readable from the JSON perspective, you need to change the " , " to "',' " so it'll end as "You' ,'Like' ,'It' "
)

 

Also, since the end result is You' ,'Like' ,'It' we need to add the pending apostrophe before the SUBSTITUTE() expression, noticed the one on labels: [ ' "

The LIST() with numbers is even easier, you don't need to wrap it on apostrophes. Also JSON don't care (AFAIK) about spaces, so even if the result of the LIST() is 100 , 50 , 100 instead of 100,50,100 of the first code without expressions, it won't matter.

Well, that's it. Hope you liked the tips and if you have any questions, ask here for sure. My knowledge of JSON is on it's infancy, but I know that with the help of you and some searching skills we will be all benefiting from this awesome APIs

PS: If you are one of those folks that don't want to pay any licence, Telegram Bot API is an awesome way to send notifications to whoever you want

PS2: TinyMCE is TERRIBLE. It took all of my <code> tags, Markdown is way better

SkrOYC_0-1644685000528.png

 

11 5 1,767
5 REPLIES 5

Hi, it is a big guide, thanks you so much. 

One question: Could be posible add a file (log.pdf) from a cell behind json in telegram message?

If you mean to send a file that was uploaded previously on a File column of your app, you can send it through Telegram Bot API.

Instead of the sendPhoto, you would use the sendDocument method.

AppSheet will make the public URL authomatically for you if you are referencing a File column type.

What I'm not sure is if you can send more than one via just one task, but it's not hard to just make more tasks as files you need.
PS: You can even send the Quickchart chart as a PDF, there is a Format option, and you should also change from sendPhoto to sendDocument

Thanks!  I'm interested but having a little trouble understanding JSON, as I have never used it before.  Here's the usage of QuickChart that has become an important part of my app:

https://www.googlecloudcommunity.com/gc/Tips-Tricks/Using-QuickChart-in-your-apps/m-p/255219/highlig...

Unfortunately, the URL my app produces now is quite long and that causes a performance issue I have described in this link.  I wonder if putting my QuickChart URL inside of JSON as you indicated would improve performance or made the URL shorted.

Hi @Kirk_Masden ! Glad you liked it.

I think your use case is on a Image column type, so this JSON thing wouldn't apply.

I mean, you could have something like this on the AppFormula and it should work:

CONCATENATE(
  "https://quickchart.io/chart?c=",
  ENCODEURL(CONCATENATE("
  {
      type:'bar',
      data:{
          labels:[ ' ", SUBSTITUTE(LIST("You", "Like", "It?"), " , ", "',' "), "],
          datasets:[{label:'SkrOYC',data:[", LIST(100, 50, 100), "]}]
      }
  }
  "
)))

But it won't be more efficient, just easier to read and write.

I wouldn't use this on Image column for the moment knowing it's not as fast but for reports is awesome (You can even add an image from quickchart on a pdf report made through AppSheet)

Thanks for taking the time to explain this to me.  ๐Ÿ˜…

Top Labels in this Space