HTTP Integration with Perl

Hi there. Having a heckuva time trying to integrate TTN POST with perl on a server. I got some instant gratification with
$ttn_post = file(‘php://input’)
on PHP, but no luck (so far) with perl. I see you managed this OK. Mind me asking how?
Thanks.
Dave

You are trying to accept an HTTP Integration message.

The original post is about sending a downlink message.

Perl was my first love but I’ve left it behind, it has it’s own little foibles and its not got the wide spread use of PHP.

So why do you have to do it in Perl?

Any web server with Perl on it (almost all) is likely to have Python on it too. Python is good for MQTT.

Which TTN are you trying this on?

Thanks Nick,
The OP in passing mentioned that (for him at least) “the handling (CGI/PERL) of the uplink data was no problem”. That sounded encouraging as I have been banging my head on this one for a couple of days. I’ve tried stuff like …
$gotit = binmode STDIN, ‘:raw’
$gotit = CGI->new()
read(STDIN, $gotit, $ENV{CONTENT_LENGTH})
… etc, etc
but haven’t seen much sign of life (except some crazy stuff from binmode). Needless to say I’ve been flailing away at this and obviously not a pro. But I have some 20-year-old perl code I wrote that’s maybe not dead yet.
Might be just one input statement away from new life!
(running perl in the cgi-bin with apache on a centos remote server. TTN is usa_west(?))
Thanks again,
Dave

I’m beginning to suspect my super power is searching …

From the CGI module’s docs,

If POSTed data is not of type application/x-www-form-urlencoded or multipart/form-data, then the POSTed data will not be processed, but instead be returned as-is in a parameter named POSTDATA. To retrieve it, use code like this:

my $data = $query->param('POSTDATA');

I think this is a direct analog to file(‘php://input’) which is exactly what I use in my PHP scripts for TTN

As Houdini might have said “I’ve been tied up lately” Anyway just back to report 100% success with the perl integration. I had tried the POSTDATA statement but somehow messed it up and went down a few other dead ends. Very simple when you know how! And all my existing perl code (formerly using websockets is now perfectly happy with ttn - both uplink & downlink)

For any perl mongers interested …

Uplink …

my $q = CGI->new;
my $data = $q->param( ‘POSTDATA’ );

These also work …
read(STDIN, $data, $ENV{‘CONTENT_LENGTH’}); # don’t use GGI
my $data = $q->query_string; # prefaced w/ POSTDATA=, in a GET format

my $json = decode_json($data);

my $gotit = $json->{‘payload_fields’}{‘myTestValue’};
my $downlink_url = $json->{‘downlink_url’};
etc …

Downlink (text to base64) …

eg. Hello World → SGVsbG8gV29ybGQ= → ttn converts to ascii → 48 65 6C 6C 6F 20 57 6F 72 6C 64 → LoRa-ESP32/Arduino converts ascii to text w/ (char) → Hello World

my $dlmessage = "Hello World";
my $payload = encode_base64($dlmessage);
# encode_base64() adds a newline to the data when it encodes). Here we chop it ...
chop($payload);

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(POST => 'https://integrations.thethingsnetwork.org/ttn-xxxxx/api/v2/down/my-app-id/my-process-id?key=ttn-account-v2.xxxxxxxxxxxxxxxxxxxxx');
$req->content_type('application/json');
$req->content('{"dev_id": "my-dev-id", "port": 1, "confirmed": false, "payload_raw": "' . $payload . '"}');
my $res = $ua->request($req);

# Check the outcome of the response w/ tail -f log.txt
open my $FH, '>>', 'log.txt';
if ($res->is_success) {
  print $FH "request OK\n" . $res->content;
} else {
  print $FH "request FAIL\n" . $res->status_line, "n";
}
close $FH;

Keep up the power-searching …
Cheers

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.