WebRtc connection in dart:html, incomplete API? - dart

What would be the equivalent in dart of the following javascript snippet?
myPeerConnection.createOffer().then(function(offer) {
return myPeerConnection.setLocalDescription(offer);
})
The straight translation:
final offer = await myPeerConnection.createOffer();
myPeerConnection.setLocalDescription(offer);
does not compile because createOffer() eventually returns a RtcSessionDescription and setLocalDescription accepts only a Map.
And RtcSessionDescription does not have a nice way to convert to a Map in the API.
Am I missing anything? Thanks!

After trying a few things, this works in my use case (at least in Chrome):
final offer = await myPeerConnection.createOffer();
myPeerConnection.setLocalDescription({"sdp": offer.sdp, "type": offer.type ?? 'offer'});

Related

How to call a Function from a Function in Twilio Serverless?

I'm trying to see about using Twilio Serverless to replace my IVR. I would like to have some centralized functions to use within the functions.
For example, My main may be something like /MainMenu, which will have all the Twml.
but it will also need to call a function like /LogStats, which will be a function that does a REST Call to my API to collect Stats.
I'd appreciate your guidance in this. I'm also a little confused about why there's a Functions Classic, and a Functions Services. Am I to assume that Functions Classic will go away?
Thanks
Update from comments
Hi Lizzie, thanks for your response. I have it working with the zoltar example.. but when I try to use it for creating a call to a REST API, it's not consistently calling the API.. Any Ideas?
Here's what I'm talking about..
const axios = require('axios');
const log = {
ask: async function(event){
try{
const res = await axios.post('https://myid.ngrok.io/api/calllogger/lognewcall', {
CallSid: event.CallSid,
Caller: event.Caller,
App: "EmgLine",
CallerCity: event.CallerCity,
CallerState: event.CallerState
});
if(!res.ok){
throw new Error(`HTTP error! Status ${res.status}`);
}
const data = await res.Message;
return data;
} catch(err){
const errMessage = `test: ${err}`;
return errMessage;
}
}
};
module.exports = log;
Twilio developer evangelist here.
The Functions Classic are the older Functions with the older Functions UI. It still works, but Functions Services are newer and recommended to use. A Service is an application container to store all your Functions and Assets, and used to manage deployments and separate environments. You will likely create a new Service for each new project you work on.
You can use code from another Function in another Function with code like this
exports.handler = function (context, event, callback) {
// First, get the path for the Function. Note that the key of the function
// is not preceded by a "/" as is the case with Assets
const zoltarPath = Runtime.getFunctions()['zoltar'].path;
// Next, use require() to import the library
const zoltar = require(zoltarPath);
// Finally, use the module as you would any other!
console.log('The answer to your riddle is: ' + zoltar.ask());
return callback();
}
Let me know if this helps at all!

In Dart, how do I add a ">>" before the input created by stdin.readLineSync()?

I'm writing a Dart console app for the first time and I've searched the Internet everywhere and can't find the proper answer.
In Python, the function raw_input(); takes user input from stdin in a similar way to Dart's stdin.readLineSync();, however raw_input(); takes a parameter: If I do something like raw_input(">>");, the CLI does something like:
>> _
In Dart, however, I cannot find a way to do something similar with stdin.readLineSync();, it simply outputs:
_
Is there a simple way for a new Dart user to accomplish this? Thank you for your time.
This might do what you want:
import 'dart:io';
main() {
stdout.write('>> ');
var result = stdin.readLineSync();
print(result);
}
write does not automatically add a newline.
A simpler way is to use the DCli package and its ask function:
var response = ask('>>');
print(response);
The ask function provides a number of other options that help capturing data from the cli such as the functions 'confirm' and 'menu'.
https://onepub.dev/packages/dcli

Twilio functions calling other Twilio functions

My Twilio function is in danger of getting too large and unwieldy. I'd like to break it up into smaller functions, and have the 'master' function call the other functions to get data as needed.
I don't see anything in the documentation about this, and the few tests I've tried have not been successful. Is there an easy/best way to go about doing this? Thanks!
this is an example of how to include code from another function:
including function's body
exports.handler = function(context, event, callback) {
let path = Runtime.getFunctions().helper.path;
let helper = require(path);
let output = helper.output_init();
}
included function's body (the name of this function needs to be 'helper' to work on this example)
function output_init(){
let output = new Twilio.Response();
output.setStatusCode(200);
output.appendHeader('Content-Type', 'application/json');
return output;
}
module.exports ={
output_init: output_init,
};
hope this helps
there is a discussion around this topic on a Google Groups forum and the details are provided from the documentation below:
Runtime Client
https://www.twilio.com/docs/runtime/client#functions
"The Function object enables developers to compose complex applications by allowing them to include and execute code stored in multiple Functions."

Download and get HTML code from a website

I need to download HTML code from some web page. What is the best way to approach this task? As I understand there are very few working web frameworks for Rust right now and hyper is the one most people use? But after searching it's documentation I couldn't find a way. The closest I got is this
extern crate hyper;
use hyper::Client;
fn main() {
let client = Client::new();
let res = client.get("http://www.bloomberg.com/")
.send()
.unwrap();
println!("{:?}", res);
}
But it returns Response, which doesn't seem to contain any code from HTML body.
Note: this answer is outdated!
I don't have the time to update this with every hyper release. But please see my answer to a very related question: How can I download a website's content into a string?
It's a bit hidden: The Response type implements the trait Read. One method of Read is read_to_string which reads everything into the a String. That's a simple way you can get the body.
extern crate hyper;
use hyper::Client;
use std::io::Read;
fn main() {
let client = Client::new();
let mut res = client.get("http://www.bloomberg.com/")
.send()
.unwrap();
let mut body = String::new();
res.read_to_string(&mut body).expect("failed to read into string");
println!("{}", body);
}
Currently Rustdoc (the HTML documentation of Rust) is a little bit misleading because Rust beginners think that trait implementations don't add any important functionality. This is not true, so better look out for it. However, the hyper documentation could be better...

Handling an HttpRequest's body in Dart

I used to do something like this:
HttpResponse res = req.response;
String dataReceived;
await req.listen((List<int> buffer) {
dataReceived = new String.fromCharCodes(buffer);
}).asFuture();
Map data = JSON.decode(dataReceived);
When I needed UTF8 support, I modified it to:
Map data = JSON.decode(await new Utf8Codec().decodeStream(request));
Kevin Moore suggested to encode/decode like this:
https://dartpad.dartlang.org/1d229cfdc1c1fd2ab877
So I've got:
Map data;
await request.listen((List<int> buffer) {
data = JSON.fuse(UTF8).decode(buffer);
}).asFuture();
Not sure that I need the asFuture():
Map data;
await request.listen((List<int> buffer) => data = JSON.fuse(UTF8).decode(buffer));
Or do I? And this method requires that I encode it into bytes on the client side:
sendData: new JsonUtf8Encoder().convert({'model': message, 'authToken': app.authToken}))
What are the benefits of this? Isn't it more to send over the wire?
I believe Shelf and/or the new RPC lib would handle this stuff for me? Shall I move to one of those? Right now, it's all homegrown.
HttpRequest is a Stream<List<int>>. You don't want to use listen because you'll only get the first "chunk" of data.
Instead you'll want to do something like this:
import 'dart:async';
import 'dart:convert';
main() async {
var input = {'a':1, 'b':2};
var decoder = JSON.fuse(UTF8).decoder;
var json = await decoder.bind(toByteStream(input)).single;
print(json);
}
Stream<List<int>> toByteStream(json) =>
_encoder.bind(new Stream.fromIterable([json]));
final _encoder = new JsonUtf8Encoder();
https://dartpad.dartlang.org/9807d0c5ed89360c9f53
Yes as you can see on https://github.com/dart-lang/shelf/blob/master/lib/src/message.dart#L136 shelf defaults to UTF-8
I am likely biased but I would definitely recommend moving over to shelf. You have several options depending on what you prefer, like:
shelf_rpc as you mentioned. I haven't used it but likely full featured API support
shelf_bind if you simply want to bind a handler function parameter to a JSON body. This is lower level, more flexible and less prescriptive but does less. e.g.
router.post('/foo', (#RequestBody() Foo foo) => ...)
shelf_rest. Adds higher level more prescriptive API support (similar to shelf_rpc).
full frameworks like redstone, mojito etc. These do more for you but you need to buy into more
Had a chat w/ Kevin to better understand his answer, and thought it best to share my learnings as a new answer.
HttpRequest is always a Stream<List<int>> – a streamed list of integers. Those integers are bytecodes, and this is commonly referred to as a bytestream. You can be sure that no matter what API you use to send data over the wire, that it is sent as a bytestream.
The HttpRequest.request() method accepts sendData in several forms...
* If specified, `sendData` will send data in the form of a [ByteBuffer],
* [Blob], [Document], [String], or [FormData] along with the HttpRequest.
Source:
https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:html.HttpRequest#id_request
...but these are just abstractions, and ultimately your data is sent as a Stream<List<int>> bytestream.
So on the server we first set up a decoder that will decode both JSON and UTF8 (for correct char handling), and then we bind that to the HttpRequest request, which is a bytestream. I think single just serves to ensure we throw an exception if we received more than one data event. Here's all the code we need to interpret an HttpRequest:
import 'dart:async';
import 'dart:convert';
static handleRequest(HttpRequest request) async {
var decoder = JSON.fuse(UTF8).decoder;
var data = await decoder.bind(request).single;
print('The decoded data received is:\n\n$data');
}

Resources