N/A
Where could I find examples of pnpjs used in Microsoft Teams apps? I am talking about apps built using the Microsoft Teams Toolkit or yo Teams, not SPFx tabs.
You use the library the same way regardless of if you're using it in a Teams app or SPFx... how you configure the library is the only real thing that would change, and those examples are in the Configuration section.
Thanks Julie, and indeed it's the configuration part I was looking for.
In SPFx, I would use:
sp.setup(this.context);
In Microsoft Teams, I don't know how to get to the SharePoint site associated with the current team. Would you have a snippet to share just for that part?
I personally do not, sorry.
@PathToSharePoint, you might have already visited this, but you can also see a collection of Teams samples at:
https://aka.ms/teams-samples
@PopWarner I have, and I love the slicing and dicing that helps with navigating that huge repository.
Unfortunately the PnPjs samples I have come across all use SPFx. What I need is the SharePoint context from within Teams directly.
Can you link to a repo with a project showing where you'd like it to work?
Sorry, I am just getting started with Teams apps and all I've done so far is follow the Microsoft tutorials.
At this point I'd be happy with just a simple example:
I have always applied sp.setup in my SPFx projects, but I don't know what it does, and if it is even required. For example, does this make sense:
sp.setup({});
Yesterday I took a look at the Teams SDK and found a property called teamSiteUrl to get the SharePoint site URL. That's where I am right now.
You can use that as the baseUrl in the setup call. Seems like a great opportunity to create the missing sample :)
Right, I'll try that. What worries me is that I might be headed in the wrong direction, if nobody felt the need to do it before...
What I am experimenting with right now is slightly different, and again it's just a shot in the dark at this point:
sp.setup({});
microsoftTeams.getContext(
context => {
var spURL = context.teamSiteUrl;
const spWeb = Web(spURL);
spWeb.lists().then((items) => {...});
I can help a bit based on this code... it would be more like:
microsoftTeams.getContext(
context => {
var spURL = context.teamSiteUrl;
const config: ISPConfiguration = { sp: { baseUrl: spURL }};
sp.setup(config);
.....
You need to pass the url into sp.setup...
After you do the setup then everything in docs just works the same.
ok, thank you both for the advice! Let me do some testing and I'll report back.
Will it work with only setting baseUrl? The main thing to solve I would say is authentication.
@koltyakov is right, you would also need to handle auth, but that gets you the base url. If you get a project setup we can look at how best to support Teams. We probably want a way to accept a teams context like we do with SPFx eventually.
Right, I need authentication and that's actually what is blocking me right now. There's a couple client side ways to do it (MSAL2, mgt) but all tutorials involve registering an application on Azure. I don't see how that would work for a solution that goes to AppSource.
If you have any pointers let me know! I am mainly working off this blog post by Bob German:
https://bob1german.com/2020/08/31/calling-microsoft-graph-from-your-teams-application-part3/
[edit] For the record, something else that slowed me down: I was going to use the Teams Toolkit to provision the solution, but then I found out that for now the toolkit only scaffolds in plain JavaScript, not TypeScript. So I'm back to using yo Teams.
@patrick-rodgers re context, maybe there's something we could learn from isolated Web Parts and reapply to Teams? I have never used them and I don't know how they get the host context. The documentation doesn't provide much detail.
A couple updates:
[Webpack error] Module not found: Error: Can't resolve '../rest' in 'C:\My Git\Graph Access Test\node_modules\@pnp\sp\presets'
Did you mean 'rest.js'?
BREAKING CHANGE: The request '../rest' failed to resolve only because it was resolved as fully specified
(probably because the origin is a '*.mjs' file or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
I've discovered that the issue can easily be replicated with the following:
import {sp} from "@pnp/sp/presets/all.js";
console.log(sp.configure());
And then on Node 14+ just run node app.js
The same issue is within Webpack 5+ (for which they are working on a fix, to work around how node does module resolution).
ESM modules requires that you for non top-level imports, specify the file extension (js, mjs) as I understand it.
If I manually modify the contents of core.js, as an example, from import { SPRest } from "../rest; to import { SPRest } from "../rest.js"; it works just fine.
Just as a reference for the file extension comment above
A file extension must be provided when using the import keyword to resolve relative or absolute specifiers. Directory indexes (e.g. './startup/index.js') must also be fully specified.
Ref: https://nodejs.org/api/esm.html#esm_mandatory_file_extensions
Having a look at this and the answer for Teams apps is to use the -commonjs variant of the modules. Teams apps aren't browser apps so selective imports provides no real advantage (bundle size doesn't matter on server, don't @ me). Is there any reason not to just use the -commonjs modules as outlined?
This is the entire reason we ended up with two varieties of package. To do the things we wanted to do for browsers we couldn't determine a way to also have it "just work" in node.
Edit: we will look at adding a docs page to explain this for Teams.
@patrick-rodgers I am a bit confused here. Teams apps such as tabs are Web pages and run in the browser, in the desktop client (electron) and on mobile. js bundles get loaded on the client side.
@patrick-rodgers - that is an incorrect assumption. Teams apps being built are predominantly being client-side scripts - a Tab for instance, or a Task module, or a meeting extension, or a Connector configuration.
@patrick-rodgers @juliemturner @wictorwilen circling back on this issue.
I'd say that the original question has been answered (short answer: no sample for now) and this thread can be closed. Thank you for the advice and ideas along the way, hopefully I'll be able to give back by submitting a sample soon.
During the discussion, a build issue has been uncovered with client side solutions. This doesn't seem to affect SPFx, but it came up with yo Teams (client side apps) and might affect other frameworks. From what I understand, it's about a rule on file extensions that already existed but was not enforced until recently. The fix would be to add the ".js" file extensions in the import statements.
Does this make sense and should we open a new issue for the fix?
Most helpful comment
@patrick-rodgers I am a bit confused here. Teams apps such as tabs are Web pages and run in the browser, in the desktop client (electron) and on mobile. js bundles get loaded on the client side.