Typings for braintree.dropin v3 typings for angular - braintree

I'm integrating Braintree Drop-in v3 into an angular app with package
npm i -save braintree-web-drop-in.
Then I found package #types/braintree-web I was following the example mentioned here however it doesn't seem to contain support for Drop-in functionality. Clearly this is not the right package.
braintree.dropin.create({
authorization: environment.braintreeKey,
selector: '#dropin-container'
}, function (err, dropinInstance) {
if (err) {
// Handle any errors that might've occurred when creating Drop-in
console.error(err);
return;
}
submitButton.addEventListener('click', function () {
dropinInstance.requestPaymentMethod(function (err, payload) {
if (err) {
// Handle errors in requesting payment method
}
// Send payload.nonce to your server
});
});
});
I have import statement
import * as braintree from "#types/braintree-web";
Then braintree gets recognized as a global namespace, however braintree.dropin is still causing me problems.
The Typescript compiler is complaining about dropin object:
Property 'dropin' does not exist on type 'typeof braintree'.
Question:
Is there some easy way to tell typescript it's all fine and roll with it? Or do I have to provide typings myself? Or do they exist somewhere already? Or it would be better to use braintree-web-package?

I solved it by using import * as dropin from 'braintree-web-drop-in'; Its possible because I have braintree module installed in node_modules
Its clearly the Typescript basics, but nerveless something I didn't knew about.
Since this question is about braintree drop in UI, here is my code combined with Typescript and angular 2. Javascript treats this differently than Typescript, so you shouldn't use function keyword inside Typescript.
braintreeIsReady: boolean;
dropIninstance: any;
ngOnInit() {
dropin.create({
authorization: environment.braintreeKey,
selector: '#dropin-container'
}, (err, dropinInstance) => {
if (err) {
// Handle any errors that might've occurred when creating Drop-in
console.error(err);
return;
}
this.dropIninstance = dropinInstance;
this.braintreeIsReady = true;
});
}
pay() {
this.dropIninstance.requestPaymentMethod((err, payload) => {
if (err) {
// deal with error
}
else {
//send nonce to the server
}
});
}

Related

Make outbound Teams PSTN call - Azure Communication Services Teams Interoperability

I try to implement a PSTN call feature using Azure Communication Services Teams Interoperability referring this sample code and use case:
https://github.com/Azure-Samples/communication-services-javascript-quickstarts/tree/main/add-1-on-1-cte-video-calling
https://learn.microsoft.com/en-us/azure/communication-services/concepts/interop/custom-teams-endpoint-use-cases#use-case-1-make-outbound-teams-pstn-call
I added the following code to the sample, but I got an error.
startPSTNButton.addEventListener('click',async () => {
try {
console.log('PSTN IN');
const pstnCallee = { phoneNumber: '+81311112222' }
const oneToOneCall = teamsCallAgent.startCall([pstnCallee], { threadId: '00000000-0000-0000-0000-000000000000' });
console.log('Call out');
// Subscribe to the call's properties and events.
subscribeToCall(oneToOneCall);
} catch (error) {
console.error(error);
}
});
Error:
CallingCommunicationError: Starting a one to one with thread ID is invalid.
at TeamsCallAgentImpl.startCall (sdk.bundle.js:183:140138)
at W.value (sdk.bundle.js:161:2267)
at HTMLButtonElement. (client.js:311:1) (anonymous) # client.js:317
Is threadId: '00000000-0000-0000-0000-000000000000' correct?
How to fix the error?
I found it out, and threadId is not required.
https://github.com/Azure/Communication/blob/master/releasenotes/acs-javascript-calling-library-release-notes.md#170-beta1-2022-08-01
const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
const oneToOneCall = teamsCallAgent.startCall(phoneCallee );
I try this, and it works fine.

In Webpack's dev server, how can I use a fallback on proxy error?

I have a Vue.JS project where a customization css is served by the backend. This can be configured using devServer.proxy.
When the backend doesn't have a custom css to serve (reutrns 404), is there a way to fallback to serving a static file ?
I tried:
devServer: {
proxy: {
'^/custom.css$': {
target: backend,
onError(err, req, res, target) { res.end(static_css) /* never called */ }
}
}
}
But onError is not called, so I may have misunderstood the doc but don't see any way to implement a fallback. Is is at all possible ?
I know I can implement this at some other level (e.g. in the browser or the backend), but this question is specifically about proxy fallback in webpack dev server.
Apparently there is a before option which allows to install our own handlers. It's not documentend but I'm not using the latest webpack. I guess it's setupMiddlewares now.
The before works like so for my specific need, but it's very flexible:
const http = require('http');
/* ... */
devServer: {
before(app) {
app.use(function(req, res, next) {
if(req.url == '/custom.css') {
http.get(backend + '/custom.css', upstream => {
if(upstream.statusCode != 200) next();
else upstream.pipe(res);
}).on('error', next).on('timeout', next);
} else next();
})
}
}
The newer setupMiddlewares is documented here.
Apparently there's also onBeforeSetupMiddleware which is deprecated on latest but unavailable on my version so I guess it's usable for versions in between.
I didn't find a lot of ressources on advanced webpack dev server use-cases other than looking at the code, so I hope this helps.

How can I get socket.io to work with deno?

My aim is to get socket.io to work with deno. Deno does have a standard library for web sockets, but that does not have a fail-over.
I think it is possible to use the UNPKG service to use an NPM package in you deno program, but I seem to get the syntax wrong for importing socket.io:
import { serve } from "https://deno.land/std/http/server.ts";
import {Socket} from "https://unpkg.com/browse/socket.io#3.0.1/dist/index.d.ts";
new Worker(new URL("worker.js", import.meta.url).href, { type: "module" });
const server = serve({ port: 3001 });
const app = new Application();
const io = Socket(3001);
// serve index page
if (req.url === "/") {
req.respond({
status: 200,
body: await Deno.open("./public/index.html"),
});
}
io.on("connection", (socket) => {
// either with send()
socket.send("Hello!");
// or with emit() and custom event names
socket.emit("greetings", "Hey!", { "ms": "jane" }, Buffer.from([4, 3, 3, 1]));
// handle the event sent with socket.send()
socket.on("message", (data) => {
console.log(data);
});
// handle the event sent with socket.emit()
socket.on("salutations", (elem1, elem2, elem3) => {
console.log(elem1, elem2, elem3);
});
});
I get the following error:
error: An unsupported media type was attempted to be imported as a module.
Specifier: https://unpkg.com/browse/socket.io#3.0.1/dist/index.d.ts
MediaType: Unknown
It fails because you are importing a .d.ts file, which is a declaration file and essentially you can't run any code from - it's purely to support types.
Instead you should replace index.d.ts with index.js
Try this:
import Socket from 'https://cdn.esm.sh/v9/socket.io#3.0.3/esnext/socket.io.js';
As #Indecisive said, you are importing a .d.ts file.
You can use #Marcos Casagrande: https://stackoverflow.com/a/61821141/6250402 (remember install socket.io module with npm)
Or use https://deno.land/std#0.79.0/ws/mod.ts

Is there a way to tell if your app is running in Microsoft Teams

I have a web app that needs to execute specific code if it is running in Microsoft Teams, however I haven't yet figured out if there is any way to tell if your app is running in teams. Any ideas or insight?
edit:
for anyone wondering we ended up using a combination of the two answers below, on app start it will check the url of the app to see if it contains "/teams". The teams app is told specifically to point to {app_name}/teams, if this case is true it will run the following code block:
import * as microsoftTeams from '#microsoft/teams-js';
if (window.location.pathname.includes('teams')) {
microsoftTeams.initialize(() => {
microsoftTeams.getContext(context => {
store.dispatch(teamsDetected(context.hostClientType!));
try {
microsoftTeams.settings.registerOnSaveHandler(saveEvent => {
microsoftTeams.settings.setSettings({
websiteUrl: window.location.href,
contentUrl: `${window.location.href}&teams`,
entityId: context.entityId,
suggestedDisplayName: document.title
});
saveEvent.notifySuccess();
});
microsoftTeams.settings.setValidityState(true);
} catch (err) {
console.error('failed to set teams settings')
}
});
});
}
As you have probably experienced, a call to microsoftTeams.getContext(...) never returns if you are not in Teams.
So I have a flag that I monitor with a setInterval and if this._teamsContext is truthy, and has sane values; and only if if has this._hasAttemptedConnection
It is a bit of a round-a-bout way.
Another mechanism I implemented a little later was passing in a flag with the URL entrypoint (in our case: this is a Teams Tab) https://<oururl>?context=teams and only using the Teams codepath when in Teams.
I have seen requests in the Microsoft Teams .js github to return a failure from the microsoftTeams.getContext(...) refer: is there any API to detect running in Teams or not?
Prior to the flag, I had some Typescript code that looks like
WireTeams(): Promise<boolean> {
this._hasAttemptedConnection = false
return new Promise<boolean>((resolve, reject) => {
microsoftTeams.initialize()
microsoftTeams.getContext((context) => {
if (context === null || context === undefined) {
resolve(false)
}
this._teamsContext = context
})
})
this._hasAttemptedConnection = true
}
As of 2022, Microsoft released version 2.0 of teams-js library. You can check https://www.npmjs.com/package/#microsoft/teams-js. You can now use the app module to check whether it is initialized.
import { app } from '#microsoft/teams-js';
bool initialized = app.isInitialized()

YouTube Data API: add a subscription

I'm using YouTube's V3 Data API to add a subscription to a channel. This occurs on a Wordpress installation.
I added Google APIs (for oauth) on Wordpress theme functions:
wp_enqueue_script( 'googleapi', 'https://apis.google.com/js/client.js?onload=googleApiClientReady', array(), '1.0.0', true );
I added in the same way the oauth javascript file, which is the first one here: https://developers.google.com/youtube/v3/code_samples/javascript.
Following this guide(https://developers.google.com/youtube/v3/docs/subscriptions/insert (Apps Script)), I extended the OAuth js with the addSubscription method.
Google Client API seems to be loaded and working as it calls correctly googleApiClientReady on the oauth javascript.
So, this is how the subscription is being inserted:
OAUTH JAVASCRIPT
... ... ...
// After the API loads
function handleAPILoaded() {
addSubscription();
}
function addSubscription() {
// Replace this channel ID with the channel ID you want to subscribe to
var channelId = 'this is filled with the channel ID';
var resource = {
snippet: {
resourceId: {
kind: 'youtube#channel',
channelId: channelId
}
}
};
try {
var response = YouTube.Subscriptions.insert(resource, 'snippet');
jQuery('#success').show();
} catch (e) {
if(e.message.match('subscriptionDuplicate')) {
jQuery('#success').show();
} else {
jQuery('#fail').show();
alert("Please send us a mail () with the following: ERROR: " + e.message);
}
}
So, the first error comes with
YouTube.Subscriptions.insert(resource, 'snippet')
It says YouTube is not defined. I replaced it with:
gapi.client.youtube.subscriptions.insert(resource, 'snippet');
And that error went away. When checking response, as the subscription isn't completed, this is what I get
{"wc":1,"hg":{"Ph":null,"hg":{"path":"/youtube/v3/subscriptions","method":"POST","params":{},"headers":{},"body":"snippet","root":"https://www.googleapis.com"},"wc":"auto"}}
So, I would like to know what's happening on that POST request and what's the solution to this.
I can post the full OAuth file, but it's just as in the example, plus that addSubscription method at the end.
Okay, I got it working, the problem was on the POST request. Here is the full method working:
// Subscribes the authorized user to the channel specified
function addSubscription(channelSub) {
var resource = {
part: 'id,snippet',
snippet: {
resourceId: {
kind: 'youtube#channel',
channelId: channelSub
}
}
};
var request = gapi.client.youtube.subscriptions.insert(resource);
request.execute(function (response) {
var result = response.result;
if (result) {
// alert("Subscription completed");
}
} else {
// alert("Subscripion failed");
// ...
}
});
}
Also make sure to load Google Apps API (in fact without it the authorize/login button won't work) and jQuery.
Any chance you can post everything that made this work...all the JS entire auth.js save for your private keys, im working on this exact problem.

Resources