This website uses cookies to ensure you get the best experience on our website.

Skip to content
LOGO
  • Company

    About IGNEK

    Learn about our story and our mission.

    Careers

    We're hiring!

    We always looking for talented peoples. Join our team!

    Blogs

    The latest industry news, updates and info.

    Case Studies

    Take a closer look at the projects we've delivered

    Webinar

    Watch our latest organized webinar

    Get in touch with our HR team

    • hr@ignek.com
    • +91 93284 95160
    • Ahmedabad, Gujarat, India – 382470
  • Services

    Enterprise Portal Development

    Custom Enterprise Portal Development for flawless Solutions

    Dedicated Development Team

    Expand Teams, Optimize Development with Our Expertise

    Back-end Development

    Empowering your digital presence with robust backend development expertise

    Front-end Development

    Crafting engaging user experiences through expert frontend development

    Digital Transformation

    Embrace digital transformation by modernizing process

    SaaS Development

    Transform your business with SaaS Innovative Solutions

    Technologies

    Liferay Services

    Development & Customization

    Theme

    Upgradation

    Migration

    Proof of Concept

    Performance Tunning

    Architecture

    Support & Maintenance

    E-commerce

    Expert Advice

    React Services

    Enterprise Development

    Custom Application

    Single Page Application

    Architecture

    API Integration

    Migration

    Consulting

    Maintenance & Support

    Spring Boot Services

    Web Service

    MVC Web Development

    API Integration

    Security

    Migration

    Microservices

    Support & Maintenance

    AEM Services

    Consulting Service

    Site Development

    Migration & Upgradation

    Integration

    Maintenance & Support

    Custom Solutions

    Content Management

    Team Augementation

  • Solution

    Ready for digital excellence

    In our rapidly evolving world, businesses are always on the lookout for fresh ways to improve their operations and connect with their audiences.

    Contact US

    Solutions

    SaaS : Software As A Service

    Transforming industries through cutting edge SaaS solutions.

    Customer Portal : Boost Business Productivity

    Streamline operations and enhance productivity with our Customer Portal solution.

    Liferay Based Intranet Portal

    Internal portal for company communication, collaboration and resources

    Integration

    Matomo Integration with Liferay

    Integrate Matomo to enable user interactions seamlessly.

    Microsoft Teams integration with Liferay

    Integrate to enable seamless collaboration, messaging within your portal.

    Jira Integration With Liferay

    Optimizes business operations by integrating with Jira.

  • Hire Us

    Liferay

    Get expert Liferay developers for seamless portal solutions.

    React JS

    Get expert ReactJS developers for dynamic web solutions.

    Web Developer

    Get custom web solutions from IGNEK's expert developers.

    Spring Boot

    Get top-notch Spring Boot developers for your project success!

    Healthcare

    Get top Healthcare Developers for cutting-edge medical software.

    MERN Stack

    Get expert MERN developers from IGNEK for custom, innovative project solutions.

    Why Hire Developers From IGNEK ?

    • Certified Developer
    • Transparent Communication
    • Flexible Hiring Modals
    • Fully Signed NDA
    • Cost Effective
    • Easy Exit Policy

    Get in touch with our Sales team

    • sales@ignek.com
    • +91 6351576580
    • info@ignek.com
    • Ahmedabad, Gujarat, India – 382470
SCHEDULE CALL
  • COMPANY
    • About
    • Case Studies
    • Blogs
    • Career
    • Webinar
  • SERVICES
    • Enterprise Portal Development
    • Dedicated Development Team
    • Back-end Development
    • Front-end Development
    • Digital Transformation
    • SaaS Development
  • SOLUTION
    • Customer Portal:  Boost Business Productivity
    • SaaS : Software as a Service
    • Liferay Based Employee Intranet Portal
  • TECHNOLOGY
    • Liferay Services
      • Liferay Development and Customization
      • Liferay Theme Development Service
      • Liferay DXP 7.4 Upgrade
      • Liferay Migration
      • Liferay Proof Of Concept
      • Liferay Performance Tuning
      • Liferay Architecture Design Service
      • Liferay Support And Maintenance Service
      • Liferay Ecommerce Development
      • Liferay Expert Advice
    • ReactJS Services
      • ReactJS Enterprise Application Development
      • ReactJS Custom Application Development
      • ReactJS Single Page Application Development (SPA)
      • ReactJS Applications Architecture
      • ReactJS API Integration
      • ReactJS Migration
      • ReactJS Consulting
      • ReactJS Maintenance and Support
    • Spring Boot Services
      • Spring Boot Web Development Service
      • Spring MVC Web Development
      • Spring Boot API Integration Service
      • Spring Boot Security
      • Spring Boot Migration Service
      • Spring Boot Microservices
      • Spring Boot Support & Maintenance Service
    • AEM Development Services
      • AEM Consulting Services
      • AEM Site Development
      • AEM Migration & Upgradation
      • AEM Integration Services
      • AEM Maintenance & Support
      • AEM Content Management
      • Custom AEM Solutions
      • AEM Team Augmentation
  • INTEGRATION
  • HIRE US
    • Hire Liferay Developer
    • Hire ReactJS Developer
    • Hire Spring Boot Developer
    • Hire Healthcare Developer
    • Hire Web Developer
    • Hire MERN Stack Developer
  • CONTACT US
  • Company

    About IGNEK

    Careers

    We're hiring!

    Blogs

    Case Studies

    Webinar

    Get in touch with our HR team

    • hr@ignek.com
    • +91 93284 95160
    • Ahmedabad, Gujarat, India – 382470
  • Services

    Enterprise Portal Development

    Dedicated Development Team

    Back-end Development

    Front-end Development

    Digital Transformation

    SaaS Development

    Technologies

    Liferay Liferay Services
    • Development & Customization
    • Theme
    • Upgradation
    • Migration
    • Proof of Concept
    • Performance Tuning
    • Architecture
    • Support & Maintenance
    • E-commerce
    • Expert Advice
    React React Services
    • Enterprise Development
    • Custom Application
    • Single Page Application
    • Architecture
    • API Integration
    • Migration
    • Consulting
    • Maintenance & Support
    Spring Boot Spring Boot Services
    • Web Service
    • MVC Web Development
    • API Integration
    • Security
    • Migration
    • Microservices
    • Support & Maintenance
    AEM AEM Services
    • Consulting Service
    • Site Development
    • Migration & Upgradation
    • Integration
    • Maintenance & Support
    • Custom Solutions
    • Content Management
    • Team Augmentation
  • Solution

    Ready for digital excellence

    In our rapidly evolving world, businesses are always on the lookout for fresh ways to improve their operations and connect with their audiences.

    Contact US

    Solutions

    SaaS : Software As A Service

    Customer Portal : Boost Business Productivity

    Liferay Based Intranet Portal

    Integration

    Matomo Integration with Liferay

    Microsoft Teams integration with Liferay

    Jira Integration With Liferay

  • Hire Us

    Liferay

    React JS

    Web Developer

    Spring Boot

    Healthcare

    MERN Stack

    Why Hire Developers From IGNEK ?

    • Certified Developer
    • Transparent Communication
    • Flexible Hiring Modals
    • Fully Signed NDA
    • Cost Effective
    • Easy Exit Policy

    Get in touch with our Sales team

    • sales@ignek.com
    • +91 6351576580
    • IGNEK
    • Ahmedabad, Gujarat, India – 382470
  • SCHEDULE CALL

Microsoft Teams integration with Liferay

  • Liferay
  • July 11, 2023

Share On :

Introduction:
  • Are you looking for a way to connect Microsoft Teams with your Liferay portal? If so, you’ve come to the right place.
  • Microsoft Teams is an incredibly useful platform for joining meetings and keeping track of events.
  • It is powered by Microsoft Graph APIs, which allow users to create meetings and events with ease.
  • The Microsoft Graph APIs provide a comprehensive range of capabilities to manage and control the events, such as creating, updating, and deleting events.
  • They also allow for customization of the events, such as setting up reminders, adding notes, and inviting participants.
  • M365 and Microsoft Graph are required to use Microsoft APIs.
  • M365’s admin portal allows us to modify permissions and uses.
Prerequisites:
  • Liferay (Any version)
  • An Microsoft account
  • Knowledge of API
  • Knowledge of HTTP request and response.
Environmental Requirements:
  • Browser
  • Liferay
  • Eclipse ID
  • Gradle
Follow these steps to create a Microsoft admin account and assign permissions:
  1. The first step is to create a Microsoft developer account. For that go to “https://developer.microsoft.com/en-us/microsoft-365/dev-program“.
Create Microsoft developer account at link
  1. Here you can see the “join now” button. When you click on it, it will redirect you to the Microsoft sign-in page. Just sign in with your Microsoft account.
  2. You can see the page below. Here you get a 90 day free developer subscription for testing purposes.
Explore Microsoft sign-in for developers
  1. Here you can find your admin account email address. Just copy it and save it.
  2. Now go to “https://admin.microsoft.com/” and sign in with the admin email address. If you don’t have the password then you can reset it.
  3. After signing in, you can see the below message. So, click on “Next” to set up authentication, or you can just skip for now by tapping “Ask later”.
Sign in to view important message
  1. Now the admin dashboard looks like the below image.
View the updated admin dashboard image
  1. Now go to the new tab and hit “https://azure.microsoft.com/“.
Azure home page
  1. Now sign in using the admin email address. After signing in you can see the home page like below.
Azure admin panel
  1. Now go to “Manage Azure Active Directory” using the “View” button.
Access Azure AD
  1. Now go to “App registrations”. And create an app using “New registration”.
App registrations panel in Azure
  1. Now enter your app name and select Supported Account types as “Accounts in any organizational directory (Any Azure AD directory – Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)” and leave Redirect URI as blank.
Create app name and account types
  1. After successful registration, you can see the below page.
View page after registration success
  1. The next step is to collect some information and store it: ClientId and TenantId. And go to “Add a certificate or secret”.
Collect ClientId and TenantId information
  1. Now create a client secret using the “New client secret” button.
Generate client secret via new button
  1. Fill in details as per needs. And click on add.
Details related to client secret
  1. Now store the “value” (client secret) of the created client secret because we can’t see it after that.
  2. Now go to API permissions from the side panel.
Access API permissions
  1. Click on “Add a permission”.
Request permissions for APIs
  1. Click on “Microsoft Graph” and after that, click on “Delegated permissions”.
Delegated permissions in Microsoft Graph
  1. Search “calendars” and select all the checkboxes. And click on “Add permissions”.
Add permissions related to calendars
  1. Like that, add all permissions as mentioned in the below list.
    1. Delegated
      • Calendars.Read
      • Calendars.Read.Shared
      • Calendars.ReadBasic
      • Calendars.ReadWrite
      • Calendars.ReadWrite.Shared
      • email
      • Mail.Read
      • Mail.Read.Shared
      • Mail.ReadBasic
      • Mail.ReadBasic.Shared
      • Mail.ReadWrite
      • Mail.ReadWrite.Shared
      • Mail.Send
      • Mail.Send.Shared
      • MailboxSettings.Read
      • MailboxSettings.ReadWrite
      • OnlineMeetings.Read
      • OnlineMeetings.ReadWrite
      • User.Read
    2. Application
      • Calendars.Read
      • Calendars.ReadBasic.All
      • Calendars.ReadWrite
      • Mail.Read
      • Mail.ReadBasic.All
      • Mail.ReadWrite
      • Mail.Send
      • MailboxSettings.Read
      • MailboxSettings.ReadWrite
      • OnlineMeetings.Read.All
      • OnlineMeetings.ReadWrite.All
List of permissions for calendar and email
  1. Then click on “Grant Admin consent for MSFT” and click on “Yes”.
Grant MSFT admin consent
  1. Go back one step and you will see the screen below.
MSFT app registration screen
  1. From the side panel, select “Users”.
Azure AD users list
  1. Here, click on your name. In my case “Dixit Baravaliya”.
Detailed view of admin user
  1. Here you can find “Object ID”. Just copy it and store it.
  2. Now in the new tab go to “https://admin.microsoft.com/” and sign in with the admin email address.
Microsoft teams admin center
  1. Go to Meetings -> Meeting Policies from the side panel.
Manage Meeting Policies screen
  1.  Choose “Global (Org-wide default)”.
Global Org-wide default detailed screen
  1. Then, in Meeting Join & Lobby -> Who can bypass the lobby, select Everyone. In this way, everyone can join the meeting even if the organizer hasn’t given his or her permission.
Managing everyone can bypass lobby Meeting Policies
  1. The APIs of Microsoft Graph are ready for use.
Liferay Rest Builder
Here I’m creating one rest builder to perform create, update, get, and delete operations on Microsoft events.Follow these steps to create a Liferay rest builder and call Microsoft APIs:
  1. First, Create Liferay Workspace and a rest builder (If you don’t know how to create a rest builder then take reference from here).
  2. Here I have created “microsoft-teams-rest” named Rest Builder.
Liferay Workspace and Microsoft Teams Rest builder
  1. Go to the microsoft-teams-rest-impl -> rest-openapi.yaml file and write the below text.
				
					// rest-openapi.yaml
info:
    description: "MicrosoftTeamsRest REST API"
    license:
        name: "Apache 2.0"
        url: "http://www.apache.org/licenses/LICENSE-2.0.html"
    title: "MicrosoftTeamsRest"
    version: v1.0
openapi: 3.0.1
paths:
  "/update-microsoft-teams-link":
    post:
      operationId: updateMicrosoftTeamsLink
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Teams"
          application/xml:
            schema:
              $ref: "#/components/schemas/Teams"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Teams"
            application/xml:
              schema:
                $ref: "#/components/schemas/Teams"
          description: ""
      tags: ["Teams"]
  "/get-microsoft-teams-link":
    get:
      operationId: getMicrosoftTeamsLink
      parameters:
        - in: query
          name: eventId
          required: true
          schema:
            type: string
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Teams"
            application/xml:
              schema:
                $ref: "#/components/schemas/Teams"
          description: ""
        404:
          description: "Teams not found"
        500:
          description: "Internal server error"
      tags: ["Teams"]
  "/delete-microsoft-teams-link":
    delete:
      operationId: deleteMicrosoftTeamsLink
      parameters:
        - in: query
          name: eventId
          required: true
          schema:
            type: string
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Teams"
            application/xml:
              schema:
                $ref: "#/components/schemas/Teams"
          description: ""
      tags: ["Teams"]
components:
  schemas:
    Teams:
      description: adding or updating microsoft teams link
      properties:
        eventId:
          description: The eventId.
          type: string
        title:
          description: The title.
          type: string
        description:
          description: The description.
          type: string
        setDate:
          description: The setDate in "yyyy-MM-dd HH:mm" format.
          type: string
        endDate:
          description: The endDate in "yyyy-MM-dd HH:mm" format.
          type: string
        timeZone:
          description: The timeZone.
          type: string
        location:
          description: The location.
          type: string
        teamsLink:
          description: The teamsLink.
          type: string
        emailAddress:
          description: The emailAddress.
          type: array
          items:
            type: string
        status:
            $ref: "#/components/schemas/Status"
    Status:
      properties:
        statusMessage:
          type: string
        statusCode:
          type: integer

				
			
  1. Now, build rest of it, and you will see the below files. Open the “TeamsResourceImpl” file.
Exploring TeamsResourceImpl file in-depth
  1. Add methods in the “TeamsResourceImpl” class file (updateMicrosoftTeamsLink, getMicrosoftTeamsLink, and deleteMicrosoftTeamsLink).
New functions in TeamsResourceImpl class
  1. Now go to modules -> microsoft-teams-rest -> microsoft-teams-rest-impl -> build.gradle. And replace with below lines.
				
					// build.gradle
dependencies {
	compile project(":modules:microsoft-teams-rest:microsoft-teams-rest-api")

	compileOnly group: "com.liferay.portal", name: "release.portal.api"
	compileOnly group: "javax.annotation", name: "javax.annotation-api", version: "1.3.2"
    compileOnly group: "javax.validation", name: "validation-api", version: "2.0.1.Final"
    compileOnly group: "javax.ws.rs", name: "javax.ws.rs-api"
	compile group: 'org.apache.httpcomponents', name: 'httpclient'
	compile group: 'org.apache.httpcomponents', name: 'httpcore'
	implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.0'

	restBuilder group: "com.liferay", name: "com.liferay.portal.tools.rest.builder", version: "1.0.222"
}

group = "microsoft.teams.rest"

				
			
  1. Now go to modules -> microsoft-teams-rest -> microsoft-teams-rest-impl -> bnd.bnd (source) file and replace with below lines.
				
					// bnd.bnd
Bundle-Name: microsoft-teams-rest-impl
Bundle-SymbolicName: microsoft.teams.rest.impl
Bundle-Version: 1.0.0

-privatepackage: \
	com.google.gson.*
				
			
  1. Now, create a package “com.ignek.microsoft.teams” in the “microsoft-teams-rest-impl/src/main/java” folder.
Package creation in designated folder
  1. Now, add an interface “MicrosoftTeamsService” and a class “MicrosoftTeamsServiceImpl” which implements “MicrosoftTeamsService”.
Implement MicrosoftTeamsService and MicrosoftTeamsServiceImpl
  1. Now, create a package “com.ignek.microsoft.teams.model” in the “microsoft-teams-rest-impl/src/main/java” folder. and create a class “ResponseDTO” that implements serializable.
				
					// ResponseDTO.java
package com.ignek.microsoft.teams.model;

import java.io.Serializable;

import javax.ws.rs.core.Response;

public class ResponseDTO implements Serializable {

	protected static Response.Status STATUS_OK = Response.Status.OK;
	protected static Response.Status STATUS_ERROR = Response.Status.INTERNAL_SERVER_ERROR;

	private final int status;
	private final String message;

	private ResponseDTO(int status, String message) {
		this.status = status;
		this.message = message;
	}
	protected ResponseDTO(Response.Status status) {
		this(status.getStatusCode(), status.getReasonPhrase());
	}
	protected ResponseDTO(Response.Status status, String message) {
		this(status.getStatusCode(), status.getReasonPhrase() + ": " + message);
	}
	public static ResponseDTO ok() {
		return new ResponseDTO(STATUS_OK);
	}
	public static ResponseDTO fail() {
		return new ResponseDTO(STATUS_ERROR);
	}
	public static ResponseDTO error(String message) {
		return new ResponseDTO(STATUS_ERROR, essage);
	}

	public int getStatus() {
		return status;
	}
	public String getMessage() {
		return message;
	}
}

				
			
  1. Now, In the same package “com.ignek.microsoft.teams.model” create a class “MicrosoftTeamsResponse” that extends ResponseDTO.
				
					// MicrosoftTeamsResponse.java
package com.ignek.microsoft.teams.model;

import com.liferay.petra.string.StringPool;

public class MicrosoftTeamsResponse extends ResponseDTO {

	private final String eventId;
	private final String link;

	private MicrosoftTeamsResponse(String link, String eventId) {
		super(STATUS_OK);
		this.eventId = eventId;
		this.link = link;
	}
	private MicrosoftTeamsResponse(String message) {
		super(STATUS_ERROR, message);
		this.eventId = StringPool.BLANK;
		this.link = StringPool.BLANK;
	}
	public static MicrosoftTeamsResponse of(String link, String eventId) {
		return new MicrosoftTeamsResponse(link, eventId);
	}
	public static MicrosoftTeamsResponse fail(String message) {
		return new MicrosoftTeamsResponse(message);
	}
	public String getEventId() {
		return eventId;
	}
	public String getLink() {
		return link;
	}
}

				
			
  1. Now, create a package “com.ignek.http.client.methods” in the “microsoft-teams-rest-impl/src/main/java” folder. and create an interface “HTTPRequestService” and a class “HTTPRequestServiceImpl” that implements “HTTPRequestService”.
Create package and class for HTTP requests
  1. In “HTTPRequestService”, add the below code.
				
					// HTTPRequestService.java
package com.ignek.http.client.methods;

import java.util.Map;

import org.apache.http.entity.ContentType;

public interface HTTPRequestService {

	String sendHTTPPostRequest(String httpURL, Map<String, String> headerMap, String requestBody, ContentType contentType);

	String sendHTTPPatchRequest(String httpURL, Map<String, String> headerMap, String requestBody, ContentType contentType);
	
	String sendHTTPGetRequest(String httpURL, Map<String, String> headerMap);

	void sendHTTPDeleteRequest(String httpURL, Map<String, String> headerMap);

}

				
			
  1. In “HTTPRequestServiceImpl”, add the below code.
				
					// HTTPRequestServiceImpl.java
package com.ignek.http.client.methods;

import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.osgi.service.component.annotations.Component;

import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.Validator;

@Component(immediate = true, service = HTTPRequestService.class)
public class HTTPRequestServiceImpl implements HTTPRequestService {

	@Override
	public String sendHTTPPostRequest(String httpURL, Map<String, String> headerMap, String requestBody, ContentType contentType) {
		HttpPost httpPost = new HttpPost(httpURL);
		HttpEntity entity = new StringEntity(requestBody, contentType);
		httpPost.setEntity(entity);
		return sendHTTPRequest(httpPost, headerMap);
	}

	@Override
	public String sendHTTPPatchRequest(String httpURL, Map<String, String> headerMap, String requestBody, ContentType contentType) {
		HttpPatch httpPatch = new HttpPatch(httpURL);
		HttpEntity entity = new StringEntity(requestBody, contentType);
		httpPatch.setEntity(entity);
		return sendHTTPRequest(httpPatch, headerMap);
	}
	
	@Override
	public String sendHTTPGetRequest(String httpURL, Map<String, String> headerMap) {
		HttpGet httpGet = new HttpGet(httpURL);
		return sendHTTPRequest(httpGet, headerMap);
	}

	@Override
	public void sendHTTPDeleteRequest(String httpURL, Map<String, String> headerMap) {
		HttpDelete httpDelete = new HttpDelete(httpURL);
		sendHTTPRequest(httpDelete, headerMap);
	}
	
	private String sendHTTPRequest(HttpUriRequest httpUriRequest, Map<String, String> headerMap) {
		try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
			headerMap.forEach((key, value) -> {
				httpUriRequest.setHeader(key, value);
			});
			HttpResponse response = client.execute(httpUriRequest);
			return Validator.isNotNull(response) ? EntityUtils.toString(response.getEntity()) : StringPool.BLANK;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return StringPool.BLANK;
	}
	
	private static final Log log = LogFactoryUtil.getLog(HTTPRequestServiceImpl.class);

}

				
			
  1. Now, go to the “MicrosoftTeamsService” file. And write the below code.
				
					// MicrosoftTeamsService.java
package com.ignek.microsoft.teams;

import com.ignek.microsoft.teams.model.MicrosoftTeamsResponse;

public interface MicrosoftTeamsService {

	MicrosoftTeamsResponse updateMicrosoftTeamsEvent(String eventId, String title, String location, String[] emails,
 String description, String startTime, String endTime, String timeZone);

	String getMicrosoftTeamsLink(String eventId);

	void deleteMicrosoftTeamsEvent(String eventId);

}

				
			
  1. Now, go to the “MicrosoftTeamsServiceImpl” file. And write the below code.
				
					// MicrosoftTeamsServiceImpl.java
package com.ignek.microsoft.teams;

import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.entity.ContentType;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.ignek.http.client.methods.HTTPRequestService;
import com.ignek.microsoft.teams.model.MicrosoftTeamsResponse;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.Validator;

@Component(immediate = true, service = MicrosoftTeamsService.class)
public class MicrosoftTeamsServiceImpl implements MicrosoftTeamsService {
	
	@Reference
	private HTTPRequestService httpRequestService;

	@Override
	public MicrosoftTeamsResponse updateMicrosoftTeamsEvent(String eventId, String title, String location, String[] emails,
String description, String startTime, String endTime, String timeZone) {
		Map<String, String> headerMap = new HashMap<>(); 
		try {
			eventId = eventId.replace(StringPool.QUOTE, StringPool.BLANK);
			String accessToken = getAccessToken();
			String httpURL = MICROSOFT_CREATE_EVENT_URL.replace("${objectId}", OBJECT_ID)
					+ (Validator.isNotNull(eventId) ? StringPool.SLASH + eventId : StringPool.BLANK);
			headerMap.put("Host", "graph.microsoft.com");
			headerMap.put("Authorization", "Bearer " + accessToken.replace(StringPool.QUOTE, StringPool.BLANK));
			headerMap.put("Content-type", ContentType.APPLICATION_JSON.toString());
			String requestBody = createRequestBody(title, location, emails, description, startTime, endTime, timeZone);
			
			String responceBody = Validator.isNotNull(eventId)
				? httpRequestService.sendHTTPPatchRequest(httpURL, headerMap, requestBody, ContentType.APPLICATION_JSON)
				: httpRequestService.sendHTTPPostRequest(httpURL, headerMap, requestBody, ContentType.APPLICATION_JSON);
			
			eventId = getEntityValueFromStringJson(responceBody, "id").replace(StringPool.QUOTE, StringPool.BLANK);
			String joinURL = getEntityValueFromStringJson(getEntityValueFromStringJson(responceBody, "onlineMeeting"), "joinUrl")
.replace(StringPool.QUOTE, StringPool.BLANK);
			
			return MicrosoftTeamsResponse.of(joinURL, eventId);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return MicrosoftTeamsResponse.fail(e.getMessage());
		}
	}

	@Override
	public String getMicrosoftTeamsLink(String eventId) {
		String httpURL = MICROSOFT_CREATE_EVENT_URL.replace("${objectId}", OBJECT_ID) + StringPool.SLASH + eventId;
		String accessToken = getAccessToken();
		Map<String, String> headerMap = new HashMap<>();
		headerMap.put("Host", "graph.microsoft.com");
		headerMap.put("Authorization", "Bearer " + accessToken.replace(StringPool.QUOTE, StringPool.BLANK));
		String responceBody = httpRequestService.sendHTTPGetRequest(httpURL, headerMap);
		return getEntityValueFromStringJson(getEntityValueFromStringJson(responceBody, "onlineMeeting"), 
"joinUrl").replace(StringPool.QUOTE, StringPool.BLANK);
	}

	@Override
	public void deleteMicrosoftTeamsEvent(String eventId) {
		String httpURL = MICROSOFT_CREATE_EVENT_URL.replace("${objectId}", OBJECT_ID) + StringPool.SLASH + eventId;
		String accessToken = getAccessToken();
		Map<String, String> headerMap = new HashMap<>();
		headerMap.put("Host", "graph.microsoft.com");
		headerMap.put("Authorization", "Bearer " + accessToken.replace(StringPool.QUOTE, StringPool.BLANK));
		httpRequestService.sendHTTPDeleteRequest(httpURL, headerMap);
	}
	
	private String createRequestBody(String title, String location, String[] emails, String description, String startDate, 
String endDate, String timeZone) {
		JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
		jsonObject.put("subject", title);
		jsonObject.put("body", createJSONObject(new String[] { "contentType", "content" }, new String[] { "HTML", description }));
		jsonObject.put("start", createJSONObject(new String[] { "dateTime", "timeZone" }, new String[] { startDate, timeZone }));
		jsonObject.put("end", createJSONObject(new String[] { "dateTime", "timeZone" }, new String[] { endDate, timeZone }));
		jsonObject.put("location", createJSONObject(new String[] { "displayName" }, new String[] { location }));
		jsonObject.put("isOnlineMeeting", Boolean.TRUE.toString());
		jsonObject.put("onlineMeetingProvider", "teamsForBusiness");
		JSONArray array = JSONFactoryUtil.createJSONArray();
		for (String email : emails) {
			JSONObject emailAddressObject = JSONFactoryUtil.createJSONObject();
			emailAddressObject.put("emailAddress", createJSONObject(new String[] { "address" }, new String[] { email }));
			array.put(emailAddressObject);
		}
		jsonObject.put("attendees", array);
		return jsonObject.toString();
	}
	
	private JSONObject createJSONObject(String[] keys, String[] values) {
		JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
		for (String key : keys) {
			jsonObject.put(key, values[Arrays.asList(keys).indexOf(key)]);
		}
		return jsonObject;
	}
	
	private String getAccessToken() {
		Map<String, Serializable> requestBodyMap = new HashMap<>();
		requestBodyMap.put("client_id", CLIENT_ID);
		requestBodyMap.put("client_secret", CLIENT_SECRET);
		requestBodyMap.put("grant_type", "client_credentials");
		requestBodyMap.put("scope", "https://graph.microsoft.com/.default");
		String postURL = MICROSOFT_TOKEN_URL.replace("${tenantId}", TENANT_ID);
		Map<String, String> headerMap = new HashMap<>(); 
		headerMap.put("Content-type", ContentType.APPLICATION_FORM_URLENCODED.toString());
		headerMap.put("Host", "login.microsoftonline.com");
		
		String response = httpRequestService.sendHTTPPostRequest(postURL, headerMap, getRequestBody(requestBodyMap), 
ContentType.APPLICATION_FORM_URLENCODED);
		return getEntityValueFromStringJson(response, "access_token");
	}
	
	private static String getRequestBody(Map<String, Serializable> map) {
		return map.toString().replace(StringPool.OPEN_CURLY_BRACE, StringPool.BLANK)
				.replace(StringPool.CLOSE_CURLY_BRACE, StringPool.BLANK)
				.replace(StringPool.COMMA + StringPool.SPACE, StringPool.AMPERSAND);
	}
	
	private String getEntityValueFromStringJson(String json, String entityName) {
		Gson gson = new Gson();
		JsonObject object = gson.fromJson(json, JsonObject.class);
		return object.get(entityName).toString();
	}
	
	private static final String CLIENT_ID = "b5ade99e-d2ef-4a7c-a9b0-7ad27xxxxx";
	private static final String CLIENT_SECRET = "q~e8Q~NvaLAqcbpNodOpirJz_-PnTDxxxxxx";
	private static final String TENANT_ID = "ea9b5a29-8a4b-4697-a846-475xxxxx";
	private static final String OBJECT_ID = "7d379439-6f76-43a9-895e-71xxxxxxx";
	private static final String MICROSOFT_TOKEN_URL = "https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token";
	private static final String MICROSOFT_CREATE_EVENT_URL = "https://graph.microsoft.com/v1.0/users/${objectId}/events";
	private static final Log log = LogFactoryUtil.getLog(MicrosoftTeamsServiceImpl.class);
}

				
			
  1. In above file please change the value of CLIENT_ID, CLIENT_SECRET, TENANT_ID, and OBJECT_ID with your data which we have stored while creating the microsoft account and application.
  2. Now, go to the “TeamsResourceImpl” file. And write the below code.
				
					// TeamsResourceImpl.java
package microsoft.teams.rest.internal.resource.v1_0;

import javax.validation.constraints.NotNull;
import javax.ws.rs.core.Response;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ServiceScope;

import com.ignek.microsoft.teams.MicrosoftTeamsService;
import com.ignek.microsoft.teams.model.MicrosoftTeamsResponse;

import microsoft.teams.rest.dto.v1_0.Status;
import microsoft.teams.rest.dto.v1_0.Teams;
import microsoft.teams.rest.resource.v1_0.TeamsResource;

/**
 * @author ignek
 */
@Component(properties = "OSGI-INF/liferay/rest/v1_0/teams.properties", scope = ServiceScope.PROTOTYPE, service = TeamsResource.class)
public class TeamsResourceImpl extends BaseTeamsResourceImpl {
	
	@Reference
	private MicrosoftTeamsService microsoftTeamsService;
	
	@Override
	public Teams updateMicrosoftTeamsLink(Teams teams) throws Exception {
		
		String eventId = teams.getEventId();
		String title = teams.getTitle();
		String description = teams.getDescription();
		String location = teams.getLocation();
		String setDate = teams.getSetDate();
		String endDate = teams.getEndDate();
		String timeZone = teams.getTimeZone();
		String[] emailAddresses = teams.getEmailAddress();
		
		MicrosoftTeamsResponse microsoftTeamsResponse = microsoftTeamsService.updateMicrosoftTeamsEvent(eventId, title, location, 
emailAddresses, description, setDate, endDate, timeZone);
		String teamsLink = microsoftTeamsResponse.getLink();
		eventId = microsoftTeamsResponse.getEventId();
		
		Status status = new Status();
		status.setStatusCode(microsoftTeamsResponse.getStatus());
		status.setStatusMessage(microsoftTeamsResponse.getMessage());
		teams.setStatus(status);
		teams.setEventId(eventId);
		teams.setTeamsLink(teamsLink);
		
		return teams;
	}
	
	@Override
	public Teams getMicrosoftTeamsLink(@NotNull String eventId) throws Exception {
		Teams teams = new Teams();
		String teamsLink = microsoftTeamsService.getMicrosoftTeamsLink(eventId);
		teams.setTeamsLink(teamsLink);
		teams.setEventId(eventId);
		
		return teams;
	}
	
	@Override
	public Teams deleteMicrosoftTeamsLink(@NotNull String eventId) throws Exception {
		Teams teams = new Teams();
		Status status = new Status();
		try {
			microsoftTeamsService.deleteMicrosoftTeamsEvent(eventId);
			status.setStatusCode(Response.Status.OK.getStatusCode());
			status.setStatusMessage("Deleted Successfully");
		} catch (Exception e) {
			status.setStatusCode(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
			status.setStatusMessage(e.getMessage());
		}
		teams.setStatus(status);
		
		return teams;
	}
	
}

				
			
  1. Now, deploy the rest module and you can test the above rest-apis using graphQL.
  2. Here, you can find graphQL for adding or updating Microsoft events. For adding an event you have to pass “eventId” as blank and for updating an event you have to pass the eventId of that event.
				
					
mutation ($teams: InputTeams!) {
  updateMicrosoftTeamsLink(teams: $teams) {
    eventId
    teamsLink
    status {
      statusCode
      statusMessage
    }
  }
}

/* Query Variables */

{
  "teams": {
    "title": "My first teams link",
    "description": "test microsoft teams link",
    "emailAddress": [
      "test@yopmail.com",
      "test1@yopmail.com"
    ],
    "setDate": "2023-05-16 13:15",
    "endDate": "2023-05-16 14:15",
    "eventId": "",
    "location": "my house",
    "timeZone": "Pacific Standard Time"
  }
}

				
			
GraphQL for Microsoft events management
  1. Here, you can find graphQL for getting Microsoft event and teams link.
				
					
{
  microsoftTeamsLink(eventId: "") {
    teamsLink
    eventId
  }
}
				
			
GraphQL for Access Microsoft event and Teams links
  1. Here, you can find graphQL for deleting Microsoft events.
				
					
mutation {
  deleteMicrosoftTeamsLink(eventId: "") {
    status {
      statusCode
      statusMessage
    }
  }
}
				
			
GraphQL for deleting Microsoft events

Note*: Microsoft APIs return many parameters in their responses. As an eventId, we are taking “id” and as a team link, we are taking “joinUrl”.

Here is an example response:

				
					
{
    "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('cd209b0b-3f83-4c35-82d2-d88a61820480')/events/$entity",
    "@odata.etag":"W/\"ZlnW4RIAV06KYYwlrfNZvQAALfZeRQ==\"",
    "id":"AAMkAGI1AAAt8AHjAAA=",
    "createdDateTime":"2017-04-15T03:00:50.7579581Z",
    "lastModifiedDateTime":"2017-04-15T03:00:51.245372Z",
    "changeKey":"ZlnW4RIAV06KYYwlrfNZvQAALfZeRQ==",
    "categories":[
    ],
    "originalStartTimeZone":"Pacific Standard Time",
    "originalEndTimeZone":"Pacific Standard Time",
    "iCalUId":"040000008200E00074C5B7101A82E00800000000DA2B357D94B5D201000000000000000010000000EC4597557F0CB34EA4CC2887EA7B17C3",
    "reminderMinutesBeforeStart":15,
    "isReminderOn":true,
    "hasAttachments":false,
    "hideAttendees": false,
    "subject":"Let's go brunch",
    "bodyPreview":"Does noon work for you?",
    "importance":"normal",
    "sensitivity":"normal",
    "isAllDay":false,
    "isCancelled":false,
    "isDraft": false,
    "isOrganizer":true,
    "responseRequested":true,
    "seriesMasterId":null,
    "showAs":"busy",
    "type":"singleInstance",
    "webLink":"https://outlook.office365.com/owa/?itemid=AAMkAGI1AAAt9AHjAAA%3D&exvsurl=1&path=/calendar/item",
    "onlineMeetingUrl":null,
    "isOnlineMeeting": true,
    "onlineMeetingProvider": "teamsForBusiness",
    "allowNewTimeProposals": true,
    "responseStatus":{
        "response":"organizer",
        "time":"0001-01-01T00:00:00Z"
    },
    "body":{
        "contentType":"html",
        "content":"Does late morning work for you?"
    },
    "start":{
        "dateTime":"2017-04-15T11:00:00.0000000",
        "timeZone":"Pacific Standard Time"
    },
    "end":{
        "dateTime":"2017-04-15T12:00:00.0000000",
        "timeZone":"Pacific Standard Time"
    },
    "location": {
        "displayName": "Harry's Bar",
        "locationType": "default",
        "uniqueId": "Harry's Bar",
        "uniqueIdType": "private"
    },
    "locations": [
        {
            "displayName": "Harry's Bar",
            "locationType": "default",
            "uniqueIdType": "unknown"
        }
    ],
    "recurrence":null,
    "attendees":[
        {
            "type":"required",
            "status":{
                "response":"none",
                "time":"0001-01-01T00:00:00Z"
            },
            "emailAddress":{
                "name":"Samantha Booth",
                "address":"samanthab@contoso.onmicrosoft.com"
            }
        }
    ],
    "organizer":{
        "emailAddress":{
            "name":"Dana Swope",
            "address":"danas@contoso.onmicrosoft.com"
        }
    },
    "onlineMeeting": {
        "joinUrl": "https://teams.microsoft.com/l/meetup-join/19%3ameeting_NzIyNzhlMGEtM2YyZC00ZmY0LTlhNzUtZmZjNWFmZGNlNzE2%40thread.v2/0?
context=%7b%22Tid%22%3a%2272f988bf-86f1-41af-91ab-2d7cd011db47%22%2c%22Oid%22%3a%22bc55b173-cff6-457d-b7a1-64bda7d7581a%22%7d"
    }
}

				
			

Explore Our Services

Discover how we can help your business thrive, whether you’re running a small startup, an SME, or a large enterprise. We’re here to understand your unique needs and goals, offering the expertise and resources to support your journey to success.

Stay informed about our Liferay services and updates by subscribing to our newsletter—just fill in the details below to subscribe.

Loading
Loading...

Related Blogs

July 27, 2022
Liferay Integration with Google Drive
Liferay Integration with Google Drive
August 1, 2023
Mail Configuration in Liferay with Gmail’s increased security-Cover Image
Mail Configuration in Liferay with Gmail’s increased security
July 10, 2023
Google Meet integration with Liferay Cover Image
Google Meet integration with Liferay
Loading...

Featured Projects Portfolios

October 3, 2023
Simplify Approvals and Goals With Agenda & Meeting SaaS Platform
Simplify Approvals and Goals With Agenda & Meeting SaaS Platform

Digital Solutions for Your Business with IGNEK

4.9

5.0

5.0

5.0

LOGO

Making the world a better place through constructing elegant hierarchies

COMPANY

  • About
  • Career
  • Case Study
  • Blogs

SERVICES

  • Enterprise Portal Development
  • Dedicated Development Team
  • Back-end Development
  • Front-end Development
  • Digital Transformation
  • SaaS Development

HIRE US

  • Liferay
  • Spring Boot
  • ReactJS
  • Healthcare
  • MERN Stack
  • AEM

CONTACT

  • info@ignek.com
  • info@ignek.com
SALES
  • sales@ignek.com
  • (+91) 635 157 6580
CAREER
  • hr@ignek.com
  • (+91) 932 849 5160
  • E 910-912, Ganesh Glory 11, Jagatpur Road, SG Highway, Ahmedabad, Gujarat - 382470

© 2018-2025 IGNEK, Inc. All rights reserved

Linkedin Facebook X-twitter Instagram