-
Notifications
You must be signed in to change notification settings - Fork 138
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
29 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -313,7 +313,7 @@ export async function markdownifyPdf( | |
|
||
function parseTeamsChannelUrl(url: string) { | ||
const m = | ||
/^https:\/\/teams.microsoft.com\/*.\/channel\/(?<channelId>.+)\/.*\?groupId=(?<teamId>([a-z0-9\-])+)$/.exec( | ||
/^https:\/\/teams.microsoft.com\/[^\/]{1,32}\/channel\/(?<channelId>.+)\/.*\?groupId=(?<teamId>([a-z0-9\-])+)$/.exec( | ||
url | ||
) | ||
Check failure Code scanning / CodeQL Polynomial regular expression used on uncontrolled data High
This
regular expression Error loading related location Loading library input Error loading related location Loading |
||
if (!m) throw new Error("Invalid Teams channel URL") | ||
|
@@ -323,7 +323,7 @@ function parseTeamsChannelUrl(url: string) { | |
|
||
let _azureToken: string | ||
async function azureGetToken(): Promise<string> { | ||
if (!_azureToken) { // TODO: refresh? | ||
if (!_azureToken) { | ||
const { DefaultAzureCredential } = await import("@azure/identity") | ||
const credential = new DefaultAzureCredential() | ||
const tokenResponse = await credential.getToken( | ||
|
@@ -349,22 +349,36 @@ export interface MicrosoftTeamsEntity { | |
*/ | ||
export async function microsoftTeamsUploadFile( | ||
channelUrl: string, | ||
folder: string, | ||
filename: string | ||
) { | ||
const { teamId, channelId } = parseTeamsChannelUrl(channelUrl) | ||
const token = await azureGetToken() | ||
const Authorization = `Bearer ${token}` | ||
|
||
const channelInfoUrl = `https://graph.microsoft.com/v1.0/teams/${teamId}/channels/${channelId}` | ||
const channelInfoRes = await fetch(channelInfoUrl, { | ||
headers: { | ||
Authorization, | ||
}, | ||
}) | ||
if (!channelInfoRes.ok) { | ||
throw new Error( | ||
`Failed to get channel info: ${channelInfoRes.status} ${channelInfoRes.statusText}` | ||
) | ||
} | ||
const channelInfo = await channelInfoRes.json() | ||
console.log(channelInfo) | ||
const folder = channelInfo.displayName | ||
|
||
// resolve channel folder name | ||
const file = await readFile(filename) | ||
const folder = "folder" | ||
const url = `https://graph.microsoft.com/v1.0/groups/${teamId}/drive/root:/${folder}/${path.basename( | ||
filename | ||
)}:/content` | ||
const res = await fetch(url, { | ||
method: "PUT", | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
Authorization, | ||
"Content-Type": "application/octet-stream", | ||
}, | ||
body: file, | ||
|
@@ -378,7 +392,7 @@ export async function microsoftTeamsUploadFile( | |
const j = (await res.json()) as MicrosoftTeamsEntity | ||
return j | ||
} | ||
|
||
/* | ||
export async function teamsPostMessage( | ||
channelUrl: string, | ||
subject: string, | ||
|
@@ -398,7 +412,10 @@ export async function teamsPostMessage( | |
if (videoFilename) { | ||
console.debug(`Uploading video ${videoFilename}...`) | ||
const videoRes = await microsoftTeamsUploadFile(channelUrl, videoFilename) | ||
const videoRes = await microsoftTeamsUploadFile( | ||
channelUrl, | ||
videoFilename | ||
) | ||
console.log(videoRes) | ||
const guid = crypto.randomUUID() | ||
body.body.content += "\n" + `<attachment id=\"${guid}\"></attachment>` | ||
|
@@ -440,14 +457,4 @@ export async function teamsPostMessage( | |
} | ||
} | ||
const segments = await workspace.readJSON(env.files[0]) | ||
for (const segment of segments) { | ||
const { id, summary, video } = segment | ||
|
||
const lines = summary.split(/\n/g) | ||
const subject = lines[0] | ||
const message = lines.slice(1).join("\n<br/>").trim() | ||
|
||
console.log(`Uploading ${id} to Teams...`) | ||
await teamsPostMessage(subject, message, video) | ||
} | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,5 @@ | ||
import { DefaultAzureCredential } from "@azure/identity" | ||
import { microsoftTeamsUploadFile } from "genaiscript/runtime" | ||
|
||
const { teamId, channelId } = | ||
/^https:\/\/teams.microsoft.com\/*.\/channel\/(?<channelId>.+)\/.*\?groupId=(?<teamId>([a-z0-9\-])+)$/.exec( | ||
env.vars.link | ||
).groups | ||
const message = "Hello from GenAIScript!" | ||
|
||
// Function to get Microsoft Graph API token using Managed Identity | ||
async function getToken(): Promise<string> { | ||
const credential = new DefaultAzureCredential() | ||
const tokenResponse = await credential.getToken( | ||
"https://graph.microsoft.com/.default" | ||
) | ||
if (!tokenResponse) { | ||
throw new Error("Failed to retrieve access token.") | ||
} | ||
return tokenResponse.token | ||
} | ||
|
||
// Function to read messages from a Teams channel | ||
async function readMessages( | ||
token: string, | ||
teamId: string, | ||
channelId: string | ||
): Promise<any> { | ||
const url = `https://graph.microsoft.com/v1.0/teams/${teamId}/channels/${channelId}/messages` | ||
const headers = { | ||
Authorization: `Bearer ${token}`, | ||
} | ||
|
||
try { | ||
const response = await fetch(url, { | ||
method: "GET", | ||
headers: headers, | ||
}) | ||
|
||
if (!response.ok) { | ||
throw new Error( | ||
`Failed to read messages: ${response.status} ${response.statusText}` | ||
) | ||
} | ||
|
||
const data = await response.json() | ||
console.log("Messages retrieved successfully:", data) | ||
return data | ||
} catch (error) { | ||
console.error("Error reading messages:", error) | ||
return undefined | ||
} | ||
} | ||
|
||
// Function to post a message in a Teams channel | ||
async function postMessage( | ||
token: string, | ||
teamId: string, | ||
channelId: string, | ||
message: string | ||
): Promise<void> { | ||
const url = `https://graph.microsoft.com/v1.0/teams/${teamId}/channels/${channelId}/messages` | ||
const headers = { | ||
Authorization: `Bearer ${token}`, | ||
"Content-Type": "application/json", | ||
} | ||
const body = JSON.stringify({ | ||
body: { | ||
content: message, | ||
}, | ||
}) | ||
|
||
try { | ||
const response = await fetch(url, { | ||
method: "POST", | ||
headers: headers, | ||
body: body, | ||
}) | ||
|
||
if (!response.ok) { | ||
throw new Error( | ||
`Failed to post message: ${response.status} ${response.statusText}` | ||
) | ||
} | ||
|
||
const data = await response.json() | ||
console.log("Message posted successfully:", data) | ||
} catch (error) { | ||
console.error("Error posting message:", error) | ||
} | ||
} | ||
|
||
const token = await getToken() | ||
|
||
const msgs = await readMessages(token, teamId, channelId) | ||
console.log(msgs) | ||
await postMessage(token, teamId, channelId, message) | ||
const teams = | ||
"https://teams.microsoft.com/l/channel/19%3Ac9392f56d1e940b5bed9abe766832aeb%40thread.tacv2/Test?groupId=5d76383e-5d3a-4b63-b36a-62f01cff2806" | ||
await microsoftTeamsUploadFile(teams, "src/rag/markdown.md") |