0

Maybe it is my fault. I have been really trying to get some documentation on how to get the change token to track the changes for a the items in a list. My main goal is to use a logic app to handle sharepoint list item changes, call another web api and update fields. I added the webhook, so far so good. Now I need to find the records that were updated since the last run, and for this, I supposed to get a change token.

I tried:

/sites/demo5/_api/web/lists/getbytitle('vendors')/items?getchanges() /sites/demo5/_api/web/lists/getbytitle('vendors')/items?getlistitemchanges()

They both return all the changes, but none of them returns the token. I didn't find any documentation how to use these functions with REST. I only found that it is available in the object model: https://learn.microsoft.com/en-us/dotnet/api/microsoft.sharepoint.spchangecollection?view=sharepoint-server (the document is not available for SharePoint Online)

So, please, how do I get this token in REST?

1 Answer 1

0

This is SharePoint Framework code, hopefully it's enough to get you unstuck. I've stripped out the pieces of the web part implementation that aren't relevant to the answer.

Clicking the button with the id getCurrentChangeTokenButton will trigger a REST API call to get the current change token for the target list. This is stored in the class-level variable named _changeToken.

Clicking the button with the id getChangesButton will trigger a REST API call to get the change made to the list items in the target list using the current change token. If changes are returned, the class-level variable named _changeToken is updated to the value of the most recent change token.

import { SPHttpClient } from '@microsoft/sp-http';

export interface IRestApiChangeTokenWebPartProps {
  description: string;
}

export default class RestApiChangeTokenWebPart extends BaseClientSideWebPart<IRestApiChangeTokenWebPartProps> {

  private _isDarkTheme: boolean = false;
  private _environmentMessage: string = '';
  private _changeToken: string = null;

  public render(): void {
    this.domElement.innerHTML = `
    <section class="${styles.restApiChangeToken} ${!!this.context.sdks.microsoftTeams ? styles.teams : ''}">
      <div class="${styles.welcome}">
        <img alt="" src="${this._isDarkTheme ? require('./assets/welcome-dark.png') : require('./assets/welcome-light.png')}" class="${styles.welcomeImage}" />
        <h2>Well done, ${escape(this.context.pageContext.user.displayName)}!</h2>
        <div>${this._environmentMessage}</div>
        <div>Web part property value: <strong>${escape(this.properties.description)}</strong></div>
      </div>
      <div>
        <button type="button" id="getCurrentChangeTokenButton">Get Current Change Token</button>
        <br/>
        <br/>
        <button type="button" id="getChangesButton">Get Changes</button>
      </div>
    </section>`;

    let getCurrentChangeTokenButton: Element = this.domElement.querySelector("#getCurrentChangeTokenButton");
    getCurrentChangeTokenButton.addEventListener("click", () => { this.onCurrentChangeTokenClicked(); });

    let getChangesButton: Element = this.domElement.querySelector("#getChangesButton");
    getChangesButton.addEventListener("click", () => { this.onGetChangesClicked(); });
  }

  private onCurrentChangeTokenClicked = async (): Promise<void> => {
    const url = this.context.pageContext.web.absoluteUrl +
      `/_api/web/lists/getbytitle('Change Token Test')?$select=CurrentChangeToken`;

    const response = await this.context.spHttpClient.get(
      url,
      SPHttpClient.configurations.v1);

    if (!response.ok) {
      const responseText = await response.text();
      throw new Error(responseText);
    }

    const responseJson = await response.json();
    debugger;

    this._changeToken = responseJson.CurrentChangeToken;
  }

  private onGetChangesClicked = async (): Promise<void> => {
    const qry: any = JSON.stringify({
      Item: true,
      Add: true,
      Update: true,
      ChangeTokenStart: this._changeToken
    });

    const url = this.context.pageContext.web.absoluteUrl +
      `/_api/web/lists/getbytitle('Change Token Test')/getChanges(@qry)?@qry=` + qry;

    const response = await this.context.spHttpClient.post(
      url,
      SPHttpClient.configurations.v1,
      {});

    if (!response.ok) {
      const responseText = await response.text();
      throw new Error(responseText);
    }

    const responseJson = await response.json();
    const items: any[] = responseJson.value;
    debugger;

    if (items.length > 0) {
      this._changeToken = items[items.length - 1].ChangeToken;
    }
  }    
}

The documentation for this stuff isn't very useful, but here are the links for completeness:

SP.List.getChanges Method

SP.ChangeQuery object

SP.ChangeCollection object

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.