After sending the response with the validation token (Create subscription: Example), the following message received:
Operation: Create; Exception: [Status Code: Unauthorized; Reason: General exception while processing]
The issue seems related to how the client is created, but testing various scopes (https://graph.microsoft.com/.default / Subscription.Read.All / Sites.Read.All) and client creation options did not resolve the exception. It's also worth noting that GET subscriptions function correctly.
const (
tenantId = "..."
clientId = "..."
clientSecret = "..."
siteId = "..."
listId = "..."
appScopes = "https://graph.microsoft.com/.default"
webhookBaseUrl = "..."
)
import (
"fmt"
"time"
"strings"
"context"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
)
func initializeGraphForUserAuth() (*msgraphsdk.GraphServiceClient, error) {
credential, _ := azidentity.NewClientSecretCredential(tenantId, clientId, clientSecret, nil)
graphClient, _ := msgraphsdk.NewGraphServiceClientWithCredentials(credential, strings.Split(appScopes, ","))
return graphClient, nil
}
func newSubscription(g *msgraphsdk.GraphServiceClient, listId string) (graphmodels.Subscriptionable, error) {
changeType := "updated"
notificationUrl := fmt.Sprintf("%s/webhook/resource-updates", webhookBaseUrl)
// lifecycleNotificationUrl := fmt.Sprintf("%s/webhook/subscription-lifecycle", webhookBaseUrl)
resource := fmt.Sprintf("/sites/%v/lists/%v", siteId, listId)
expirationDateTime := time.Now().Add(time.Hour)
clientState := "SecretClientState"
requestBody := graphmodels.NewSubscription()
requestBody.SetChangeType(&changeType)
requestBody.SetNotificationUrl(¬ificationUrl)
// requestBody.SetLifecycleNotificationUrl(&lifecycleNotificationUrl)
requestBody.SetResource(&resource)
requestBody.SetExpirationDateTime(&expirationDateTime)
requestBody.SetClientState(&clientState)
subscription, err := g.Subscriptions().Post(context.Background(), requestBody, nil)
return subscription, err
}
func main() {
startWebhook() // Handles subscription validation; no issues
graphClient, _ := initializeGraphForUserAuth()
getSubscriptions(graphClient) // Returns an empty list with subscriptions (expected); no exceptions
subscription, err := newSubscription(graphClient, listId)
fmt.Println(">>> ", subscription, err)
// >>> <nil> Operation: Create; Exception: [Status Code: Unauthorized; Reason: General exception while processing]
}
Yeah, the application appeared registered under "delegated permissions," whereas creating a Sharepoint list subscription requires an "application subscription."
https://learn.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-1.0&tabs=http#permissions