Send direct message to a user via MS Teams programmatically

nettech 171 Reputation points
2023-10-22T18:07:53.19+00:00

Hi,

We are currently using teams web hooks extensively to send notifications to teams channels.

Sometimes we have situations where we need to send a teams message to a user directly, but have not found a way to accomplish this task using powershell.

Is it possible to make an Invoke-RestMethod PowerShell call to send a message to a user directly?

Thank you

Microsoft Teams | Development
Microsoft Security | Microsoft Graph
0 comments No comments
{count} vote

Accepted answer
  1. Prasad-MSFT 8,981 Reputation points Microsoft External Staff Moderator
    2023-10-23T05:58:16.5733333+00:00

    It is not possible to send a direct message to a user using Teams Incoming Webhook. The Incoming Webhook is designed to post messages to a specific channel, not to individual users. However, you can achieve this by creating a Teams bot application. Teams bot applications can send messages to individual users, group chats, and public channels.

    To send a message to a user directly, you would need to use the Microsoft Bot Framework and the Teams SDK. You would need to capture the user's Teams-specific identifiers, which you can do by fetching the roster or user profile data, subscribing to conversation events, or using Microsoft Graph.

    var turnContext = new TurnContext(new AdapterWithErrorHandler(new ConfigurationCredentialProvider(Configuration)), activity);
    var conversationParameters = new ConversationParameters
    {
        IsGroup = false,
        Bot = turnContext.Activity.Recipient,
        Members = new ChannelAccount[] { new ChannelAccount(userId) },
        TenantId = tenantId
    };
    
    await ((BotFrameworkAdapter)turnContext.Adapter).CreateConversationAsync(
        channelId,
        serviceUrl,
        credentials,
        conversationParameters,
        async (t1, c1) =>
        {
            var reply = MessageFactory.Text("Hello, user!");
            await t1.SendActivityAsync(reply, c1);
        },
        cancellationToken);
    
    

    Please refer to the Microsoft Bot Framework documentation and Teams SDK documentation for more detailed information on how to create a bot and send messages to users.

    Thanks, 

    Prasad Das

    ************************************************************************* 

    If the response is helpful, please click "Accept Answer" and upvote it. You can share your feedback via Microsoft Teams Developer Feedback link. Click here to escalate.

    1 person found this answer helpful.
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Prashant Bali (Upwork Global Inc) 75 Reputation points Microsoft External Staff
    2023-12-02T09:33:03.14+00:00

    It is now possible to send messages to personal chat(1:1) or to group chat in Microsoft Teams using Microsoft Graph API. And yes, the messages will be displayed in the Teams application using Microsoft Graph API.

    Please refer the "1:1 and group chat messages" section from the below microsoft documentation link:

    chatMessage resource type

    Also, below is the graph API to send a message to any conversation you want using Post HTTP method :

    https://graph.microsoft.com/beta/users/{user-id}/chats/{chat-id}/messages

    To fetch {user-id} and {chat-id}, please follow the below steps using Get HTTP method:

    Fetch the user id of a logged-in user or user id of other user using below graph API's:

    https://graph.microsoft.com/v1.0/me
    https://graph.microsoft.com/v1.0/users

    Fetch the conversation/chat id of a user:

    https://graph.microsoft.com/beta/me/chats
    https://graph.microsoft.com/beta/users/{id}/chats

    As of now, there is no graph API to reply to a personal chat but we can reply to any team's channel message using Microsoft Graph API.

    If the response is helpful, please click "Accept Answer" and upvote it.


  2. Shahil Nissam A P 0 Reputation points
    2024-11-15T06:43:45.2833333+00:00

    Send Messages via Microsoft Teams Using Microsoft Graph API in Laravel

    If you're looking to send messages to Microsoft Teams users using the Microsoft Graph API, you've come to the right place! We’ve successfully integrated the API to send messages directly to Teams users by leveraging Laravel and Microsoft’s OAuth 2.0 authentication.

    User's image

    Overview

    This solution allows you to:

    1. Authenticate using your Microsoft credentials.
    2. Retrieve the User ID based on the email address.
    3. Find or Create a Chat between the logged-in user and the target user.
    4. Send a Message to the target user via Microsoft Teams.

    We have created a service class MSGraphClient to interact with the Graph API, including methods for token retrieval, user ID lookup, chat creation, and message sending.

    1. Environment Setup (.env file)

    Before getting started, make sure to configure the following in your .env file:

    MICROSOFT_TENANT_ID=your_tenant_id
    MICROSOFT_CLIENT_ID=your_client_id
    MICROSOFT_CLIENT_SECRET=your_client_secret
    MICROSOFT_SCOPE=https://graph.microsoft.com/.default
    MICROSOFT_USERNAME=your_username_email
    MICROSOFT_PASSWORD=your_password
    

    This setup will allow you to authenticate and interact with Microsoft Graph.

    2. The MSGraphClient Service Class (Important)

    This service class is responsible for authenticating the user, fetching their ID, finding or creating a chat, and sending the message.

    namespace
    

    namespace App\Services;

    use Illuminate\Support\Facades\Http;

    class MSGraphClient

    {

    public function getMicrosoftToken()
    
    {
    
        $response = Http::asForm()->post('https://login.microsoftonline.com/' . env('MICROSOFT_TENANT_ID') . '/oauth2/v2.0/token', [
    
            'client_id' => env('MICROSOFT_CLIENT_ID'),
    
            'client_secret' => env('MICROSOFT_CLIENT_SECRET'),
    
            'scope' => env('MICROSOFT_SCOPE'),
    
            'username' => env('MICROSOFT_USERNAME'),
    
            'password' => env('MICROSOFT_PASSWORD'),
    
            'grant_type' => 'password',
    
        ]);
    
        if ($response->successful()) {
    
            return $response->json()['access_token'];
    
        } else {
    
            throw new \Exception("Failed to obtain Microsoft OAuth token: " . $response->body());
    
        }
    
    }
    
    public function getUserId($email)
    
    {
    
        $token = $this->getMicrosoftToken();
    
        $response = Http::withToken($token)->get("https://graph.microsoft.com/v1.0/users/{$email}");
    
        if ($response->successful()) {
    
            return $response->json()['id'];
    
        } else {
    
            throw new \Exception("Failed to retrieve user ID: " . $response->body());
    
        }
    
    }
    
    public function getChatId($targetUserId)
    
    {
    
        $token = $this->getMicrosoftToken();
    
        $loggedInUserId = $this->getUserId(env('MICROSOFT_USERNAME'));
    
        // Check if a chat already exists
    
        $response = Http::withToken($token)->get("https://graph.microsoft.com/v1.0/me/chats");
    
        if ($response->successful()) {
    
            foreach ($response->json()['value'] as $chat) {
    
                if ($chat['chatType'] === 'oneOnOne' && isset($chat['members'][1]) && $chat['members'][1]['id'] === $targetUserId) {
    
                    return $chat['id'];
    
                }
    
            }
    
        }
    
        // If no chat exists, create one
    
        $response = Http::withToken($token)->post("https://graph.microsoft.com/v1.0/chats", [
    
            'chatType' => 'oneOnOne',
    
            'members' => [
    
                [
    
                    '@odata.type' => '#microsoft.graph.aadUserConversationMember',
    
                    'roles' => ['owner'],
    
                    '******@odata.bind' => 'https://graph.microsoft.com/v1.0/users/' . $targetUserId
    
                ],
    
                [
    
                    '@odata.type' => '#microsoft.graph.aadUserConversationMember',
    
                    'roles' => ['owner'],
    
                    '******@odata.bind' => 'https://graph.microsoft.com/v1.0/users/' . $loggedInUserId
    
                ]
    
            ]
    
        ]);
    
        if ($response->successful()) {
    
            return $response->json()['id'];
    
        } else {
    
            throw new \Exception("Failed to create or find chat: " . $response->body());
    
        }
    
    }
    
    public function sendMessageToUser($email, $messageContent)
    
    {
    
        $targetUserId = $this->getUserId($email);
    
        $chatId = $this->getChatId($targetUserId);
    
        // Send message to the chat
    
        $response = Http::withToken($this->getMicrosoftToken())->post("https://graph.microsoft.com/v1.0/chats/{$chatId}/messages", [
    
            'body' => [
    
                'content' => $messageContent
    
            ]
    
        ]);
    
        if ($response->successful()) {
    
            return $response->json();
    
        } else {
    
            throw new \Exception("Failed to send message: " . $response->body());
    
        }
    
    }
    

    }

    3. Controller Logic

    To trigger the message sending functionality, use the following controller method:

    public function sendMessage()
    {
        try {
            $email = 'user@example.com';  // Target recipient email
            $messageContent = 'This is a system triggered message from the OMS application.';  // Message content
            $response = $this->msGraphClient->sendMessageToUser($email, $messageContent);
            return response()->json(['message' => 'Message sent successfully!', 'response' => $response], 200);
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }
    
    

    Issue Encountered When Using Azure Bot Service Bot ID to Send Messages

    When we attempted to use the Azure Bot Service Bot ID for sending messages to Microsoft Teams, we encountered an error:

    {
    

    { "error": { "code": "Unauthorized", "message": "Message POST is allowed in application-only context only for import purposes. Refer to https://docs.microsoft.com/microsoftteams/platform/graph-api/import-messages/import-external-messages-to-teams for more details." } }

    This error occurred because the Microsoft Graph API restricts sending messages through bot IDs for external (non-bot) user interactions. So the solution to this issue was to authenticate via OAuth and use the authenticated user's access token to send messages, rather than relying on the bot ID. This ensures that the message is sent within the appropriate context, following the application-only restrictions outlined by Microsoft.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.