Skip to content

Commit a5f0bda

Browse files
committed
fix(auth): address PR feedback
1 parent c31f872 commit a5f0bda

6 files changed

Lines changed: 184 additions & 127 deletions

File tree

examples/node-auth/index.js

Lines changed: 0 additions & 110 deletions
This file was deleted.

examples/node-live-token/index.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
const { createClient, LiveTranscriptionEvents } = require("../../dist/main/index");
2+
const fetch = require("cross-fetch");
3+
4+
const live = async () => {
5+
console.log("transcribing url with auth factory");
6+
7+
const authFactory = async () => {
8+
const deepgramTokenClient = createClient(process.env.DEEPGRAM_API_KEY);
9+
10+
const { result: tokenResult, error: tokenError } = await deepgramTokenClient.auth.grantToken();
11+
12+
if (tokenError) console.error(tokenError);
13+
if (!tokenError) return tokenResult.access_token;
14+
};
15+
16+
const deepgramClient = createClient({ accessToken: authFactory });
17+
18+
const url = "http://stream.live.vc.bbcmedia.co.uk/bbc_world_service";
19+
20+
// We will collect the is_final=true messages here so we can use them when the person finishes speaking
21+
let is_finals = [];
22+
23+
const connection = deepgramClient.listen.live({
24+
model: "nova-3",
25+
language: "en-US",
26+
// Apply smart formatting to the output
27+
smart_format: true,
28+
// To get UtteranceEnd, the following must be set:
29+
interim_results: true,
30+
utterance_end_ms: 1000,
31+
vad_events: true,
32+
// Time in milliseconds of silence to wait for before finalizing speech
33+
endpointing: 300,
34+
// Keyterm Prompting allows you improve Keyword Recall Rate (KRR) for important keyterms or phrases up to 90%.
35+
keyterm: ["BBC"],
36+
});
37+
38+
connection.on(LiveTranscriptionEvents.Open, () => {
39+
connection.on(LiveTranscriptionEvents.Close, () => {
40+
console.log("Connection closed.");
41+
});
42+
43+
connection.on(LiveTranscriptionEvents.Metadata, (data) => {
44+
console.log(`Deepgram Metadata: ${data}`);
45+
});
46+
47+
connection.on(LiveTranscriptionEvents.Transcript, (data) => {
48+
const sentence = data.channel.alternatives[0].transcript;
49+
50+
// Ignore empty transcripts
51+
if (sentence.length == 0) {
52+
return;
53+
}
54+
if (data.is_final) {
55+
// We need to collect these and concatenate them together when we get a speech_final=true
56+
// See docs: https://developers.deepgram.com/docs/understand-endpointing-interim-results
57+
is_finals.push(sentence);
58+
59+
// Speech final means we have detected sufficent silence to consider this end of speech
60+
// Speech final is the lowest latency result as it triggers as soon an the endpointing value has triggered
61+
if (data.speech_final) {
62+
const utterance = is_finals.join(" ");
63+
console.log(`Speech Final: ${utterance}`);
64+
is_finals = [];
65+
} else {
66+
// These are useful if you need real time captioning and update what the Interim Results produced
67+
console.log(`Is Final: ${sentence}`);
68+
}
69+
} else {
70+
// These are useful if you need real time captioning of what is being spoken
71+
console.log(`Interim Results: ${sentence}`);
72+
}
73+
});
74+
75+
connection.on(LiveTranscriptionEvents.UtteranceEnd, (_data) => {
76+
const utterance = is_finals.join(" ");
77+
console.log(`Deepgram UtteranceEnd: ${utterance}`);
78+
is_finals = [];
79+
});
80+
81+
connection.on(LiveTranscriptionEvents.SpeechStarted, (_data) => {
82+
// console.log("Deepgram SpeechStarted");
83+
});
84+
85+
connection.on(LiveTranscriptionEvents.Error, (err) => {
86+
console.error(err);
87+
});
88+
89+
fetch(url)
90+
.then((r) => r.body)
91+
.then((res) => {
92+
res.on("readable", () => {
93+
connection.send(res.read());
94+
});
95+
});
96+
});
97+
};
98+
99+
live();

examples/node-prerecorded/index.js

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,62 @@ const { createClient } = require("../../dist/main/index");
22
const fs = require("fs");
33
const path = require("path");
44

5+
const transcribeUrlAuthWithFactory = async () => {
6+
console.log("transcribing url with auth factory");
7+
8+
const authFactory = async () => {
9+
const deepgramTokenClient = createClient(process.env.DEEPGRAM_API_KEY);
10+
11+
const { result: tokenResult, error: tokenError } = await deepgramTokenClient.auth.grantToken();
12+
13+
if (tokenError) console.error(tokenError);
14+
if (!tokenError) return tokenResult.access_token;
15+
};
16+
17+
const deepgramClient = createClient({ accessToken: authFactory });
18+
19+
console.log("Transcribing URL", "https://dpgr.am/spacewalk.wav");
20+
const { result, error } = await deepgramClient.listen.prerecorded.transcribeUrl(
21+
{
22+
url: "https://dpgr.am/spacewalk.wav",
23+
},
24+
{
25+
model: "nova-3",
26+
}
27+
);
28+
29+
if (error) console.error(error);
30+
if (!error) console.dir(result, { depth: 1 });
31+
};
32+
33+
const transcribeUrlWithAccessToken = async () => {
34+
console.log("transcribing url with access token");
35+
36+
const deepgramTokenClient = createClient(process.env.DEEPGRAM_API_KEY);
37+
38+
const { result: tokenResult, error: tokenError } = await deepgramTokenClient.auth.grantToken();
39+
40+
if (tokenError) console.error(tokenError);
41+
42+
const deepgramClient = createClient({ accessToken: tokenResult.access_token });
43+
44+
console.log("Transcribing URL", "https://dpgr.am/spacewalk.wav");
45+
const { result, error } = await deepgramClient.listen.prerecorded.transcribeUrl(
46+
{
47+
url: "https://dpgr.am/spacewalk.wav",
48+
},
49+
{
50+
model: "nova-3",
51+
}
52+
);
53+
54+
if (error) console.error(error);
55+
if (!error) console.dir(result, { depth: 1 });
56+
};
57+
558
const transcribeUrl = async () => {
59+
console.log("transcribing url with api key");
60+
661
const deepgram = createClient(process.env.DEEPGRAM_API_KEY);
762

863
console.log("Transcribing URL", "https://dpgr.am/spacewalk.wav");
@@ -12,7 +67,6 @@ const transcribeUrl = async () => {
1267
},
1368
{
1469
model: "nova-3",
15-
keyterm: ["spacewalk"],
1670
}
1771
);
1872

@@ -21,6 +75,8 @@ const transcribeUrl = async () => {
2175
};
2276

2377
const transcribeFile = async () => {
78+
console.log("transcribing file with api key");
79+
2480
const deepgram = createClient(process.env.DEEPGRAM_API_KEY);
2581

2682
const filePath = path.join(__dirname, "../spacewalk.wav");
@@ -30,12 +86,15 @@ const transcribeFile = async () => {
3086
console.log("Transcribing file", file);
3187
const { result, error } = await deepgram.listen.prerecorded.transcribeFile(file, {
3288
model: "nova-3",
33-
keyterm: ["spacewalk"],
3489
});
3590

3691
if (error) console.error(error);
3792
if (!error) console.dir(result, { depth: 1 });
3893
};
3994

40-
transcribeUrl();
41-
transcribeFile();
95+
(async () => {
96+
await transcribeUrl();
97+
await transcribeFile();
98+
await transcribeUrlAuthWithFactory();
99+
await transcribeUrlWithAccessToken();
100+
})();

src/lib/types/DeepgramClientOptions.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ interface ITransport<C, O> {
2424
}
2525

2626
export type DefaultNamespaceOptions = {
27-
key?: string;
27+
key?: string | IKeyFactory;
28+
accessToken?: string | IKeyFactory;
2829
fetch: {
2930
options: { url: TransportUrl };
3031
};
@@ -34,7 +35,8 @@ export type DefaultNamespaceOptions = {
3435
} & NamespaceOptions;
3536

3637
export interface NamespaceOptions {
37-
key?: string;
38+
key?: string | IKeyFactory;
39+
accessToken?: string | IKeyFactory;
3840
fetch?: ITransport<IFetch, TransportFetchOptions>;
3941
websocket?: ITransport<IWebSocket, TransportWebSocketOptions>;
4042
}
@@ -58,7 +60,7 @@ export type DefaultClientOptions = {
5860
*/
5961
export interface DeepgramClientOptions {
6062
key?: string | IKeyFactory;
61-
accessToken?: string;
63+
accessToken?: string | IKeyFactory;
6264
global?: NamespaceOptions & { url?: string; headers?: { [index: string]: any } };
6365
listen?: NamespaceOptions;
6466
manage?: NamespaceOptions;

src/packages/AbstractClient.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,28 @@ export abstract class AbstractClient extends EventEmitter {
4444
constructor(options: DeepgramClientOptions) {
4545
super();
4646

47-
if (options.accessToken) {
47+
// run the factory for the access token if it's a function
48+
if (typeof options.accessToken === "function") {
49+
this.factory = options.accessToken;
50+
this.accessToken = this.factory();
51+
} else {
4852
this.accessToken = options.accessToken;
4953
}
5054

55+
// run the factory for the key if it's a function
5156
if (typeof options.key === "function") {
5257
this.factory = options.key;
5358
this.key = this.factory();
5459
} else {
5560
this.key = options.key;
5661
}
5762

58-
if (!this.key) {
63+
// if we still have neither, try to use the DEEPGRAM_API_KEY environment variable
64+
if (!this.key && !this.accessToken) {
5965
this.key = process.env.DEEPGRAM_API_KEY as string;
6066
}
6167

68+
// if we STILL have neither, throw an error
6269
if (!this.key && !this.accessToken) {
6370
throw new DeepgramError("A deepgram API key or temporary auth token is required.");
6471
}

0 commit comments

Comments
 (0)