How to open url in messaging extension? - botframework

I have updated my bot builder package from 4.6.0 to 4.9.0 i.e., the latest version.
We have handleTeamsMessagingExtensionFetchTask method which returns a promise. The return type is changed in version 4.9.0. The return type right now is the Promise of MessagingExtensionActionResponse.
With this return type, there is no way indicated in the documentation regarding opening a URL.
I have added the return type I was using in version 4.6.0 and that was working fine but it seems like there's no way in current update for performing such operations.
return await {
task: {
type: 'continue', value: {
width: 450,
height: 600,
title: 'Abc'
url: '********',
fallbackUrl: '*******'
}
}
} as MessagingExtensionActionResponse;

Initiate a message extension with open action URL. Please find the below piece of code
protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
var response = new MessagingExtensionActionResponse()
{
Task = new TaskModuleContinueResponse()
{
Value = new TaskModuleTaskInfo()
{
Height = 720,
Width = 900,
Title = "Testing ME with URL,
Url = "https://1f0bd229.ngrok.io/myPage"
},
},
};
return response;
}
Let me know if this doesn't help you out

Related

Why am I getting a 400 Bad request when calling Plaid's linkTokenCreate function?

I am attempting to set up Plaid in my app, and am following the Quickstart guide for Node.js and Express. When I call the client.linkTokenCreate function I am getting a status 400 Bad Request response. I believe my code exactly matches the quickstart, and I am using sandbox mode, so I am unsure where I am going wrong.
const { Configuration, PlaidApi, PlaidEnvironments, Products, CountryCode } = require("plaid");
const configuration = new Configuration({
basePath: PlaidEnvironments[process.env.PLAID_ENV],
baseOptions: {
headers: {
"PLAID-CLIENT-ID": process.env.PLAID_CLIENT_ID,
"PLAID-SECRET": process.env.PLAID_SECRET,
},
},
});
console.log(configuration)
const client = new PlaidApi(configuration);
router.post("/create_link_token", async (req, res) => {
// Get the client_user_id by searching for the current user
// const user = await User.find(...);
// const clientUserId = user.id;
const request = {
user: {
// This should correspond to a unique id for the current user.
client_user_id: "test123",
},
client_name: "Name Of App",
products: [Products.Auth],
language: "en",
webhook: 'https://app.com',
country_codes: [CountryCode.Us],
};
try {
console.log("request",process.env.PLAID_CLIENT_ID,process.env.PLAID_SECRET)
const createTokenResponse = await client.linkTokenCreate(request);
console.log("createTokenResponse", createTokenResponse);
res.status(200).json(createTokenResponse);
} catch (error) {
console.log("error", error.message)
res.send(error.message)
}
});

Is it possible to get the raw body on a custom made endpoint on strapi?

I'm building a custom endpoint on Strapi. For this endpoint, I need to have the raw body content. Is it possible to obtain it from the ctx variable?
stripe : async(ctx) => {
// Handle the event
const sig = ctx.request.headers['stripe-signature']
let event = null
try {
// ctx.request.body needs to be the original raw body
event = stripe.webhooks.constructEvent(ctx.request.body,sig, endpointSecret)
}catch (e) {
ctx.badRequest(null,e)
return
}
Create a middleware (/config/middleware.js) and update it to the following
module.exports = {
settings: {
cors: {
enabled: true,
},
parser: {
enabled: true,
multipart: true,
includeUnparsed: true,
},
},
};
In the controller (/api/<model>/controllers/<model>.js):
const unparsed = require("koa-body/unparsed.js");
const unparsedBody = ctx.request.body[unparsed];
The official koa-bodyparser package actually does this out of the box. See: https://github.com/koajs/bodyparser#raw-body
Here is a small example:
import Koa from 'koa';
import KoaRouter from '#koa/router';
import koaBodyParser from 'koa-bodyparser';
const app = new Koa();
const router = new KoaRouter();
const stripeCheckout = (ctx, next) => {
const sig = ctx.request.header['stripe-signature'];
let event;
if (!process.env.STRIPE_ENDPOINT_SECRET) {
throw new Error('Missing Stripe endpoint secret.');
}
try {
event = stripe.webhooks.constructEvent(
ctx.request.rawBody,
sig,
endpointSecret: process.env.STRIPE_ENDPOINT_SECRET
);
} catch (err) {
logger('error', err);
ctx.status = 400;
ctx.body = `Webhook Error: ${err.message}`;
return next();
}
// ... do something with the event
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
// ... do something with the checkout session
}
// return a response to acknowledge receipt of the event
ctx.status = 200;
ctx.body = { received: true };
return next();
};
// POST
router.post('/stripe-checkout', stripeCheckout);
app.use(koaBodyParser());
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(port, () => {
logger('log', `✅ Done! Server is listening on http://localhost:${port}`);
});
I'm not sure to understand your needs.
ctx.request.body contains the original body of your request.
After that if you want to send event as response body you can do this like that.
ctx.body = event;
And a warning in your code. You wrote define a const for event and you assign event withe the result of your strapi webhook. You have to define a let variable.
It actually works by switching on "includingUnparsed" in the request environment configuration (config/environments/development/request.json -> parser.includedUnparsed: true).
You can access the unparsed body using the koa-body built-in feature for that:
Some applications require crytopgraphic verification of request bodies, for example webhooks from slack or stripe. The unparsed body can be accessed if includeUnparsed is true in koa-body's options. When enabled, import the symbol for accessing the request body from unparsed = require('koa-body/unparsed.js'), or define your own accessor using unparsed = Symbol.for('unparsedBody'). Then the unparsed body is available using ctx.request.body[unparsed].
koa-body docs

Use progress bar dialog in async task using Future in Flutter

I want to create common class for execute API. Now i needed to add progress dialog while executing task and after complete task dialog should be dismiss.I google lot but not get appropriate solution So help me to achieve it.
For Http Client i used dio plugin.
Please help me for adding progress dialog in this class so when i create request using this class it added progress dialog while executing task. i create this type of class in java but now i want to add it in flutter.
HttpRequest.dart
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
class HttpRequest {
void post(BuildContext context,String url, dynamic data, HttpListener listener) {
Dio dio = new Dio();
dio.post(url, data: data)
.then((Response<dynamic> response) {
if (response.statusCode == 200) {
listener.onSuccess(response.data);
} else {
listener.onError("Error");
}
})
.catchError((Exception error) {
listener.onError(error.toString());
});
}
}
abstract class HttpListener {
void onSuccess(dynamic result);
void onError(String error);
}
It's better to show progressbar in widgets, not in common classes.
Use below example (using http package):
class HttpRequest {
final JsonDecoder _decoder = new JsonDecoder();
Future post(String url, dynamic data) async {
http.Response response = await http.post(url,body: data);
if(response.statusCode < 200 || response.statusCode > 300){
throw new Exception('Faild');
} else {
return _decoder.convert(response.body);
}
}
}
The button that calls post method:
child: MaterialButton(onPressed: () async {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}));
HttpRequest _util = new HttpRequest();
try{
var res = await _util.post('someurl',_data);
} catch(Exception) {
//Handle Exception
} finally {
Navigator.pop(context);
}
});
I made a public package, future_progress_dialog, which is the opposite concept of package.
You wanted to put progress dialog in the task. But I tried the opposite way, putting Future task into the dialog.
https://pub.dev/packages/future_progress_dialog
With this package you can make a progress dialog like this.
var result = await showDialog(
context: context,
child: FutureProgressDialog(future, 'Loading...'));
I hope this would be helpful.
It is better to do it in fully async mode
onPressed: () async {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}));
authenticate().then((value) {
Navigator.pop(context);
Navigator.push(context, MaterialPageRoute(builder: (context) => HomePage()));
}).onError((error, stackTrace) {
Navigator.pop(context);
_showErrorToast(context);
});
},

ReplyToId' cannot be null

This exception is continuously throwing. This started since i updated botframework to 3.5.3.
Code :
MessagesController :
await Conversation.SendAsync(activity, () => new DefaultDialog());
Than in my DefaultDialog :
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
var msg = await argument;
await Helper.CallMenu(context, msg);
In CallMenu function :
internal static async Task CallMenu(IDialogContext context, IMessageActivity msg)
{
await MenuFirstPart(context, msg);
In MenuFirstPart function :
internal static async Task MenuFirstPart(IDialogContext context, IMessageActivity msg)
{
await context.PostAsync("I can assist you with : ");
msg.AttachmentLayout = AttachmentLayoutTypes.Carousel;
msg.Attachments = new List<Attachment>();
ThumbnailCard thumbnailCard = new ThumbnailCard()
{
Buttons = new List<CardAction>
{
new CardAction ()
{
Value = "Method_News",
Type = "postBack",
Title = "News"
},
new CardAction()
{
Value = "Method_About",
Type = "postBack",
Title = "About"
},
new CardAction ()
{
Value = "Method_Help",
Type = "postBack",
Title = "Help"
},
},
};
msg.Attachments.Add(thumbnailCard.ToAttachment());
await context.PostAsync(msg);
}
Exception is thrown when context is trying to post msg.
Any help ? Or how to downgrade my bot to 3.5.0. This worked fine there ...
You are using the incoming message (msg) and sending that back.
You need to create a new message instead. Use the following:
var reply = context.MakeMessage();

redirect a request with firefox addon

Currently I use addon sdk to develop a firefox extension,which can redirect some request without loading them.
For example, a page refer a.js (maybe have something like this <script src='example.com/a.js'>),
then, I want to redirect this request to example2.com/b.js
Now,with nsIContentPolicy I can block example.com/a.js,
But I don't know how to load example2.com/b.js at the time when a.js is blocked.
my codes now look like this:
const { Cc, Ci } = require("chrome");
const xpcom = require("sdk/platform/xpcom");
const { Class } = require("sdk/core/heritage");
exports.gcleaner = Class({
extends: xpcom.Unknown,
interfaces: ["nsIContentPolicy"],
shouldLoad: function (contType, contLoc, reqOrig, ctx, typeGuess, extra) {
//https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentPolicy#shouldLoad()
if (contType === 2) //2 means js
{
var blockReg = new RegExp('example.com/a.js');
if (contLoc['spec'].match(blockReg))
{
return Ci.nsIContentPolicy.REJECT;
};
};
return Ci.nsIContentPolicy.ACCEPT;
},
shouldProcess: function (contType, contLoc, reqOrig, ctx, mimeType, extra) {
return Ci.nsIContentPolicy.ACCEPT;
}
});
let factory = xpcom.Factory({
Component: exports.gcleaner,
description: "hello world",
contract: "#liujiacai.net/gcleaner"
});
var catman = Cc["#mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
catman.addCategoryEntry("content-policy", "speeding.gcleaner", factory.contract, false, true);
Thanks!
I have a sdk module which does this here
https://github.com/jetpack-labs/pathfinder/blob/master/lib/redirect.js

Resources